19 KiB
Tencent IP Port Dev Deploy Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 将当前 ForgeFlow ERP 前后端部署到腾讯云 1Panel Ubuntu 服务器,临时开启动态加载,通过 公网 IP + 端口 访问,数据库继续连接阿里云 MySQL。
Architecture: 临时测试阶段不走域名、HTTPS、Nginx/OpenResty 反代。浏览器访问 Vite dev server http://腾讯云公网IP:5173,前端请求 FastAPI http://腾讯云公网IP:8000/api,后端连接阿里云 MySQL 121.40.97.156:3306。稳定后再切到正式生产架构:前端静态构建、OpenResty 反代 /api、HTTPS、后端仅监听本机。
Tech Stack: Ubuntu 22.04/1Panel, Python 3, FastAPI/Uvicorn, Vue 3/Vite, Node.js 20, MySQL on Aliyun.
Phase 0: 部署边界确认
本计划只做临时测试部署,不代表最终生产配置。
临时测试访问方式:
浏览器
-> http://<腾讯云公网IP>:5173
Vite dev server,支持前端热更新
前端 API 请求
-> http://<腾讯云公网IP>:8000/api
FastAPI/Uvicorn,使用 --reload 支持后端动态加载
后端数据库连接
-> 121.40.97.156:3306
阿里云 MySQL
需要提前准备的信息:
export TENCENT_IP="<腾讯云服务器公网IP>"
export ALIYUN_MYSQL_HOST="121.40.97.156"
export ALIYUN_MYSQL_PORT="3306"
export ERP_DB_NAME="jiaheng_erp"
export ERP_DB_USER="<数据库用户名>"
export ERP_DB_PASSWORD="<数据库密码>"
本阶段必须接受的临时风险:
5173和8000会临时暴露在公网,只适合测试期。- Vite dev server 和
uvicorn --reload不是最终生产运行方式。 - 如果直接连现有阿里云数据库,腾讯云上的操作会真实写入同一个库。
- 数据库账号不要长期使用
root,至少正式前要换成 ERP 专用账号。
Phase 1: 腾讯云服务器基础准备
Task 1: 登录服务器并确认系统
- Step 1: SSH 登录腾讯云服务器
ssh root@<腾讯云公网IP>
Expected:
成功进入 Ubuntu shell
- Step 2: 确认系统版本和架构
uname -a
lsb_release -a || cat /etc/os-release
Expected:
Linux VM-0-14-ubuntu ...
Ubuntu ...
x86_64
Task 2: 安装基础依赖
- Step 1: 更新 apt 包索引
sudo apt update
Expected:
Reading package lists... Done
- Step 2: 安装 Python、构建工具、Git、MySQL 客户端
sudo apt install -y git curl build-essential python3 python3-venv python3-pip mysql-client tmux
Expected:
git, curl, python3, python3-venv, mysql-client, tmux 安装完成
- Step 3: 安装 Node.js 20
如果当前没有 Node,或者 node -v 低于 20,执行:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
验证:
node -v
npm -v
Expected:
v20.x.x
10.x.x 或更高
Phase 2: 网络和防火墙放行
Task 3: 腾讯云安全组放行临时端口
- Step 1: 在腾讯云控制台安全组放行 TCP 端口
放行入站规则:
TCP 5173 来源:你的办公公网 IP/32
TCP 8000 来源:你的办公公网 IP/32
TCP 22 来源:你的办公公网 IP/32
如果测试人员公网 IP 不固定,临时可用:
TCP 5173 来源:0.0.0.0/0
TCP 8000 来源:0.0.0.0/0
但这只能用于短期测试,稳定后必须收口。
Expected:
外网可以访问 5173 和 8000,不再被腾讯云安全组拦截
Task 4: 1Panel 或 Ubuntu 防火墙放行端口
- Step 1: 如果使用 1Panel 防火墙,在 1Panel 面板中放行
端口:5173/tcp
端口:8000/tcp
- Step 2: 如果服务器启用了 ufw,执行放行
sudo ufw allow 5173/tcp
sudo ufw allow 8000/tcp
sudo ufw status
Expected:
5173/tcp ALLOW
8000/tcp ALLOW
Task 5: 阿里云 MySQL 放行腾讯云公网 IP
- Step 1: 在阿里云服务器或 RDS 安全组中放行腾讯云公网 IP
放行规则:
入站 TCP 3306 来源:<腾讯云公网IP>/32
- Step 2: 在腾讯云服务器测试 MySQL 连通性
mysql -h 121.40.97.156 -P 3306 -u <数据库用户名> -p -e "SELECT NOW() AS db_time;"
Expected:
+---------------------+
| db_time |
+---------------------+
| 2026-... |
+---------------------+
如果报错:
ERROR 2003 Can't connect to MySQL server
处理方向:
优先检查阿里云安全组、MySQL bind-address、防火墙、账号 Host 权限。
Phase 3: 部署项目代码
Task 6: 准备项目目录
- Step 1: 创建部署目录
sudo mkdir -p /opt/ForgeFlow-ERP
sudo chown -R $USER:$USER /opt/ForgeFlow-ERP
Expected:
/opt/ForgeFlow-ERP 可由当前用户读写
Task 7: 上传或拉取代码
推荐方式 A:服务器可以访问 Git 仓库时使用 git clone。
- Step 1A: 克隆项目
cd /opt
git clone <ForgeFlow-ERP仓库地址> ForgeFlow-ERP
cd /opt/ForgeFlow-ERP
git status
Expected:
On branch ...
working tree clean
推荐方式 B:如果仓库暂时不方便从服务器拉取,就从 Mac 同步代码。
- Step 1B: 在 Mac 上执行 rsync 上传
rsync -av --delete \
--exclude 'frontend/node_modules' \
--exclude 'backend/.venv' \
--exclude '.git' \
/Users/souplearn/Gitlab/py/ForgeFlow-ERP/ \
root@<腾讯云公网IP>:/opt/ForgeFlow-ERP/
Expected:
代码同步到 /opt/ForgeFlow-ERP
- Step 2: 在服务器确认目录结构
cd /opt/ForgeFlow-ERP
ls -la
ls -la backend frontend
Expected:
backend/
frontend/
README.md
Phase 4: 后端动态加载部署
Task 8: 配置后端 .env
- Step 1: 创建后端环境变量文件
cd /opt/ForgeFlow-ERP/backend
cp .env.example .env
- Step 2: 编辑
.env
nano /opt/ForgeFlow-ERP/backend/.env
推荐内容:
APP_NAME=Baihua Hardware ERP API
APP_ENV=staging-dev
APP_HOST=0.0.0.0
APP_PORT=8000
MYSQL_HOST=121.40.97.156
MYSQL_PORT=3306
MYSQL_DATABASE=jiaheng_erp
MYSQL_USER=<数据库用户名>
MYSQL_PASSWORD=<数据库密码>
ALLOWED_ORIGINS=http://<腾讯云公网IP>:5173
AUTH_SECRET_KEY=<生成一串至少32位的随机字符串>
AUTH_TOKEN_EXPIRE_MINUTES=480
生成随机密钥:
python3 - <<'PY'
import secrets
print(secrets.token_urlsafe(48))
PY
Expected:
输出一串随机字符串,将它填入 AUTH_SECRET_KEY
注意:
不要把正式数据库密码、AUTH_SECRET_KEY 发到聊天或提交到 Git。
Task 9: 安装后端依赖
- Step 1: 创建虚拟环境
cd /opt/ForgeFlow-ERP/backend
python3 -m venv .venv
- Step 2: 安装依赖
cd /opt/ForgeFlow-ERP/backend
. .venv/bin/activate
pip install -U pip
pip install -r requirements.txt
Expected:
Successfully installed fastapi uvicorn sqlalchemy pymysql ...
Task 10: 临时启动后端动态加载
- Step 1: 用 tmux 启动后端
tmux new -s forgeflow-backend
在 tmux 窗口内执行:
cd /opt/ForgeFlow-ERP/backend
. .venv/bin/activate
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
Expected:
Uvicorn running on http://0.0.0.0:8000
Started reloader process
退出 tmux 但保留进程:
按 Ctrl+B,然后按 D
- Step 2: 服务器本机验证后端
curl -s http://127.0.0.1:8000/ | python3 -m json.tool
curl -s http://127.0.0.1:8000/api/system/health | python3 -m json.tool
Expected:
{
"app": "ok",
"database": {
"connected": true
}
}
- Step 3: Mac 或浏览器外网验证后端
curl -s http://<腾讯云公网IP>:8000/api/system/health
Expected:
能返回 app ok,database connected true
Phase 5: 前端动态加载部署
Task 11: 配置前端 .env
- Step 1: 创建前端环境变量文件
cd /opt/ForgeFlow-ERP/frontend
cp .env.example .env
- Step 2: 修改 API 地址
nano /opt/ForgeFlow-ERP/frontend/.env
内容:
VITE_API_BASE_URL=http://<腾讯云公网IP>:8000/api
Expected:
前端所有 API 请求都会打到腾讯云后端 8000 端口
Task 12: 安装前端依赖
- Step 1: 安装 npm 依赖
cd /opt/ForgeFlow-ERP/frontend
npm install
Expected:
added ... packages
Task 13: 临时启动前端动态加载
- Step 1: 用 tmux 启动前端
tmux new -s forgeflow-frontend
在 tmux 窗口内执行:
cd /opt/ForgeFlow-ERP/frontend
npm run dev -- --host 0.0.0.0 --port 5173
Expected:
VITE v5.x.x ready
Local: http://localhost:5173/
Network: http://<内网IP>:5173/
退出 tmux 但保留进程:
按 Ctrl+B,然后按 D
- Step 2: 服务器本机验证前端
curl -I http://127.0.0.1:5173
Expected:
HTTP/1.1 200 OK
- Step 3: 浏览器访问
http://<腾讯云公网IP>:5173/login?redirect=/
Expected:
出现 ERP 登录页
Phase 6: 测试期进程守护
tmux 适合第一天快速验证。如果需要测试环境持续跑几天,建议改成 systemd 管理,但仍然保留动态加载。
Task 14: 创建后端 dev systemd 服务
- Step 1: 创建服务文件
sudo nano /etc/systemd/system/forgeflow-backend-dev.service
内容:
[Unit]
Description=ForgeFlow ERP Backend Dev Reload
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/ForgeFlow-ERP/backend
ExecStart=/opt/ForgeFlow-ERP/backend/.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
Restart=always
RestartSec=3
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
- Step 2: 启动服务
sudo systemctl daemon-reload
sudo systemctl enable forgeflow-backend-dev
sudo systemctl start forgeflow-backend-dev
sudo systemctl status forgeflow-backend-dev --no-pager
Expected:
Active: active (running)
- Step 3: 查看日志
journalctl -u forgeflow-backend-dev -f
Expected:
Uvicorn running on http://0.0.0.0:8000
Task 15: 创建前端 dev systemd 服务
- Step 1: 查出 npm 路径
which npm
Expected:
/usr/bin/npm
- Step 2: 创建服务文件
sudo nano /etc/systemd/system/forgeflow-frontend-dev.service
如果 which npm 输出 /usr/bin/npm,内容如下:
[Unit]
Description=ForgeFlow ERP Frontend Vite Dev Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/ForgeFlow-ERP/frontend
ExecStart=/usr/bin/npm run dev -- --host 0.0.0.0 --port 5173
Restart=always
RestartSec=3
Environment=NODE_ENV=development
[Install]
WantedBy=multi-user.target
- Step 3: 启动服务
sudo systemctl daemon-reload
sudo systemctl enable forgeflow-frontend-dev
sudo systemctl start forgeflow-frontend-dev
sudo systemctl status forgeflow-frontend-dev --no-pager
Expected:
Active: active (running)
- Step 4: 查看日志
journalctl -u forgeflow-frontend-dev -f
Expected:
VITE v5.x.x ready
Phase 7: 动态加载更新流程
Task 16: 代码更新后验证热加载
- Step 1: 更新代码
如果使用 Git:
cd /opt/ForgeFlow-ERP
git pull
如果使用 rsync,在 Mac 重新执行同步命令:
rsync -av --delete \
--exclude 'frontend/node_modules' \
--exclude 'backend/.venv' \
--exclude '.git' \
/Users/souplearn/Gitlab/py/ForgeFlow-ERP/ \
root@<腾讯云公网IP>:/opt/ForgeFlow-ERP/
- Step 2: 如果只改后端 Python 代码
Expected:
uvicorn --reload 自动重载,无需手动重启
验证:
journalctl -u forgeflow-backend-dev -n 80 --no-pager
- Step 3: 如果改前端 Vue/CSS/JS
Expected:
Vite dev server 自动热更新浏览器页面
验证:
journalctl -u forgeflow-frontend-dev -n 80 --no-pager
- Step 4: 如果改了依赖
后端依赖变更:
cd /opt/ForgeFlow-ERP/backend
. .venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart forgeflow-backend-dev
前端依赖变更:
cd /opt/ForgeFlow-ERP/frontend
npm install
sudo systemctl restart forgeflow-frontend-dev
Expected:
依赖安装成功,服务重启成功
Phase 8: 功能验收清单
Task 17: 登录和基础页面验收
- Step 1: 打开登录页
http://<腾讯云公网IP>:5173/login?redirect=/
Expected:
登录页正常渲染,浏览器控制台无 CORS 报错
- Step 2: 登录 ERP
Expected:
登录成功,进入首页
- Step 3: 打开浏览器开发者工具 Network
Expected:
API 请求地址是 http://<腾讯云公网IP>:8000/api/...
状态码不是 CORS error
Task 18: 核心业务验收
- Step 1: 基础资料页面
验证:
供应商名录、客户名录、原材料名录、产品需规清单能打开
- Step 2: 订单与采购页面
验证:
销售订单列表、采购订单、到货入库、质量校验能打开
- Step 3: 仓库页面
验证:
百华仓库六大库能打开,出入库弹窗能打开
- Step 4: 生产执行页面
验证:
工单台账、工序报工能打开
- Step 5: 发货概览页面
验证:
发货台账能打开
Task 19: Excel 导入导出验收
- Step 1: 测试导出
验证:
供应商名录、原材料名录、客户名录、仓库期初模板、盘库清单导出正常
- Step 2: 测试导入
验证:
上传 Excel 时无 413、CORS、权限、临时目录报错
- Step 3: 检查响应头
Expected:
浏览器能识别 Content-Disposition,下载文件名正常
说明:
后端 CORS 已 expose Content-Disposition,只要 ALLOWED_ORIGINS 配对即可。
Phase 9: 常见故障处理
Task 20: 前端页面打不开
- Step 1: 检查 Vite 服务
sudo systemctl status forgeflow-frontend-dev --no-pager
journalctl -u forgeflow-frontend-dev -n 120 --no-pager
Expected:
Active: active (running)
VITE ready
- Step 2: 检查端口监听
ss -lntp | grep 5173
Expected:
0.0.0.0:5173
如果只看到 127.0.0.1:5173,说明没有绑定公网网卡,需要加:
npm run dev -- --host 0.0.0.0 --port 5173
Task 21: 后端接口打不开
- Step 1: 检查后端服务
sudo systemctl status forgeflow-backend-dev --no-pager
journalctl -u forgeflow-backend-dev -n 120 --no-pager
- Step 2: 检查端口监听
ss -lntp | grep 8000
Expected:
0.0.0.0:8000
- Step 3: 本机 curl
curl -s http://127.0.0.1:8000/api/system/health
Expected:
本机通则进程正常;外网不通则优先查腾讯云安全组和 1Panel 防火墙。
Task 22: 登录时报 CORS
- Step 1: 确认前端访问地址
http://<腾讯云公网IP>:5173
- Step 2: 确认后端
.env
grep ALLOWED_ORIGINS /opt/ForgeFlow-ERP/backend/.env
Expected:
ALLOWED_ORIGINS=http://<腾讯云公网IP>:5173
- Step 3: 修改后重启后端
sudo systemctl restart forgeflow-backend-dev
Task 23: 数据库连接失败
- Step 1: 用 mysql 客户端直连
mysql -h 121.40.97.156 -P 3306 -u <数据库用户名> -p -e "SELECT 1;"
Expected:
返回 1
- Step 2: 如果 MySQL 客户端通,但后端 health 不通
检查:
grep MYSQL /opt/ForgeFlow-ERP/backend/.env
journalctl -u forgeflow-backend-dev -n 120 --no-pager
处理方向:
数据库名、账号、密码、账号 Host 权限、SQLAlchemy 连接字符串。
Phase 10: 临时阶段转正式生产阶段
临时测试稳定后,再做以下切换。
Task 24: 正式化前端
- Step 1: 生产构建
cd /opt/ForgeFlow-ERP/frontend
npm run build
Expected:
dist/ 构建成功
- Step 2: 用 1Panel OpenResty/Nginx 托管 dist
站点根目录:
/opt/ForgeFlow-ERP/frontend/dist
Task 25: 正式化后端
- Step 1: 后端改为只监听本机
正式阶段后端不再暴露公网端口:
127.0.0.1:8000
- Step 2: systemd 去掉
--reload
正式命令:
/opt/ForgeFlow-ERP/backend/.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
Task 26: 正式化反向代理
- Step 1: 配置 OpenResty/Nginx
核心规则:
location /api/ {
proxy_pass http://127.0.0.1:8000/api/;
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 / {
try_files $uri $uri/ /index.html;
}
- Step 2: 前端正式环境 API 改为相对路径
VITE_API_BASE_URL=/api
Task 27: 正式化安全策略
- Step 1: 关闭临时公网端口
腾讯云安全组和服务器防火墙关闭:
5173/tcp
8000/tcp
只保留:
80/tcp
443/tcp
22/tcp
- Step 2: 配置域名和 HTTPS
ERP 正式访问地址:https://<正式域名>
- Step 3: 数据库账号最小权限
正式账号只给 ERP 所需库权限:
CREATE USER 'forgeflow_erp'@'<腾讯云公网IP>' IDENTIFIED BY '<强密码>';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, REFERENCES
ON jiaheng_erp.* TO 'forgeflow_erp'@'<腾讯云公网IP>';
FLUSH PRIVILEGES;
Final Verification
- 腾讯云服务器能访问阿里云 MySQL。
http://<腾讯云公网IP>:8000/api/system/health返回后端和数据库正常。http://<腾讯云公网IP>:5173/login?redirect=/能打开登录页。- 登录后页面 API 请求没有 CORS 报错。
- Excel 导入导出正常。
- 基础资料、订单、采购、仓库、生产、发货页面都能打开。
- 修改前端代码后 Vite 能热更新。
- 修改后端代码后 Uvicorn 能自动 reload。
- 测试期结束后有明确计划关闭公网
5173和8000。
Recommended Execution Mode
先用 tmux 跑通当天部署,再切 systemd 守护。
原因:
tmux 启动最快,排错最直观;确认前后端、数据库、跨域都通后,再用 systemd 固化。
如果需要我来执行,建议按这个顺序:
1. 先要腾讯云公网 IP、SSH 登录方式、数据库测试账号。
2. 执行 Phase 1 到 Phase 5,让系统先能访问。
3. 执行 Phase 8 做业务验收。
4. 验收没问题后执行 Phase 6,把进程挂 systemd。
5. 等测试稳定后,再执行 Phase 10 转正式生产配置。