version: '3.8' # ================================================ # Math Platform - Docker Secrets Configuration # ================================================ # USO: # 1. Crear archivos de secrets en ./secrets/ # 2. docker-compose -f docker-compose.secrets.yml up -d # # PRODUCCIÓN: # - Usar Docker Swarm: docker secret create db_password secrets/db_password.txt # - O usar Vault/Sealed Secrets en Kubernetes # ================================================ secrets: db_password: file: ./secrets/db_password.txt redis_password: file: ./secrets/redis_password.txt jwt_secret: file: ./secrets/jwt_secret.txt ai_api_key: file: ./secrets/ai_api_key.txt telegram_token: file: ./secrets/telegram_token.txt telegram_chat_id: file: ./secrets/telegram_chat_id.txt session_secret: file: ./secrets/session_secret.txt monitor_db_password: file: ./secrets/monitor_db_password.txt services: # PostgreSQL con secrets postgres: image: postgres:15.4-alpine container_name: math-postgres environment: POSTGRES_USER: mathuser POSTGRES_PASSWORD_FILE: /run/secrets/db_password POSTGRES_DB: mathdb PGDATA: /var/lib/postgresql/data/pgdata MONITOR_DB_PASSWORD_FILE: /run/secrets/monitor_db_password secrets: - db_password - monitor_db_password volumes: - postgres_data:/var/lib/postgresql/data - ./docker/init-scripts:/docker-entrypoint-initdb.d:ro ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U mathuser -d mathdb"] interval: 10s timeout: 5s retries: 5 start_period: 10s networks: - math-network restart: unless-stopped logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Redis con password secret redis: image: redis:7.2.3-alpine container_name: math-redis command: > redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru --tcp-backlog 511 --timeout 0 --tcp-keepalive 300 --requirepass $(cat /run/secrets/redis_password) secrets: - redis_password volumes: - redis_data:/data ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 start_period: 10s networks: - math-network restart: unless-stopped # Backend con múltiples secrets backend: build: context: . dockerfile: docker/Dockerfile.backend image: math-backend:${VERSION:-1.0.0} container_name: math-backend secrets: - db_password - redis_password - jwt_secret - ai_api_key - telegram_token - telegram_chat_id - session_secret environment: NODE_ENV: production VERSION: ${VERSION:-1.0.0} DATABASE_URL: postgresql://mathuser:/run/secrets/db_password@postgres:5432/mathdb REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD_FILE: /run/secrets/redis_password AI_API_BASE_URL: ${AI_API_BASE_URL:-https://coding-intl.dashscope.aliyuncs.com/v1} AI_API_KEY_FILE: /run/secrets/ai_api_key AI_MODEL: ${AI_MODEL:-MiniMax-M2.5} TELEGRAM_BOT_TOKEN_FILE: /run/secrets/telegram_token TELEGRAM_ADMIN_CHAT_ID_FILE: /run/secrets/telegram_chat_id JWT_SECRET_FILE: /run/secrets/jwt_secret JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-15m} SESSION_SECRET_FILE: /run/secrets/session_secret BACKEND_PORT: 3001 LOG_LEVEL: ${LOG_LEVEL:-info} CORS_ORIGIN: http://localhost:3000,http://localhost volumes: - backend_logs:/app/logs - ./pdfs:/app/pdfs:ro ports: - "3001:3001" depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - math-network restart: unless-stopped # Frontend frontend: build: context: . dockerfile: docker/Dockerfile.frontend image: math-frontend:${VERSION:-1.0.0} container_name: math-frontend environment: NODE_ENV: production PORT: 3000 NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:3001} NEXT_PUBLIC_APP_NAME: ${NEXT_PUBLIC_APP_NAME:-Plataforma de Álgebra Lineal} ports: - "3000:3000" depends_on: backend: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - math-network restart: unless-stopped # Nginx Reverse Proxy nginx: image: nginx:1.25.3-alpine container_name: math-nginx volumes: - ./docker/nginx.conf:/etc/nginx/nginx.conf:ro - ./docker/logs:/var/log/nginx - ./docker/ssl:/etc/nginx/ssl:ro ports: - "80:80" - "443:443" depends_on: frontend: condition: service_healthy backend: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s networks: - math-network restart: unless-stopped volumes: postgres_data: driver: local redis_data: driver: local backend_logs: driver: local networks: math-network: driver: bridge ipam: config: - subnet: 172.20.0.0/16