整理docker
This commit is contained in:
+2
-53
@@ -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
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
@@ -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__":
|
||||||
|
|||||||
Reference in New Issue
Block a user