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

433 lines
14 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 企微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