# ========================================= # AngelaMos | 2026 # Production | compose.yml # ========================================= name: ${APP_NAME:-template} services: # Nginx + Frontend nginx: build: context: . dockerfile: infra/docker/frontend-builder.prod args: - VITE_API_URL=${VITE_API_URL:-/api} - VITE_APP_TITLE=${VITE_APP_TITLE:-My App} container_name: ${APP_NAME:-template}-nginx ports: - "${NGINX_HOST_PORT:-8420}:80" depends_on: backend: condition: service_healthy networks: - frontend - backend deploy: resources: limits: cpus: '1.0' memory: 256M reservations: cpus: '0.25' memory: 64M restart: unless-stopped # FastAPI backend backend: build: context: ./backend dockerfile: ../infra/docker/fastapi.prod container_name: ${APP_NAME:-template}-backend expose: - "8000" env_file: - .env environment: - ENVIRONMENT=production - DEBUG=false - RELOAD=false depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - backend deploy: resources: limits: cpus: '2.0' memory: 1G reservations: cpus: '0.5' memory: 256M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] interval: 30s timeout: 5s retries: 3 start_period: 40s restart: unless-stopped # PostgreSQL DB db: image: postgres:18-alpine container_name: ${APP_NAME:-template}-db ports: - "${POSTGRES_HOST_PORT:-3420}:5432" volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} - POSTGRES_DB=${POSTGRES_DB:-app_db} networks: - backend deploy: resources: limits: cpus: '1.0' memory: 512M reservations: cpus: '0.25' memory: 128M healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-app_db}"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped # Redis redis: image: redis:7-alpine container_name: ${APP_NAME:-template}-redis ports: - "${REDIS_HOST_PORT:-6420}:6379" volumes: - redis_data:/data command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}} networks: - backend deploy: resources: limits: cpus: '0.5' memory: 256M reservations: cpus: '0.1' memory: 64M healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped # Cloudflare Tunnel cloudflared: image: cloudflare/cloudflared:latest container_name: ${APP_NAME:-template}-tunnel command: tunnel run --token ${CLOUDFLARE_TUNNEL_TOKEN} networks: - backend depends_on: nginx: condition: service_started deploy: resources: limits: cpus: '0.5' memory: 128M reservations: cpus: '0.1' memory: 32M restart: unless-stopped networks: frontend: driver: bridge backend: driver: bridge volumes: postgres_data: redis_data: