Files
Nexus/docs/design/plans/2026-06-04-1panel-docker-production.md
T
Nexus Deploy 7b33b745a0 feat(deploy): add 1Panel Docker one-click install script
Automates clone, docker/.env.prod, compose up, and health check for 2C8G prod stack.
2026-06-05 22:52:44 +08:00

11 KiB
Raw Blame History

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.ymldev/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(静态由 FastAPI StaticFiles 提供,无需双份 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+
内存 ≥ 4GBMySQL + 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-*.sqlnexus.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 — 一键安装(推荐)

在 1Panel 终端

export NEXUS_GITEA_TOKEN='你的Gitea令牌'
export NEXUS_DOMAIN='api.synaglobal.vip'
# 从宝塔迁机:
# export NEXUS_FROM_ENV='/www/wwwroot/api.synaglobal.vip/.env'

cd /opt/nexus 2>/dev/null && git pull || true
# 若尚未 clone,从任意目录:
curl -fsSL "http://66.154.115.8:3000/admin/Nexus/raw/branch/main/deploy/install-1panel-docker.sh" | bash
# 或已 clone 后:
# cd /opt/nexus && bash deploy/install-1panel-docker.sh --skip-clone

脚本:deploy/install-1panel-docker.shclone → .env.prodcompose up/health)。

Phase 2b — 手工准备代码与生产 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_KEY
  • NEXUS_API_KEY
  • NEXUS_ENCRYPTION_KEY
  • NEXUS_DATABASE_URL → 改为 Compose 内网:mysql+aiomysql://nexus:<密码>@mysql:3306/nexus
  • NEXUS_REDIS_URLredis://redis:6379/0
  • NEXUS_CORS_ORIGINShttps://api.synaglobal.vip
  • NEXUS_API_BASE_URLhttps://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/healthok

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

  1. 1Panel → 网站 → 创建站点 → 域名 api.synaglobal.vip
  2. HTTPS → Let's Encrypt 一键申请
  3. 反向代理 → 目标 http://127.0.0.1:8600(或「配置文件」粘贴 deploy/1panel/openresty-nexus.conf.example 内容)

要点(与 deploy/nginx_https.conf 对齐):

路径 行为
/api/ 反代 APIproxy_read_timeout 300s
/ws/ WebSocketUpgrade + 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/healthok
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 — 切流量与下线宝塔

  1. 确认新机 L5 全通过
  2. DNS api.synaglobal.vip → 新 IP(若换机)
  3. 观察 24hAgent、告警、Telegram
  4. 宝塔机:停 nexus supervisor、保留备份后关机或降级为备用

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,勿随意扩多实例)
2C8G 调优 mysql-prod-2c8g.cnf + 容器内存上限 + pool 30/20

2C8G 资源预算(约)

组件 上限
MySQL 2G 容器 / innodb_buffer_pool_size=1024M
Redis 384M 容器 / maxmemory 256mb
Nexus 2G 容器
1Panel + OS 其余 ~3G

docker/.env.prod 建议包含:NEXUS_DB_POOL_SIZE=30NEXUS_DB_MAX_OVERFLOW=20


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
内存不足 ≥4GBMySQL 可限 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 三服务 healthy
  • https://api.synaglobal.vip/healthok
  • 登录 + 文件管理 + WebSSH + 至少 1 台 Agent 心跳正常
  • 宝塔已下线或不再承担流量
  • changelog + 验收报告已写入

11. 变更记录

日期 说明
2026-06-04 初版:1Panel + Docker Compose 生产迁移 SSOT