name: budget-capex services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: budget POSTGRES_USER: budget POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env} TZ: ${TZ:-Europe/Lisbon} volumes: - db-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U budget -d budget"] interval: 10s timeout: 5s retries: 10 api: build: ./backend image: budget-capex-api:latest restart: unless-stopped depends_on: db: condition: service_healthy backup: condition: service_healthy environment: DATABASE_URL: postgresql+psycopg://budget:${POSTGRES_PASSWORD}@db:5432/budget SECRET_KEY: ${SECRET_KEY:?set SECRET_KEY in .env} ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@example.com} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?set ADMIN_PASSWORD in .env} ADMIN_NAME: ${ADMIN_NAME:-Administrator} DEFAULT_LANGUAGE: ${DEFAULT_LANGUAGE:-pt} COOKIE_SECURE: ${COOKIE_SECURE:-false} SESSION_HOURS: ${SESSION_HOURS:-12} TZ: ${TZ:-Europe/Lisbon} volumes: # the api asks the backup container for a fresh backup here before every database upgrade - backup-requests:/requests web: build: ./frontend image: budget-capex-web:latest restart: unless-stopped depends_on: - api environment: SITE_ADDRESS: ${SITE_ADDRESS:-:80} ports: - "${HTTP_PORT:-8080}:80" - "${HTTPS_PORT:-8443}:443" volumes: - caddy-data:/data backup: image: postgres:16-alpine restart: unless-stopped depends_on: db: condition: service_healthy entrypoint: ["/bin/sh", "/scripts/backup.sh"] healthcheck: test: ["CMD", "test", "-f", "/tmp/first-backup-done"] interval: 5s timeout: 3s retries: 120 environment: PGHOST: db PGUSER: budget PGDATABASE: budget PGPASSWORD: ${POSTGRES_PASSWORD} BACKUP_TIME: ${BACKUP_TIME:-02:30} BACKUP_KEEP_DAYS: ${BACKUP_KEEP_DAYS:-30} TZ: ${TZ:-Europe/Lisbon} volumes: - ./backup/backup.sh:/scripts/backup.sh:ro - ./backup/restore.sh:/usr/local/bin/restore.sh:ro - ${BACKUP_DIR:-./backups}:/backups - backup-requests:/requests volumes: db-data: caddy-data: backup-requests: