services: db: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD required} POSTGRES_DB: ${POSTGRES_DB:-availability} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 restart: unless-stopped backend: build: context: ./backend dockerfile: Dockerfile environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-availability} SYNC_DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-availability} SMTP_HOST: ${SMTP_HOST:-} SMTP_PORT: ${SMTP_PORT:-587} SMTP_USER: ${SMTP_USER:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-} ZULIP_SITE: ${ZULIP_SITE:-} ZULIP_EMAIL: ${ZULIP_EMAIL:-} ZULIP_API_KEY: ${ZULIP_API_KEY:-} ZULIP_STREAM: ${ZULIP_STREAM:-general} depends_on: db: condition: service_healthy restart: unless-stopped frontend: build: context: ./frontend dockerfile: Dockerfile.prod args: VITE_API_URL: ${VITE_API_URL:-} depends_on: - backend restart: unless-stopped expose: - '80' volumes: postgres_data: