version: '3.8' services: postgres: image: postgres:15-alpine container_name: veza-postgres-prod environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/database/backup:/backup:ro networks: - veza-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" redis: image: redis:7-alpine container_name: veza-redis-prod command: > redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes --appendfsync everysec --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data networks: - veza-network healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" backend-api: image: veza/backend-api:latest container_name: veza-backend-api-prod build: context: ./veza-backend-api dockerfile: Dockerfile environment: DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 JWT_SECRET: ${JWT_SECRET} JWT_EXPIRY: ${JWT_EXPIRY:-24h} API_ENV: production APP_ENV: production # CORS configuration (Required in production) CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-https://app.veza.com,https://www.veza.com} LOG_LEVEL: ${LOG_LEVEL:-INFO} API_PORT: 8080 APP_PORT: 8080 depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - veza-network healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/healthz"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" ports: - "8080:8080" chat-server: image: veza/chat-server:latest container_name: veza-chat-server-prod build: context: ./veza-chat-server dockerfile: Dockerfile environment: DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 LOG_LEVEL: ${LOG_LEVEL:-INFO} PORT: 8081 depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - veza-network healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8081/healthz"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" ports: - "8081:8081" stream-server: image: veza/stream-server:latest container_name: veza-stream-server-prod build: context: ./veza-stream-server dockerfile: Dockerfile environment: DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 LOG_LEVEL: ${LOG_LEVEL:-INFO} PORT: 8082 RUST_LOG: info,stream_server=info depends_on: redis: condition: service_healthy networks: - veza-network healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8082/healthz"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" ports: - "8082:8082" frontend: image: veza/frontend:latest container_name: veza-frontend-prod build: context: ./apps/web dockerfile: Dockerfile environment: VITE_API_URL: ${VITE_API_URL} VITE_WS_URL: ${VITE_WS_URL} VITE_STREAM_URL: ${VITE_STREAM_URL} depends_on: - backend-api - chat-server - stream-server networks: - veza-network healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" ports: - "80:80" prometheus: image: prom/prometheus:latest container_name: veza-prometheus volumes: - ./config/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/usr/share/prometheus/console_libraries' - '--web.console.templates=/usr/share/prometheus/consoles' ports: - "9090:9090" networks: - veza-network restart: unless-stopped grafana: image: grafana/grafana:latest container_name: veza-grafana volumes: - grafana_data:/var/lib/grafana - ./config/grafana:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin} - GF_USERS_ALLOW_SIGN_UP=false ports: - "3000:3000" depends_on: - prometheus networks: - veza-network restart: unless-stopped volumes: postgres_data: driver: local redis_data: driver: local prometheus_data: driver: local grafana_data: driver: local networks: veza-network: driver: bridge