# Maintenance services, layered on top of docker-compose.yml with a second -f. # # These are one-shot `run --rm` targets, never part of the running stack, which # is why docker-compose.yml alone is what the playbook passes to `up` via # stack_files. Bringing the stack up with both files would start them as # long-running services. services: backup: image: postgres:17-alpine profiles: ["maintenance"] depends_on: db: condition: service_healthy environment: PGPASSWORD: ${POSTGRES_PASSWORD:?set it in .env on the host} volumes: - ./backups:/backups entrypoint: - sh - -c - 'pg_dump -h db -U webapp webapp > /backups/webapp-$(date +%Y%m%dT%H%M%S).sql' networks: - backend migrate: build: context: ./app image: example/webapp:local profiles: ["maintenance"] depends_on: db: condition: service_healthy environment: DATABASE_URL: postgres://webapp:${POSTGRES_PASSWORD:?set it in .env on the host}@db:5432/webapp # Migrations must be safe to run twice: an update run can be repeated, and # the playbook does not track whether the last one finished. command: ["/app/migrate.sh"] networks: - backend