7.0 KiB
7.0 KiB
部署与运维手册(与 release/prod 基线一致)
最后核对:2026-08-30,总工 HEL-270 上线前总验收。本手册是测试与正式环境唯一的部署/回滚/备份/巡检操作依据,取代散落在宿主机 DEPLOYMENT.txt 里的历史记录(旧记录仅作存档)。
1. 物料与目录
| 物料 | 说明 |
|---|---|
deploy/Dockerfile |
python:3.12-slim-bookworm,非 root(uid 10001 app),只读根文件系统 |
deploy/compose.yaml |
cap_drop ALL、no-new-privileges、pids 128、mem 512m、cpu 1.0、healthcheck |
deploy/.env.example |
配置模板;deploy/.env 已 gitignore,口令永不入库 |
deploy/deploy.sh |
TAG=<tag> ./deploy.sh,默认镜像 tag=当前提交 sha |
deploy/rollback.sh |
./rollback.sh <tag>,只换应用不动数据 |
deploy/backup.sh |
在线热备 + 保留策略(30 天日备 + 12 个月月备) |
deploy/monitor.sh |
每 5 分钟健康 + 磁盘 ≥80% 告警,写 ALERT.log |
数据目录:deploy/../data/(app.db + files/)。银行原始文件按 SHA-256 内容哈希不可变保存,任何操作不得改写。
2. 正式配置铁律
- 不得出现
admin/admin123:APP_BOOTSTRAP_ADMIN_PASSWORD正式环境不设值,首启由控制台读取随机生成的一次性初始口令,首登立即改密;管理员用户名避开admin。 - 登录失败限流默认开启(5 次/10 分钟锁账号+IP)。
APP_LOGIN_RATE_LIMIT_DISABLED=1仅限本地调试,正式 .env 不得携带。 - 密钥/口令/证书私钥不进仓库、不进评论、不进任务元数据。
- HTTPS:正式暴露一律经反向代理(推荐同机 Caddy 容器,内网自签或内部 CA 证书,反代到容器 4173);不占用 NAS 系统 nginx 的 80/443。公司电脑分发根证书即可。
- 日志:容器 stdout 走 docker json-file,限幅
max-size=10m, max-file=3(daemon 或 composelogging配置);审计日志在库内(append-only 触发器保护)。
3. 部署步骤(测试与正式一致)
git fetch && git checkout release/prod && git pull
cd deploy
cp .env.example .env # 首次;按上面铁律填写
# .env 必设 APP_UID/APP_GID = data/ 目录属主的 uid/gid(宿主机 `id <用户>`),
# 否则 SQLite WAL 写库报 readonly
TAG=$(git rev-parse --short HEAD) ./deploy.sh
curl -fsS http://127.0.0.1:4173/ >/dev/null && echo healthy
部署前手工备份(四件套 + 镜像 tag 存档):
STAMP=$(date +%Y%m%d-%H%M%S)
tar -C .. -czf ../backups/source-$STAMP.tar.gz --exclude='../data' --exclude='../.git' .
cp .env ../backups/env-$STAMP
docker exec caiwuzongzhang-app python -c "import sqlite3; s=sqlite3.connect('/app/data/app.db'); d=sqlite3.connect('/tmp/b.db'); s.backup(d); d.close(); s.close()"
docker cp caiwuzongzhang-app:/tmp/b.db ../backups/app.db.$STAMP
3.1 正式环境部署(同宿主机隔离,2026-08-30 首次上线采用)
测试与正式同宿主机并行,靠 compose 项目名/容器名/端口三隔离:
| 项 | 测试环境 | 正式环境 |
|---|---|---|
| 目录 | /home/leefer/caiwuzongzhang-test |
/home/leefer/caiwuzongzhang-prod |
| compose 项目 | deploy(默认) |
COMPOSE_PROJECT_NAME=caiwuzongzhang-prod |
| 应用容器 | caiwuzongzhang-app |
caiwuzongzhang-prod-app |
| 端口 | 4173(对外) |
127.0.0.1:4174(仅本机,反代上游) |
| HTTPS | 无 | nginx 反代 8443(COMPOSE_PROFILES=tls) |
| 访问 | http://192.168.200.36:4173/ | https://192.168.200.36:8443/ |
首次部署顺序:
git clone <repo> /home/leefer/caiwuzongzhang-prod && cd /home/leefer/caiwuzongzhang-prod
git checkout release/prod
mkdir -p data/files backups && chown -R 10001:10001 data # 容器内 app uid
cd deploy
cp .env.example .env # 按下述差异填写
./tls/gen-cert.sh # 生成内部 CA + 服务器证书(SAN 含对外 IP)
TAG=<发布镜像tag> docker compose up -d # 不带 --build,直接用已验收镜像
docker logs <应用容器> 2>&1 | grep "shown once" # 首启一次性初始口令,只出现一次
正式 .env 与测试的差异(铁律):
COMPOSE_PROJECT_NAME=caiwuzongzhang-prod、APP_CONTAINER_NAME=caiwuzongzhang-prod-app、APP_PORT_MAP=127.0.0.1:4174:4173COMPOSE_PROFILES=tls、PROXY_CONTAINER_NAME=caiwuzongzhang-proxy、PROXY_PORT_MAP=8443:8443APP_UID=10001/APP_GID=10001(data/ 已 chown 10001)- 管理员用户名自定(如
jinniu-admin);不设APP_BOOTSTRAP_ADMIN_PASSWORD(首启控制台取随机一次性口令,首登立即改密) - 不设
APP_LOGIN_RATE_LIMIT_DISABLED(限流默认开启)
证书与信任分发:
tls/certs/ca.crt发给各公司电脑安装到「受信任的根证书颁发机构」(安装指引见交接文档);ca.key/server.key永不离开宿主机。- 服务器证书有效期 5 年,到期前用
./tls/gen-cert.sh重签并docker compose restart proxy。
4. 回滚(应用层,5 分钟内)
cd deploy && ./rollback.sh <上一个镜像tag>
数据层恢复见下节。两套动作互不干扰:应用回滚不改数据;数据恢复不换镜像。
5. 备份与恢复演练
- 备份:cron
15 2 * * *运行deploy/backup.sh;月结后再手动跑一次。 - 恢复步骤(已演练,隔离环境验证):
mkdir -p /tmp/restore/data && cp backups/daily/app.db.<stamp> /tmp/restore/data/app.dbtar -C /tmp/restore/data -xzf backups/daily/files.<stamp>.tar.gz(解出files/)- 用一份独立
deploy-restore目录(.env指向/tmp/restore、端口错开)docker compose up -d --build - 核对:
PRAGMA integrity_check、各表行数、金额合计、source_files哈希清单与生产一致后才可顶替。
- 演练频率:上线前 1 次(HEL-270 已做),之后每季度 1 次,结果记入本文件末尾。
6. 巡检与告警
cron */5 * * * * 运行 deploy/monitor.sh;连续失败或磁盘 ≥80% 时查看 deploy/ALERT.log 并按需扩容/清理。容器重启策略 unless-stopped。
宿主机 crontab(leefer,2026-08-30 起,正式环境):
15 2 * * * cd /home/leefer/caiwuzongzhang-prod/deploy && CONTAINER=caiwuzongzhang-prod-app ./backup.sh >> backup.log 2>&1
*/5 * * * * cd /home/leefer/caiwuzongzhang-prod/deploy && CONTAINER=caiwuzongzhang-prod-app HEALTH_URL=http://127.0.0.1:4174/ ./monitor.sh >/dev/null 2>&1
01 3 1 * * rsync -a /home/leefer/caiwuzongzhang-prod/backups/monthly/ /vol1/caiwuzongzhang-backups/monthly/
(第三行为月度异盘副本:/vol1 是与系统盘不同的物理卷;如后续提供真正的异机目标,改为该目标。)
7. 升级数据库
应用启动时自动执行迁移(MIGRATIONS,当前版本 10)。迁移只前不改写历史;回退 schema 用对应 down 迁移,先备份后操作。
8. 演练记录
- 2026-08-30 HEL-270:备份恢复演练 + 版本回滚演练各 1 次,隔离环境完成,原始证据未改动。详见 HEL-270 验收评论。