26dd3bb387
主要变更: 1. 动态更新功能 - 新增 Python 更新服务 (docker/update-service.py) - 添加系统更新前端页面 (frontend/src/pages/SystemUpdate.tsx) - 配置 Nginx 代理更新服务 API - 更新 Docker 启动脚本支持多进程管理 - 修复权限验证接口 (AuthController.verify) 2. Release 创建脚本 - 新增 create-release.sh 脚本支持快速创建 GitHub Release - 支持自动拼接 -beta 后缀(pre-release) - 支持无交互模式(--yes 参数) - 添加详细的使用文档 3. GitHub Actions 增强 - 添加更新包构建和上传流程 - 支持 Pre-release 检测和过滤 4. 文档完善 - 添加动态更新技术方案文档 - 添加 Docker 版本号确定流程文档 - 添加 Release 脚本使用说明
7.8 KiB
7.8 KiB
Docker 版本号确定流程
概述
Docker 镜像的版本号从 GitHub Release Tag 获取,通过 GitHub Actions 自动传递到 Dockerfile,最终存储在容器内的 /app/version.json 文件中。
完整流程
1. GitHub Release Tag (v1.0.0)
↓
2. GitHub Actions 触发
↓
3. 从 Tag 提取版本号
↓
4. 作为 build-args 传递给 Dockerfile
↓
5. Dockerfile 写入 /app/version.json
↓
6. 容器运行时读取版本号
详细步骤
步骤 1: 创建 GitHub Release
通过 GitHub Releases 页面或 create-release.sh 脚本创建 Release:
# 示例:创建 v1.0.1 版本
./create-release.sh -t v1.0.1 -T "Release v1.0.1" -d "更新内容"
结果:
- 创建 Git tag:
v1.0.1 - 创建 GitHub Release:
v1.0.1 - 触发 GitHub Actions workflow
步骤 2: GitHub Actions 触发
GitHub Actions 监听 release: published 事件:
# .github/workflows/docker-build.yml
on:
release:
types:
- published # 当创建 release 时触发
事件数据:
github.event.release.tag_name:"v1.0.1"github.event.release.prerelease:false或true
步骤 3: 提取版本号
GitHub Actions 从 Tag 中提取版本号:
# .github/workflows/docker-build.yml (步骤: Extract version)
TAG_NAME="${{ github.event.release.tag_name }}" # "v1.0.1"
VERSION=${TAG_NAME#v} # "1.0.1" (移除 v 前缀)
提取结果:
VERSION:"1.0.1"(纯版本号,无 v 前缀)TAG:"v1.0.1"(完整 tag,带 v 前缀)IS_PRERELEASE:false或true
版本号格式验证:
- ✅ 正确:
v1.0.0,v2.10.102,v1.0.0-beta - ❌ 错误:
v1.0,1.0.0,v1.0.0.1
步骤 4: 传递构建参数
版本号作为 Docker build-args 传递给 Dockerfile:
# .github/workflows/docker-build.yml
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
build-args: |
BUILD_IN_DOCKER=false
VERSION=${{ steps.extract_version.outputs.VERSION }} # "1.0.1"
GIT_TAG=${{ steps.extract_version.outputs.TAG }} # "v1.0.1"
GITHUB_REPO_URL=https://github.com/WrBug/PolyHermes
步骤 5: Dockerfile 接收参数
Dockerfile 使用 ARG 接收构建参数:
# Dockerfile (第 92-94 行)
ARG VERSION=dev # 默认值: dev
ARG GIT_TAG=dev # 默认值: dev
# 写入 version.json
RUN echo "{\"version\":\"${VERSION}\",\"tag\":\"${GIT_TAG}\",\"buildTime\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > /app/version.json
生成的文件内容 (/app/version.json):
{
"version": "1.0.1",
"tag": "v1.0.1",
"buildTime": "2026-01-20T15:30:00Z"
}
步骤 6: 容器运行时读取
更新服务通过 /api/update/version 接口读取版本号:
# docker/update-service.py
def get_current_version():
"""获取当前版本"""
if VERSION_FILE.exists():
with open(VERSION_FILE) as f:
data = json.load(f)
return data.get('version', 'unknown') # 返回: "1.0.1"
前端通过 API 获取并显示:
// frontend/src/pages/SystemUpdate.tsx
const response = await apiClient.get('/update/version')
const { version } = response.data.data // "1.0.1"
不同场景下的版本号
场景 1: GitHub Actions 自动构建(正式发布)
输入:
- Release Tag:
v1.0.1 - Release Type: Published (正式版本)
流程:
- GitHub Actions 提取:
VERSION="1.0.1",GIT_TAG="v1.0.1" - 传递给 Dockerfile
- 生成
/app/version.json:{"version": "1.0.1", "tag": "v1.0.1", ...}
Docker 镜像标签:
wrbug/polyhermes:v1.0.1✅wrbug/polyhermes:latest✅ (因为不是 pre-release)
场景 2: Pre-release(测试版本)
输入:
- Release Tag:
v1.0.1-beta - Release Type: Pre-release
流程:
- GitHub Actions 提取:
VERSION="1.0.1-beta",GIT_TAG="v1.0.1-beta" - 传递给 Dockerfile
- 生成
/app/version.json:{"version": "1.0.1-beta", "tag": "v1.0.1-beta", ...}
Docker 镜像标签:
wrbug/polyhermes:v1.0.1-beta✅wrbug/polyhermes:latest❌ (pre-release 不推送到 latest)
场景 3: 本地构建(开发环境)
命令行:
docker build -t polyhermes:local .
流程:
- 没有传递
VERSION和GIT_TAG参数 - Dockerfile 使用默认值:
VERSION=dev,GIT_TAG=dev - 生成
/app/version.json:{"version": "dev", "tag": "dev", ...}
显式指定版本号:
docker build \
--build-arg VERSION=1.0.1 \
--build-arg GIT_TAG=v1.0.1 \
-t polyhermes:local .
场景 4: 本地 Docker Compose
docker-compose.yml:
services:
app:
build:
context: .
args:
VERSION: 1.0.1
GIT_TAG: v1.0.1
版本号存储位置
容器内路径
/app/version.json
文件格式
{
"version": "1.0.1", // 纯版本号(无 v 前缀)
"tag": "v1.0.1", // 完整 tag(带 v 前缀)
"buildTime": "2026-01-20T15:30:00Z" // 构建时间(UTC)
}
访问方式
1. 通过 API:
curl http://localhost/api/update/version
2. 进入容器查看:
docker exec -it <container_id> cat /app/version.json
3. 前端显示:
- 系统设置 → 系统更新页面
- 显示当前版本:
v1.0.1
版本号的作用
1. 显示当前版本
前端和系统更新页面显示当前运行的版本号。
2. 检查更新
更新服务通过比较当前版本和 GitHub 最新版本判断是否有更新:
# docker/update-service.py
current_version = get_current_version() # "1.0.1"
latest_version = fetch_latest_release() # "1.0.2"
if compare_versions(latest_version, current_version) > 0:
# 有新版本,提示更新
3. 版本追踪
记录 Docker 镜像的构建版本,便于追踪和回滚。
关键文件
| 文件 | 作用 | 版本号来源 |
|---|---|---|
.github/workflows/docker-build.yml |
GitHub Actions 工作流 | github.event.release.tag_name |
Dockerfile |
Docker 构建配置 | 构建参数 VERSION, GIT_TAG |
/app/version.json |
版本号存储文件 | Dockerfile 生成 |
docker/update-service.py |
更新服务 | 读取 /app/version.json |
常见问题
Q1: 为什么版本号是 dev?
A: 本地构建时没有传递版本号参数,使用了默认值。
解决:
docker build \
--build-arg VERSION=1.0.1 \
--build-arg GIT_TAG=v1.0.1 \
-t polyhermes:local .
Q2: 如何查看当前容器的版本号?
A:
# 方法1: API 接口
curl http://localhost/api/update/version
# 方法2: 进入容器
docker exec -it <container_id> cat /app/version.json
# 方法3: 前端页面
系统设置 → 系统更新 → 查看"当前版本"
Q3: 版本号格式错误怎么办?
A: GitHub Actions 会验证版本号格式:
- ✅ 正确:
v1.0.0,v1.0.0-beta - ❌ 错误:
v1.0,1.0.0
如果格式错误,构建会失败并提示错误信息。
Q4: Pre-release 和正式版本的版本号有什么区别?
A:
- 格式: 都可以使用相同的格式(
v1.0.1-betavsv1.0.1) - 存储: 都存储在
/app/version.json中 - Docker 标签: Pre-release 不会推送到
latest标签 - 通知: Pre-release 不会发送 Telegram 通知
总结
Docker 版本号的确定流程:
- 来源: GitHub Release Tag
- 提取: GitHub Actions 从 tag 中提取版本号
- 传递: 通过 Docker build-args 传递
- 存储: 写入容器内的
/app/version.json - 使用: 用于显示、检查更新、版本追踪
关键点:
- ✅ 版本号来自 GitHub Release Tag
- ✅ 格式必须符合:
v数字.数字.数字[-后缀] - ✅ 默认值为
dev(本地构建时) - ✅ 支持 Pre-release 标记