zlwu 4f364bc9a0 提交 1 mesiac pred
..
packages d84f4b944c 提交 4 mesiacov pred
生产环境数据库备份的shell脚本 b430e75a4b 提交 1 mesiac pred
README.md c9fb39395c 提交 1 mesiac pred
backend.env.production.example c9fb39395c 提交 1 mesiac pred
deploy-checklist.md d84f4b944c 提交 4 mesiacov pred
deploy-release.sh fdf7d391a6 提交 2 mesiacov pred
nginx-dbapp.shanxiachem.com.conf 5fe53c5481 提交 2 mesiacov pred
nginx-shanxia-miniprogram-static.conf 7b1d4c8729 提交 3 mesiacov pred
nginx-shanxia2.0.conf 4f364bc9a0 提交 1 mesiac pred
web-admin.env.production.example c9fb39395c 提交 1 mesiac pred

README.md

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. 配置生产环境变量

  1. 复制 生产环境部署/backend.env.production.example → 服务器 backend/.env.production
  2. 以本地 backend/.env 中的 DATABASE / Redis / MinIO 值为基准填入
  3. 必须修改的生产项:
    • DEBUG=false
    • SECRET_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. 构建前端

  1. 复制 生产环境部署/web-admin.env.production.example → web-admin/.env.production
  2. 构建:
cd web-admin
pnpm install
pnpm build
# 产物:web-admin/dist/
  1. 打包 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 配置

  1. 使用本目录 nginx-shanxia2.0.conf(已按 9911 / 9111 写好)
  2. 检查并重载:
nginx -t
nginx -s reload
# 或 systemctl reload nginx
  1. 验证:
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_URL
  • REDIS_*
  • MINIO_* / STORAGE_TYPE=minio
  • DEFAULT_TENANT_NO=shanxia2.0
  • API_ENCRYPT_*(当前本地为 false,生产保持一致即可;若开启需前后端同时开启且密钥一致)

生产额外注意:

  • DEBUG=false
  • LOGIN_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 数据库变更

  1. 在 docs/sql/ 编写增量 SQL
  2. 在生产库按顺序执行
  3. 再发版后端/前端

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. 回滚策略

  1. 前端:/iflytek/shanxia2.0/bak/web-* 中对应备份覆盖回 web(注意勿误删业务依赖的 dist/src)
  2. 后端:从 bak/backend-* 还原后,在 backend 目录执行 PORT=9111 WORKERS=1 ENV_FILE=./.env.production ./start-prod.sh restart
  3. 数据库:增量 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 上线检查清单(可打印)