获取Dockerfile中的环境变量值

8ljdwjyq  于 2023-04-11  发布在  Docker
关注(0)|答案(9)|浏览(426)

我正在为一个ruby应用程序构建一个容器。我的应用程序的配置包含在环境变量中(通过dotenv加载到应用程序中)。
其中一个配置变量是应用程序的public ip,它在内部用于创建链接。我需要在容器中添加一个dnsmasq条目,将此ip指向127.0.0.1,这样它就可以像没有容器化一样获取应用程序的链接。
因此,我尝试在我的Dockerfile中设置一个ENV,它将向容器传递一个环境变量。
我试过几种方法。

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

所有东西都传递“REQUEST_DOMAIN”字符串而不是环境变量的值。有没有一种方法可以将环境变量的值从主机传递到容器?

tmb3ates

tmb3ates1#

您应该在Dockerfile中使用ARG指令,这是用于此目的的。
ARG指令定义了一个变量,用户可以在构建时使用--build-arg <varname>=<value>标志通过docker build命令将其传递给构建器。
所以你的 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

**注1:**如果您在Dockerfile中引用了ARG,但在--build-arg中将其排除,则您的镜像将不会构建。
**注2:**如果用户指定的build参数没有在Dockerfile中定义,则build会输出警告:

[警告]一个或多个build-args [foo]未使用。

jogvjijk

jogvjijk2#

因此,您可以:cat Dockerfile | envsubst | docker build -t my-target -
然后有一个Dockerfile,类似于:

ENV MY_ENV_VAR $MY_ENV_VAR

我猜可能有一些特殊字符的问题,但这至少对大多数情况都有效。

ddhy6vgd

ddhy6vgd3#

这是为那些希望在构建过程中使用.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变量传递给build命令中的args。典型的.env文件

SECRET_KEY=blahblah
DATABASE_URL=dburl

现在,当你运行docker-compose up -d命令时,docker-compose文件从.env文件中获取值,然后将其传递给docker-compose文件。现在Web的Dockerfile包含所有在构建过程中通过args的变量。现在典型的Web的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作为arg。现在让我们将ENV中的那些作为ENV SECRET_KEY ${SECRET_KEY?secretkeynotset}使用。现在即使是docker容器也在其环境中拥有这些变量。* 记住不要使用ARG $SECRET_KEY(我这样做了)。它应该是ARG SECRET_KEY *

olmpazwi

olmpazwi4#

使用envsubst而不失去使用COPYADD等命令的能力,并且不使用中间文件的替代方案是使用Bash的Process Substitution

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

t9eec4r05#

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

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

然后在Dockerfile中

ADD build /build
RUN /build/test.sh

其中test.sh从www.example.com加载MYVARenv.sh

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

dfddblmv6#

如果你只是想找到并替换Dockerfile中的所有环境变量($ExampleEnvVar),那么构建它就可以了:
envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -

2ekbmq32

2ekbmq327#

使用build-arg时...
docker build --build-arg CODE_VERSION=1.2 Dockerfile
...假设变量在FROM之后不可用:

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}

FROM之前声明的ARG在构建阶段之外,因此不能在FROM之后的任何指令中使用。
通常,如果在FROM期间不需要,则ARG s应放置在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

ymdaylpp

ymdaylpp8#

你可以在容器启动时直接传递env变量:

docker run -e [your_variable_name = your_variable_value] [image to instanciate]

示例:

docker run --rm -e TARGET=192.168.1.9 ubuntu env

输出为:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=36399469e519
TARGET=192.168.1.9
HOME=/root

目标变量已添加到当前容器的env变量中!

yvt65v4c

yvt65v4c9#

添加-e键,用于将环境变量传递到容器。例如:

$ 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

相关问题