家里 NAS 上跑了不少 Docker 服务,比如 CPA 网关、青龙、DDNS、Home Assistant 等。这些服务的镜像会不定期发布新版本,每次需要手动去拉取、重建,久了就很烦。
前段时间折腾 CPA 网关自动更新,逐步从青龙脚本 → Portainer API → SSH 操作,最后收敛到了一个通用方案:一个脚本 + 一个配置文件,跑在群晖任务计划程序上,定时检查所有服务的 GitHub release,自动拉取镜像并按需重建容器。
方案架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ┌─────────────────────────────────────────────────┐ │ 群晖 DSM Task Scheduler │ │ 每天 6:00 / 18:00 各跑一次 │ │ │ │ ┌──────────────────────────────────────┐ │ │ │ docker-auto-update.sh │ │ │ │ │ │ │ │ 读取 services.json 配置 │ │ │ │ ↓ │ │ │ │ 对每个服务: │ │ │ │ 1. 查询 GitHub latest release │ │ │ │ 2. 比对本地版本记录 │ │ │ │ 3. 若有新版本 → docker pull │ │ │ │ 4. 按模式决定是否 compose up -d │ │ │ │ 5. 企业微信推送通知 │ │ │ └──────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘
|
两种模式
| 模式 |
动作 |
适用场景 |
pull_only |
只拉取镜像到本地 |
容器独立运行,不在 Compose 管理下,或者想手动择机重建 |
pull_and_rebuild |
拉取镜像 + docker compose up -d 重建 |
Compose 管理的服务,全自动更新 |
配置文件格式
脚本通过一个 JSON 文件管理所有服务,新增服务只需加一条记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "services": [ { "name": "CPA 网关", "github_repo": "router-for-me/CLIProxyAPI", "docker_image": "eceasy/cli-proxy-api", "mode": "pull_and_rebuild", "compose_dir": "/volume1/docker/cpa", "compose_file": "compose.yaml", "container_name": "cli-proxy-api", "notify": true } ] }
|
各字段说明:
| 字段 |
说明 |
name |
服务显示名称,用于日志和通知 |
github_repo |
GitHub 仓库 owner/repo,用于查询最新 release tag |
docker_image |
Docker 镜像名,不含 tag |
mode |
pull_only 或 pull_and_rebuild |
compose_dir |
(仅 rebuild 模式) Compose 项目目录 |
compose_file |
(仅 rebuild 模式) Compose 文件名,默认 compose.yaml |
container_name |
容器名,用于从运行态反查当前版本(可选) |
notify |
是否推送企业微信通知 |
文件结构
1 2 3 4 5 6 7 8
| /volume1/docker/scripts/compose/ ├── update.sh # 通用更新脚本 ├── services.json # 服务配置文件(可随时增删) ├── .wecom-config # 企业微信通知凭据(权限 600) ├── state/ # 各服务的版本记录 │ ├── CPA_网关.version │ └── ... └── update.log # 运行日志
|
群晖任务计划程序配置
DSM 控制面板 → 任务计划程序:
1 2 3 4
| 任务名称: Docker 自动更新 用户: root 运行命令: bash /volume1/docker/scripts/compose/update.sh 定时: 每天 06:00 / 18:00
|
通知效果
有更新时,企业微信会收到类似这样的推送:
1 2 3 4 5
| ✅ **Docker 镜像更新** >CPA 网关: v7.2.71 → v7.2.74 >模式: 拉取 + 重建 >compose: /volume1/docker/cpa/compose.yaml >⏱ 2026-07-14 18:00:23
|
失败时推送警告:
1 2 3
| ⚠️ **CPA 网关 拉取失败** >eceasy/cli-proxy-api:v7.2.74 镜像拉取失败 >⏱ 2026-07-14 18:00:23
|
无更新时脚本静默退出,不产生通知。
脚本核心逻辑
1 2 3 4 5 6 7 8 9 10
| for 每个服务 in services.json: 1. curl GitHub API → 获取最新 release tag 2. 读取本地 .version 文件 → 获取当前版本 3. 版本比较 - 相同 → 跳过 - 新版本 → docker pull 4. 根据 mode 决定是否 docker compose up -d 5. 写入新版本到 .version 文件 6. 清理旧镜像 7. 推送企业微信通知
|
关键设计:
- 互斥锁:防止定时任务重叠执行
- 版本状态文件:每次检查后记录版本,避免重复拉取同一个版本
- compose.yaml 备份:更新前自动
.bak,失败时回滚
- 幂等安全:无新版本时静默退出,不影响正在运行的服务
使用场景扩展
目前配置了 CPA 网关的自动更新,后续想加新服务只需在 services.json 追加一条记录。例如添加青龙的自动更新:
1 2 3 4 5 6 7 8
| { "name": "青龙面板", "github_repo": "whyour/qinglong", "docker_image": "whyour/qinglong", "mode": "pull_only", "container_name": "qinglong-web-1", "notify": true }
|
青龙使用 pull_only 模式——镜像拉取后择机手动重建,避免自动重启打断正在跑的任务。
📝 本文由 AI 助手群晖仕辅助生成