# ============================================ # Docker Compose pour Production Neah # ============================================ # Ce fichier configure l'application complète pour la production # # Usage: # docker-compose -f docker-compose.prod.yml --env-file .env.production up -d # # IMPORTANT: # - Modifiez les mots de passe par défaut avant le déploiement ! # - Configurez les volumes pour la persistance des données # - Ajustez les ports selon votre infrastructure réseau services: # ============================================ # PostgreSQL - Base de données principale # ============================================ db: image: postgres:15-alpine container_name: neah-postgres-prod restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-neah_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-CHANGE_ME_IN_PRODUCTION} POSTGRES_DB: ${POSTGRES_DB:-calendar_db} # Configuration pour la production POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" ports: # Exposer uniquement sur localhost pour la sécurité (ou utilisez un réseau Docker) - "127.0.0.1:5432:5432" # Pour accès externe depuis Vercel, utilisez plutôt un tunnel SSH ou VPN volumes: # Volume nommé pour la persistance (géré par Docker) - postgres_data:/var/lib/postgresql/data # Optionnel: sauvegardes automatiques # - ./backups:/backups healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 10s timeout: 5s retries: 5 # Sécurité: limiter les ressources deploy: resources: limits: cpus: '2' memory: 2G reservations: cpus: '1' memory: 1G # ============================================ # Redis - Cache et sessions # ============================================ redis: image: redis:7-alpine container_name: neah-redis-prod restart: unless-stopped command: > redis-server --requirepass ${REDIS_PASSWORD:-CHANGE_ME_IN_PRODUCTION} --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru ports: # Exposer uniquement sur localhost pour la sécurité - "127.0.0.1:6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 5 # Sécurité: limiter les ressources deploy: resources: limits: cpus: '1' memory: 1G reservations: cpus: '0.5' memory: 512M # ============================================ # MinIO - Stockage S3-compatible (optionnel) # ============================================ # Décommentez si vous utilisez MinIO pour le stockage de fichiers # minio: # image: minio/minio:latest # container_name: neah-minio-prod # restart: unless-stopped # environment: # MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin} # MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-CHANGE_ME_IN_PRODUCTION} # ports: # - "127.0.0.1:9000:9000" # API # - "127.0.0.1:9001:9001" # Console # volumes: # - minio_data:/data # command: server /data --console-address ":9001" # healthcheck: # test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] # interval: 30s # timeout: 20s # retries: 3 # deploy: # resources: # limits: # cpus: '1' # memory: 1G # ============================================ # Application Next.js # ============================================ app: build: context: . dockerfile: Dockerfile.prod container_name: neah-app-prod restart: unless-stopped ports: - "${APP_PORT:-3000}:3000" depends_on: db: condition: service_healthy redis: condition: service_healthy environment: # Database DATABASE_URL: ${DATABASE_URL:-postgresql://${POSTGRES_USER:-neah_user}:${POSTGRES_PASSWORD:-CHANGE_ME_IN_PRODUCTION}@db:5432/${POSTGRES_DB:-calendar_db}?schema=public} # Redis REDIS_URL: ${REDIS_URL:-redis://:${REDIS_PASSWORD:-CHANGE_ME_IN_PRODUCTION}@redis:6379} # NextAuth NEXTAUTH_URL: ${NEXTAUTH_URL:-https://hub.slm-lab.net} NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-CHANGE_ME_IN_PRODUCTION} # Keycloak KEYCLOAK_ISSUER: ${KEYCLOAK_ISSUER:-} KEYCLOAK_CLIENT_ID: ${KEYCLOAK_CLIENT_ID:-} KEYCLOAK_CLIENT_SECRET: ${KEYCLOAK_CLIENT_SECRET:-} KEYCLOAK_REALM: ${KEYCLOAK_REALM:-} NEXT_PUBLIC_KEYCLOAK_ISSUER: ${NEXT_PUBLIC_KEYCLOAK_ISSUER:-} # Node environment NODE_ENV: production NEXT_TELEMETRY_DISABLED: 1 # MinIO / S3 Configuration (required for mission file uploads) MINIO_S3_UPLOAD_BUCKET_URL: ${MINIO_S3_UPLOAD_BUCKET_URL:-https://dome-api.slm-lab.net} MINIO_AWS_REGION: ${MINIO_AWS_REGION:-us-east-1} MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} # API URLs (required for mission creation) NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://hub.slm-lab.net} NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://hub.slm-lab.net} # N8N Integration (required for mission creation workflow) N8N_API_KEY: ${N8N_API_KEY} N8N_WEBHOOK_URL: ${N8N_WEBHOOK_URL:-https://brain.slm-lab.net/webhook/mission-created} N8N_DELETE_WEBHOOK_URL: ${N8N_DELETE_WEBHOOK_URL:-https://brain.slm-lab.net/webhook/mission-delete} # Autres variables d'environnement (ajoutez les vôtres) # volumes: # Optionnel: monter des fichiers de configuration ou des uploads # - ./uploads:/app/uploads healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"] interval: 30s timeout: 10s retries: 3 start_period: 40s deploy: resources: limits: cpus: '2' memory: 2G reservations: cpus: '1' memory: 1G volumes: # Volume pour PostgreSQL - persistance des données postgres_data: driver: local # Optionnel: utiliser un driver de volume externe pour les sauvegardes # driver_opts: # type: nfs # o: addr=nfs-server.example.com,nolock,soft,rw # device: ":/path/to/nfs/share" # Volume pour Redis - persistance AOF redis_data: driver: local # Volume pour MinIO (si activé) # minio_data: # driver: local # ============================================ # Réseaux (optionnel) # ============================================ # Décommentez pour isoler les services dans un réseau Docker # networks: # neah_network: # driver: bridge # ipam: # config: # - subnet: 172.20.0.0/16 # ============================================ # NOTES IMPORTANTES POUR LA PRODUCTION # ============================================ # # 1. SÉCURITÉ: # - Changez TOUS les mots de passe par défaut # - Utilisez des secrets Docker ou un gestionnaire de secrets (HashiCorp Vault, etc.) # - Limitez l'exposition des ports (utilisez 127.0.0.1 au lieu de 0.0.0.0) # - Configurez un firewall pour limiter l'accès aux ports exposés # - Activez SSL/TLS pour PostgreSQL si accessible depuis l'extérieur # # 2. CONNEXION DEPUIS VERCEL: # - Option A: Tunnel SSH (recommandé) # ssh -L 5432:localhost:5432 user@your-server # - Option B: VPN (si disponible) # - Option C: Exposer PostgreSQL avec SSL (moins sécurisé, nécessite configuration SSL) # # 3. SAUVEGARDES: # - Configurez des sauvegardes automatiques de PostgreSQL # - Sauvegardez régulièrement les volumes Docker # - Testez la restauration des sauvegardes # # 4. MONITORING: # - Surveillez l'utilisation des ressources (CPU, mémoire, disque) # - Configurez des alertes pour les problèmes de santé # - Utilisez des outils comme Prometheus + Grafana # # 5. MIGRATIONS PRISMA: # - Exécutez les migrations avant chaque déploiement: # docker-compose -f docker-compose.prod.yml run --rm app npx prisma migrate deploy # - Testez les migrations en staging avant la production # - Gardez un plan de rollback pour chaque migration