services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-budget} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-budget} POSTGRES_DB: ${POSTGRES_DB:-budget_tracker} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-budget} -d ${POSTGRES_DB:-budget_tracker}"] interval: 10s timeout: 5s retries: 5 start_period: 10s backend: build: context: ./backend dockerfile: Dockerfile restart: unless-stopped environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-budget}:${POSTGRES_PASSWORD:-budget}@db:5432/${POSTGRES_DB:-budget_tracker} SECRET_KEY: ${SECRET_KEY:-change-me-in-production} ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-15} REFRESH_TOKEN_EXPIRE_DAYS: ${REFRESH_TOKEN_EXPIRE_DAYS:-7} CORS_ORIGINS: ${CORS_ORIGINS:-["http://localhost"]} DEBUG: "false" depends_on: db: condition: service_healthy healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health')\""] interval: 30s timeout: 10s retries: 3 start_period: 30s frontend: build: context: ./frontend dockerfile: Dockerfile restart: unless-stopped ports: - "${FRONTEND_PORT:-80}:80" depends_on: backend: condition: service_healthy volumes: pgdata: