构建 docker-compose 镜像并将其推送到容器注册表中

Posted

技术标签:

【中文标题】构建 docker-compose 镜像并将其推送到容器注册表中【英文标题】:Build and push docker-compose image into container registry 【发布时间】:2021-12-22 02:15:32 【问题描述】:

我会使用 docker-compose 创建一个 docker 映像并将其推送到 gitlab container registrydocker-compose 文件有一些 build.args 所以在编译期间我使用 --env-file 标志传递 env 文件。 Dockerfile 图像分为两步:baseproduction,这是内容:

FROM node:17.0-alpine AS base

ARG GITLAB_ACCESS_TOKEN

WORKDIR /usr/src/app

COPY .npmrc ./
COPY package*.json ./

RUN npm i

COPY . .

FROM base AS production

RUN npm run build

这是docker-compose.yml

version: '3.8'
services: 
  aaa-bbb:
    container_name: ccc
    environment:
      - GITLAB_ACCESS_TOKEN=$GITLAB_ACCESS_TOKEN
    build:
      context: .
      dockerfile: Dockerfile
      target: base
      args:
        GITLAB_ACCESS_TOKEN: $GITLAB_ACCESS_TOKEN
        PORT: $PORT
    image: aaa-bbb/ccc:$TAG_VERSION
    restart: always
    ports:
      - 80:$PORT
    command: yarn start:dev

这个是docker-compose.prod.yml:

version: '3.8'
services: 
  aaa-bbb:
    container_name: ccc
    environment:
      - GITLAB_ACCESS_TOKEN=$GITLAB_ACCESS_TOKEN
    build:
      context: .
      dockerfile: Dockerfile
      target: production
      args:
        GITLAB_ACCESS_TOKEN: $GITLAB_ACCESS_TOKEN
        PORT: $PORT
    image: aaa-bbb/ccc:$TAG_VERSION
    restart: always
    ports:
      - 80:$PORT
    command: yarn start:prd

要构建图像,我使用以下命令:docker-compose --env-file ./config/.production.env -f docker-compose.yml -f docker-compose.prod.yml build --no-cache

这是构建并存储到容器中的 gitlab 管道步骤,重新注册 docker 映像:

create_image:
  image: docker
  stage: create-image
  services:
    - docker:dind
  before_script:
    - TAG_VERSION=$(awk -F= '$1 == "TAG_VERSION"  print $2 ' ./config/.production.env)
    - apk add --no-cache docker-compose
    - docker image prune -f
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - echo "???? Image creation started..."
    - docker-compose --env-file ./config/.production.env -f docker-compose.yml -f docker-compose.prod.yml build --no-cache
    - docker-compose --env-file ./config/.production.env push aaa-bbb/ccc:$TAG_VERSION
    - echo "???? Image created successfully!"

这是管道的输出:

Removing intermediate container 1187fec9a21e
 ---> b0c14918a07b
[Warning] One or more build-args [PORT] were not consumed
Successfully built b0c14918a07b
Successfully tagged aaa-bbb/ccc:1.0.0
$ docker-compose --env-file ./config/.production.env push aaa-bbb/ccc:$TAG_VERSION
No such service: aaa-bbb/ccc:1.0.0
Cleaning up project directory and file based variables 00:00
ERROR: Job failed: exit code 1

如您所见,有以下警告:[Warning] One or more build-args [PORT] were not consumed 在我在本地测试期间它没有出现,其次我有一个标记为 aaa-bbb/ccc:1.0.0 的服务,但我无法推送它,因为没有服务。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

您的第一个问题是在您的 docker-compose.yml 中定义了一个名为 PORT 的构建参数,但您的 Dockerfile 中不存在该参数。因此 docker 警告它被定义但未被使用。

你可以通过添加来解决这个问题

ARG PORT
EXPOSE $PORT

Dockerfile 的末尾。如果您想设置默认值(例如 HTTP 端口 80)作为端口,您可以使用此表单:ARG PORT=80

如果您需要有关Dockerfiles 的更多信息,可以在https://docs.docker.com/engine/reference/builder/ 的参考文档中阅读更多相关信息

但这不会导致错误。使用docker-compose 推送时,您使用服务名称而不是图像。所以在你的情况下,正确的命令是

docker-compose --env-file ./config/.production.env push aaa-bbb

另外,您需要在docker-compose.yml 中添加图片名称的完整 URL。即:

services: 
  aaa-bbb:
    [redacted]
    image: your.gitlab.instance/perhapssomegroup/aaa-bbb/ccc:$TAG_VERSION
    [redacted]

您可以在https://docs.docker.com/compose/reference/ 阅读有关docker-compose 的更多信息,并在https://docs.docker.com/compose/compose-file/compose-file-v3/ 阅读有关其yml 文件的更多信息

我建议将我发布的所有文档链接放在快速拨号(也称为书签)上,因为您可能非常需要它们。

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。 感谢您提供详细的回答,但尽管在执行docker-compose push 时已登录container register,但它会尝试在docker.io 上使用push 而不是gitlab 容器注册表跨度> 正确。您需要使用指向您自己的注册表的完整 URL 设置 image: 键。我将此添加到答案中。 请注意,PORT 在语法上不正确。你的意思是EXPOSE 你是对的@th3g3ntl3man。感谢您指出。我相应地修正了答案。

以上是关于构建 docker-compose 镜像并将其推送到容器注册表中的主要内容,如果未能解决你的问题,请参考以下文章

在 Dockerfile/Docker-Compose 中使用提交的容器镜像是不是可行? [复制]

如何使用 Azure Pipeline 将 Docker 映像“推送”到 Azure 容器注册表?

推送时自动部署 docker 镜像

Dockerfile 和 docker-compose.yml的区别

使用 gitlab-ci 构建多个 Docker 镜像

如何将docker容器添加到现有docker网络