在Dockerfile中获取环境变量值

我正在为一个ruby应用程序构建一个容器。我的应用程序的配置包含在环境变量中(在应用程序中加载dotenv)。

其中一个配置变量是应用程序的公共ip,它在内部用于创建链接。 我需要添加一个dnsmasq条目,将这个ip指向容器内的127.0.0.1,这样它就可以获取应用程序的链接,就像它没有被容器化一样

因此,我试图在Dockerfile中设置ENV,它将传递一个环境变量给容器。

我尝试了一些方法。

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

所有内容都传递“REQUEST_DOMAIN”字符串而不是环境变量的值。 是否有一种方法将环境变量值从主机传递到容器?< / p >

372933 次浏览
添加-e键,用于将环境变量传递给容器。 例子:< / p >
$ MYSQLHOSTIP=$(sudo docker inspect -format="\{\{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash


root@87f235949a13:/# echo $DBIP
172.17.0.2

所以你可以做: cat Dockerfile | envsubst | docker build -t my-target - < / p >

然后创建一个Dockerfile,内容如下:

ENV MY_ENV_VAR $MY_ENV_VAR

我猜某些特殊字符可能会有问题,但至少在大多数情况下这是可行的。

从运行时创建的文件中加载环境变量。

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

... 然后在Dockerfile中

ADD build /build
RUN /build/test.sh

where test.sh从env.sh加载MYVAR

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

你应该在Dockerfile中使用ARG指令,这是为了这个目的。

ARG指令定义了一个变量,用户可以在构建时使用--build-arg <varname>=<value>标志使用docker构建命令将该变量传递给构建器。

所以你的Dockerfile会有这样一行:

ARG request_domain

或者如果您更喜欢默认值:

ARG request_domain=127.0.0.1

现在你可以在Dockerfile中引用这个变量:

ENV request_domain=$request_domain

然后你将像这样构建你的容器:

$ docker build --build-arg request_domain=mydomain Dockerfile
< p > < br > 注意1:如果你在Dockerfile中引用了ARG,但在--build-arg中排除了它,你的映像将无法构建。

注2:如果用户指定的构建参数没有在Dockerfile中定义,构建将输出一个警告:

[警告]一个或多个build-args [foo]未被消耗

使用envsubst而不失去使用COPYADD等命令的能力,并且不使用中间文件的替代方法是使用Bash的进程替换:

docker build -f <(envsubst < Dockerfile) -t my-target .

如果你只是想找到并替换Dockerfile中的所有环境变量($ExampleEnvVar),然后构建它,这将工作:

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -

这是为那些希望在构建期间使用.env文件将env变量从docker-compose传递给dockerfile,然后将这些参数作为env变量传递给容器的人准备的。 典型的docker-compose文件

services:
web:
build:
context: ./api
dockerfile: Dockerfile
args:
- SECRET_KEY=$SECRET_KEY
- DATABASE_URL=$DATABASE_URL
- AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
.env文件中的env变量传递给构建命令中的参数。 典型的.env文件

SECRET_KEY=blahblah
DATABASE_URL=dburl

现在,当您运行docker-compose up -d命令时,docker-compose file将从.env文件中获取值,然后将其传递给docker-compose file。现在web的Dockerfile在构建过程中通过参数包含了所有这些变量。典型的dockerfile,

FROM python:3.6-alpine


ARG SECRET_KEY
ARG DATABASE_URL
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ARG AWS_BUCKET
ARG AWS_REGION
ARG CLOUDFRONT_DOMAIN


ENV CELERY_BROKER_URL redis://redis:6379/0
ENV CELERY_RESULT_BACKEND redis://redis:6379/0
ENV C_FORCE_ROOT true
ENV SECRET_KEY  ${SECRET_KEY?secretkeynotset}
ENV DATABASE_URL ${DATABASE_URL?envdberror}
现在我们在dokcerfile中收到了那些secret_key和db url作为参数。现在让我们使用ENV中的那些作为ENV SECRET_KEY ${SECRET_KEY?secretkeynotset}。现在,即使docker容器在它的环境中也有这些变量。 记住不要使用ARG $SECRET_KEY(我这样做了)。它应该是ARG SECRET_KEY

当使用build-arg

docker build --build-arg CODE_VERSION=1.2 Dockerfile

...考虑变量在FROM之后不可用:

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}

FROM之前声明的ARG在构建阶段之外,因此它不能在FROM之后的任何指令中使用。

通常__abc0应该放在FROM之后,如果在FROM期间不需要的话:

FROM base:xy
ARG  ABC=123

要使用在第一个FROM之前声明的ARG的默认值,请使用在构建阶段中不带值的ARG指令:

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact