Add Dockerfile.prod, docker-compose.prod.yml, OpenResty example, and migration plan for Baota to 1Panel + Compose deployment.
9.7 KiB
1Panel + Docker Compose 生产迁移计划
| 项 | 内容 |
|---|---|
| 日期 | 2026-06-04 |
| 状态 | 计划 — 待在新 VPS 或同机试跑后执行 |
| 目标 | 脱离宝塔,用 1Panel 管机 + Docker Compose 跑 Nexus 全栈 |
| 关联 | 2026-06-03-docker.md · docker-compose.yml · deploy/nginx_https.conf |
1. 背景与目标
1.1 现状
- 生产:
47.254.123.106/api.synaglobal.vip,宝塔 + 裸机 Git + Supervisor + Nginx - 代码:Gitea
main@811eb97+ - 本地:已有
docker-compose.yml(dev/staging),不含前端构建(Dockerfile依赖预构建web/app/)
1.2 目标架构
flowchart TB
subgraph internet [Internet]
Users[浏览器 / Agent]
Agents[2000+ Agent]
end
subgraph vps [VPS + 1Panel]
OP[OpenResty HTTPS]
subgraph compose [Docker Compose prod]
NX[nexus:8600]
MY[(mysql:3306)]
RD[(redis:6379)]
end
Vol1[(mysql-data)]
Vol2[(redis-data)]
Vol3[(nexus-state .env)]
end
Users --> OP
Agents --> OP
OP -->|127.0.0.1:8600| NX
NX --> MY
NX --> RD
MY --> Vol1
RD --> Vol2
NX --> Vol3
原则
- 1Panel:防火墙、SSL、备份、终端、Compose 编排 UI
- Nexus:单 Compose 栈(MySQL + Redis + API/静态 SPA)
- OpenResty:只反代到
127.0.0.1:8600(静态由 FastAPIStaticFiles提供,无需双份web/app) - 密钥不动:
NEXUS_SECRET_KEY/NEXUS_API_KEY/NEXUS_ENCRYPTION_KEY从宝塔.env原样迁入
2. 涉及文件清单
| 文件 | 作用 |
|---|---|
Dockerfile.prod |
多阶段:Node 构建前端 + Python 镜像 |
docker/docker-compose.prod.yml |
生产 Compose(不暴露 DB 端口、仅绑定 127.0.0.1:8600) |
docker/.env.prod.example |
生产环境变量模板(不入 Git) |
deploy/1panel/openresty-nexus.conf.example |
1Panel 网站反代参考 |
docs/project/production-verification-checklist.md |
L5 验收 |
本计划不修改 docker-compose.yml(继续服务本地 dev)。
3. 服务器前置条件
| 项 | 要求 |
|---|---|
| OS | Ubuntu 22.04+ / Debian 11+ |
| 内存 | ≥ 4GB(MySQL + Redis + Nexus + 1Panel) |
| 磁盘 | ≥ 40GB(视 Agent 历史与日志) |
| 域名 | api.synaglobal.vip A 记录指向本机 |
| 1Panel | 官方安装脚本 最新稳定版 |
| Docker | 由 1Panel 安装或自带 |
建议:在新 VPS 试跑通过后再切 DNS,宝塔旧机保留 24~48h 回滚窗口。
4. 实施步骤
Phase 0 — 备份宝塔生产(必做)
在旧宝塔机执行:
# 1) 整库备份
mysqldump -u Nexus -p nexus > /tmp/nexus-$(date +%F).sql
# 2) 复制 .env(含不可改密钥)
cp /www/wwwroot/api.synaglobal.vip/.env /tmp/nexus.env.backup
# 3) 可选:web/data
tar czf /tmp/nexus-web-data.tar.gz -C /www/wwwroot/api.synaglobal.vip/web data
将 nexus-*.sql、nexus.env.backup 下载到本机安全位置(勿提交 Git)。
Phase 1 — 安装 1Panel
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh
sudo bash quick_start.sh
记录面板地址、端口、管理员密码。
安全:改默认端口、开防火墙仅放行 22 / 443 / 面板端口。
Phase 2 — 准备代码与生产 env
在 1Panel 终端或 SSH:
export NEXUS_ROOT=/opt/nexus
sudo mkdir -p "$NEXUS_ROOT"
sudo git clone http://66.154.115.8:3000/admin/Nexus.git "$NEXUS_ROOT"
cd "$NEXUS_ROOT"
git checkout main && git pull
创建 docker/.env.prod(从 docker/.env.prod.example 复制):
cp docker/.env.prod.example docker/.env.prod
chmod 600 docker/.env.prod
nano docker/.env.prod
从宝塔 .env 原样填入(不可改项):
NEXUS_SECRET_KEYNEXUS_API_KEYNEXUS_ENCRYPTION_KEYNEXUS_DATABASE_URL→ 改为 Compose 内网:mysql+aiomysql://nexus:<密码>@mysql:3306/nexusNEXUS_REDIS_URL→redis://redis:6379/0NEXUS_CORS_ORIGINS→https://api.synaglobal.vipNEXUS_API_BASE_URL→https://api.synaglobal.vip
MySQL 密码:可用宝塔库密码,或新设强密码并在导入后统一。
Phase 3 — 构建并启动 Compose
cd /opt/nexus
docker compose -f docker/docker-compose.prod.yml --env-file docker/.env.prod up -d --build
docker compose -f docker/docker-compose.prod.yml ps
docker compose -f docker/docker-compose.prod.yml logs -f nexus
等待 MySQL healthy → Nexus entrypoint 写/恢复 .env → /health 为 ok:
curl -s http://127.0.0.1:8600/health # 期望: ok
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8600/app/ # 期望: 200
Phase 4 — 导入 MySQL 数据
# 上传 nexus-YYYY-MM-DD.sql 到 /tmp/
docker compose -f docker/docker-compose.prod.yml exec -T mysql \
mysql -uroot -p"$MYSQL_ROOT_PASSWORD" nexus < /tmp/nexus-2026-06-04.sql
验证:
docker compose -f docker/docker-compose.prod.yml exec mysql \
mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SELECT COUNT(*) FROM servers;"
注意:若库名/用户与宝塔不同,先建用户再导入;导入前建议空库或 --force 策略写进 runbook。
Phase 5 — 1Panel OpenResty 反代 + SSL
- 1Panel → 网站 → 创建站点 → 域名
api.synaglobal.vip - HTTPS → Let's Encrypt 一键申请
- 反向代理 → 目标
http://127.0.0.1:8600(或「配置文件」粘贴deploy/1panel/openresty-nexus.conf.example内容)
要点(与 deploy/nginx_https.conf 对齐):
| 路径 | 行为 |
|---|---|
/api/ |
反代 API,proxy_read_timeout 300s |
/ws/ |
WebSocket,Upgrade + Connection upgrade,超时 3600s |
/health |
反代(或仅内网探测) |
/app/ |
反代(容器内 StaticFiles) |
client_max_body_size |
100m(上传/推送) |
WS 日志:勿记录 query 中的 JWT(示例配置已用 $uri 无 $args)。
Phase 6 — 在 1Panel 中托管 Compose(可选)
1Panel → 容器 → 编排 → 导入 /opt/nexus/docker/docker-compose.prod.yml
环境文件指向 docker/.env.prod,便于 UI 启停、看日志、备份卷。
Phase 7 — L5 验收
按 docs/project/production-verification-checklist.md:
| # | 检查 | 命令/预期 |
|---|---|---|
| 1 | HTTPS health | curl -s https://api.synaglobal.vip/health → ok |
| 2 | SPA | 浏览器 /app/ 登录 |
| 3 | JWT | 未登录 /api/servers/ → 401 |
| 4 | WebSocket | 仪表盘连接、告警刷新 |
| 5 | WebSSH | 终端页连一台子机 |
| 6 | Agent | 子机心跳仍指向同域名,Redis key 有 TTL |
| 7 | 后台任务 | 10min 内 MySQL 有心跳历史写入 |
记录到 docs/reports/2026-06-04-1panel-migration-verification.md(验收后创建)。
Phase 8 — 切流量与下线宝塔
- 确认新机 L5 全通过
- DNS
api.synaglobal.vip→ 新 IP(若换机) - 观察 24h:Agent、告警、Telegram
- 宝塔机:停
nexussupervisor、保留备份后关机或降级为备用
5. 生产 Compose 与开发差异
| 项 | dev docker-compose.yml |
prod docker-compose.prod.yml |
|---|---|---|
| 构建 | Dockerfile |
Dockerfile.prod(含前端 build) |
| MySQL/Redis 端口 | 可映射宿主机 | 不映射(仅 compose 网络) |
| Nexus 端口 | 8600:8600 |
127.0.0.1:8600:8600 |
| env 文件 | docker/.env |
docker/.env.prod |
| 副本数 | 1 | 1(后台任务 primary worker,勿随意扩多实例) |
6. 日常运维
6.1 升级(Gitea 有新 commit)
cd /opt/nexus
git fetch && git reset --hard origin/main
docker compose -f docker/docker-compose.prod.yml --env-file docker/.env.prod up -d --build
curl -s http://127.0.0.1:8600/health
6.2 备份(1Panel 计划任务 + 手动)
| 对象 | 方式 |
|---|---|
| MySQL | 1Panel 数据库备份 或 mysqldump cron |
卷 nexus-state |
含持久化 .env,随卷备份 |
卷 nexus-web-data |
web/data/config.json 等 |
6.3 日志
docker compose -f docker/docker-compose.prod.yml logs -f --tail=200 nexus
7. 回滚
| 场景 | 操作 |
|---|---|
| 新版本故障 | git reset --hard <旧commit> + compose up -d --build |
| 数据库误操作 | 恢复 Phase 0 的 mysqldump |
| 切 DNS 后严重故障 | DNS 指回宝塔旧 IP;旧机 supervisorctl start nexus |
| 密钥误改 | 禁止随意重生成;从 nexus.env.backup 恢复 |
8. 风险与对策
| 风险 | 对策 |
|---|---|
| 密钥变更导致 Agent/凭据失效 | Phase 0/2 原样迁移三项 KEY |
| 多副本重复 schedule/retry | 生产 replicas: 1 |
| 前端未进镜像 | 必须用 Dockerfile.prod |
| OpenResty WS 超时 | /ws/ 读超时 ≥ 3600s |
| 内存不足 | ≥4GB;MySQL 可限 innodb_buffer_pool_size |
| 1Panel 与 Compose 端口冲突 | Nexus 仅监听 127.0.0.1:8600 |
9. 与 Coolify 的关系
本方案 不需要 Coolify。若后续要 Git push 自动构建,可在 1Panel 稳定运行后,再评估:
- 1Panel 编排 + Gitea Webhook 触发
compose up --build - 或同机加装 Coolify 仅负责 Nexus 镜像 CI
10. 验收标准(DoD)
- 1Panel 安装且仅必要端口开放
docker compose -f docker/docker-compose.prod.yml ps三服务 healthyhttps://api.synaglobal.vip/health→ok- 登录 + 文件管理 + WebSSH + 至少 1 台 Agent 心跳正常
- 宝塔已下线或不再承担流量
- changelog + 验收报告已写入
11. 变更记录
| 日期 | 说明 |
|---|---|
| 2026-06-04 | 初版:1Panel + Docker Compose 生产迁移 SSOT |