2026-06-14 16:49:18 +08:00
|
|
|
|
# =============================================================================
|
|
|
|
|
|
# 企微IT智能服务台 — Docker Compose(公司内网服务器版)
|
|
|
|
|
|
# =============================================================================
|
|
|
|
|
|
# 目标服务器:10.90.5.110
|
|
|
|
|
|
# 域名:itsupport.servyou.com.cn
|
|
|
|
|
|
#
|
|
|
|
|
|
# 用法:
|
|
|
|
|
|
# 1. 上传部署包到服务器
|
|
|
|
|
|
# 2. cp .env.example .env && vim .env # 填入真实配置
|
|
|
|
|
|
# 3. docker compose up -d # 启动所有服务
|
|
|
|
|
|
# 4. docker compose logs -f # 查看日志
|
|
|
|
|
|
#
|
|
|
|
|
|
# 架构:
|
|
|
|
|
|
# 客户端浏览器 → Nginx:80 → { /itdesk/, /itagent/, /itadmin/, /api/, /ws/ }
|
|
|
|
|
|
# =============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
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 — 缓存服务(token、会话、员工信息)
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
redis:
|
|
|
|
|
|
image: redis:7-alpine
|
|
|
|
|
|
container_name: wecom_it_redis
|
|
|
|
|
|
restart: unless-stopped
|
2026-07-18 02:16:56 +08:00
|
|
|
|
command: redis-server --appendonly yes --save 900 1 --save 300 10 --requirepass "${REDIS_PASSWORD:?REDIS_PASSWORD must be set in .env}"
|
2026-06-14 16:49:18 +08:00
|
|
|
|
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"
|
|
|
|
|
|
|
2026-07-08 21:54:57 +08:00
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# Neo4j 5 — 知识图谱存储(社区版)
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
neo4j:
|
|
|
|
|
|
image: neo4j:5-community
|
|
|
|
|
|
container_name: wecom_it_neo4j
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
environment:
|
|
|
|
|
|
NEO4J_AUTH: neo4j/${NEO4J_PASSWORD}
|
|
|
|
|
|
NEO4J_PLUGINS: '["apoc"]'
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- neo4j_data:/data
|
|
|
|
|
|
- neo4j_logs:/logs
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD-SHELL", "cypher-shell -u neo4j -p ${NEO4J_PASSWORD} 'RETURN 1'"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 10
|
|
|
|
|
|
networks:
|
|
|
|
|
|
- it-desk-internal
|
|
|
|
|
|
logging:
|
|
|
|
|
|
driver: "json-file"
|
|
|
|
|
|
options:
|
|
|
|
|
|
max-size: "10m"
|
|
|
|
|
|
max-file: "3"
|
|
|
|
|
|
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# FastAPI 后端 — 核心业务服务
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
backend:
|
|
|
|
|
|
build:
|
2026-08-03 18:46:10 +08:00
|
|
|
|
context: ./src/backend
|
2026-06-14 16:49:18 +08:00
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
|
image: wecom-it-desk-backend:latest
|
|
|
|
|
|
container_name: wecom_it_backend
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
environment:
|
|
|
|
|
|
# 企微凭证
|
|
|
|
|
|
- WECOM_CORP_ID=${WECOM_CORP_ID}
|
|
|
|
|
|
- WECOM_AGENT_ID=${WECOM_AGENT_ID}
|
|
|
|
|
|
- WECOM_SECRET=${WECOM_SECRET}
|
2026-07-11 23:13:10 +08:00
|
|
|
|
- WECOM_APPROVAL_SECRET=${WECOM_APPROVAL_SECRET:-}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
- WECOM_TOKEN=${WECOM_TOKEN}
|
|
|
|
|
|
- WECOM_ENCODING_AES_KEY=${WECOM_ENCODING_AES_KEY}
|
2026-07-17 23:08:59 +08:00
|
|
|
|
# 企微 SSO 回调地址(扫码登录用)
|
|
|
|
|
|
- WECOM_SSO_CALLBACK_BASE=${WECOM_SSO_CALLBACK_BASE:-https://itsupport.servyou.com.cn}
|
2026-07-11 23:13:10 +08:00
|
|
|
|
# ITSM 运维平台(app_id/app_secret 待申请,先占位)
|
|
|
|
|
|
- ITSM_APP_ID=${ITSM_APP_ID:-}
|
|
|
|
|
|
- ITSM_APP_SECRET=${ITSM_APP_SECRET:-}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# 数据库(Docker 内部网络,用容器名通信)
|
|
|
|
|
|
- DATABASE_URL=postgresql://${POSTGRES_USER:-wecom}:${POSTGRES_PASSWORD:-wecom_secret}@postgres:5432/${POSTGRES_DB:-wecom_it_desk}
|
|
|
|
|
|
# Redis(Docker 内部网络)
|
2026-07-18 02:16:56 +08:00
|
|
|
|
# v4.0 P1-7:密码改为 .env 注入(原硬编码已入 git 历史,2026-07-18 轮换)
|
|
|
|
|
|
# 新密码为 32 位字母数字,无需 URL 编码;若含特殊字符必须用 REDIS_PASSWORD_ENCODED
|
|
|
|
|
|
- REDIS_URL=redis://:${REDIS_PASSWORD_ENCODED:-${REDIS_PASSWORD}}@redis:6379/0
|
|
|
|
|
|
# 应用环境(v4.0 P1-7 修复:生产 UA 校验和 IP 白名单依赖此变量,此前未传入容器)
|
|
|
|
|
|
- APP_ENV=${APP_ENV:-production}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# CORS
|
|
|
|
|
|
- CORS_ORIGINS=${CORS_ORIGINS:-http://itsupport.servyou.com.cn}
|
|
|
|
|
|
# AI 服务(Dify)
|
|
|
|
|
|
- DIFY_API_URL=${DIFY_API_URL}
|
|
|
|
|
|
- DIFY_API_KEY=${DIFY_API_KEY}
|
|
|
|
|
|
- DIFY_TIMEOUT=${DIFY_TIMEOUT:-30}
|
2026-07-17 23:21:28 +08:00
|
|
|
|
# Dify 原生直连(优先于 dify2openai 代理,修复 [object Object] bug)
|
|
|
|
|
|
- DIFY_NATIVE_BASE_URL=${DIFY_NATIVE_BASE_URL:-}
|
|
|
|
|
|
- DIFY_NATIVE_API_KEY=${DIFY_NATIVE_API_KEY:-}
|
2026-08-03 18:46:10 +08:00
|
|
|
|
# Dify 双路径超时预算切分(v4.0 P0-6,20+20 < wait_for 30s)
|
|
|
|
|
|
# 2026-07-20: 12→20,用户反馈高峰期超时较多
|
|
|
|
|
|
- DIFY_NATIVE_TIMEOUT=${DIFY_NATIVE_TIMEOUT:-20}
|
|
|
|
|
|
- DIFY_PROXY_TIMEOUT=${DIFY_PROXY_TIMEOUT:-20}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# 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}
|
2026-07-17 23:08:59 +08:00
|
|
|
|
# 百度语音识别(ASR)
|
|
|
|
|
|
- BAIDU_ASR_APP_ID=${BAIDU_ASR_APP_ID:-}
|
|
|
|
|
|
- BAIDU_ASR_API_KEY=${BAIDU_ASR_API_KEY:-}
|
|
|
|
|
|
- BAIDU_ASR_SECRET_KEY=${BAIDU_ASR_SECRET_KEY:-}
|
2026-07-08 21:54:57 +08:00
|
|
|
|
# Neo4j 知识图谱
|
|
|
|
|
|
- NEO4J_URI=${NEO4J_URI:-bolt://neo4j:7687}
|
|
|
|
|
|
- NEO4J_USER=${NEO4J_USER:-neo4j}
|
|
|
|
|
|
- NEO4J_PASSWORD=${NEO4J_PASSWORD}
|
|
|
|
|
|
- NEO4J_DATABASE=${NEO4J_DATABASE:-neo4j}
|
|
|
|
|
|
- NEO4J_MAX_CONNECTION_LIFETIME=${NEO4J_MAX_CONNECTION_LIFETIME:-3600}
|
|
|
|
|
|
- NEO4J_MAX_CONNECTION_POOL_SIZE=${NEO4J_MAX_CONNECTION_POOL_SIZE:-50}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# Mock 登录(生产环境默认关闭,如需临时调试请在 .env 中显式设置为 true)
|
|
|
|
|
|
- MOCK_LOGIN_ENABLED=${MOCK_LOGIN_ENABLED:-false}
|
2026-07-13 02:17:03 +08:00
|
|
|
|
# 终端页面基础URL(用于NE2005等终端生成二维码)
|
|
|
|
|
|
- TERMINAL_BASE_URL=${TERMINAL_BASE_URL:-https://itsupport.servyou.com.cn/itterminal/}
|
2026-06-14 16:49:18 +08:00
|
|
|
|
# 服务配置
|
|
|
|
|
|
- BACKEND_HOST=0.0.0.0
|
|
|
|
|
|
- BACKEND_PORT=8000
|
2026-06-14 21:55:57 +08:00
|
|
|
|
# 上传文件目录(持久化)
|
|
|
|
|
|
- UPLOAD_DIR=/app/uploads
|
2026-07-09 13:46:48 +08:00
|
|
|
|
# 运行期日志目录(供"运行期日志"管理页面读取,需与下方 volumes 挂载一致)
|
|
|
|
|
|
- RUNTIME_LOG_DIR=/app/logs
|
2026-07-17 23:08:59 +08:00
|
|
|
|
# 安全告警(企微机器人 webhook)
|
|
|
|
|
|
- CONTENT_AUDIT_WEBHOOK=${CONTENT_AUDIT_WEBHOOK}
|
2026-06-14 21:55:57 +08:00
|
|
|
|
volumes:
|
2026-08-03 18:46:10 +08:00
|
|
|
|
# 代码热更新(生产环境:宿主机 ./src/backend/app → 容器 /app/app)
|
|
|
|
|
|
- ./src/backend/app:/app/app
|
2026-06-14 21:55:57 +08:00
|
|
|
|
- backend-uploads:/app/uploads
|
2026-07-09 13:46:48 +08:00
|
|
|
|
- ${RUNTIME_LOG_HOST_DIR:-/var/log/wecom-it-desk}:/app/logs
|
2026-06-14 16:49:18 +08:00
|
|
|
|
depends_on:
|
|
|
|
|
|
postgres:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
redis:
|
|
|
|
|
|
condition: service_healthy
|
2026-07-08 21:54:57 +08:00
|
|
|
|
neo4j:
|
|
|
|
|
|
condition: service_healthy
|
2026-06-14 16:49:18 +08:00
|
|
|
|
command: >
|
|
|
|
|
|
/bin/sh -c "
|
2026-07-05 17:03:36 +08:00
|
|
|
|
echo '>>> 启动 API 服务 (跳过迁移)...' &&
|
2026-07-09 11:50:19 +08:00
|
|
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 1
|
2026-06-14 16:49:18 +08:00
|
|
|
|
"
|
|
|
|
|
|
networks:
|
|
|
|
|
|
- it-desk-internal
|
|
|
|
|
|
healthcheck:
|
2026-06-14 21:55:57 +08:00
|
|
|
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"]
|
|
|
|
|
|
interval: 30s
|
|
|
|
|
|
timeout: 10s
|
2026-06-14 16:49:18 +08:00
|
|
|
|
retries: 3
|
2026-06-14 21:55:57 +08:00
|
|
|
|
start_period: 40s
|
2026-06-14 16:49:18 +08:00
|
|
|
|
logging:
|
|
|
|
|
|
driver: "json-file"
|
|
|
|
|
|
options:
|
|
|
|
|
|
max-size: "20m"
|
|
|
|
|
|
max-file: "5"
|
|
|
|
|
|
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
# Nginx — 反向代理 + 静态文件服务
|
|
|
|
|
|
# --------------------------------------------------------------------------
|
|
|
|
|
|
nginx:
|
|
|
|
|
|
image: nginx:1.27-alpine
|
|
|
|
|
|
container_name: wecom_it_nginx
|
|
|
|
|
|
restart: unless-stopped
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "80:80"
|
|
|
|
|
|
- "443:443"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
|
|
|
|
- ./nginx/ssl:/etc/nginx/ssl:ro
|
2026-08-03 18:46:10 +08:00
|
|
|
|
- ./src/frontend-h5/dist:/usr/share/nginx/html/itdesk:ro
|
|
|
|
|
|
- ./src/frontend-h5/dist:/usr/share/nginx/html/h5:ro
|
|
|
|
|
|
- ./src/frontend-agent/dist:/usr/share/nginx/html/itagent:ro
|
|
|
|
|
|
- ./src/frontend-admin/dist:/usr/share/nginx/html/itadmin:ro
|
|
|
|
|
|
- ./src/frontend-terminal/dist:/usr/share/nginx/html/itterminal:ro
|
2026-06-14 16:49:18 +08:00
|
|
|
|
depends_on:
|
|
|
|
|
|
- backend
|
|
|
|
|
|
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
|
2026-07-08 21:54:57 +08:00
|
|
|
|
neo4j_data:
|
|
|
|
|
|
name: wecom_it_neo4j_data
|
|
|
|
|
|
neo4j_logs:
|
|
|
|
|
|
name: wecom_it_neo4j_logs
|
2026-06-14 21:55:57 +08:00
|
|
|
|
backend-uploads:
|
|
|
|
|
|
name: wecom_it_backend_uploads
|