Dockerfile如何在docker compose构建过程中传递环境变量

6

我写了一个 Dockerfile,它使用了两个参数:

FROM jessie
MAINTAINER Zeinab Abbasimazar
#Build Arguments
ARG REP_USER
ARG REP_PASS
# Build
RUN echo 'REP_USER:'$REP_USER', REP_PASS:'$REP_PASS

我为构建写了一个docker-compose.yml

version: "2"
services:
  ui:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        REP_USER: $REP_USER
        REP_PASS: $REP_PASS

我不想直接在compose文件中定义这些参数,因此我尝试在docker compose构建期间发送它们:

REP_USER=myusername REP_PASS=mypassword docker-compose build

但这并没有起作用。我修改了我的Dockerfile,使用这些参数作为环境变量;因此我删除了ARG行:

FROM jessie
MAINTAINER Zeinab Abbasimazar
# Build
RUN echo 'REP_USER:'$REP_USER', REP_PASS:'$REP_PASS

还有 docker-compose.yml 文件:

version: "2"
  services:
    ui:
      build:
        context: .
        dockerfile: Dockerfile

我尝试运行 REP_USER=myusername REP_PASS=mypassword docker-compose build,但仍然没有结果。

我还尝试将这些信息保存到一个 env 文件中:

version: "2"
services:
  ui:
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - myenv.env

但是似乎 env 文件在构建时不起作用,它们只参与运行时。

编辑1:

Docker 版本为 1.12.6,不支持使用 --build-arg 传递参数。

编辑2:

我尝试按照 这里 描述的方法使用 .env 文件:

cat .env 
REP_USER=myusername
REP_PASS=mypassword

然后我调用了 docker-compose config,返回的结果如下:

networks: {}
services:
  ui:
    build:
      args:
        REP_PASS: mypassword
        REP_USER: myusername
      context: /home/zeinab/Workspace/ZiZi-Docker/Test/test-exec-1
      dockerfile: Dockerfile
version: '2.0'
volumes: {}

这意味着我的问题得到了解决。
编辑3:
我还尝试了docker-compose arg documentation的第三部分在我的docker-compose.yml文件中:
version: "2"
services:
  ui:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - REP_USER
        - REP_PASS

并执行:

export REP_USER=myusername;export REP_PASS=mypassword;sudo docker-compose build --no-cache

仍然没有得到我想要的。

3个回答

4

您可以按照这里的描述,使用Docker Compose设置构建参数:

docker-compose build [--build-arg key=val...]
docker-compose build --build-arg REP_USER=myusername --build-arg REP_PASS=mypassword

顺便说一下,就我所知,构建参数是可用性和确定性构建之间的妥协。Docker旨在以确定的方式构建。也就是说,无论您在哪里执行构建,生成的镜像应该是相同的。因此,客户端忽略它执行的环境(变量)似乎是合乎逻辑的。


我的 Docker 版本是 1.12.6,不支持那个。 - Zeinab Abbasimazar
很遗憾。更新不是一个选项吗?在“正常”的Linux系统中,您只需将最新版本的docker-compose放入$HOME/bin中,它应该会被执行而不是系统默认值。 - fzgregor
我会检查是否可以更新;并非所有在办公室的工作方式都在我的控制之下。 - Zeinab Abbasimazar
没错,这就是我所说的“正常”。一些公司安全措施可能会禁止它。如果echo "$PATH"的输出中包含$HOME/bin,那么它应该可以工作。(原则上) - fzgregor
当这样做时,docker-compose文件应该是什么样子? - basickarl

1
在docker-compose文件中,变量替换的正确语法是${VARNAME}。尝试使用以下示例:
version: "2"
  services:
    ui:
      build:
        context: .
        dockerfile: Dockerfile
      args:
        REP_USER: ${REP_USER}
        REP_PASS: ${REP_PASS}

1

我终于找到了解决方案。我在问题中也提到了它。我先尝试了一次失败,然后发现我命名.env文件时打了一个错别字; 它应该是.evn

我尝试按照这里描述的使用.env文件:

cat .env 
REP_USER=myusername
REP_PASS=mypassword

我接着调用了docker-compose config命令,它返回了以下内容:

networks: {}
services:
  ui:
    build:
      args:
        REP_PASS: mypassword
        REP_USER: myusername
      context: /home/zeinab/Workspace/ZiZi-Docker/Test/test-exec-1
      dockerfile: Dockerfile
version: '2.0'
volumes: {}

这意味着我的问题已得到解决。我应该提到这个答案真的很有帮助。

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