# WHOOSH Production Docker Compose Configuration version: '3.8' services: # PostgreSQL Database (Production) whoosh_postgres: image: postgres:15 container_name: whoosh_postgres_prod environment: POSTGRES_DB: whoosh POSTGRES_USER: whoosh POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password POSTGRES_HOST_AUTH_METHOD: md5 ports: - "5432:5432" volumes: - postgres_prod_data:/var/lib/postgresql/data - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql - ./database/backup:/backup healthcheck: test: ["CMD-SHELL", "pg_isready -U whoosh -d whoosh"] interval: 30s timeout: 10s retries: 5 restart: unless-stopped networks: - whoosh_network secrets: - postgres_password deploy: resources: limits: memory: 2G cpus: '1.0' reservations: memory: 1G cpus: '0.5' # Redis Cache (Production) whoosh_redis: image: redis:7-alpine container_name: whoosh_redis_prod ports: - "6379:6379" volumes: - redis_prod_data:/data - ./redis/redis.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 5 restart: unless-stopped networks: - whoosh_network deploy: resources: limits: memory: 512M cpus: '0.5' # WHOOSH Backend (Production) whoosh_backend: build: context: ./backend dockerfile: Dockerfile.prod image: registry.home.deepblack.cloud/whoosh/backend:latest container_name: whoosh_backend_prod ports: - "8087:8087" environment: - DATABASE_URL=postgresql://whoosh:${POSTGRES_PASSWORD}@whoosh_postgres:5432/whoosh - REDIS_URL=redis://whoosh_redis:6379/0 - ENVIRONMENT=production - CORS_ORIGINS=https://whoosh.deepblack.cloud,https://www.whoosh.deepblack.cloud - GITEA_BASE_URL=https://gitea.deepblack.cloud - GITEA_TOKEN_FILE=/run/secrets/gitea_token - SECRET_KEY_FILE=/run/secrets/secret_key - AGE_MASTER_KEY_FILE=/run/secrets/age_master_key - SENTRY_DSN_FILE=/run/secrets/sentry_dsn - LOG_LEVEL=INFO depends_on: whoosh_postgres: condition: service_healthy whoosh_redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8087/health"] interval: 30s timeout: 10s retries: 3 volumes: - template_storage:/app/templates - ./logs:/app/logs restart: unless-stopped networks: - whoosh_network secrets: - gitea_token - secret_key - age_master_key - sentry_dsn deploy: resources: limits: memory: 1G cpus: '1.0' reservations: memory: 512M cpus: '0.5' # WHOOSH Frontend (Production) whoosh_frontend: build: context: ./frontend dockerfile: Dockerfile.prod image: registry.home.deepblack.cloud/whoosh/frontend:latest container_name: whoosh_frontend_prod ports: - "3000:80" environment: - REACT_APP_API_URL=https://api.whoosh.deepblack.cloud - REACT_APP_ENVIRONMENT=production - REACT_APP_SENTRY_DSN=${SENTRY_DSN} depends_on: - whoosh_backend healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped networks: - whoosh_network deploy: resources: limits: memory: 512M cpus: '0.5' # Nginx Reverse Proxy whoosh_nginx: image: nginx:alpine container_name: whoosh_nginx_prod ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf - ./nginx/ssl:/etc/nginx/ssl - ./nginx/logs:/var/log/nginx depends_on: - whoosh_frontend - whoosh_backend restart: unless-stopped networks: - whoosh_network # Prometheus Monitoring whoosh_prometheus: image: prom/prometheus:latest container_name: whoosh_prometheus_prod ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml - 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' restart: unless-stopped networks: - whoosh_network # Grafana Dashboard whoosh_grafana: image: grafana/grafana:latest container_name: whoosh_grafana_prod ports: - "3001:3000" environment: - GF_SECURITY_ADMIN_PASSWORD_FILE=/run/secrets/grafana_password - GF_USERS_ALLOW_SIGN_UP=false volumes: - grafana_data:/var/lib/grafana - ./monitoring/grafana/dashboards:/etc/grafana/provisioning/dashboards - ./monitoring/grafana/datasources:/etc/grafana/provisioning/datasources secrets: - grafana_password restart: unless-stopped networks: - whoosh_network # Log Aggregation whoosh_loki: image: grafana/loki:latest container_name: whoosh_loki_prod ports: - "3100:3100" volumes: - ./monitoring/loki.yml:/etc/loki/local-config.yaml - loki_data:/loki command: -config.file=/etc/loki/local-config.yaml restart: unless-stopped networks: - whoosh_network volumes: postgres_prod_data: driver: local redis_prod_data: driver: local template_storage: driver: local prometheus_data: driver: local grafana_data: driver: local loki_data: driver: local networks: whoosh_network: driver: bridge ipam: config: - subnet: 172.21.0.0/16 secrets: postgres_password: external: true gitea_token: external: true secret_key: external: true age_master_key: external: true sentry_dsn: external: true grafana_password: external: true