name: it0 services: # ===== Infrastructure ===== postgres: image: postgres:16-alpine container_name: it0-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-it0} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-it0_dev} POSTGRES_DB: ${POSTGRES_DB:-it0} ports: - "15432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-databases.sh:/docker-entrypoint-initdb.d/init-databases.sh healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-it0}"] interval: 10s timeout: 5s retries: 5 networks: - it0-network redis: image: redis:7-alpine container_name: it0-redis restart: unless-stopped ports: - "16379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - it0-network # ===== API Gateway ===== api-gateway: build: context: ../../packages/gateway container_name: it0-api-gateway restart: unless-stopped environment: - JWT_SECRET=${JWT_SECRET:-dev-jwt-secret} ports: - "18000:8000" - "18001:8001" depends_on: auth-service: condition: service_healthy agent-service: condition: service_healthy ops-service: condition: service_healthy inventory-service: condition: service_healthy monitor-service: condition: service_healthy comm-service: condition: service_healthy audit-service: condition: service_healthy healthcheck: test: ["CMD", "kong", "health"] interval: 10s timeout: 5s retries: 3 networks: - it0-network # ===== Backend Services (shared Dockerfile.service) ===== auth-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: auth-service SERVICE_PORT: 3001 container_name: it0-auth-service restart: unless-stopped ports: - "13001:3001" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - JWT_SECRET=${JWT_SECRET:-dev-jwt-secret} - JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-dev-jwt-refresh-secret} - AUTH_SERVICE_PORT=3001 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3001/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - it0-network agent-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: agent-service SERVICE_PORT: 3002 container_name: it0-agent-service restart: unless-stopped ports: - "13002:3002" volumes: - ${HOME}/.claude:/home/appuser/.claude - ${HOME}/.claude.json:/home/appuser/.claude.json - claude_tenants:/data/claude-tenants - ${HOME}/.ssh/rwadurian_ed25519:/tmp/host-ssh-key:ro environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - AGENT_ENGINE_TYPE=claude_agent_sdk - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL} - AGENT_SERVICE_PORT=3002 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3002/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - it0-network ops-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: ops-service SERVICE_PORT: 3003 container_name: it0-ops-service restart: unless-stopped ports: - "13003:3003" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - OPS_SERVICE_PORT=3003 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3003/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - it0-network inventory-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: inventory-service SERVICE_PORT: 3004 container_name: it0-inventory-service restart: unless-stopped ports: - "13004:3004" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - VAULT_MASTER_KEY=${VAULT_MASTER_KEY:-dev-vault-key} - INVENTORY_SERVICE_PORT=3004 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3004/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy networks: - it0-network monitor-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: monitor-service SERVICE_PORT: 3005 container_name: it0-monitor-service restart: unless-stopped ports: - "13005:3005" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - MONITOR_SERVICE_PORT=3005 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3005/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy networks: - it0-network comm-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: comm-service SERVICE_PORT: 3006 container_name: it0-comm-service restart: unless-stopped ports: - "13006:3006" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - TWILIO_ACCOUNT_SID=${TWILIO_ACCOUNT_SID} - TWILIO_AUTH_TOKEN=${TWILIO_AUTH_TOKEN} - TWILIO_PHONE_NUMBER=${TWILIO_PHONE_NUMBER} - COMM_SERVICE_PORT=3006 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3006/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - it0-network audit-service: build: context: ../.. dockerfile: Dockerfile.service args: SERVICE_NAME: audit-service SERVICE_PORT: 3007 container_name: it0-audit-service restart: unless-stopped ports: - "13007:3007" environment: - DB_HOST=postgres - DB_PORT=5432 - DB_USERNAME=${POSTGRES_USER:-it0} - DB_PASSWORD=${POSTGRES_PASSWORD:-it0_dev} - DB_DATABASE=${POSTGRES_DB:-it0} - REDIS_URL=redis://redis:6379 - AUDIT_SERVICE_PORT=3007 healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3007/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: postgres: condition: service_healthy networks: - it0-network voice-service: build: context: ../../packages/services/voice-service container_name: it0-voice-service restart: unless-stopped ports: - "13008:3008" volumes: - ../../data/voice-models/huggingface:/root/.cache/huggingface - ../../data/voice-models/torch-hub:/root/.cache/torch/hub environment: - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL} - AGENT_SERVICE_URL=http://agent-service:3002 - WHISPER_MODEL=${WHISPER_MODEL:-base} - KOKORO_MODEL=${KOKORO_MODEL:-kokoro-82m} - KOKORO_VOICE=${KOKORO_VOICE:-zf_xiaoxiao} - DEVICE=${VOICE_DEVICE:-cpu} - STT_PROVIDER=${STT_PROVIDER:-local} - TTS_PROVIDER=${TTS_PROVIDER:-local} - OPENAI_API_KEY=${OPENAI_API_KEY} - OPENAI_BASE_URL=${OPENAI_BASE_URL} - OPENAI_STT_MODEL=${OPENAI_STT_MODEL:-gpt-4o-transcribe} - OPENAI_TTS_MODEL=${OPENAI_TTS_MODEL:-tts-1} - OPENAI_TTS_VOICE=${OPENAI_TTS_VOICE:-alloy} healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:3008/docs')\""] interval: 30s timeout: 10s retries: 5 start_period: 120s depends_on: - agent-service networks: - it0-network # ===== Frontend ===== web-admin: build: context: ../../it0-web-admin container_name: it0-web-admin restart: unless-stopped ports: - "13000:3000" environment: - HOSTNAME=0.0.0.0 - API_BASE_URL=http://api-gateway:8000 - NEXT_PUBLIC_API_BASE_URL=/api/proxy - NEXT_PUBLIC_WS_URL=wss://it0api.szaiai.com healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://127.0.0.1:3000/',r=>{process.exit(r.statusCode<500?0:1)}).on('error',()=>process.exit(1))\""] interval: 30s timeout: 5s retries: 3 start_period: 15s depends_on: - api-gateway networks: - it0-network volumes: postgres_data: claude_tenants: networks: it0-network: driver: bridge