feat(deploy): 容器化 + 一键独立部署 —— 5 服务镜像 + prod compose + 安装/备份/许可

此前应用服务只是本机裸二进制、无 Dockerfile、无法交付。本提交把项目从"只能在我笔记本
跑"变成"任何人一条命令起一整套",是「演示 / 拉投资 / 卖给客户独立部署」的可交付基础。

- Dockerfile ×5:gateway/dispatcher/mcp-go 多阶段(distroless static, 36–55MB);
  mcp-py(python-slim, 268MB);admin(node 构建→nginx 托管 SPA + 反代 /api,76MB)。
  Go 构建上下文为仓库根以兜住 replace ../sundynix-shared;.dockerignore 瘦上下文。
- docker-compose.prod.yml:应用 + 基建一把起;经服务名互连(顺带避开 localhost DNS 坑);
  基建端口不对宿主暴露;depends_on 健康检查保序(mcp-go 待 Milvus healthy);
  APP_ENV=production 强制密钥校验 + 锁 CORS + 管理员白名单。
- .env.example + DEPLOY.md:两类密钥分层(引导密钥走 .env,模型 key 控制台加密存库);
  首次管理员流程;安全建议。LICENSE 专有(授权模型可后定)。
- scripts/backup.sh + restore.sh:PG 逻辑备份 + 各数据卷快照 / 恢复。
- .gitignore 挡 .env*(密钥不入库)。

live:5 镜像全构建通过;独立 project 起整套 → nginx→gateway→NATS→dispatcher→mcp 全链路
注册+提任务 running→done,depends_on 保序生效。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-26 15:23:36 +08:00
parent 165ecb4ec6
commit a5fd251fc0
17 changed files with 545 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
node_modules
dist
.env
+15
View File
@@ -0,0 +1,15 @@
# 运维控制台:node 构建 SPA → nginx 托管 + 反代网关 API(一个 URL 访问整套)。
# docker build -t sundynix/admin sundynix-admin
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# VITE_GATEWAY 留空 → 前端走相对路径 /api/...,由 nginx 反代到 gateway(同源、免跨域)。
ENV VITE_GATEWAY=""
RUN npm run build
FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
+30
View File
@@ -0,0 +1,30 @@
# 运维控制台静态托管 + 反代网关 API(一个 URL 同时给前端与 /api)。
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# SPA 路由:找不到文件回退 index.html(前端路由接管)。
location / {
try_files $uri $uri/ /index.html;
}
# 网关 API:反代到 compose 网络内的 gateway 服务。
location /api/ {
proxy_pass http://gateway:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# SSE(token 流 / 执行轨迹):关闭缓冲 + 长超时,否则流式会被攒住/断开。
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 1h;
proxy_send_timeout 1h;
}
# 健康/指标直通(运维探活)。
location = /healthz { proxy_pass http://gateway:8080; }
location = /readyz { proxy_pass http://gateway:8080; }
}