# Production deployment example. Development continues to run Java from the IDE. name: labtimesheet-prod services: app: image: "${LAB_IMAGE:?Set LAB_IMAGE to an immutable sha-* image tag}" restart: unless-stopped environment: SPRING_PROFILES_ACTIVE: prod LAB_DB_URL: "${LAB_DB_URL:?Set the JDBC PostgreSQL URL}" LAB_DB_USERNAME: "${LAB_DB_USERNAME:?Set the database username}" LAB_DB_PASSWORD: "${LAB_DB_PASSWORD:?Set the database password}" LAB_PUBLIC_ORIGIN: "${LAB_PUBLIC_ORIGIN:?Set the public HTTPS origin}" LAB_SECURITY_MASTER_KEY: "${LAB_SECURITY_MASTER_KEY:?Set a Base64 256-bit key}" LAB_FORWARD_HEADERS_STRATEGY: "${LAB_FORWARD_HEADERS_STRATEGY:?Set the explicit proxy strategy}" ports: # Bind locally by default; terminate HTTPS in a reverse proxy on the same host. - "${LAB_HTTP_BIND:-127.0.0.1}:${LAB_HTTP_PORT:-8080}:8080" depends_on: postgres: condition: service_healthy # External-database mode leaves the bundled-db profile disabled. required: false read_only: true tmpfs: - /tmp:size=64m,mode=1777 cap_drop: - ALL security_opt: - no-new-privileges:true stop_grace_period: 40s healthcheck: test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8080/actuator/health/readiness"] interval: 30s timeout: 5s start_period: 45s retries: 3 postgres: # Pinned PostgreSQL 18.4 multi-architecture image. image: postgres:18.4@sha256:a02db8cac496f15b094798a38254f14d6e00741f709360e5e00bb6668ea31636 profiles: ["bundled-db"] restart: unless-stopped environment: POSTGRES_DB: "${POSTGRES_DB:-labtimesheet}" POSTGRES_USER: "${POSTGRES_USER:-labtimesheet}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?Set the bundled PostgreSQL password}" volumes: # PostgreSQL 18 stores versioned data beneath this parent directory. - postgres_data:/var/lib/postgresql shm_size: 256mb security_opt: - no-new-privileges:true healthcheck: test: ["CMD-SHELL", "pg_isready -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""] interval: 10s timeout: 5s retries: 10 start_period: 10s volumes: # Container replacement keeps this volume. It is not a substitute for backups. postgres_data: