---
title: "Spring Boot and PostgreSQL on One VM with Observability and Backup"
description: "Validated Rehost architecture for a Spring Boot JAR and self-managed PostgreSQL on one STACKIT VM with restricted ingress, Observability, and Server Backup."
sidebar:
  badge:
    text: "STACKIT"
    variant: success
scfAsset:
  managed: false
  category: 'blueprint'
  external: false
  tags: ["design-and-mobilize", "design", "target-architecture", "rehost", "spring-boot", "vm", "postgresql", "observability", "backup"]
  maintainers:
    - user: "lukas.weberruss"
      role: true
      website: true
source_url: "https://framework.stackit.cloud/migration/assetcontainer/stackit/architecture-spring-boot-vm-load-balancer-monitoring-backup/"
source_file: "docs/migration/assetcontainer/stackit/architecture-spring-boot-vm-load-balancer-monitoring-backup.mdx"
---

## Overview

This pattern represents the validated low-change target for the Spring Boot Rehost example. The JAR
continues to run as a `systemd` service, while PostgreSQL remains self-managed on the same VM. The
runtime and database operating models therefore stay VM-centric.

The baseline is intentionally one VM. It demonstrates repeatable migration controls and operations
readiness, not application or database high availability.

## Typical use case

- **Low change tolerance**: business behavior must remain stable during migration.
- **Short migration windows**: runtime relocation should be predictable and repeatable.
- **Operations continuity**: teams keep VM-centric operating procedures while moving to STACKIT.

## Architecture diagram

```d2
vars: {
  d2-config: {
    pad: 32
  }
}

style.font-size: 22

direction: right

Internet: "Internet" {
  icon: ../../../../../../public/stackit-icons/networking/ip.svg
}

VMProject: "Application Project" {
  PublicIP: "Public IP"
  VM: "Ubuntu VM" {
    icon: ../../../../../../public/stackit-icons/computing/virtual-machine.svg
    link: https://docs.stackit.cloud/products/compute-engine/server/
    App: "Spring Boot JAR + systemd"
    DB: "Self-managed PostgreSQL"
    Exporter: "Node exporter"
  }
  Obs: "Observability" {
    icon: ../../../../../../public/stackit-icons/logging-monitoring/observability.svg
    link: https://docs.stackit.cloud/products/logging-and-monitoring/observability/
  }
  BackupArchive: "Backup Archive" {
    icon: ../../../../../../public/stackit-icons/computing/archive.svg
    link: https://docs.stackit.cloud/products/compute-engine/server-backup-management/
  }
}

Internet -> VMProject.PublicIP: "restricted HTTP/SSH"
VMProject.PublicIP -> VMProject.VM.App
VMProject.VM.App -> VMProject.VM.DB: "localhost SQL"
VMProject.Obs -> VMProject.VM.Exporter: "restricted scrape"
VMProject.VM -> VMProject.BackupArchive: "boot-volume backup"
```

## Design best practices

- **Restrict ingress explicitly**: allow SSH and application traffic only from approved source CIDRs;
  allow exporter traffic only from STACKIT service ranges.
- **Keep credentials out of state and inventory**: pass the PostgreSQL password through the process
  environment and store the generated runtime environment file as root-only.
- **Define observability minimum set**: include infrastructure and application health metrics before go-live.
- **Separate recovery layers**: use the database pre-restore dump for cutover rollback and Server Backup
  for VM-level disaster recovery.
- **State the availability boundary**: one VM with a local database has a shared failure domain. Add a
  load balancer or second node only with a separately designed database and consistency model.
- **Use explicit security groups and ingress rules**: expose only required ports and protocols.

Confirm which volumes the backup policy covers and rehearse recovery independently of cutover
rollback. The available server-backup features do not by themselves prove PostgreSQL consistency
or the application's recovery objectives.

> From the STACKIT docs: [Features and benefits › Features](https://docs.stackit.cloud/products/compute-engine/server-backup-management/basics/features-and-benefits/#features) (Source updated 13.11.2025, copied 06.10.2026)

- Automated, monitored server backups with easy recovery
- Create backups for one, multiple, or all volumes connected to a server at any time
- The advanced custom backup schedules enable automated backups to be created
- Freely select the retention period after which backups are automatically deleted
- Partly restore certain files by seamlessly restoring a volume backup to a new volume

## Related migration assets

- <LinkChip href="/migration/assetcontainer/stackit/rehost-automation-spring-boot-terraform-ansible/">Runbook Asset: Rehost Spring Boot with Terraform/OpenTofu and Ansible</LinkChip>

## Repository usage and required settings

<LinkCard
  title="STACKIT CMF Rehost Spring Boot repository"
  href="https://github.com/stackitcloud/stackit-cmf-rehost-springboot"
/>

1. Copy the example file: `cp env.tfvars.example env.tfvars`
2. Set required values:

```hcl
create_project             = true
target_project_name        = "cmf-rehost-springboot"
target_project_owner_email = "owner@sa.stackit.cloud"
parent_container_id        = "cmf-parent-container-id"
service_account_key_path   = "/path/to/stackit-sa-key.json"

run_ansible                = true
jar_local_path             = "ansible/files/springboot-app.jar"
availability_zone          = "eu01-1"
machine_type               = "g2i.2"
ssh_allowed_cidr           = "203.0.113.10/32"
app_allowed_cidr           = "203.0.113.10/32"
enable_observability       = true
enable_node_exporter       = true
enable_local_postgresql    = true
enable_server_backup       = true
```

3. Optional CMF feature wrapper (`flags.env`):

```dotenv
setup_project=true
setup_observability=true
setup_database=false
setup_workload=true
setup_loadgen=false
setup_dns=false
```

4. Apply:

```bash
terraform init
terraform apply -var-file=env.tfvars
```

Expected result: `application_url` serves the Spring Boot app directly from the VM on the configured
application port. PostgreSQL listens for the application on localhost, Observability scrapes node
exporter, and the boot volume has an enabled daily backup schedule.

## Availability boundary and extensions

This baseline has no automatic failover. A load-balancer or multi-VM variant is useful only after
application session handling, PostgreSQL placement, write consistency, health checks, TLS, and traffic
switching have been designed and tested together. Treat that as a separate architecture decision, not
as an implicit property of this Rehost path.
