Files
Blizzard a5fd251fc0 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>
2026-06-26 15:23:36 +08:00

39 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# 备份 sundynix-agentix 全部有状态数据(PG / Neo4j / Milvus / MinIO / NATS-JetStream)。
# 用法:scripts/backup.sh [输出目录] 默认 ./backups/<时间戳>
# 建议 cron 每日跑,产物拷到异机。
set -euo pipefail
COMPOSE="docker compose -f docker-compose.prod.yml"
TS="$(date +%Y%m%d-%H%M%S)"
OUT="${1:-./backups/$TS}"
mkdir -p "$OUT"
echo "[backup] → $OUT"
# PostgreSQL:逻辑备份(可跨版本恢复)。
echo "[backup] postgres…"
$COMPOSE exec -T postgres pg_dump -U sundynix sundynix | gzip > "$OUT/postgres.sql.gz"
# Neo4j:在线 dump(社区版用 cypher-shell 导出关系;这里用 APOC/dump 兼容写法的简化版——
# 社区版无 neo4j-admin 在线 dump,改为停服卷拷或用 cypher 导出。此处导出全图为 cypher。)
echo "[backup] neo4j…"
$COMPOSE exec -T neo4j sh -lc 'command -v neo4j-admin >/dev/null 2>&1 && neo4j-admin database dump neo4j --to-stdout 2>/dev/null' \
> "$OUT/neo4j.dump" 2>/dev/null || echo "[backup] neo4j 在线 dump 不可用(社区版),改用卷快照见下"
# 数据卷快照(Milvus / MinIO / Neo4j 兜底 / JetStream):用临时容器打 tar。
backup_volume () { # $1=卷名 $2=输出文件
local vol; vol="$($COMPOSE config --volumes | grep -E "^${1}\$" || true)"
local full="$(docker volume ls --format '{{.Name}}' | grep -E "_${1}\$" | head -1)"
[ -z "$full" ] && { echo "[backup] 卷 $1 未找到,跳过"; return; }
echo "[backup] volume $full"
docker run --rm -v "$full":/data -v "$(cd "$OUT" && pwd)":/out alpine \
sh -c "cd /data && tar czf /out/$2 ."
}
backup_volume milvus_data milvus_data.tar.gz
backup_volume minio_data minio_data.tar.gz
backup_volume neo4j_data neo4j_data.tar.gz
backup_volume nats_data nats_data.tar.gz
echo "[backup] 完成。务必另存 .env(含 SUNDYNIX_SECRET_KEY,丢了模型密钥全废):cp .env $OUT/env.bak"
echo "$OUT"