在构建阶段将来自docker-compose的环境变量传递给容器 [英] Pass environment variables from docker-compose to container at build stage

查看:283
本文介绍了在构建阶段将来自docker-compose的环境变量传递给容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用单个 Dockerfile ,几个 docker-compose 文件和几个 envoronment_variables 文件。我需要它为每个环境使用不同的python依赖文件。



假设我们创建一个 web 在两个环境中的服务:开发生产。为此,我创建以下文件结构:

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

目标是实例化要求_ *。txt Dockerfile 中的c $ c>文件在容器的构建过程中。根据文档,我尝试了这个天真的方法,似乎不起作用:


  1. 将名称定义为环境变量:


    • envs / dev.env: REQUIREMENTS = requirements_dev.txt li>
    • envs / prod.env: REQUIREMENTS = requirements_prod.txt


      • Dockerfile 中使用此环境变量:

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


      • 在<$ c中导入相应的定义$ c> docker-compose 配置:

         版本:'2'

        服务:
        web:
        build:./web
        env_file:
        - envs / dev.env#在docker-compose-dev.yml
        - envs /prod.env #在docker-compose-prod.yml
        ...


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



docker-compose 文档有一个注释:


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


但是要使用<$ c Dockerfile 中的$ c> ARG 选项,如 ARG REQUIREMENTS ,需要一个对应的 args 选项在 docker-compose 中,像这样:

 服务:
web:
build:
上下文:./web
args:
- REQUIREMENTS

然而,使用此配置,我的测试也失败,因为根据文档,采用Dockerfile中 REQUIREMENTS 变量的值来自


正在运行Compose的环境


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



所以我的问题是:


是否可以将环境变量从<$在$ code> docker-compose Dockerfile env_file >在构建时而不在我的shell中设置变量



解决方案

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

  version:'2'
services:
web :
build:
上下文:./web
args:
要求:envs / dev.env

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

  FROM python:3.5 
ENV PYTHONUNBUFFERED 1
ENV APP_ROOT / usr / src / app
ARG要求
...
COPY $ REQUIREMENTS $ APP_ROOT /
运行点安装-r $ APP_ROOT / $需求

我验证了这一点,并创建了一个最小化的功能在Github的nal演示:



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


I am trying to create configuration for several environments with a single Dockerfile, several docker-compose files and several envoronment_variables files. I need it to use a different file with python dependencies for each environment.

Let's say, we create a web service in two environments: development and production. To achieve this, I create the following file structure:

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

The objective is to instantiate the proper name of a requirements_*.txt file in the Dockerfile during the container's build process. According to the documentation, I tried this naïve approach, which doesn't seem to work:

  1. Define the name as an environment variable:
    • envs/dev.env: REQUIREMENTS=requirements_dev.txt
    • envs/prod.env: REQUIREMENTS=requirements_prod.txt
  2. Use this environment variable in the 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. Import the corresponding definition in a docker-compose configuration:

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

When I run docker-compose up --build docker-compose-dev.yml, the $REQUIREMENTS variable is not defined at the build process.

In the docker-compose documentation there is a note on this:

Note: If your service specifies a build option, variables defined in environment files will not be automatically visible during the build. Use the args sub-option of build to define build-time environment variables.

But to use the ARG option in the Dockerfile, like ARG REQUIREMENTS, one needs a corresponding args option in docker-compose, like this:

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

Nevertheless, with this configuration my tests also failed, because, according to the documentation, the value of the REQUIREMENTS variable in Dockerfile is taken from

the environment where Compose is running

Therefore, it takes value from my shell, but not from envs/dev.env.

So my question is:

Is it possible to pass environment variable from env_file in docker-compose to Dockerfile at build time without setting variables locally in my shell?

解决方案

Your docker-compose.yml should look like this:

version: '2'
services:
  web:
    build:
      context: ./web
      args:
        REQUIREMENTS: "envs/dev.env"

Your Dockerfile should define the build-argument using ARG like this:

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

I validated this and created a minified functional demo at Github:

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

这篇关于在构建阶段将来自docker-compose的环境变量传递给容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆