整理docker

This commit is contained in:
2026-09-01 19:15:57 +08:00
parent 47f61587af
commit e64e064306
4 changed files with 50 additions and 131 deletions
+2 -53
View File
@@ -1,17 +1,9 @@
# 汽车零部件智能报价 — 两个 MCP 服务 + 鉴权管理后台 编排 # 汽车零部件智能报价 — MCP 服务编排
# 生产环境:docker compose up -d # 生产环境:docker compose up -d
# 默认连生产库 10.100.154.100:5432,对外 10.100.154.100:8001/8002/8003/8902 # 默认连生产库 10.100.154.100:5432
# 8001 = mcp-for-erp, 8002 = mcp-for-crm # 8001 = mcp-for-erp, 8002 = mcp-for-crm
# 8003 = mcp-auth-backend(FastAPI 纯 API)
# 8902 = mcp-auth-frontend(Nginx 托管 React 静态文件,/api 反代 8003)
# 开发环境:本机直接 python server.py(不入容器)
# source .env.dev 后到 mcp-for-{erp,crm}/src 执行 python server.py
# 连开发库 47.101.220.40:5432,对外 localhost:8001/8002/8000
# 也可用 docker 跑开发:docker compose --env-file .env.dev up -d
# 停止:docker compose down # 停止:docker compose down
# 日志:docker compose logs -f # 日志:docker compose logs -f
# 网络模式 host:容器直接共享宿主网络栈,绕开 Docker 桥接 FORWARD 链,
# 便于局域网其他机器直接访问(无需 ports 映射)
services: services:
mcp-for-erp: mcp-for-erp:
build: build:
@@ -28,10 +20,7 @@ services:
- ERP_DB_USER=${ERP_DB_USER:-postgres} - ERP_DB_USER=${ERP_DB_USER:-postgres}
- ERP_DB_PASSWORD=${ERP_DB_PASSWORD:-digiwin} - ERP_DB_PASSWORD=${ERP_DB_PASSWORD:-digiwin}
- ERP_DB_NAME=${ERP_DB_NAME:-smart_quotation_auto} - ERP_DB_NAME=${ERP_DB_NAME:-smart_quotation_auto}
# 对外地址(用于 OAuth 资源元数据),按实际部署机 IP 调整
- MCP_PUBLIC_URL=${MCP_PUBLIC_URL_ERP:-http://10.100.154.100:8001} - MCP_PUBLIC_URL=${MCP_PUBLIC_URL_ERP:-http://10.100.154.100:8001}
# 鉴权(调用 mcp-auth 后端 API 校验,不直连鉴权库)
# per-service API Key:由 mcp-auth 后端签发,各服务独立
- MCP_AUTH_API_URL=${MCP_AUTH_API_URL:-http://10.100.154.100:8003} - MCP_AUTH_API_URL=${MCP_AUTH_API_URL:-http://10.100.154.100:8003}
- MCP_AUTH_API_KEY=${ERP_MCP_AUTH_API_KEY:-change-me-erp-key} - MCP_AUTH_API_KEY=${ERP_MCP_AUTH_API_KEY:-change-me-erp-key}
restart: unless-stopped restart: unless-stopped
@@ -51,47 +40,7 @@ services:
- CRM_DB_USER=${CRM_DB_USER:-postgres} - CRM_DB_USER=${CRM_DB_USER:-postgres}
- CRM_DB_PASSWORD=${CRM_DB_PASSWORD:-digiwin} - CRM_DB_PASSWORD=${CRM_DB_PASSWORD:-digiwin}
- CRM_DB_NAME=${CRM_DB_NAME:-smart_quotation_auto} - CRM_DB_NAME=${CRM_DB_NAME:-smart_quotation_auto}
# 对外地址(用于 OAuth 资源元数据),按实际部署机 IP 调整
- MCP_PUBLIC_URL=${MCP_PUBLIC_URL_CRM:-http://10.100.154.100:8002} - MCP_PUBLIC_URL=${MCP_PUBLIC_URL_CRM:-http://10.100.154.100:8002}
# 鉴权(调用 mcp-auth 后端 API 校验,不直连鉴权库)
# per-service API Key:由 mcp-auth 后端签发,各服务独立
- MCP_AUTH_API_URL=${MCP_AUTH_API_URL:-http://10.100.154.100:8003} - MCP_AUTH_API_URL=${MCP_AUTH_API_URL:-http://10.100.154.100:8003}
- MCP_AUTH_API_KEY=${CRM_MCP_AUTH_API_KEY:-change-me-crm-key} - MCP_AUTH_API_KEY=${CRM_MCP_AUTH_API_KEY:-change-me-crm-key}
restart: unless-stopped restart: unless-stopped
# MCP Auth Backend — FastAPI 纯 API 服务(端口 8003)
mcp-auth-backend:
build:
context: ./mcp-auth/backend
dockerfile: Dockerfile
image: mcp-auth-backend:latest
container_name: mcp-auth-backend
network_mode: host
environment:
- AUTH_DB_HOST=${AUTH_DB_HOST:-10.100.154.100}
- AUTH_DB_PORT=${AUTH_DB_PORT:-5432}
- AUTH_DB_USER=${AUTH_DB_USER:-postgres}
- AUTH_DB_PASSWORD=${AUTH_DB_PASSWORD:-digiwin}
- AUTH_DB_NAME=${AUTH_DB_NAME:-mcp_auth}
# 鼎捷云 IAM 鉴权配置
- IAM_BASE_URL=${IAM_BASE_URL:-https://iam.digiwincloud.com.cn}
- IAM_APP_TOKEN=${IAM_APP_TOKEN:-eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImRhdGEtYnVzaW5lc3MtZGVtbyIsInNpZCI6MH0.Spo64LstbWxjYNefVFAbEbgfjzZoQGNcqKSGuYUOCRk}
- IAM_CACHE_TTL=${IAM_CACHE_TTL:-30}
# Redis 缓存配置
- REDIS_HOST=${REDIS_HOST:-10.100.154.100}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_DB=${REDIS_DB:-0}
- REDIS_PASSWORD=${REDIS_PASSWORD:-digiwin}
restart: unless-stopped
# MCP Auth Frontend — Nginx 托管 React 静态文件,/api 反代后端 8003(端口 8902)
mcp-auth-frontend:
build:
context: ./mcp-auth/frontend
dockerfile: Dockerfile
image: mcp-auth-frontend:latest
container_name: mcp-auth-frontend
network_mode: host
environment:
- BACKEND_URL=${BACKEND_URL:-http://10.100.154.100:8003}
restart: unless-stopped
+28
View File
@@ -0,0 +1,28 @@
# MCP Auth Backend — FastAPI 纯 API 服务(端口 8003)
# 启动:docker compose up -d
# 停止:docker compose down
# 日志:docker compose logs -f
services:
mcp-auth-backend:
build:
context: .
dockerfile: Dockerfile
image: mcp-auth-backend:latest
container_name: mcp-auth-backend
network_mode: host
environment:
- AUTH_DB_HOST=${AUTH_DB_HOST:-10.100.154.100}
- AUTH_DB_PORT=${AUTH_DB_PORT:-5432}
- AUTH_DB_USER=${AUTH_DB_USER:-postgres}
- AUTH_DB_PASSWORD=${AUTH_DB_PASSWORD:-digiwin}
- AUTH_DB_NAME=${AUTH_DB_NAME:-mcp_auth}
# 鼎捷云 IAM 鉴权配置
- IAM_BASE_URL=${IAM_BASE_URL:-https://iam.digiwincloud.com.cn}
- IAM_APP_TOKEN=${IAM_APP_TOKEN:-eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImRhdGEtYnVzaW5lc3MtZGVtbyIsInNpZCI6MH0.Spo64LstbWxjYNefVFAbEbgfjzZoQGNcqKSGuYUOCRk}
- IAM_CACHE_TTL=${IAM_CACHE_TTL:-30}
# Redis 缓存配置
- REDIS_HOST=${REDIS_HOST:-10.100.154.100}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_DB=${REDIS_DB:-0}
- REDIS_PASSWORD=${REDIS_PASSWORD:-digiwin}
restart: unless-stopped
+15
View File
@@ -0,0 +1,15 @@
# MCP Auth Frontend — Nginx 托管 React 静态文件,/api 反代后端 8003(端口 8902)
# 启动:docker compose up -d
# 停止:docker compose down
# 日志:docker compose logs -f
services:
mcp-auth-frontend:
build:
context: .
dockerfile: Dockerfile
image: mcp-auth-frontend:latest
container_name: mcp-auth-frontend
network_mode: host
environment:
- BACKEND_URL=${BACKEND_URL:-http://10.100.154.100:8003}
restart: unless-stopped
+5 -78
View File
@@ -1,4 +1,4 @@
"""初始化 mcp_auth 库 + 灌入现有静态 token + 注册 MCP 服务(一次性迁移脚本)。 """初始化 mcp_auth 库 + 建表(一次性脚本)。
用法: 用法:
# 开发库(47.101.220.40) # 开发库(47.101.220.40)
@@ -7,39 +7,21 @@
# 生产库(10.100.154.100) # 生产库(10.100.154.100)
python seed.py --host 10.100.154.100 --user postgres --password digiwin python seed.py --host 10.100.154.100 --user postgres --password digiwin
幂等:可重复执行,已存在的 token / service 跳过。 幂等:可重复执行,表已存在则跳过。
""" """
import argparse import argparse
import asyncio import asyncio
import hashlib
import os import os
import secrets
from pathlib import Path from pathlib import Path
import asyncpg import asyncpg
# 现有静态 token → (client_id, service_scope, description)
# 与 docker-compose.yml 历史配置一致,迁移后可从 compose 删除
STATIC_TOKENS = [
("erp-token-trae-2026", "trae", "both", "Trae IDE 客户端(跨 ERP+CRM)"),
("erp-token-partner-a", "partner-a", "erp", "合作伙伴 A(仅 ERP)"),
("crm-token-trae-2026", "trae", "both", "Trae IDE 客户端(跨 ERP+CRM)"),
("crm-token-partner-a", "partner-a", "crm", "合作伙伴 A(仅 CRM)"),
("dev-token-trae", "trae", "both", "开发环境共用 token"),
]
# MCP 服务初始注册:service_name → description
INITIAL_SERVICES = [
("erp", "ERP 数据服务(汽车零部件智能报价)"),
("crm", "CRM 数据服务(汽车零部件智能报价)"),
]
INIT_SQL_PATH = Path(__file__).resolve().parent.parent / "sql" / "init.sql" INIT_SQL_PATH = Path(__file__).resolve().parent.parent / "sql" / "init.sql"
async def main() -> None: async def main() -> None:
parser = argparse.ArgumentParser(description="初始化 mcp_auth 库并迁移静态 token + 注册服务") parser = argparse.ArgumentParser(description="初始化 mcp_auth 库并建表")
parser.add_argument("--host", default=os.getenv("MCP_AUTH_DB_HOST", "127.0.0.1")) parser.add_argument("--host", default=os.getenv("MCP_AUTH_DB_HOST", "127.0.0.1"))
parser.add_argument("--port", type=int, default=int(os.getenv("MCP_AUTH_DB_PORT", "5432"))) parser.add_argument("--port", type=int, default=int(os.getenv("MCP_AUTH_DB_PORT", "5432")))
parser.add_argument("--user", default=os.getenv("MCP_AUTH_DB_USER", "postgres")) parser.add_argument("--user", default=os.getenv("MCP_AUTH_DB_USER", "postgres"))
@@ -65,65 +47,10 @@ async def main() -> None:
) )
init_sql = INIT_SQL_PATH.read_text(encoding="utf-8") init_sql = INIT_SQL_PATH.read_text(encoding="utf-8")
await conn.execute(init_sql) await conn.execute(init_sql)
print(f"[建表] mcp_token / mcp_token_log / admin_user / mcp_service 已就绪") print("[建表] mcp_token / mcp_token_log / admin_user / mcp_service 已就绪")
# 3. 灌入静态 token(幂等:token_hash 已存在则跳过)
inserted = 0
skipped = 0
for token, client_id, scope, desc in STATIC_TOKENS:
token_hash = hashlib.sha256(token.encode()).hexdigest()
token_prefix = token[:12] + "…"
result = await conn.execute(
"""INSERT INTO mcp_token (token_hash, token_prefix, client_id, service_scope, status, description, created_by)
VALUES ($1, $2, $3, $4, 'active', $5, 'seed.py')
ON CONFLICT (token_hash) DO NOTHING""",
token_hash, token_prefix, client_id, scope, desc,
)
if result.endswith("1"):
inserted += 1
else:
skipped += 1
print(f"[迁移] 静态 token:新增 {inserted} 条,跳过 {skipped} 条(已存在)")
# 4. 注册 MCP 服务 + 生成 per-service API Key(幂等:已存在则跳过)
print(f"[服务] 注册 MCP 服务:")
for service_name, desc in INITIAL_SERVICES:
existing = await conn.fetchrow(
"SELECT service_id FROM mcp_service WHERE service_name = $1 AND status = 'active'",
service_name,
)
if existing:
print(f" {service_name}: 已存在,跳过")
continue
plain_key = secrets.token_urlsafe(32)
key_hash = hashlib.sha256(plain_key.encode()).hexdigest()
await conn.execute(
"""INSERT INTO mcp_service (service_name, api_key, api_key_hash, description, created_by)
VALUES ($1, $2, $3, $4, 'seed.py')""",
service_name, plain_key, key_hash, desc,
)
print(f" {service_name}: API Key = {plain_key}")
print(f" → 配置到 MCP 服务的 MCP_AUTH_API_KEY 环境变量")
# 5. 列出当前 token 概览
rows = await conn.fetch(
"SELECT token_prefix, client_id, service_scope, status FROM mcp_token ORDER BY token_id"
)
print(f"\n[概览] mcp_token 表共 {len(rows)} 条:")
for r in rows:
print(f" {r['token_prefix']:<16} client={r['client_id']:<12} scope={r['service_scope']:<6} status={r['status']}")
svc_rows = await conn.fetch(
"SELECT service_name, api_key, status FROM mcp_service ORDER BY service_id"
)
print(f"\n[概览] mcp_service 表共 {len(svc_rows)} 条:")
for r in svc_rows:
print(f" {r['service_name']:<8} api_key={r['api_key']:<44} status={r['status']}")
await conn.close() await conn.close()
print("\n[完成] MCP 服务 API Key 仅在本次输出,请立即保存到 .env.dev")
print("\n[完成] 数据库初始化完毕,种子数据请通过管理后台操作")
if __name__ == "__main__": if __name__ == "__main__":