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