1
Deployment and Release
biss edited this page 2026-07-24 12:00:48 +08:00
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.

部署与发布

项目支持框架依赖发布、自包含跨平台程序包和 Docker 镜像。生产部署前先完成配置参考中的上线检查。

1. 部署前准备

至少准备:

  • 生产 MySQL 8.4 数据库及最小权限账号;
  • 两项相互独立且至少 32 字符的密钥;
  • 强初始管理员密码;
  • HTTPS 入口或反向代理;
  • 持久化日志收集方式;
  • 数据库备份和恢复方案;
  • 多实例部署所需 Redis
  • 端口、防火墙和健康检查策略。

生产环境不需要 Node.js 运行服务。Node.js 只在构建 Vue 前端时使用。

2. 本机统一发布

在仓库根目录运行:

pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\publish.ps1

脚本会:

  1. ClientApp 执行 npm ci
  2. 构建 Vue 生产资源;
  3. 发布 Eis.Web
  4. 发布 Eis.Tools

输出:

artifacts/publish/web
artifacts/publish/tools

启动 Web

dotnet .\artifacts\publish\web\Eis.Web.dll

查看数据库工具:

dotnet .\artifacts\publish\tools\Eis.Tools.dll --help

这种发布方式需要服务器预装兼容的 .NET 10 Runtime。

3. 发布物目录建议

生产服务器可采用:

eis/
├─ current/               当前 Web 发布物
├─ tools/                 与当前版本匹配的数据库工具
├─ config/                由平台管理,不纳入发布压缩包
├─ data/                  仅 SQLite 部署使用
├─ logs/                  若采用文件日志
└─ releases/
   ├─ 1.2.2/
   └─ 1.2.3/

配置和持久化数据不要放进每次覆盖的应用发布目录。升级前保留上一版发布物,以便代码回滚;数据库发生不兼容升级时,还必须配套数据库恢复方案。

4. 自包含跨平台程序包

Gitea Actions 默认构建:

  • win-x64.zip
  • linux-x64.tar.gz
  • linux-arm64.tar.gz

手动选择扩展平台后增加:

  • win-arm64
  • osx-x64
  • osx-arm64

每个包包含:

eis-<版本>-<RID>/
├─ app/                   Web 与数据库工具,共享运行时和依赖
├─ README.md
├─ LICENSE
└─ .env.example

还会生成 SHA256SUMS

Windows 启动:

.\app\Eis.Web.exe

Windows 数据库工具:

.\app\Eis.Tools.exe --help

Linux/macOS

./app/Eis.Web
./app/Eis.Tools --help

自包含包不要求目标机预装 .NET Runtime。

5. Docker 镜像

本地构建:

docker build --tag hengzhun-exam-system:local .

镜像:

  • 基于 ASP.NET Core 10 Runtime
  • 包含 Web 和 /app/tools/Eis.Tools.dll
  • 默认监听 0.0.0.0:4173
  • 使用非 root 用户;
  • 数据目录 /app/data
  • 通过 /health/live 健康检查。

Docker Compose

创建配置:

Copy-Item -LiteralPath .\.env.docker.example -Destination .\.env.docker

替换密钥和管理员密码后:

docker compose up --build --detach
docker compose ps
docker compose logs --follow app

默认使用 SQLite,数据库位于命名卷:

exam-information-data:/app/data

停止并保留数据:

docker compose down

删除容器和全部命名卷数据:

docker compose down --volumes

最后一个命令具有破坏性,只在明确清空 SQLite 数据时使用。

6. MySQL 和 Redis 容器部署

使用外部 MySQL 时,以环境变量覆盖 Compose 中的默认 SQLite 配置:

DATABASE_CLIENT=mysql
DATABASE_URL=mysql://...

然后可以移除 SQLite 数据卷挂载,但应先确认没有需要迁移的现有 SQLite 数据。

使用 Redis

REDIS_URL=redis://redis-host:6379/0
REDIS_SESSION_DB=1

容器中的 127.0.0.1 指向容器自身。MySQL 或 Redis 在其他容器或主机上时,应使用 Compose 服务名、内网 DNS 或实际主机地址。

7. 生产启动顺序

推荐:

  1. 完成数据库备份。
  2. 部署新版本到独立目录或拉取新镜像。
  3. 使用与新版本匹配的工具执行非破坏性数据库预检或初始化。
  4. 注入生产环境变量。
  5. 单实例启动新版本。
  6. 检查 /health/live/health/migration
  7. 检查首页、登录、静态资源和数据库连接。
  8. 多实例部署时再逐步替换其余实例。
  9. 完成关键业务烟测。
  10. 保留上一版本和回滚记录。

若结构版本不匹配,不要继续滚动启动所有实例。

8. 健康检查与监控

存活

GET /health/live

正常响应包含:

{
  "status": "healthy",
  "service": "Eis.Web",
  "framework": ".NET 10"
}

组件状态

GET /health/migration

重点检查:

  • legacyApiRemoved: true
  • cache.status
  • authentication.stateBackend
  • 原生模块启用状态

cache.status=unavailable 表示普通 Redis 不可用且正在使用本机回退;认证 Redis 如果明确配置却连接失败,应用通常无法完成启动。

监控还应包含:

  • HTTP 5xx
  • 登录失败率;
  • 数据库连接和慢查询;
  • Redis 连接;
  • 容器重启次数;
  • 磁盘或 SQLite 卷容量;
  • 关键批量任务和审批错误。

9. HTTPS 与代理

建议在受管入口、反向代理或负载均衡器终止 TLS,只对外提供 HTTPS。代理配置需要:

  • 转发到应用 4173
  • 保留必要的 Host 和转发协议头;
  • 允许 Excel/PDF 所需响应大小;
  • 对 Vue History 路由使用应用自己的回退,不把 /api/* 错误改写成首页;
  • 对登录 Cookie 保持同站点访问模型。

代理和应用的公开域名变化后,检查文书二维码中的验真链接是否指向正确外部地址。

10. Gitea Actions 发布

工作流:

.gitea/workflows/publish.yml

触发方式:

  • 推送 v* 标签;
  • Actions 页面手动运行;
  • 普通分支推送不会触发耗时发布。

流水线:

  1. 构建 Vue
  2. 运行 Release 配置的 .NET 测试;
  3. 构建自包含平台包;
  4. 上传工作流制品;
  5. 构建 linux/amd64linux/arm64 Docker 镜像;
  6. 推送 Docker Hub 和 Gitea Registry
  7. 标签构建创建正式 Release 或 Pre-release。

必要配置

Actions Variables

  • DOCKERHUB_IMAGE
  • REGISTRY_USERNAME

Actions Secrets

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN
  • REGISTRY_TOKEN

Release 使用内置 GITEA_TOKEN,仓库或组织的任务令牌最大权限需要允许 Releases Write。

Gitea 镜像当前固定发布到:

git.biss.click/biss/eis-dotnet

Docker Hub 镜像名由 DOCKERHUB_IMAGE 变量决定。

Runner 需要访问:

  • Docker daemon
  • GitHub Actions 源;
  • Docker Hub
  • git.biss.click
  • QEMU 注册能力。

11. 版本标签

稳定版本:

git tag v1.2.3
git push origin v1.2.3

会生成语义化镜像标签和 latest

预发布:

git tag v1.3.0-rc.1
git push origin v1.3.0-rc.1

带连字符的版本会创建 Gitea Pre-release,不覆盖稳定版 latest 或主次版本标签。

发布标签前应确认标签所指提交已经通过本地检查,标签推送后不应移动同名标签来替换已发布制品。

12. 升级与回滚

升级

  • 阅读版本变更;
  • 备份数据库;
  • 保存旧配置和密钥;
  • 验证新版本所需环境变量;
  • 用隔离数据库或测试环境演练;
  • 部署并检查健康状态;
  • 执行核心业务烟测。

代码回滚

若数据库结构仍兼容:

  1. 停止新版本;
  2. 恢复上一发布目录或镜像标签;
  3. 使用原有配置启动;
  4. 检查健康状态和关键业务。

数据回滚

如果新版本已执行不兼容数据库变更,不能只回滚二进制。必须按事先验证的数据库恢复方案恢复匹配版本的数据。

不要通过 database reset 实现生产回滚。

13. 部署后验收

  • 首页和公告正常;
  • 公开验真页可访问;
  • 管理员可登录和退出;
  • TOTP 登录可完成;
  • 各角色只能看见自己的数据范围;
  • Vue 语义 URL 直接刷新正常;
  • Excel 模板可下载;
  • PDF 文书可生成并验真;
  • 数据写入后公开和成绩缓存及时失效;
  • 数据库备份任务正常;
  • 监控能发现进程、数据库和 Redis 故障。