如何使用Azure DevOps从Docker镜像中获取并保存Artifact?
Azure DevOps Docker构建流程Artifact留存方案
Docker构建场景下的Artifact分两类:构建过程生成的普通文件(编译产物、扫描报告、日志等)、Docker镜像本身,两类留存逻辑不同,以下是可直接复用的操作流程和常见问题排查点。
可落地操作流程
1. 留存普通文件类构建产物
Docker镜像构建运行在独立容器环境中,容器内的文件不会自动同步到流水线Agent的本地目录,直接发布Artifact会因为找不到文件失败,必须先把文件从容器内拷贝到Agent工作目录:
- 第一步:Dockerfile使用多阶段构建,将需要留存的产物统一放在命名构建阶段(比如命名为
build),避免和运行时镜像混放 - 第二步:在Docker镜像构建任务之后,添加命令行任务执行拷贝逻辑,将容器内的目标文件拷贝到Agent预置的Artifact暂存目录,参考代码:
# 基于刚构建完成的镜像创建临时容器(无需启动服务) container_id=$(docker create <你的镜像名:$(Build.BuildId)>) # 拷贝容器内指定路径的产物到暂存目录 docker cp $container_id:/path/to/your/target/files $(Build.ArtifactStagingDirectory)/ # 清理临时容器 docker rm $container_id
- 第三步:添加
Publish Build Artifacts任务,发布路径选择$(Build.ArtifactStagingDirectory),自定义Artifact名称,发布位置选择Azure Pipelines即可,执行完就能在流水线运行结果的Artifact栏看到留存的文件。
2. 留存Docker镜像作为Artifact
如果需要留存镜像本身而非内部文件,不需要依赖容器镜像仓库,直接将构建好的镜像导出为tar归档包,再走Artifact发布流程即可:
- 在Docker构建任务之后添加命令行任务,执行镜像导出命令:
docker save -o $(Build.ArtifactStagingDirectory)/image-$(Build.BuildId).tar <你的镜像名:$(Build.BuildId)>
- 后续同样使用
Publish Build Artifacts任务发布这个tar包,后续使用时直接执行docker load -i 镜像包名.tar即可导入使用。
常见留存失败问题排查
遇到Artifact发布异常时,按以下优先级核对:
- 路径配置错误:不要在Publish任务里直接填Docker容器内部路径(比如
/app/output),Agent本地不存在这个路径必然报错。所有待发布文件必须先拷贝到Agent本地目录,优先使用$(Build.ArtifactStagingDirectory)预置变量,不要写硬编码路径。 - 文件权限问题:使用Linux自托管Agent时,docker相关命令生成的文件默认权限为root,会导致后续发布任务无读取权限,在拷贝/导出命令之后加一行
sudo chmod -R 755 $(Build.ArtifactStagingDirectory)/*修改权限即可。 - 任务顺序错误:Publish Artifacts任务必须放在Docker构建、文件拷贝/导出步骤之后,不要放在Docker资源清理步骤之后。可以在发布任务前加一行目录打印命令
ls -R $(Build.ArtifactStagingDirectory)(Linux)或者Get-ChildItem -Recurse $(Build.ArtifactStagingDirectory)(Windows),通过流水线日志确认暂存目录下确实存在待发布文件,再排查后续问题。 - 静默失败问题:如果脚本里镜像名、标签填写错误,docker cp/save命令执行失败但流水线没有终止,会导致发布空目录。在脚本开头添加错误拦截:Linux脚本加
set -euo pipefail,PowerShell脚本加$ErrorActionPreference = "Stop",任意命令执行失败直接终止流水线,避免无感知的错误。
内容的提问来源于stack exchange,提问作者jazzbass
相关产品推荐
相关产品推荐

