Files
senmesh-zc/backend/docs/生产部署说明.md
KodouWZF 47273ae3fd init: 信创文件安全传输系统内外网本地 Docker 部署
包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套
compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。

说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者
明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT
密钥;上生产前需替换。
2026-11-02 10:59:03 +08:00

221 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# s-file 生产部署 / 上线说明
> 适用版本:2026-09-14(含用户启停/注销、机构账号查询、手机号查记录、机构上传配置、禁用踢下线黑名单)
> 构建产物:`target/s-file.jar`(Spring Boot 可执行 fat jar,需 JDK 8)
---
## 0. 上线前必须处理(阻断项)
### 0.1 替换 spire.pdf 占位 jar ⚠️
本机构开发机的 `~/.m2/repository/e-iceblue/spire.pdf/3.7.4/` 中目前安装的是**编译级 stub(空实现)jar**——它能保证编译打包通过,但 **PDF 盖章功能(`PdfUtils.pdfStampPerPage`)运行时必然失败**。
上线前必须:
1. 从公司私服获取真实的 `spire.pdf-3.7.4.jar`(阿里云与 e-iceblue 官方仓库均无此版本);
2. 覆盖 `~/.m2/repository/e-iceblue/spire.pdf/3.7.4/spire.pdf-3.7.4.jar`(pom 同步覆盖);
3. 重新 `mvn clean package -DskipTests`;
4. 验证:解包 jar 中 `com/spire/pdf/PdfDocument.class` 应为真实实现(stub 版仅 300~500 字节)。
> 若该业务暂时不用 PDF 盖章,可带 stub 上线,但需明确告知团队。
### 0.2 提供生产配置文件
**仓库内不含任何运行配置**(application.yml 是外置的)。启动时通过 `spring.config.additional-location` 挂载。生产模板如下(按实际环境修改):
```yaml
server:
port: 8080
spring:
application:
name: s-file
datasource:
# 生产为达梦 DM8;驱动 com.dameng.jdbc.driver(pom 已含依赖)
url: jdbc:dm://<DB_HOST>:5236/S_FILE
driver-class-name: com.dameng.jdbc.driver
username: <DB_USER>
password: <DB_PASSWORD>
druid:
initial-size: 5
min-idle: 5
max-active: 20
validation-query: SELECT 1
redis: # 必须可用:登录缓存 + 禁用/注销踢下线黑名单依赖 Redis
host: <REDIS_HOST>
port: 6379
timeout: 5000
rabbitmq:
host: <MQ_HOST>
port: 5672
username: <MQ_USER>
password: <MQ_PASSWORD>
servlet:
multipart:
max-file-size: 500MB # 按网盘需求调整
max-request-size: 500MB
main:
allow-bean-definition-overriding: true
mybatis-plus:
mapper-locations: classpath*:com/senmesh/**/mapper/*.xml # 必须有,否则自定义 XML 的接口全部报 Invalid bound statement
system:
code: 1
# 发号器雪花 workerId:键格式 code.snowflake.workid.<本机IP>
# 单机部署:直接写死本机 IP 的键;多机部署:每台机器一个键、值必须不同且 0~31
"[code.snowflake.workid.192.168.1.10]": 1
security:
jwt:
enable: true
secret: <上线前必须换成 64 字节以上随机串,勿用文档示例>
expiration: 86400 # token 有效期(秒)
header: Authorization
ignoring: /error,/favicon.ico,/v2/api-docs,/swagger-resources/**
login-page: /login
superior-only: false # true=仅平台机构用户可登录系统;按部署侧实际选择
use-local: true
allow-if-all-abstain-decisions: true
oauth2:
enable: false
anonymous: "" # 匿名白名单按需追加(逗号分隔,如 /file/upload)
user:
default:
password: <新用户初始密码>
file:
upload-dir: /data/upload # 容器/主机上需存在且可写
storage:
type: local # 阿里云 OSS 则改 ali 并补齐 oss 配置
transfer:
location: "1" # 内网侧 "1",外网侧 "2" —— 两侧必须相反!
send-dir: /data/transfer/send
receive-dir: /data/transfer/receive
unpack-risk-check: false
dify:
risk:
rule:
api-key: <真实key或占位>
scan:
api-key: <真实key或占位> # 必填(可为占位),否则启动失败
rabbitmq:
custom:
topic-exchange-name: s-file-topic
delayed-exchange-name: s-file-delayed
broadcast-id: s-file-broadcast
swagger:
enable: false # 生产必须 false
```
### 0.3 数据库变更
- **已有生产库**:执行 `db/upgrade-20260914-upload-config.sql`(达梦执行「1. MySQL / 达梦 DM8」一节,建 `x_upload_config` 表)。其余本次功能无表结构变更。
- **全新库**:先执行 `db/init-table.sql`(达梦按 MySQL 兼容模式)+ `db/init-data.sql`(平台、平台机构、admin 账号、文件种类字典)。
- 执行后验证:`select count(*) from x_upload_config;` 无报错即建表成功(0 行为正常,未配置的机构走默认策略)。
### 0.4 目录与权限
```
mkdir -p /data/upload /data/transfer/send /data/transfer/receive
chown -R <运行用户> /data
```
外网侧与内网侧通过 `file.transfer.location` 区分,`send-dir`/`receive-dir` 指向各自的摆渡目录(网闸/摆渡盘)。
---
## 1. 启动方式
### 1.1 裸机 / 虚拟机(JDK 8)
```bash
# 需 JDK 1.8(java -version 确认)
java -Xms1g -Xmx2g \
-Dspring.config.additional-location=file:/opt/sfile/config/application.yml \
-jar /opt/sfile/s-file.jar \
> /opt/sfile/logs/stdout.log 2>&1 &
```
多节点时按节点 IP 配置不同的 `code.snowflake.workid.<ip>`(可用启动参数 `-DCODE_SNOWFLAKE_WORKID_<IP大写>=<n>` 环境变量方式,`_` 映射 `.`)。
### 1.2 Docker
```bash
# 构建(context 内需 s-file.jar 与 Dockerfile,Dockerfile 在 src/main/resources/)
cp target/s-file.jar <build-context>/ && docker build -t s-file:<版本> <build-context>
docker run -d --name sfile-app --restart unless-stopped -p 8080:8080 \
-v /opt/sfile/config/application.yml:/config/application.yml:ro \
-v /data/upload:/data/upload \
-v /data/transfer/send:/data/transfer/send \
-v /data/transfer/receive:/data/transfer/receive \
-e SPRING_CONFIG_ADDITIONAL_LOCATION=file:/config/application.yml \
-e CODE_SNOWFLAKE_WORKID_<容器IP大写下划线>=1 \
s-file:<版本>
```
> 注意:基础镜像 `freshworks/oraclejdk8` 为 amd64,arm64 主机需 `--platform linux/amd64`;workerId 键里的 IP 用容器固定 IP(自定义网络 `--ip`),容器重建 IP 不变。
---
## 2. 前端发布
```bash
cd senmesh-zc-legacy
bun install
bun run build # 产出 dist/(.env.production 已带 VITE_APP_TITLE 引号修复,规避 Bun env 解析 bug)
```
- `dist/` 交由 nginx 托管;
- nginx 需将 `/api` 反代到后端并**去掉 `/api` 前缀**(与 vite dev 代理行为一致):
```nginx
location /api/ {
proxy_pass http://<后端IP>:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 500m; # 与后端 multipart 上限匹配
}
```
- `.env.production` 当前值:`VITE_API_URL=`(空,走同域 /api)、`VITE_INIT_PASSWORD`(前端判断初始密码强制改密用)——如有调整需重新 build。
---
## 3. 本次版本功能与数据依赖清单(验收用)
| 功能 | 依赖 | 验收方法 |
|---|---|---|
| 用户启用/禁用/注销(管理员) | DB `uc_user.enabled/status`;**Redis**(禁用踢下线黑名单) | 禁用后该用户已登录 token 立即失效(302/401),重新登录被拒 |
| 机构管理员启停本机构用户 | 无额外依赖 | 机构管理员可启停本机构用户;跨机构返回「只能操作本机构的用户」 |
| 机构账号查询(超管) | 新增只读查询 | 管理后台-机构账号页正常出列表与筛选 |
| 按手机号查上传/发送/接收记录 | 无额外依赖 | 输入手机号出记录;发送/接收方向由部署侧 `file.transfer.location` 决定 |
| 机构上传配置 | 新表 `x_upload_config` | 管理后台-上传配置保存后,该机构网盘上传立即按策略拦截 |
| 禁用踢下线 | Redis key `user:disabled:{userId}` | `redis-cli keys 'user:disabled:*'` 可见禁用标记 |
---
## 4. 上线步骤建议
1. 生产库执行 0.3 升级 SQL(执行前备份);
2. 替换真实 spire.pdf jar 并重新打包(0.1),核对 jar 时间戳;
3. 准备 application.yml(0.2 模板),**核对 JWT secret 已更换、dify api-key 已填、swagger.enable=false**;
4. 创建 /data 目录,确定内外网 location;
5. 部署后端(1.1 或 1.2),观察启动日志出现 `Started SFileApplication`;
6. 构建并发布前端(2),nginx reload;
7. 验收第 3 节清单(至少:admin 登录、上传一个非白名单文件被拒、禁用一个测试用户并确认其会话失效、记录查询出数据);
8. 观察日志无 `ERROR`,Redis 中 `user:disabled:*` 与登录缓存键正常。
## 5. 回滚
- 后端:保留上一版 jar/镜像,停新启旧即可(本次无破坏性 DDL/DML,`x_upload_config` 留存不影响旧版本运行);
- 前端:nginx 指回上一版 dist 目录;
- 数据库:无需回滚(仅新增表)。