# DevPocket Server Production Docker Compose Configuration # Production environment with optimized settings version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: devpocket-postgres-prod restart: always environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8" volumes: - postgres_data:/var/lib/postgresql/data - ./backups:/backups networks: - devpocket-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 30s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Redis for caching and rate limiting redis: image: redis:7-alpine container_name: devpocket-redis-prod restart: always volumes: - redis_data:/data - ./config/redis-prod.conf:/usr/local/etc/redis/redis.conf:ro command: redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD} networks: - devpocket-network healthcheck: test: ["CMD", "redis-cli", "--pass", "${REDIS_PASSWORD}", "ping"] interval: 30s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "3" # DevPocket API Server (Multiple instances for load balancing) api: build: context: . dockerfile: Dockerfile restart: always environment: NODE_ENV: production PORT: 8000 DATABASE_URL: ${DATABASE_URL} REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 JWT_SECRET: ${JWT_SECRET} JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} RESEND_API_KEY: ${RESEND_API_KEY} FROM_EMAIL: ${FROM_EMAIL} FRONTEND_URL: ${FRONTEND_URL} BASE_URL: ${BASE_URL} CLUSTER_NAME: ${CLUSTER_NAME} # Rate limiting RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000} RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-100} AUTH_RATE_LIMIT_MAX_REQUESTS: ${AUTH_RATE_LIMIT_MAX_REQUESTS:-5} ENV_RATE_LIMIT_MAX_REQUESTS: ${ENV_RATE_LIMIT_MAX_REQUESTS:-10} # WebSocket configuration WS_HEARTBEAT_INTERVAL: ${WS_HEARTBEAT_INTERVAL:-30000} WS_MAX_CONNECTIONS_PER_USER: ${WS_MAX_CONNECTIONS_PER_USER:-10} # Environment limits FREE_PLAN_MAX_ENVIRONMENTS: ${FREE_PLAN_MAX_ENVIRONMENTS:-2} STARTER_PLAN_MAX_ENVIRONMENTS: ${STARTER_PLAN_MAX_ENVIRONMENTS:-5} PRO_PLAN_MAX_ENVIRONMENTS: ${PRO_PLAN_MAX_ENVIRONMENTS:-20} # Production settings DEBUG: false LOG_LEVEL: ${LOG_LEVEL:-info} volumes: - ./logs:/app/logs depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - devpocket-network healthcheck: test: ["CMD", "node", "./dist/scripts/healthcheck.js"] interval: 30s timeout: 10s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "5" deploy: replicas: 3 resources: limits: cpus: '1.0' memory: 1G reservations: cpus: '0.5' memory: 512M # Nginx Load Balancer and Reverse Proxy nginx: image: nginx:alpine container_name: devpocket-nginx-prod restart: always ports: - "80:80" - "443:443" volumes: - ./config/nginx-prod.conf:/etc/nginx/nginx.conf:ro - ./config/ssl:/etc/nginx/ssl:ro - ./logs/nginx:/var/log/nginx - /var/run/docker.sock:/tmp/docker.sock:ro depends_on: - api networks: - devpocket-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Log aggregation (Optional) fluentd: image: fluentd:v1.16-debian-1 container_name: devpocket-fluentd restart: always volumes: - ./config/fluentd.conf:/fluentd/etc/fluentd.conf:ro - ./logs:/var/log/app networks: - devpocket-network profiles: - logging # Monitoring (Optional) prometheus: image: prom/prometheus:latest container_name: devpocket-prometheus restart: always ports: - "9090:9090" volumes: - ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--storage.tsdb.retention.time=200h' - '--web.enable-lifecycle' networks: - devpocket-network profiles: - monitoring grafana: image: grafana/grafana:latest container_name: devpocket-grafana restart: always ports: - "3001:3000" environment: GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD} volumes: - grafana_data:/var/lib/grafana - ./config/grafana:/etc/grafana/provisioning networks: - devpocket-network profiles: - monitoring volumes: postgres_data: driver: local redis_data: driver: local prometheus_data: driver: local grafana_data: driver: local networks: devpocket-network: driver: bridge