version: '3.8' services: # Database Service database: build: context: ./database dockerfile: Dockerfile image: candidat/database:${APP_VERSION:-latest} container_name: candidat-database environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} ports: - "${DB_PORT:-3307}:3306" - "${DB_X_PORT:-33061}:33060" # MySQL X Protocol for development volumes: - db_data:/var/lib/mysql networks: - candidat-network restart: unless-stopped command: --default-authentication-plugin=mysql_native_password healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 deploy: resources: limits: memory: 1G reservations: memory: 512M # Backend Service backend: build: context: ./backend dockerfile: Dockerfile image: candidat/backend:${APP_VERSION:-latest} container_name: candidat-backend environment: NODE_ENV: ${NODE_ENV:-production} DB_HOST: database DB_PORT: 3306 DB_NAME: ${MYSQL_DATABASE} DB_USER: ${MYSQL_USER} DB_PASSWORD: ${MYSQL_PASSWORD} AI_PROVIDER: ${AI_PROVIDER} OPENROUTER_API_KEY: ${OPENROUTER_API_KEY} OPENROUTER_MODEL: ${OPENROUTER_MODEL} OPENROUTER_BASE_URL: ${OPENROUTER_BASE_URL} OPENROUTER_REL_PATH: ${OPENROUTER_REL_PATH} OPENROUTER_TEMPERATURE: ${OPENROUTER_TEMPERATURE} AI_PORT: ${AI_PORT} AI_MODEL: ${AI_MODEL} # Stripe Payment Configuration STRIPE_PUBLISHABLE_KEY: ${STRIPE_PUBLISHABLE_KEY} STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY} STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET} ports: - "${BACKEND_PORT:-8083}:8083" volumes: # Development hot reloading (only if NODE_ENV=development) - ./backend/src:/app/src:ro depends_on: database: condition: service_healthy networks: - candidat-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8083/rest/ai/test-ai"] interval: 30s timeout: 10s retries: 3 start_period: 40s deploy: resources: limits: memory: 512M reservations: memory: 256M # Frontend Service frontend: build: context: ./frontend dockerfile: Dockerfile image: candidat/frontend:${APP_VERSION:-latest} container_name: candidat-frontend environment: NODE_ENV: ${NODE_ENV:-production} NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY} ports: - "${FRONTEND_PORT:-3000}:3000" volumes: # Development hot reloading (only if NODE_ENV=development) - ./frontend/src:/app/src:ro depends_on: backend: condition: service_healthy networks: - candidat-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000"] interval: 30s timeout: 10s retries: 3 start_period: 30s deploy: resources: limits: memory: 256M reservations: memory: 128M # Chatbot Service chatbot: build: context: ./AISApp dockerfile: Dockerfile image: candidat/chatbot:${APP_VERSION:-latest} container_name: candidat-chatbot environment: ASPNETCORE_ENVIRONMENT: ${NODE_ENV:-production} OPENROUTER_API_KEY: ${OPENROUTER_API_KEY} CHATBOT_DB_HOST: database CHATBOT_DB_NAME: ${MYSQL_DATABASE} CHATBOT_DB_USER: ${MYSQL_USER} CHATBOT_DB_PASSWORD: ${MYSQL_PASSWORD} CHATBOT_DB_PORT: 3306 ports: - "${CHATBOT_PORT:-5000}:80" depends_on: database: condition: service_healthy networks: - candidat-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost/api/chat"] interval: 30s timeout: 10s retries: 3 start_period: 40s deploy: resources: limits: memory: 512M reservations: memory: 256M # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: candidat-nginx ports: - "${NGINX_PORT:-80}:80" - "${NGINX_SSL_PORT:-443}:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/ssl:/etc/nginx/ssl:ro - nginx_logs:/var/log/nginx depends_on: - frontend - backend - chatbot networks: - candidat-network restart: unless-stopped healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s deploy: resources: limits: memory: 128M reservations: memory: 64M volumes: db_data: driver: local nginx_logs: driver: local networks: candidat-network: driver: bridge