在docker中标记图像

在docker中标记图像,docker,Docker,我有一个jenkins服务器监控git回购,并在代码更改上构建docker映像。作为构建的一部分,.git目录被忽略,但是我想将git提交散列与映像相关联,这样我就可以确切地知道生成该映像所使用的代码版本,并检查映像是否是最新的 显而易见的解决方案是使用类似“应用程序名称分支名称:提交哈希”的标记图像,但对于许多开发分支,我只想保留最后一个良好的构建,添加更多标记将使清理旧构建变得更加困难(而不是在生成映像时使用jenkins内部版本号,然后重新标记为:latest并取消标记内部版本号) 另一种

我有一个jenkins服务器监控git回购,并在代码更改上构建docker映像。作为构建的一部分,.git目录被忽略,但是我想将git提交散列与映像相关联,这样我就可以确切地知道生成该映像所使用的代码版本,并检查映像是否是最新的

显而易见的解决方案是使用类似“应用程序名称分支名称:提交哈希”的标记图像,但对于许多开发分支,我只想保留最后一个良好的构建,添加更多标记将使清理旧构建变得更加困难(而不是在生成映像时使用jenkins内部版本号,然后重新标记为:latest并取消标记内部版本号)

另一种可能性是标签,但尽管最初看起来很有希望,但在实践中证明标签更为复杂

我能看到的将标签直接应用于图像的唯一方法是Dockerfile,它不能使用构建环境变量,因此我需要使用某种模板来生成自定义Dockerfile

应用标签的另一种方法是使用一些简单的命令(例如bash)从图像启动一个容器,并将标签作为docker运行参数传入。然后可以将该容器作为新图像提交。这有一个不幸的副作用,即使图像的默认命令与标签容器一起使用(本例中为bash)而不是原始Dockerfile中的任何内容。对于我的应用程序,我无法使用实际命令,因为它将开始更改应用程序状态


所有这些似乎都不是特别理想的—是否有其他人找到了更好的方法?

docker v1.9.0中添加了对这一点的支持,因此如果您同意,将docker安装更新到该版本将解决您的问题

用法在下面的拉取请求中描述:


以以下Dockerfile文件为例:

并将其构建到名为
test
的图像中,就像任何人都会天真地做的那样:

docker build -t test .
然后检查
test
图像以检查
git commit
标签的最终值:

docker inspect -f '{{index .ContainerConfig.Labels "git-commit"}}' test
docker inspect -f '{{index .ContainerConfig.Labels "git-commit"}}' test
不为人知的

现在,再次构建映像,但这次使用
--build arg
选项:

docker build -t test --build-arg GIT_COMMIT=0123456789abcdef .
然后检查
test
图像以检查
git commit
标签的最终值:

docker inspect -f '{{index .ContainerConfig.Labels "git-commit"}}' test
docker inspect -f '{{index .ContainerConfig.Labels "git-commit"}}' test
0123456789abcdef


参考资料:

  • 选项的Docker生成命令文档
  • 指令的Dockerfile引用
  • 指令的Dockerfile引用

您可以在创建图像时在命令行上指定标签

docker build -t myproject --label "myproject.version=githash" .
除了硬编码版本,您还可以直接从git获得:

docker build -t myproject --label "myproject.version=`git describe`" .
要从图像中读取标签,可以使用带有格式字符串的
docker inspect

docker inspect -f '{{index .Config.Labels "myproject.version"}}' myproject

如果您使用的是docker compose,您可以:


其中,
COMMIT\u HASH
是您的,它保存COMMIT HASH。

我想我可能会使用一个模板引擎来生成包含构建变量值的Dockerfile。在我看来,构建时间是正确的操作点。此解决方案不使用来自构建过程(发生在容器内部)的信息要创建标签,它要求元数据在容器外部是已知的。我相信OP的情况与我相同,我们希望通过标签公开有关内部构建的元数据。例如,我可能希望为代码覆盖率添加标签,这是在执行特定的RUN命令后确定的。