--- version: "3.8" x-postgres-env: &postgres-env POSTGRES_DB: ${POSTGRES_DB:-keila} POSTGRES_USER: ${POSTGRES_USER:-keila} services: app: environment: <<: *postgres-env # The entrypoint assembles DB_URL from these plus the postgres_password secret, because Keila accepts no discrete connection variables of its own. POSTGRES_HOST: ${STACK_NAME}_db secrets: - postgres_password db: # Keila's own compose sample pins nothing (postgres:alpine, currently 18) and its CI only tests 13, so this version is our choice rather than upstream's. 17 is well above the tested floor, is not the newest major upstream has never run, and matches the other recipes here so one pg_backup.sh covers them all. image: ${DB_DOCKER_IMAGE:-postgres}:${DB_DOCKER_VERSION:-17-alpine} # give Postgres time to shut down cleanly: the Swarm default (10s) force-kills it mid-shutdown on every redeploy, which wipes the cumulative stats (pg_stat_*) that autovacuum's triggers depend on stop_grace_period: 2m volumes: - db-data:/var/lib/postgresql/data networks: - internal environment: <<: *postgres-env POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password secrets: - postgres_password healthcheck: test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER -d $$POSTGRES_DB"] interval: 10s timeout: 5s retries: 5 deploy: labels: backupbot.backup: ${ENABLE_BACKUPS:-true} backupbot.backup.pre-hook: "/pg_backup.sh backup" backupbot.backup.volumes.db-data.path: "backup.sql" backupbot.restore.post-hook: '/pg_backup.sh restore' configs: - source: pg_backup target: /pg_backup.sh mode: 0555 volumes: db-data: configs: pg_backup: name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION:-v1} file: pg_backup.sh secrets: postgres_password: external: true name: ${STACK_NAME}_postgres_password_${SECRET_POSTGRES_PASSWORD_VERSION:-v1}