如何仅在Docker镜像构建无错误成功时才将其推送到Docker Hub
现有脚本的风险说明
首先直接解答你的核心疑问:
- 如果构建过程出错,
docker build会返回非0的退出码,你当前的脚本没有做执行状态判断,会直接继续执行后面的推送命令 - 会不会推送损坏镜像分两种情况:你当前脚本里的
docker push命令存在标签笔误(多了一层myserver:前缀),这种情况下推送会直接失败;如果把标签修正为和构建时一致的name/myserver:latest,只要本地存在旧的同名标签镜像,就会把旧镜像推送到Docker Hub覆盖远端的正常版本,极端情况下如果构建到一半生成了损坏的同名标签镜像,也会把损坏镜像推上去。
最简修复方案(仅确保构建成功才推送)
你可以直接用命令串联符&&控制执行逻辑,只有前面的命令执行成功(退出码为0)才会执行后面的命令,修复后的基础脚本示例:
#!/bin/bash # 可选:提前清理旧的构建缓存,释放NAS存储空间 docker builder prune -f # 仅构建成功才执行推送操作,同时修正了标签笔误 docker build --no-cache -t name/myserver:latest . && docker push name/myserver:latest # 可选:增加错误状态判断,方便后续扩展告警逻辑 if [ $? -ne 0 ]; then # 这里可以对接NAS的系统通知、邮件、内网消息推送等,及时告知构建失败 echo "镜像构建或推送执行失败" exit 1 fi
完整的NAS定时执行方案
- 第一步:把上述脚本保存到NAS的固定路径下,例如
/volume1/docker/scripts/build-and-push.sh,给脚本添加执行权限:chmod +x /volume1/docker/scripts/build-and-push.sh - 第二步:配置定时执行规则,群晖、威联通等主流NAS都自带可视化计划任务功能,直接在GUI界面添加任务、设置每6小时执行一次上述脚本即可;也可以通过crontab配置,添加如下规则:
0 */6 * * * /bin/bash /volume1/docker/scripts/build-and-push.sh >> /var/log/docker-build.log 2>&1
上述规则会把脚本的所有执行日志输出到指定文件,方便后续排查问题。
进阶优化建议
- 增加多标签管理:不要每次都只使用
latest标签,可以追加构建时间、代码commit哈希作为额外标签,避免直接覆盖旧的可用版本,示例:
TAG=$(date +%Y%m%d%H%M) docker build --no-cache -t name/myserver:$TAG -t name/myserver:latest . if [ $? -eq 0 ]; then docker push name/myserver:$TAG docker push name/myserver:latest fi
- 增加构建前置逻辑:如果是基于代码仓库构建,记得在构建前先拉取最新代码,避免用本地旧代码重复构建
- 增加资源限制:NAS性能通常有限,可以给
docker build加上资源限制参数,避免构建任务占用过多资源影响NAS其他服务运行,示例:docker build --cpus 2 --memory 2g --no-cache ... - 增加可用性校验:构建完成后可以先临时启动容器做简单的可用性测试,比如检测服务端口是否能通、基础接口是否正常返回,测试通过后再执行推送,进一步避免损坏镜像上线
内容的提问来源于stack exchange,提问作者Marc
相关产品推荐
相关产品推荐

