shanxia2.0 生产环境部署方案
目标机器:
121.43.228.102
与现有 CRM(80 端口 /web.conf)并存,通过 9911(前端)+ 9111(后端) 独立端口部署山峡一体化门户。
1. 部署思路总览
1.1 架构
┌─────────────────────────────────────────┐
│ 121.43.228.102 │
│ │
浏览器 ──────────►│ nginx :9911 │
(管理端) │ ├─ / → 静态 dist (SPA) │
│ └─ /api/* → 127.0.0.1:9111 │
│ │
│ uvicorn :9111 (FastAPI) │
│ ├─ MySQL 47.99.164.66:3306 │
│ ├─ Redis 47.99.164.66:16379 │
│ └─ MinIO 47.99.164.66:20004 │
│ │
浏览器 ──────────►│ nginx :80 (现有 CRM,保持不变) │
(CRM) │ └─ /prod-api/* → :8080 │
└─────────────────────────────────────────┘
1.2 核心原则
| 项 | 说明 |
|---|---|
| 端口隔离 | CRM 继续占用 80;shanxia2.0 使用 9911/9111,互不影响 |
| 同库同中间件 | 数据库、Redis、MinIO 与本地开发一致(远程 47.99.164.66) |
| Nginx 反代 API | 前端 VITE_API_URL=/api,由 Nginx 转发到后端,避免浏览器跨域 |
| 后端仅本机监听 | 9111 建议只绑定 127.0.0.1,对外只暴露 9911 |
| 环境文件分离 | 生产使用 backend/.env.production,不直接使用开发 .env |
| 构建在本地/CI | 服务器只放 dist 与 Python 源码,不在生产机跑 pnpm dev |
1.3 目录约定(生产机)
| 路径 | 内容 |
|---|---|
/iflytek/shanxia2.0/backend |
Python 后端源码 + venv + .env.production |
/iflytek/shanxia2.0/web/dist |
前端 pnpm build 产物(仓库对应 web-admin/dist) |
/etc/nginx/conf.d/shanxia2.0.conf |
Nginx 站点配置(见同目录模板) |
仓库前端工程名为
web-admin,部署到服务器时目录按约定命名为web/dist。
2. 前置条件
2.1 服务器软件
- Python 3.9+(与本地 venv 一致;需
python3-venv) - Nginx(已有,用于 CRM)
- Node.js 20.19+ / pnpm 8.8+(仅在构建机构建,生产机可选)
2.2 网络与防火墙
- 安全组/防火墙放行 9911/TCP(对外 Web 访问)
- 9111 建议不对公网开放(仅 Nginx 本机反代)
- 确认生产机可访问
47.99.164.66:3306 / 16379 / 20004
2.3 数据库
- 库名:
shanxia2.0(与本地DATABASE_URL一致) - 基线 DDL:
docs/sql/shanxia2.0.sql - 增量脚本:按日期顺序执行
docs/sql/2026*.sql等迁移文件 - 可选表:
docs/sql/optional-sys-api-request-log.sql(不建表则设置API_REQUEST_LOG_ENABLED=false)
3. 部署步骤
阶段 A:准备代码(本地或 CI)
A1. 检出/打包后端
# 本地打包示例(排除 venv、日志、缓存)
cd /path/to/shanxia2.0
tar czf shanxia2.0-backend.tar.gz \
--exclude='backend/venv' \
--exclude='backend/logs' \
--exclude='backend/__pycache__' \
--exclude='backend/.env' \
backend/
A2. 配置生产环境变量
- 复制
生产环境部署/backend.env.production.example→ 服务器backend/.env.production - 以本地
backend/.env中的 DATABASE / Redis / MinIO 值为基准填入 - 必须修改的生产项:
DEBUG=falseSECRET_KEY→ 随机长字符串(勿用默认值)LOGIN_RSA_PRIVATE_KEY_PEM→ 固定 PEM(多 worker / 重启后登录公钥不变)BACKEND_CORS_ORIGINS=["http://121.43.228.102:9911"](若后续绑域名一并加入)PUBLIC_WEB_ORIGIN=http://121.43.228.102:9911(公开 H5 页链接)
A3. 构建前端
- 复制
生产环境部署/web-admin.env.production.example→web-admin/.env.production - 构建:
cd web-admin
pnpm install
pnpm build
# 产物:web-admin/dist/
- 打包 dist:
tar czf shanxia2.0-web-dist.tar.gz -C web-admin dist
阶段 B:上传到生产机
# 在本地执行(示例)
scp shanxia2.0-backend.tar.gz root@121.43.228.102:/iflytek/shanxia2.0/
scp shanxia2.0-web-dist.tar.gz root@121.43.228.102:/iflytek/shanxia2.0/
scp 生产环境部署/nginx-shanxia2.0.conf root@121.43.228.102:/etc/nginx/conf.d/
在服务器解压:
mkdir -p /iflytek/shanxia2.0/backend /iflytek/shanxia2.0/web
cd /iflytek/shanxia2.0
tar xzf shanxia2.0-backend.tar.gz
mkdir -p web && tar xzf shanxia2.0-web-dist.tar.gz -C web
# 解压后路径应为 /iflytek/shanxia2.0/web/dist/index.html
阶段 C:后端初始化与启动
cd /iflytek/shanxia2.0/backend
# 创建虚拟环境并安装依赖
python3 -m venv venv
./venv/bin/pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 确认环境文件
ls -la .env.production
# 启动(端口 9111,2 worker)
PORT=9111 WORKERS=2 ENV_FILE=./.env.production ./start-prod.sh start
# 查看状态与日志
./start-prod.sh status
./start-prod.sh logs
健康检查(服务器本机):
curl -s http://127.0.0.1:9111/health
# 期望:{"status":"healthy"}
阶段 D:Nginx 配置
- 使用本目录
nginx-shanxia2.0.conf(已按 9911 / 9111 写好) - 检查并重载:
nginx -t
nginx -s reload
# 或 systemctl reload nginx
- 验证:
curl -s http://127.0.0.1:9911/health
curl -s http://127.0.0.1:9911/api/... # 任选一个公开接口
curl -I http://127.0.0.1:9911/
阶段 E:业务验收
| 检查项 | 操作 | 期望 |
|---|---|---|
| 静态页 | 浏览器打开 http://121.43.228.102:9911 |
登录页正常 |
| 登录 | admin / 111111(或实际账号) | RSA 登录成功,进入工作台 |
| API 代理 | F12 Network 看请求 | 均为同源 /api/...,无 CORS 报错 |
| 附件 | 上传/预览 | MinIO URL 可访问 |
| 路由 | 刷新任意 #/pl/... 页面 |
不出现 404(SPA fallback) |
| CRM 不受影响 | 访问 http://121.43.228.102 |
CRM 仍正常 |
4. 与 CRM Nginx 配置的对比
| 对比项 | CRM (web.conf) |
shanxia2.0 (shanxia2.0.conf) |
|---|---|---|
| 监听端口 | 80 | 9911 |
| 静态根目录 | /iflytek/prod/dist |
/iflytek/shanxia2.0/web/dist |
| API 前缀 | /prod-api/ |
/api/ |
| 后端端口 | 8080 (Java) | 9111 (Python) |
| SSE | 有专用 location | 当前门户暂无 SSE,可后续按需追加 |
shanxia2.0 的 Nginx 写法参照 CRM 的代理头、超时、Gzip、SPA fallback,仅替换端口与路径前缀。
5. 环境变量要点
5.1 后端(.env.production)
详见 backend.env.production.example。与本地 .env 对齐的字段:
DATABASE_URLREDIS_*MINIO_*/STORAGE_TYPE=minioDEFAULT_TENANT_NO=shanxia2.0API_ENCRYPT_*(当前本地为false,生产保持一致即可;若开启需前后端同时开启且密钥一致)
生产额外注意:
DEBUG=falseLOGIN_ALLOW_PLAINTEXT_LOGIN=false- 配置固定
LOGIN_RSA_PRIVATE_KEY_PEM(可从本地生成后复制,或使用openssl genrsa 2048)
5.2 前端(.env.production,构建时生效)
详见 web-admin.env.production.example:
VITE_API_URL=/api(走 Nginx 同源代理)VITE_BASE_URL=/VITE_API_ENCRYPT_ENABLED=false(与后端一致)VITE_MINIO_BASE_URL=https://res.shanxiachem.com/ruoyi(与后端MINIO_BASE_URL一致)
6. 日常运维
6.0 一键发版(推荐)
macOS 本机从仓库根目录执行(凭据读自根目录 生产机器账号密码,密码不写进脚本):
./生产环境部署/deploy-release.sh
# 已有 dist 时可跳过构建:
./生产环境部署/deploy-release.sh --skip-build
顺序:本地 pnpm build → 备份远程 web → 同步 dist(保留远程 dist/src)→ 备份远程 backend → 替换 backend/app → PORT=9111 WORKERS=1 ENV_FILE=./.env.production ./start-prod.sh restart → 健康检查。
备份落在 /iflytek/shanxia2.0/bak/web-* 与 backend-*。依赖:ssh、rsync、sshpass(brew install hudochenkov/sshpass/sshpass)、pnpm。
6.1 更新后端(手工)
cd /iflytek/shanxia2.0/backend
# 上传新代码后
./venv/bin/pip install -r requirements.txt
PORT=9111 WORKERS=1 ENV_FILE=./.env.production ./start-prod.sh restart
6.2 更新前端(手工)
# 本地 build 后上传 dist;务必保留远程 dist/src
rsync -avz --delete --exclude 'src/' web-admin/dist/ root@121.43.228.102:/iflytek/shanxia2.0/web/dist/
# 无需重启后端;浏览器强刷或清缓存
6.3 数据库变更
- 在
docs/sql/编写增量 SQL - 在生产库按顺序执行
- 再发版后端/前端
6.4 日志位置
| 组件 | 路径 |
|---|---|
| 后端 | /iflytek/shanxia2.0/backend/logs/backend-prod.log |
| Nginx | 按现有 CRM 同样 log 目录配置(可在 conf 中取消注释) |
6.5 开机自启(可选)
可使用 systemd unit 管理 start-prod.sh:
# /etc/systemd/system/shanxia2.0-backend.service
[Unit]
Description=shanxia2.0 FastAPI Backend
After=network.target
[Service]
Type=forking
WorkingDirectory=/iflytek/shanxia2.0/backend
Environment=PORT=9111
Environment=WORKERS=2
Environment=ENV_FILE=/iflytek/shanxia2.0/backend/.env.production
ExecStart=/iflytek/shanxia2.0/backend/start-prod.sh start
ExecStop=/iflytek/shanxia2.0/backend/start-prod.sh stop
Restart=on-failure
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable shanxia2.0-backend
systemctl start shanxia2.0-backend
7. 回滚策略
- 前端:
/iflytek/shanxia2.0/bak/web-*中对应备份覆盖回web(注意勿误删业务依赖的dist/src) - 后端:从
bak/backend-*还原后,在backend目录执行PORT=9111 WORKERS=1 ENV_FILE=./.env.production ./start-prod.sh restart - 数据库:增量 SQL 应可逆或先备份;重大变更前
mysqldump
8. 后续可选增强
- 域名 + HTTPS:为 9911 配置
portal.shanxiachem.com+ SSL,并更新BACKEND_CORS_ORIGINS - API 加密:生产开启
API_ENCRYPT_ENABLED=true,前后端密钥与排除路径保持一致 - 独立 API 域名:小程序/外部系统可配置
http://121.43.228.102:9911/api或单独域名 - 监控:对
/health做存活探测;对接现有 Spring Boot Admin 以外的监控
9. 文件清单
| 文件 | 用途 |
|---|---|
README.md |
本文档 |
deploy-release.sh |
macOS 一键发版(前端→后端,含备份与健康检查) |
nginx-shanxia2.0.conf |
Nginx 站点模板 |
backend.env.production.example |
后端生产环境变量模板 |
web-admin.env.production.example |
前端构建环境变量模板 |
deploy-checklist.md |
上线检查清单(可打印) |