Files
wecom_it_smart_desk/deploy-server/docker-compose.split.yml
T

432 lines
14 KiB
YAML
Raw Normal View History

# =============================================================================
# 企微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
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