version: '3.8' services: api: build: context: . dockerfile: apps/api/Dockerfile.prod env_file: - .env.production environment: - NODE_ENV=production expose: - "3000" depends_on: db: condition: service_healthy redis: condition: service_healthy networks: - gridpilot-network restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 1G reservations: cpus: '0.5' memory: 512M healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" website: build: context: . dockerfile: apps/website/Dockerfile.prod env_file: - .env.production environment: - NODE_ENV=production - NEXT_TELEMETRY_DISABLED=1 expose: - "3000" depends_on: redis: condition: service_healthy networks: - gridpilot-network restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 1G reservations: cpus: '0.5' memory: 512M healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" db: image: postgres:15-alpine restart: unless-stopped environment: - POSTGRES_DB=${POSTGRES_DB:-gridpilot_db} - POSTGRES_USER=${POSTGRES_USER:-user} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password} - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C command: > postgres -c shared_buffers=256MB -c max_connections=200 -c effective_cache_size=1GB -c maintenance_work_mem=64MB -c checkpoint_completion_target=0.9 -c wal_buffers=16MB -c default_statistics_target=100 -c random_page_cost=1.1 -c effective_io_concurrency=200 -c work_mem=2621kB -c min_wal_size=1GB -c max_wal_size=4GB expose: - "5432" volumes: - prod_db_data:/var/lib/postgresql/data - ./backups:/backups networks: - gridpilot-network deploy: resources: limits: cpus: '1' memory: 2G reservations: cpus: '0.5' memory: 512M healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-user} -d ${POSTGRES_DB:-gridpilot_db}"] interval: 10s timeout: 5s retries: 5 logging: driver: "json-file" options: max-size: "10m" max-file: "3" redis: image: redis:7-alpine restart: unless-stopped command: > redis-server --maxmemory 512mb --maxmemory-policy allkeys-lru --save 60 1000 --appendonly yes --appendfsync everysec --requirepass ${REDIS_PASSWORD:-CHANGE_ME_IN_PRODUCTION} expose: - "6379" volumes: - prod_redis_data:/data networks: - gridpilot-network deploy: resources: limits: cpus: '0.5' memory: 768M reservations: cpus: '0.25' memory: 256M healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 logging: driver: "json-file" options: max-size: "5m" max-file: "2" nginx: image: nginx:stable-alpine ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/ssl:/etc/nginx/ssl:ro - nginx_cache:/var/cache/nginx depends_on: - api - website networks: - gridpilot-network restart: unless-stopped deploy: resources: limits: cpus: '0.5' memory: 256M reservations: cpus: '0.25' memory: 128M healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost/health"] interval: 30s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: gridpilot-network: driver: bridge volumes: prod_db_data: prod_redis_data: nginx_cache: