Dir*_*irk 11 tags docker docker-compose
根据这个和这个 GitHub问题,目前在使用docker-compose
构建一个或多个图像时,如何为服务的图像提供多个标签没有本地方式.
我的用例是构建docker-compose.yml
文件中定义的图像,并使用一些自定义标记(例如某些构建编号或日期或类似标记)标记一次,并将其标记为latest
.
虽然docker
使用docker tag可以轻松实现这一点,但docker-compose
只允许在图像键中设置一个标记.使用docker tag
连同docker-compose
是不是一种选择对我,因为我要保持我的所有码头工人有关的定义docker-compose.yml
文件,而不是将其复制过来到我的构建脚本.
在首先使用docker-compose
和不必硬编码/复制图像名称的情况下,设置多个标签会有什么好处?
Dir*_*irk 11
我提出了几个不同复杂程度的解决方法.它们都依赖于${IMAGE_TAG}
存储代表例如构建号的自定义标记的假设.我们希望使用此标记以及标记所有服务的图像latest
.
grep
docker-compose.yml
文件中的图像名称images=$(cat docker-compose.yml | grep 'image: ' | cut -d':' -f 2 | tr -d '"')
for image in $images
do
docker tag "${image}":"${IMAGE_TAG}" "${image}":latest
done
Run Code Online (Sandbox Code Playgroud)
但是,如果某人添加了docker-compose.yml
例如看起来像的评论,则这很容易出错# Purpose of this image: do something useful...
.
使用${IMAGE_TAG}
在你的环境变量docker-compose.yml
描述文件中的第一个例子在这里.
然后,只需运行构建过程两次,每次${IMAGE_TAG}
使用不同的值替换:
IMAGE_TAG="${IMAGE_TAG}" docker-compose build
IMAGE_TAG=latest docker-compose build
Run Code Online (Sandbox Code Playgroud)
第二个构建过程应该比第一个构建过程快得多,因为所有图像层仍应从第一次运行中缓存.
这种方法的缺点是它会使每个单独服务的两个后续构建过程充斥您的日志输出,这可能会使搜索更难以查找有用的东西.
此外,如果你有任何命令Dockerfile
总是刷新构建缓存(例如,ADD
从具有自动更新last-modified
头的远程位置获取命令,添加由外部进程不断更新的文件等),那么额外的构建可能会减慢速度显着下降.
docker-compose.yml
使用一些内联Python代码从文件中解析图像名称使用yaml
Python中的真实解析器(或任何其他语言,例如Ruby
或者perl
系统上安装的任何语言)比第一次提到的grep
方法更强大,因为它不会被评论或编写yml
文件的奇怪但有效的方式混淆.
在Python中,这可能如下所示:
images=$(python3 <<-EOF # make sure below to indent with tabs, not spaces; or omit the "-" before "EOF" and use no indention at all
import yaml
content = yaml.load(open("docker-compose.build.yml"))
services = content["services"].values()
image_names = (service["image"].split(":")[0] for service in services)
print("\n".join(image_names))
EOF
)
for image in ${images}
do
docker tag ${image}:${IMAGE_TAG} ${image}:latest
done
Run Code Online (Sandbox Code Playgroud)
这种方法的缺点是执行构建的机器必须安装Python3以及PyYAML库.如前所述,此模式可以类似地与Python2或任何其他安装的编程语言一起使用.
docker
命令的组合获取图像名称使用一些本机docker
和docker-compose
命令(使用go-templates)的以下方法编写起来有点复杂,但也可以很好地工作.
# this should be set to something unique in order to avoid conflicts with other running docker-compose projects
compose_project_name=myproject.tagging
# create containers for all services without starting them
docker-compose --project-name "${compose_project_name}" up --no-start
# get image names without tags for all started containers
images=$(docker-compose --project-name "${compose_project_name}" images -q | xargs docker inspect --format='{{ index .RepoTags 0}}' | cut -d':' -f1)
# iterate over images and re-tag
for image in ${images}
do
docker tag "${image}":"${IMAGE_TAG}" "${image}":latest
done
# clean-up created containers again
docker-compose --project-name "${compose_project_name}" down
Run Code Online (Sandbox Code Playgroud)
虽然这种方法没有任何外部依赖性并且比grep
方法更安全,但是在大型设置上执行创建和删除容器可能需要几秒钟(尽管通常不是问题).
Rom*_*ain 11
正如@JordanDeyton 所建议的,extends
不能再在 Compose 文件格式中使用,> 3
并且版本中添加的扩展字段功能3.4
可以替换它以实现相同的目标。这是一个例子。
version: "3.4"
# Define common behavior
x-ubi-httpd:
&default-ubi-httpd
build: ubi-httpd
# Other settings can also be shared
image: ubi-httpd:latest
# Define one service by wanted tag
services:
# Use the extension as is
ubi-httpd_latest:
*default-ubi-httpd
# Override the image tag
ubi-httpd_major:
<< : *default-ubi-httpd
image: ubi-httpd:1
ubi-httpd_minor:
<< : *default-ubi-httpd
image: ubi-httpd:1.0
# Using an environment variable defined in a .env file for e.g.
ubi-httpd_patch:
<< : *default-ubi-httpd
image: "ubi-httpd:${UBI_HTTPD_PATCH}"
Run Code Online (Sandbox Code Playgroud)
现在可以使用所有定义的标签构建图像
version: "3.4"
# Define common behavior
x-ubi-httpd:
&default-ubi-httpd
build: ubi-httpd
# Other settings can also be shared
image: ubi-httpd:latest
# Define one service by wanted tag
services:
# Use the extension as is
ubi-httpd_latest:
*default-ubi-httpd
# Override the image tag
ubi-httpd_major:
<< : *default-ubi-httpd
image: ubi-httpd:1
ubi-httpd_minor:
<< : *default-ubi-httpd
image: ubi-httpd:1.0
# Using an environment variable defined in a .env file for e.g.
ubi-httpd_patch:
<< : *default-ubi-httpd
image: "ubi-httpd:${UBI_HTTPD_PATCH}"
Run Code Online (Sandbox Code Playgroud)
您还可以采取以下方法:
# build is your actual build spec
build:
image: myrepo/myimage
build:
...
...
# these extend from build and just add new tags statically or from environment variables or
version_tag:
extends: build
image: myrepo/myimage:v1.0
some_other_tag:
extends: build
image: myrepo/myimage:${SOME_OTHER_TAG}
Run Code Online (Sandbox Code Playgroud)
然后你可以运行docker-compose build
并且docker-compose push
你将构建并推送正确的标记图像集
现在有一个使用buildx Baker 的内置解决方案,在v.0.7.0中发布。此功能是根据我在https://github.com/docker/buildx/issues/396中的建议实现的。
Docker 是捆绑buildx
安装的,但是,如果您在 Mac 上运行 Docker Desktop,则buildx
在撰写本文时捆绑的版本较旧,您将需要安装buildx
Docker 之外的正确版本。
将扩展字段添加x-bake
到您的docker-compose.yaml
:
version: '3.9'
services:
my-app:
image: my-repo/my-image:latest
build:
context: .
dockerfile: Dockerfile
x-bake:
tags:
- my-repo/my-image:${MY_TAG_1}
- my-repo/my-image:${MY_TAG_2}
- my-repo/my-image:${MY_TAG_3}
- my-other-repo/my-image:${MY_TAG_1}
- my-other-repo/my-image:${MY_TAG_2}
- my-other-repo/my-image:${MY_TAG_3}
Run Code Online (Sandbox Code Playgroud)
要构建并标记图像,请运行:
buildx bake --load
Run Code Online (Sandbox Code Playgroud)
要构建、标记图像并将其推送到存储库甚至多个存储库:
buildx bake --push
Run Code Online (Sandbox Code Playgroud)
我有一些使用环境变量的简洁解决方案(默认变量值的bash语法,在我来说是,latest
但是您可以使用任何东西),这是我的写法:
version: '3'
services:
app:
build: .
image: myapp-name:${version:-latest}
Run Code Online (Sandbox Code Playgroud)
使用默认标记生成并推送(如果需要推送到注册表),请使用环境变量更改版本,然后再次生成并推送:
docker-compose build
docker-compose push
export version=0.0.1
docker-compose build
docker-compose push
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6905 次 |
最近记录: |