# Production configuration # with external Nginx (config template provided) # # Usage: # 1. Fill backend/.env with real production secrets (cp backend/.env.example # backend/.env if it doesn't exist yet). The same file is used for dev and # prod — there is no separate .env.prod. # 2. Run: make prod (or: docker compose --env-file backend/.env -f docker-compose.prod.yml up -d) # # Prerequisites: # 1. Configure your external Nginx using nginx/nginx.conf as reference # 2. Configure backend/.env with DOMAIN services: app: build: context: ./backend dockerfile: Dockerfile container_name: agent_delta_backend volumes: - media_data:/app/media env_file: - ./backend/.env environment: - DEBUG=false - ENVIRONMENT=production - POSTGRES_HOST=db - REDIS_HOST=redis - QDRANT_HOST=qdrant - QDRANT_PORT=6333 - TASKIQ_BROKER_URL=redis://redis:6379/1 - TASKIQ_RESULT_BACKEND=redis://redis:6379/1 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 networks: - backend-internal ports: - "8000:8000" depends_on: db: condition: service_healthy redis: condition: service_healthy qdrant: condition: service_healthy restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 512M reservations: cpus: '0.5' memory: 256M db: image: postgres:16-alpine container_name: agent_delta_db environment: - POSTGRES_USER=${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB:-agent_delta} volumes: - postgres_data:/var/lib/postgresql/data # NO external ports - only accessible within backend-internal network networks: - backend-internal healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 512M redis: image: redis:7-alpine container_name: agent_delta_redis command: redis-server --requirepass ${REDIS_PASSWORD:?REDIS_PASSWORD is required} # NO external ports - only accessible within backend-internal network volumes: - redis_data:/data networks: - backend-internal healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped deploy: resources: limits: cpus: '0.5' memory: 256M qdrant: image: qdrant/qdrant:v1.18.1 container_name: agent_delta_qdrant # NO external ports in production - only accessible within backend-internal network volumes: - qdrant_data:/qdrant/storage networks: - backend-internal healthcheck: test: ["CMD", "curl", "-f", "http://localhost:6333/healthz"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped deploy: resources: limits: cpus: '1' memory: 512M taskiq_worker: image: agent_delta_backend:dev container_name: agent_delta_taskiq_worker volumes: - media_data:/app/media command: taskiq worker app.worker.taskiq_app:broker --workers 4 env_file: - ./backend/.env environment: - DEBUG=false - POSTGRES_HOST=db - REDIS_HOST=redis - QDRANT_HOST=qdrant - QDRANT_PORT=6333 - TASKIQ_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/1 - TASKIQ_RESULT_BACKEND=redis://:${REDIS_PASSWORD}@redis:6379/1 networks: - backend-internal depends_on: app: condition: service_started redis: condition: service_healthy db: condition: service_healthy restart: unless-stopped deploy: replicas: 2 resources: limits: cpus: '0.5' memory: 512M reservations: cpus: '0.25' memory: 256M taskiq_scheduler: image: agent_delta_backend:dev container_name: agent_delta_taskiq_scheduler command: taskiq scheduler app.worker.taskiq_app:scheduler env_file: - ./backend/.env environment: - DEBUG=false - REDIS_HOST=redis - QDRANT_HOST=qdrant - QDRANT_PORT=6333 - TASKIQ_BROKER_URL=redis://:${REDIS_PASSWORD}@redis:6379/1 - TASKIQ_RESULT_BACKEND=redis://:${REDIS_PASSWORD}@redis:6379/1 networks: - backend-internal depends_on: app: condition: service_started redis: condition: service_healthy restart: unless-stopped deploy: resources: limits: cpus: '0.25' memory: 128M frontend: build: context: ./frontend dockerfile: Dockerfile container_name: agent_delta_frontend environment: - NODE_ENV=production - BACKEND_URL=http://app:8000 - BACKEND_WS_URL=ws://app:8000 networks: - backend-internal ports: - "3000:3000" depends_on: - app restart: unless-stopped deploy: resources: limits: cpus: '0.5' memory: 256M networks: backend-internal: driver: bridge internal: true volumes: media_data: postgres_data: redis_data: qdrant_data: