如何在 docker-compose 中定义 build-args?

Posted

技术标签:

【中文标题】如何在 docker-compose 中定义 build-args?【英文标题】:How to define build-args in docker-compose? 【发布时间】:2018-11-16 22:59:50 【问题描述】:

我有以下 docker-compose 文件

version: '3'
services:
    node1:
            build: node1
            image: node1
            container_name: node1

    node2:
            build: node2
            image: node2
            container_name: node2

我可以构建两个映像并使用单个命令启动它们

docker-compose up -d --build

但我想在构建中使用 build-args。 compose 范围之外的图像的原始构建脚本看起来像这样

#!/bin/sh
docker build \
--build-arg ADMIN_USERNNAME_1=weblogic \
--build-arg ADMIN_PASSWORD_1=weblogic1 \
--build-arg ADMIN_NAME_1=admin \
--build-arg ...
--build-arg ... \
-t test/foo .

两个图像都将使用同名但值不同的构建参数。此外,由于有几十个构建参数,将它们存储在特定于 compose 服务的构建属性文件中会很方便。 docker-compose 可以吗?

【问题讨论】:

对后来人的警告:对于密码,您可以考虑使用秘密管理器(Vault、k8s 秘密、aws sms、docker swarm 秘密)而不是构建 arg 以避免安全漏洞。构建时 arg 将烘焙图像中的凭据,这意味着任何具有拉取访问权限的人都可以读取它。避免在构建时使用凭据。 关于安全性的非常重要的说明,非常感谢。这是一个解决方案:pythonspeed.com/articles/build-secrets-docker-compose 【参考方案1】:

您可以使用 docker-compose 的构建命令定义您的 args

示例 Dockerfile:

FROM nginx:1.13

RUN apt-get -y update && apt-get install -y \
    apache2-utils && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ARG username
ARG password

RUN htpasswd -bc /etc/nginx/.htpasswd $username $password

docker-compose 文件:

version: '3'
services:
  node1:
     build: ./dir

./dir 包含 Dockerfile,我使用以下命令构建:

docker-compose build --build-arg username="my-user" --build-arg password="my-pass"

我已经看到了:

Step 5/5 : RUN htpasswd -bc /etc/nginx/.htpasswd $username $password
 ---> Running in 80735195e35d
Adding password for user my-user
 ---> c52c92556825

我提高了我的筹码:

docker-compose up -d

现在我可以检查 nginx 容器内部,并且我的用户名和(加密的)密码在那里:

docker@default:~/test$ docker exec -it test_node1_1 bash
root@208e4d75e2bd:/# cat /etc/nginx/.htpasswd
my-user:$apr1$qg4I/5RO$KMaOPvjbnKdZH37z2WYfe1

使用此方法,您可以将build args 传递给您的docker-compose 堆栈。

【讨论】:

环境变量可以按照你说的使用,但是必须在.env中定义,而不是在compose文件里面 这个答案非常有用,它实际上显示了docker-compose 如何在命令行上与--build-arg 一起使用,您可以在Dockerfiledocker-compose.yml 中定义您的ARG - :args 数组定义,然后最终在命令行上覆盖它。 似乎是正确的,但对其他人来说,要小心将凭据烘焙成这样的图像。用户名/密码应在运行时完成,因此您的产品凭据不会显示在您的存储库中 这是我一直在寻找的答案,表明--build-arg 可以与docker-compose 一起使用【参考方案2】:

您可以直接在 docker-compose 文件中指定参数:

node1:
    build: node1
        args:
            ADMIN_USERNNAME: weblogic1
            ADMIN_PASSWORD: weblogic1
            ADMIN_NAME: admin1
    image: node1
    container_name: node1

详情请参阅official docs。

【讨论】:

也许可以完成答案并在 docker 文件中显示它是如何访问的,允许 FROM ? 如果您通过添加args 使用build: .,则需要删除构建前面的点并为上下文添加一个新行:context: .。否则会产生 yaml 扫描错误。 由于某种原因,docker-compose 文件中的 args 在尝试使用 shell var 时对我不起作用。相反,我在运行命令时必须使用--build-arg VARNAME=$VARNAME【参考方案3】:

在你的Dockerfile

ARG CERTBOT_TAG=latest
FROM certbot/certbot:$CERTBOT_TAG

在您的docker-compose.yml 文件中:

version: '3.4'
services:
  certbot:
    build:
       context: .
       args:                                                                     
         - CERTBOT_TAG: v0.40.1

你可以建立或建立你的服务:

docker-compose build certbot

【讨论】:

我在使用这种格式时出错,ERROR: The Compose file './docker-compose.yml' is invalid because: services.certbot.build.args contains "CERTBOT_TAG": "v0.40.1", which is an invalid type, it should be a string 我的解决方案是删除 - 以将其变成字符串而不是对象。 @heralight 请修正 YAML 语法!【参考方案4】:

Docker 文件

ARG ACCOUNT_ID

FROM $ACCOUNT_ID.dkr.ecr.ap-southeast-1.amazonaws.com/my-composer:latest as composer
LABEL stage=intermediate

Buildspec 或 CLI 执行以下命令。

docker-compose build --build-arg ACCOUNT_ID="23423432423" --no-cache

如果您想在 CLI 中打印 ACCOUNT_ID

ARG ACCOUNT_ID

FROM amazonlinux:latest
RUN yum -y install aws-cli 
RUN echo $ACCOUNT_ID

FROM $ACCOUNT_ID.dkr.ecr.ap-southeast-1.amazonaws.com/my-composer:latest as composer
LABEL stage=intermediate

注意:ARG 应该在所有 FROM 语句的顶部,然后它将作为全局 ARG 工作。

【讨论】:

【参考方案5】:

正如 Salek 上面提到的,添加 context: . 会有所帮助。

例如:

version: '3.5'
services:
  app:
    build:
      context: .
      args:
        NODE_VERSION: 14.15.4
       

`

【讨论】:

以上是关于如何在 docker-compose 中定义 build-args?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 docker-compose.yml 中重建 docker 容器?

如何定义使用 docker-compose 构建的图像的名称

如何从.env文件获取环境变量到docker-compose.yml?

Docker-Compose

docker-compose:为绑定挂载和托管挂载定义挂载

如何获得正确的 docker-compose Multiline 环境变量格式?