2026-08-06-test-env-bare-metal-deploy.md 13 KB

测试环境裸机部署 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 在 101.35.245.122 的 /root/zkxw 以裸机方式部署 web-admin(Nginx :10001)与 backend(127.0.0.1:10002),中间件复用本机开发环境的 47.99.164.66。

Architecture: 本机 pnpm build:test + rsync 前端静态资源;本机 rsync backend 源码;测试机安装 Nginx、用已有 Python 3.12.3 建 .venv、start-test.sh 绑定本机回环。Nginx 反代 /api 与 /health,不反代 MinIO。

Tech Stack: Nginx、Python 3.12.3 + venv + uvicorn、backend/start-test.sh、Vue 3 web-admin(pnpm build:test)、rsync/ssh

Spec: docs/superpowers/specs/2026-08-06-test-env-bare-metal-deploy-design.md


File Structure

路径 职责
测试环境部署/zkxw-test-10001.conf 新建:测试机 Nginx server 块(10001)
测试环境部署/README.md 改写:新拓扑、端口、安装与发版步骤
web-admin/.env.test 仅更新注释中的访问入口 IP/端口
docs/superpowers/specs/2026-08-06-test-env-bare-metal-deploy-design.md 已存在,实现时勿改需求;若步骤偏差仅改计划
服务器 /root/zkxw/** 运行时产物与 .env.test(不进 git)
测试环境机器的账号密码 仅本机 SSH 用,禁止 commit / 写入计划正文

不新建 Docker compose;不在服务器装 Node。


Task 1: 仓库内新增 Nginx site 片段

Files:

  • Create: 测试环境部署/zkxw-test-10001.conf

  • [ ] Step 1: 创建完整 Nginx 配置文件

写入以下内容(无 MinIO 反代;API/health 指向本机 10002):

# ZKXW 测试环境(裸机)— 部署到 101.35.245.122
# 用法(按发行版二选一):
#   Ubuntu/Debian: 复制到 /etc/nginx/sites-available/zkxw-test-10001.conf
#                  ln -sf ... /etc/nginx/sites-enabled/
#   RHEL/CentOS:   复制到 /etc/nginx/conf.d/zkxw-test-10001.conf
#   nginx -t && systemctl reload nginx

server {
    listen 10001;
    listen [::]:10001;
    server_name 101.35.245.122 localhost 127.0.0.1;

    root /root/zkxw/web-admin/dist;
    index index.html;

    client_max_body_size 100M;

    access_log /var/log/nginx/zkxw_admin_10001_access.log;
    error_log  /var/log/nginx/zkxw_admin_10001_error.log;

    location = /health {
        proxy_pass http://127.0.0.1:10002/health;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_connect_timeout 10s;
        proxy_read_timeout 30s;
    }

    location ^~ /docs {
        proxy_pass http://127.0.0.1:10002;
        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;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location = /openapi.json {
        proxy_pass http://127.0.0.1:10002/openapi.json;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
    }

    location ^~ /api/ {
        proxy_pass http://127.0.0.1:10002;
        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;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 10s;
        proxy_send_timeout 120s;
        proxy_read_timeout 120s;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}
  • Step 2: 本地核对关键指令

Run:

grep -E 'listen|proxy_pass|root |minio' 测试环境部署/zkxw-test-10001.conf

Expected: listen 10001;root /root/zkxw/web-admin/dist;proxy_pass 均为 127.0.0.1:10002;无 minio 行。

  • Step 3: Commit(仅当用户要求提交时执行;否则跳过)
git add 测试环境部署/zkxw-test-10001.conf
git commit -m "$(cat <<'EOF'
docs: add nginx site for test env on port 10001

EOF
)"

Task 2: 更新测试部署 README 与前端 env 注释

Files:

  • Modify: 测试环境部署/README.md(全文按新拓扑重写核心章节;可保留文末修订记录并追加一行)
  • Modify: web-admin/.env.test(仅注释)

  • [ ] Step 1: 重写 测试环境部署/README.md 关键

用下列结构覆盖/重写文档(保留必要历史可放「修订记录」)。正文不要写入任何数据库密码或机器 root 密码。

必须包含:

  1. 拓扑表:
角色 地址
入口 http://101.35.245.122:10001
Nginx 静态 /root/zkxw/web-admin/dist
后端 127.0.0.1:10002(仅本机)
中间件 与本机 backend/.env 相同(47.99.164.66)
MinIO 浏览器 http://47.99.164.66:20004/zkxw(直连,Nginx 不反代)
  1. 机装:Python 已有 3.12.3;需安装 Nginx;探测 apt/yum/dnf 后安装示例:
# Debian/Ubuntu
sudo apt-get update && sudo apt-get install -y nginx

# RHEL/CentOS/Alma(示例)
sudo yum install -y nginx   # 或 dnf install -y nginx
sudo systemctl enable --now nginx
  1. 目录、.env.test 来源(从本机 backend/.env 复制为服务器 .env.test)、启动:
cd /root/zkxw/backend
python3.12 -m venv .venv
./.venv/bin/pip install -U pip
./.venv/bin/pip install -r requirements.txt
HOST=127.0.0.1 PORT=10002 ./start-test.sh start
  1. Nginx 启用 zkxw-test-10001.conf 的命令。

  2. 日常发版 rsync 命令(与 spec §6.2 一致)。

  3. 验收 curl(与 spec §7 一致)。

  4. 说明:旧 8112 / 双机拓扑已废弃,以本文件为准。

  • Step 2: 更新 web-admin/.env.test 注释

将文件头注释改为类似:

# Web Admin 测试环境(打包:pnpm build:test)
# 访问入口:http://101.35.245.122:10001
# Nginx 将 /api 反代至本机 127.0.0.1:10002
# MinIO:浏览器直连 http://47.99.164.66:20004/zkxw(不经测试机 Nginx)

保持现有 VITE_* 变量值不变(VITE_API_URL=/api、VITE_MINIO_BASE_URL=http://47.99.164.66:20004/zkxw 等)。

  • Step 3: Commit(仅当用户要求时)
git add 测试环境部署/README.md web-admin/.env.test
git commit -m "$(cat <<'EOF'
docs: document bare-metal test deploy on 10001/10002

EOF
)"

Task 3: SSH 探测服务器并安装 Nginx

Files: 无仓库文件;操作目标 101.35.245.122

前置:本机可 SSH 登录(密钥或密码)。不要把密码写进仓库或命令历史脚本文件。

  • Step 1: 探测 OS、Python、端口占用
ssh root@101.35.245.122 'set -e
uname -a
cat /etc/os-release | head -20
python3.12 --version || python3 --version
which nginx || true
ss -lntp | grep -E "10001|10002" || true
mkdir -p /root/zkxw/web-admin/dist /root/zkxw/backend /root/zkxw/nginx
'

Expected: Python 显示 3.12.x;nginx 可能不存在;目录创建成功。

  • Step 2: 按发行版安装 Nginx 并开机自启

若 ID 为 ubuntu/debian:

ssh root@101.35.245.122 'export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y nginx
systemctl enable nginx
systemctl start nginx
nginx -v
'

若为 rhel/centos/almalinux/rocky:

ssh root@101.35.245.122 'yum install -y nginx || dnf install -y nginx
systemctl enable nginx
systemctl start nginx
nginx -v
'

Expected: nginx version: nginx/...

  • Step 3: 上传并启用 site
scp 测试环境部署/zkxw-test-10001.conf root@101.35.245.122:/root/zkxw/nginx/zkxw-test-10001.conf

然后在服务器上(按 Step 1 探测结果选一条路径):

Debian/Ubuntu:

ssh root@101.35.245.122 '
cp /root/zkxw/nginx/zkxw-test-10001.conf /etc/nginx/sites-available/zkxw-test-10001.conf
ln -sfn /etc/nginx/sites-available/zkxw-test-10001.conf /etc/nginx/sites-enabled/zkxw-test-10001.conf
# 若 default 占口冲突可保留;本 site 仅 10001
nginx -t && systemctl reload nginx
'

RHEL 系:

ssh root@101.35.245.122 '
cp /root/zkxw/nginx/zkxw-test-10001.conf /etc/nginx/conf.d/zkxw-test-10001.conf
nginx -t && systemctl reload nginx
'

Expected: nginx: configuration file ... test is successful

  • Step 4: 提醒安全组

确认云控制台入站已放行 TCP 10001(本步无法在代码中完成;执行者勾选确认)。


Task 4: 部署 backend 并启动

Files: 服务器 /root/zkxw/backend;本机源 backend/

  • Step 1: rsync 源码

在仓库根目录执行:

rsync -avz \
  --exclude '.venv' \
  --exclude 'venv' \
  --exclude '__pycache__' \
  --exclude '*.pyc' \
  --exclude 'logs' \
  --exclude 'graphify-out' \
  --exclude '.env' \
  --exclude '.env.*' \
  backend/ root@101.35.245.122:/root/zkxw/backend/

Expected: start-test.sh、requirements.txt、app/ 出现在远端。

  • Step 2: 生成并上传 .env.test(不进 git)

本机:

cp backend/.env /tmp/zkxw-env.test
# 确认中间件段与开发一致;勿把 /tmp/zkxw-env.test 加入 git
scp /tmp/zkxw-env.test root@101.35.245.122:/root/zkxw/backend/.env.test
rm -f /tmp/zkxw-env.test
  • Step 3: 建 venv 并装依赖
ssh root@101.35.245.122 '
set -e
cd /root/zkxw/backend
python3.12 -m venv .venv
./.venv/bin/pip install -U pip
./.venv/bin/pip install -r requirements.txt
./.venv/bin/python -c "import uvicorn; print(uvicorn.__version__)"
chmod +x start-test.sh
'

Expected: 打印 uvicorn 版本;无 pip 失败。

  • Step 4: 探测中间件连通性(从测试机)
ssh root@101.35.245.122 '
set -e
timeout 5 bash -c "echo >/dev/tcp/47.99.164.66/3306" && echo mysql_ok
timeout 5 bash -c "echo >/dev/tcp/47.99.164.66/16379" && echo redis_ok
timeout 5 bash -c "echo >/dev/tcp/47.99.164.66/20004" && echo minio_ok
'

Expected: 三行 *_ok。若失败:先修安全组/防火墙,不要继续启动(否则后端会连库失败)。

  • Step 5: 启动后端
ssh root@101.35.245.122 '
cd /root/zkxw/backend
HOST=127.0.0.1 PORT=10002 ./start-test.sh start
HOST=127.0.0.1 PORT=10002 ./start-test.sh status
curl -s http://127.0.0.1:10002/health
'

Expected: status 为 RUNNING;health 返回 JSON/成功体(非连接拒绝)。


Task 5: 本机打包前端并 rsync

Files:

  • Build: web-admin/dist/
  • Remote: /root/zkxw/web-admin/dist/

  • [ ] Step 1: 打包

cd web-admin
pnpm install
pnpm build:test
ls dist/index.html

Expected: dist/index.html 存在。

  • Step 2: 上传
rsync -avz --delete web-admin/dist/ root@101.35.245.122:/root/zkxw/web-admin/dist/

(在仓库根执行时路径如上;若已在 web-admin 目录则用 dist/。)

Expected: rsync 完成无 error。


Task 6: 端到端验收

  • Step 1: 本机/外网验收命令
curl -s -o /dev/null -w '%{http_code}\n' http://101.35.245.122:10001/
curl -s http://101.35.245.122:10001/health
curl -s -o /dev/null -w '%{http_code}\n' --connect-timeout 5 http://101.35.245.122:10002/health || echo '10002_closed_ok'

Expected:

  • 第一行:200
  • 第二行:健康检查成功响应
  • 第三行:失败或超时,并打印 10002_closed_ok(证明未对公网开放)

  • [ ] Step 2: API 冒烟

curl -s -o /dev/null -w '%{http_code}\n' \
  http://101.35.245.122:10001/api/web/auth/login-rsa-public-key

Expected: 200(或业务约定的成功码;非 502/504)。

  • Step 3: 浏览器手工

打开 http://101.35.245.122:10001/,确认页面加载;用测试账号登录(默认文档账号以环境实际为准,常见 admin)。附件若打不开,检查浏览器到 47.99.164.66:20004 是否可达。

  • Step 4: 更新设计/README 修订记录(可选)

在 测试环境部署/README.md 修订记录追加:2026-08-06 | 裸机部署 10001/10002 于 101.35.245.122。

  • Step 5: Commit 仓库文档变更(仅当用户要求)

将 Task 1–2 产生的仓库文件与本计划、spec 一并提交(排除 测试环境机器的账号密码、任何 .env.test)。


Spec coverage (self-review)

Spec 要求 Task
无 Docker 应用部署 Task 3–5(裸机)
Nginx 10001 + 静态 + /api + /health Task 1, 3
后端 127.0.0.1:10002 Task 4
中间件照搬本机 .env Task 4 Step 2
MinIO 直连不反代 Task 1(配置无 minio)、验收说明
安装 Nginx;Python 用 3.12.3 Task 3, 4
本机 build:test + rsync Task 5
验收清单 Task 6
更新 README / env 注释 / nginx 片段 Task 1–2
不提交密钥 全文约束

Placeholder scan: 无 TBD;发行版分支在 Task 3 用探测后二选一,非占位。


Execution notes for agents

  • SSH 失败时先修网络/密钥,勿把 root 密码写入 git。
  • start-test.sh 每次启停都带上 HOST=127.0.0.1 PORT=10002,避免回到默认 0.0.0.0:8112。
  • 依赖安装若因缺少 python3.12-venv 失败:Debian 上 apt-get install -y python3.12-venv 后再建 venv。