# ============================================================================= # 企微IT智能服务台 — Docker Compose(多服务拆分版) # ============================================================================= # 目标服务器:10.90.5.110 # 域名:itsupport.servyou.com.cn # # 架构说明: # - 将单体 backend 拆分为 5 个独立服务 # - 共享 PostgreSQL 和 Redis # - Nginx 根据路径路由到不同服务 # # 服务划分: # - core-svc: 核心服务(鉴权、员工、角色) # - conversation-svc: 会话服务(会话、消息、H5、WS) # - agent-svc: 坐席服务(坐席管理、快捷回复) # - ai-svc: AI 服务(Dify 调用、Wingman) # - admin-svc: 管理服务(仪表盘、配置、集成、审核) # # 用法: # 1. 上传部署包到服务器 # 2. cp .env.example .env && vim .env # 填入真实配置 # 3. docker compose -f docker-compose.split.yml up -d # 启动所有服务 # 4. docker compose -f docker-compose.split.yml logs -f # 查看日志 # # 蓝绿部署: # ./blue-green-deploy.sh deploy blue # 部署到 blue 环境 # ./blue-green-deploy.sh deploy green # 部署到 green 环境 # ./blue-green-deploy.sh switch blue # 切换流量到 blue # ============================================================================= services: # -------------------------------------------------------------------------- # PostgreSQL 16 — 持久化数据库(共享) # -------------------------------------------------------------------------- postgres: image: postgres:16-alpine container_name: wecom_it_postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-wecom} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-wecom_secret} POSTGRES_DB: ${POSTGRES_DB:-wecom_it_desk} volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-wecom}"] interval: 5s timeout: 5s retries: 5 networks: - it-desk-internal logging: driver: "json-file" options: max-size: "10m" max-file: "3" # -------------------------------------------------------------------------- # Redis 7 — 缓存服务(共享) # -------------------------------------------------------------------------- redis: image: redis:7-alpine container_name: wecom_it_redis restart: unless-stopped command: redis-server --appendonly yes --save 900 1 --save 300 10 volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 5 networks: - it-desk-internal logging: driver: "json-file" options: max-size: "10m" max-file: "3" # -------------------------------------------------------------------------- # Core Service — 核心服务(鉴权、员工、角色) # -------------------------------------------------------------------------- core-svc: build: context: ./backend dockerfile: Dockerfile image: wecom-it-desk:${CORE_VERSION:-latest} container_name: wecom_it_core restart: unless-stopped environment: # 服务标识 - SERVICE_NAME=core # 企微凭证 - WECOM_CORP_ID=${WECOM_CORP_ID} - WECOM_AGENT_ID=${WECOM_AGENT_ID} - WECOM_SECRET=${WECOM_SECRET} - WECOM_TOKEN=${WECOM_TOKEN} - WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY} # 数据库 - DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk} # Redis - REDIS_URL=redis://redis:6379/0 # CORS - CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn} # Mock 登录 - MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false} # 服务配置 - BACKEND_HOST=0.0.0.0 - BACKEND_PORT=8001 volumes: - backend-uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8001 --workers 1 networks: - it-desk-internal deploy: resources: limits: memory: 512M reservations: memory: 256M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8001/health').read()"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # -------------------------------------------------------------------------- # Conversation Service — 会话服务(会话、消息、H5、WebSocket) # -------------------------------------------------------------------------- conversation-svc: build: context: ./backend dockerfile: Dockerfile image: wecom-it-desk:${CONVERSATION_VERSION:-latest} container_name: wecom_it_conversation restart: unless-stopped environment: - SERVICE_NAME=conversation # 企微凭证 - WECOM_CORP_ID=${WECOM_CORP_ID} - WECOM_AGENT_ID=${WECOM_AGENT_ID} - WECOM_SECRET=${WECOM_SECRET} - WECOM_TOKEN=${WECOM_TOKEN} - WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY} # 数据库 - DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk} # Redis - REDIS_URL=redis://redis:6379/0 # CORS - CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn} # Mock 登录 - MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false} # 服务配置 - BACKEND_HOST=0.0.0.0 - BACKEND_PORT=8002 volumes: - backend-uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8002 --workers 2 networks: - it-desk-internal deploy: resources: limits: memory: 1G reservations: memory: 512M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8002/health').read()"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "15m" max-file: "5" # -------------------------------------------------------------------------- # Agent Service — 坐席服务 # -------------------------------------------------------------------------- agent-svc: build: context: ./backend dockerfile: Dockerfile image: wecom-it-desk:${AGENT_VERSION:-latest} container_name: wecom_it_agent restart: unless-stopped environment: - SERVICE_NAME=agent # 企微凭证 - WECOM_CORP_ID=${WECOM_CORP_ID} - WECOM_AGENT_ID=${WECOM_AGENT_ID} - WECOM_SECRET=${WECOM_SECRET} - WECOM_TOKEN=${WECOM_TOKEN} - WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY} # 数据库 - DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk} # Redis - REDIS_URL=redis://redis:6379/0 # CORS - CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn} # Mock 登录 - MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false} # 服务配置 - BACKEND_HOST=0.0.0.0 - BACKEND_PORT=8003 volumes: - backend-uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8003 --workers 1 networks: - it-desk-internal deploy: resources: limits: memory: 512M reservations: memory: 256M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8003/health').read()"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # -------------------------------------------------------------------------- # AI Service — AI 服务(Dify 调用、Wingman) # -------------------------------------------------------------------------- ai-svc: build: context: ./backend dockerfile: Dockerfile image: wecom-it-desk:${AI_VERSION:-latest} container_name: wecom_it_ai restart: unless-stopped environment: - SERVICE_NAME=ai # 企微凭证 - WECOM_CORP_ID=${WECOM_CORP_ID} - WECOM_AGENT_ID=${WECOM_AGENT_ID} - WECOM_SECRET=${WECOM_SECRET} - WECOM_TOKEN=${WECOM_TOKEN} - WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY} # 数据库 - DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk} # Redis - REDIS_URL=redis://redis:6379/0 # CORS - CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn} # Mock 登录 - MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false} # AI 服务(Dify) - DIFY_API_URL=${DIFY_API_URL} - DIFY_API_KEY=${DIFY_API_KEY} - DIFY_TIMEOUT=${DIFY_TIMEOUT:-30} # AI Wingman - DIFY_WINGMAN_API_URL=${DIFY_WINGMAN_API_URL:-} - DIFY_WINGMAN_API_KEY=${DIFY_WINGMAN_API_KEY:-} - DIFY_WINGMAN_TIMEOUT=${DIFY_WINGMAN_TIMEOUT:-30} # 服务配置 - BACKEND_HOST=0.0.0.0 - BACKEND_PORT=8004 volumes: - backend-uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8004 --workers 1 networks: - it-desk-internal deploy: resources: limits: memory: 1G reservations: memory: 512M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8004/health').read()"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "15m" max-file: "5" # -------------------------------------------------------------------------- # Admin Service — 管理服务(仪表盘、配置、集成、审核) # -------------------------------------------------------------------------- admin-svc: build: context: ./backend dockerfile: Dockerfile image: wecom-it-desk:${ADMIN_VERSION:-latest} container_name: wecom_it_admin restart: unless-stopped environment: - SERVICE_NAME=admin # 企微凭证 - WECOM_CORP_ID=${WECOM_CORP_ID} - WECOM_AGENT_ID=${WECOM_AGENT_ID} - WECOM_SECRET=${WECOM_SECRET} - WECOM_TOKEN=${WECOM_TOKEN} - WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY} # 数据库 - DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk} # Redis - REDIS_URL=redis://redis:6379/0 # CORS - CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn} # Mock 登录 - MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false} # 服务配置 - BACKEND_HOST=0.0.0.0 - BACKEND_PORT=8005 volumes: - backend-uploads:/app/uploads depends_on: postgres: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8005 --workers 1 networks: - it-desk-internal deploy: resources: limits: memory: 512M reservations: memory: 256M healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8005/health').read()"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # -------------------------------------------------------------------------- # Nginx — 反向代理 + 静态文件服务 + 路由分发 # -------------------------------------------------------------------------- nginx: image: nginx:1.27-alpine container_name: wecom_it_nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx/nginx-split.conf:/etc/nginx/nginx.conf:ro - ./nginx/ssl:/etc/nginx/ssl:ro - ./frontend-h5/dist:/usr/share/nginx/html/itdesk:ro - ./frontend-agent/dist:/usr/share/nginx/html/itagent:ro - ./frontend-admin/dist:/usr/share/nginx/html/itadmin:ro - ./frontend-portal/dist:/usr/share/nginx/html/itportal:ro depends_on: core-svc: condition: service_healthy conversation-svc: condition: service_healthy agent-svc: condition: service_healthy ai-svc: condition: service_healthy admin-svc: condition: service_healthy networks: - it-desk-internal healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:80/itdesk/health || exit 1"] interval: 15s timeout: 5s retries: 3 logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ============================================================================= # 网络 # ============================================================================= networks: it-desk-internal: driver: bridge # ============================================================================= # 数据卷 # ============================================================================= volumes: postgres_data: name: wecom_it_postgres_data redis_data: name: wecom_it_redis_data backend-uploads: name: wecom_it_backend_uploads