如何在docker-compose中使用多个图像标签

6yoyoihd  于 2023-06-29  发布在  Docker
关注(0)|答案(6)|浏览(113)

根据thisthis GitHub的问题,目前还没有一种原生的方法,可以在使用docker-compose构建一个或多个镜像时为服务的镜像提供多个标签。
我的用例是构建在docker-compose.yml文件中定义的图像,并使用一些自定义的标签(例如一些建筑物没有。或日期或类似),并且一次为latest
虽然使用docker tag可以很容易地通过普通docker实现,但docker-compose只允许在图像键中设置一个标签。对我来说,将docker tagdocker-compose一起使用不是一个选择,因为我想将所有与docker相关的定义保存在docker-compose.yml文件中,而不是将它们复制到构建脚本中。
什么是一个体面的解决方案,以实现设置多个标签与docker-compose,而不必硬编码/复制图像名称第一?

omhiaaxx

omhiaaxx1#

我有一些使用环境变量的漂亮而干净的解决方案(默认变量值的bash语法,在我的例子中是latest,但你可以使用任何东西),这是我的compose:

version: '3'
services:
  app:
    build: .
    image: myapp-name:${version:-latest}

使用默认标签构建并推送(如果您需要推送到注册表),使用环境变量更改版本并再次构建并推送:

docker-compose build
docker-compose push
export version=0.0.1
docker-compose build
docker-compose push
ghhkc1vu

ghhkc1vu2#

您还可以采取以下方法:

# 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}

然后,您只需运行docker-compose builddocker-compose push,即可构建并推送正确的标记映像集。

3bygqnnd

3bygqnnd3#

正如@JordanDeyton所建议的那样,extends不能再用于编写文件格式> 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}"

现在可以使用所有已定义的标记构建图像

$ docker-compose build
# ...

$ docker images | grep ubi-httpd
# ubi-httpd  1       8cc412411805  3 minutes ago  268MB
# ubi-httpd  1.0     8cc412411805  3 minutes ago  268MB
# ubi-httpd  1.0.1   8cc412411805  3 minutes ago  268MB
# ubi-httpd  latest  8cc412411805  3 minutes ago  268MB
cidc1ykv

cidc1ykv4#

我想出了几个不同复杂程度的变通方法。它们都依赖于${IMAGE_TAG}存储表示例如构建号我们希望用这个标签以及latest来标记所有服务的图像。

grepdocker-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

但是,如果有人在docker-compose.yml中添加了注解,例如:看起来像# Purpose of this image: do something useful...

构建两次

使用${IMAGE_TAG}作为docker-compose.yml文件中的环境变量,如here in the first example所述。
然后,简单地运行构建过程两次,每次用不同的值替换${IMAGE_TAG}

IMAGE_TAG="${IMAGE_TAG}" docker-compose build
IMAGE_TAG=latest docker-compose build

第二个构建过程应该比第一个快得多,因为所有图像层仍然应该从第一次运行中缓存。
这种方法的缺点是,它会用每个服务的两个后续构建过程淹没日志输出,这可能会使搜索有用的东西变得更加困难。
此外,如果您在Dockerfile中有任何命令总是刷新构建缓存(例如:ADD命令从远程位置获取,并自动更新last-modified头文件,添加由外部进程不断更新的文件等),那么额外的构建可能会显着减慢速度。

使用一些内联Python代码解析docker-compose.yml文件中的图像名称

在Python(或任何其他语言,如Rubyperl或任何安装在您系统上的语言)中使用真实的的yaml解析器比第一次提到的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

这种方法的缺点是执行构建的机器必须安装Python3沿着PyYAML库。如前所述,此模式可以类似地用于Python 2或安装的任何其他编程语言。

结合一些docker命令获取镜像名称

下面的方法使用了一些原生的dockerdocker-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

虽然这种方法没有任何外部依赖项,并且比grep方法更安全,但在创建和删除容器的大型设置上可能需要多几秒钟的时间(通常不是问题)。

h4cxqtbf

h4cxqtbf5#

现在有一个使用buildx bake的内置解决方案,在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}

要构建并标记映像,请运行:

buildx bake --load

要构建、标记和推送映像到存储库甚至多个存储库,请执行以下操作:

buildx bake --push
7uhlpewt

7uhlpewt6#

像许多人建议的那样使用extends是次优的,因为它会为生成的每个图像产生不同的校验和。这通常是不好的,因为您可以确保在生产环境中使用一致的映像。

# cat docker-compose.yml 
version: "3.8"
services:

  container:
    build:
      context: .
    image: test/image:1

 # adds a copy of the image tagged with the build id
  extra-tags:
    extends: container
    image: test/image:2
  latest:
    extends: container
    image: test/image:3# 
# cat Dockerfile 
# syntax=docker/dockerfile:1
FROM alpine:3.15

# docker compose build
[+] Building 2.9s (13/13) FINISHED                                                                                                                                                                                                               
 => [latest internal] load build definition from Dockerfile                                                                                                                                                                                 0.0s
 => => transferring dockerfile: 84B                                                                                                                                                                                                         0.0s
 => [latest internal] load .dockerignore                                                                                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                                                                                             0.0s
 => [latest] resolve image config for docker.io/docker/dockerfile:1                                                                                                                                                                         1.2s
 => [container internal] load build definition from Dockerfile                                                                                                                                                                              0.0s
 => => transferring dockerfile: 84B                                                                                                                                                                                                         0.0s
 => [container internal] load .dockerignore                                                                                                                                                                                                 0.0s
 => => transferring context: 2B                                                                                                                                                                                                             0.0s
 => [extra-tags internal] load build definition from Dockerfile                                                                                                                                                                             0.0s
 => => transferring dockerfile: 84B                                                                                                                                                                                                         0.0s
 => [extra-tags internal] load .dockerignore                                                                                                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                                                                                                             0.0s
 => CACHED [container] docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b14                                                                                                 0.1s
 => => resolve docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b14                                                                                                                        0.0s
 => [extra-tags internal] load metadata for docker.io/library/alpine:3.15                                                                                                                                                                   1.0s
 => CACHED [container 1/1] FROM docker.io/library/alpine:3.15@sha256:3362f865019db5f14ac5154cb0db2c3741ad1cce0416045be422ad4de441b081                                                                                                       0.1s
 => => resolve docker.io/library/alpine:3.15@sha256:3362f865019db5f14ac5154cb0db2c3741ad1cce0416045be422ad4de441b081                                                                                                                        0.0s
 => [latest] exporting to image                                                                                                                                                                                                             0.2s
 => => exporting layers                                                                                                                                                                                                                     0.0s
 => => exporting manifest sha256:67e737bfe3d8955deeebd531025697ed4e8c4a4c263b9f1ea9bc7b4bc0330105                                                                                                                                           0.0s
 => => exporting config sha256:b2fe3df223ec66ebfa2c8e2dac5760b42a79eefb9abc83c2f0c5972e371c6e52                                                                                                                                             0.0s
 => => exporting attestation manifest sha256:1a18ee3574147462eea9d4b46ffaa30a69b5211b70238ba3f548e67b24a06aa8                                                                                                                               0.1s
 => => exporting manifest list sha256:19a2d2908947fa148c536b1d7b487e01d0aaa5ae4a8250fae41ac53ce2ae103d                                                                                                                                      0.0s
 => => naming to docker.io/test/image:3                                                                                                                                                                                                     0.0s
 => => unpacking to docker.io/test/image:3                                                                                                                                                                                                  0.0s
 => [container] exporting to image                                                                                                                                                                                                          0.2s
 => => exporting layers                                                                                                                                                                                                                     0.0s
 => => exporting manifest sha256:1f4ea8de74e009308a75606c3eb0adfad16bd5a0c495b1e5e790414adbb9e09e                                                                                                                                           0.0s
 => => exporting config sha256:021dc0c803e68082939d5a0ecd37d6f8e25be82eb9425b45296ad3cbd2373c29                                                                                                                                             0.0s
 => => exporting attestation manifest sha256:a297fc379c4b1a509de3b106f3f4e478d8f64b95abb1f516d584ce148f42cbec                                                                                                                               0.1s
 => => exporting manifest list sha256:73cb361e578dab7451a61a3381bb1d3fa228273de97dc7ed8ff5032498ac7049                                                                                                                                      0.0s
 => => naming to docker.io/test/image:1                                                                                                                                                                                                     0.0s
 => => unpacking to docker.io/test/image:1                                                                                                                                                                                                  0.0s
 => [extra-tags] exporting to image                                                                                                                                                                                                         0.2s
 => => exporting layers                                                                                                                                                                                                                     0.0s
 => => exporting manifest sha256:03f127f826024b1a0e194aa00bae4feba34af4471832d6d4b19d6b4cebd26d7f                                                                                                                                           0.0s
 => => exporting config sha256:3e45d21e99ff3ca466cf3197927e614d542da5d548f929422dfb7889fa55e546                                                                                                                                             0.0s
 => => exporting attestation manifest sha256:419d1dff28c183ab66a3c7724cf26248c58d4e452eae54e605cf3504ce15eefb                                                                                                                               0.1s
 => => exporting manifest list sha256:d671e4950218e44569fca1a74aebb100999deb24acaa2003149bc743cf1316d4                                                                                                                                      0.0s
 => => naming to docker.io/test/image:2                                                                                                                                                                                                     0.0s
 => => unpacking to docker.io/test/image:2                                                                                                                                                                                                  0.0s
# docker images --digests | grep ^test/
test/image                                        1                                                       sha256:73cb361e578dab7451a61a3381bb1d3fa228273de97dc7ed8ff5032498ac7049   73cb361e578d   2 minutes ago    9.07MB
test/image                                        2                                                       sha256:d671e4950218e44569fca1a74aebb100999deb24acaa2003149bc743cf1316d4   d671e4950218   2 minutes ago    9.07MB
test/image                                        3                                                       sha256:19a2d2908947fa148c536b1d7b487e01d0aaa5ae4a8250fae41ac53ce2ae103d   19a2d2908947   2 minutes ago    9.07MB

相关问题