如何在docker-compose中定义构建参数?

178

我有以下的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中是否可行?


11
警告后续使用者:对于密码,您可能考虑使用秘密管理器(Vault、k8s secrets、aws sms、docker swarm secrets)而不是构建参数,以避免安全漏洞。构建时参数将在镜像中嵌入凭据,这意味着任何具有拉取访问权限的人都可以读取它。避免在构建时使用凭据。 - James Fulford
2
关于安全性的非常重要的注意事项,非常感谢。这里有一个解决方案:https://pythonspeed.com/articles/build-secrets-docker-compose/ - sekrett
@Bira 我不明白这个问题与AWS有什么关系。问题中没有提到它,而docker-compose确实是一个独立的产品。 - Raphael
5个回答

186

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

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

查看一个完整的示例:MWE

官方文档(遗留版本v3 在这里)包含所有细节。


2
由于某些原因,当我尝试使用shell变量时,docker-compose文件中的args对我不起作用。相反,我必须在运行命令时使用--build-arg VARNAME=$VARNAME - harvzor
@harvzor 不确定你的意思是什么。你希望 docker-compose 在其自身的运行时之外访问 Bash 变量吗?是的,那样不起作用,也不应该这样做。但是,你可以使用环境变量:https://docs.docker.com/compose/environment-variables/ - Raphael
有关多行 --build-arg,请参见 https://dev59.com/ilQJ5IYBdhLWcg3wu4ix#67135826 - prayagupa

52
你可以在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”堆栈。

1
环境变量可以像你说的那样使用,但它们必须在 .env 文件中定义,而不是在 compose 文件内部。 - Alejandro Galera
3
这个答案非常有用,它实际上展示了如何在命令行中使用 docker-compose--build-arg。您可以在 Dockerfiledocker-compose.yml 中定义 ARG - args 数组,最后可以在命令行中覆盖它。请确保翻译内容通俗易懂但不改变原意。 - CvRChameleon
1
看起来是正确的,但对于其他人来说,要小心像这样将凭据嵌入到镜像中。用户名/密码应该在运行时完成,这样您的生产凭据就不会出现在仓库中。 - James Fulford
这就是我一直在寻找的答案,表明 --build-arg 可以与 docker-compose 一起使用。 - Gostega

47
在你的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

2
我在使用以下格式时遇到了错误: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我的解决方案是将 - 删除,将其转换为字符串而不是对象。 - alete
@heralight请修复YAML语法! - Martynas Jusevičius

7
正如Salek在上面提到的那样,添加context: .是有帮助的。
例如:
version: '3.5'
services:
  app:
    build:
      context: .
      args:
        NODE_VERSION: 14.15.4
       

`


2
"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 工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接