【问题标题】:Pass environment variables from docker-compose to container at build stage在构建阶段将环境变量从 docker-compose 传递到容器
【发布时间】:2017-06-04 12:13:27
【问题描述】:

我正在尝试使用单个Dockerfile、多个docker-compose 文件和多个envoronment_variables 文件为多个环境创建配置。我需要它为每个环境使用具有 python 依赖项的不同文件。

假设我们在两个环境中创建了一个web 服务:developmentproduction。为此,我创建了以下文件结构:

docker-compose-dev.yml
docker-compose-prod.yml
envs/
  dev.env
  prod.env
web/
  Dockerfile
  requirements_dev.txt 
  requirements_prod.txt

目标是在容器的build 过程中在Dockerfile 中实例化requirements_*.txt 文件的正确名称。根据文档,我尝试了这种幼稚的方法,但似乎不起作用:

  1. 将名称定义为环境变量:
    • envs/dev.env: REQUIREMENTS=requirements_dev.txt
    • envs/prod.env: REQUIREMENTS=requirements_prod.txt
  2. Dockerfile 中使用此环境变量:

    FROM python:3.5
    ENV PYTHONUNBUFFERED 1
    ENV APP_ROOT /usr/src/app
    ...
    COPY $REQUIREMENTS $APP_ROOT/
    RUN pip install -r $APP_ROOT/$REQUIREMENTS
    
  3. docker-compose配置中导入对应的定义:

    version: '2'
    
    services:
        web:
            build: ./web
            env_file:
                - envs/dev.env   # in docker-compose-dev.yml
                - envs/prod.env   # in docker-compose-prod.yml
            ...
    

当我运行docker-compose up --build docker-compose-dev.yml 时,$REQUIREMENTS 变量未在构建过程中定义。

docker-composedocumentation 中有一个注释:

注意:如果您的服务指定了构建选项,则环境文件中定义的变量在构建期间将不会自动可见。使用 build 的 args 子选项来定义构建时环境变量。

但是要在Dockerfile 中使用ARG 选项,例如ARG REQUIREMENTS,需要在docker-compose 中使用相应的args 选项,如下所示:

services:
    web:
        build:
            context: ./web
            args:
                - REQUIREMENTS

尽管如此,使用此配置我的测试也失败了,因为根据documentation,Dockerfile 中REQUIREMENTS 变量的值取自

Compose 运行的环境

因此,它从我的 shell 中获取价值,而不是来自 envs/dev.env

所以我的问题是:

是否可以在构建时将环境变量docker-compose中的docker-compose 传递到Dockerfile,而无需在我的shell中本地设置变量?

【问题讨论】:

  • 我自己也遇到了这个问题。尝试使用env_filebuild: args: FOO: ${SOME_VAR:-foo},似乎SOME_VAR 没有从env_file 加载。也许这是env_file 插值发生在或不适用于构建arg 分辨率的错误?跨度>
  • 我在其他一些问题中读到了一个声明,即 Dockerfile 被设计为自包含的,并且不依赖于外部环境。但是,另一方面,它与argsARG 的目的相矛盾。所以不清楚是bug还是功能。

标签: docker docker-compose


【解决方案1】:

您的 docker-compose.yml 应该如下所示:

version: '2'
services:
  web:
    build:
      context: ./web
      args:
        REQUIREMENTS: "requirements_dev.txt"

您的 Dockerfile 应该使用 ARG 定义构建参数,如下所示:

FROM python:3.5
ENV PYTHONUNBUFFERED 1
ENV APP_ROOT /usr/src/app
ARG REQUIREMENTS
...
COPY $REQUIREMENTS $APP_ROOT/
RUN pip install -r $APP_ROOT/$REQUIREMENTS

我对此进行了验证,并在 Github 上创建了一个缩小的功能演示:

https://github.com/jannikweichert/stackoverflow-41747843

【讨论】:

  • 谢谢,这确实有效!虽然,需要硬编码docker-compose.yml 中的变量,而不是从*.env 文件中读取它们,但这总比没有好。
  • 太棒了!好消息是,由于您的 Dockerfile 是一个包含必要输入变量的明确信息的规范,您的 docker-compose 是您的容器设置的明确规范。开发人员无需检查其他文件即可查看发生了什么
猜你喜欢
  • 2020-02-23
  • 2017-09-18
  • 2020-12-17
  • 2019-09-14
  • 1970-01-01
  • 2019-11-03
  • 2020-11-07
  • 2019-02-25
相关资源
最近更新 更多