Dockerfile:如何从文件内容设置环境变量
Dockerfile: how to set env variable from file contents
我想在我的 Dockerfile 中设置一个环境变量。
我有一个 .env
文件,如下所示:
FOO=bar
。
在我的 Dockerfile 中,我有一个解析该文件内容并将其分配给 FOO 的命令。
RUN 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'
我 运行 遇到的问题是上面的脚本没有 return 我需要的。事实上,它没有 return 任何东西。
当我 运行 docker-compose up --build
时,它失败并出现此错误。
The command '/bin/sh -c 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'' returned a non-zero code: 127
我知道命令 /bin/sh -c 'echo "$(cut -d'=' -f2 <<< $(grep FOO .env))"'
会生成正确的输出,但我不知道如何将该输出分配给环境变量。
对我做错了什么有什么建议吗?
首先,您看到的错误。我怀疑问题中未包含 "not found" 错误消息。如果是这种情况,那么第一个问题是您尝试 运行 一个完整字符串的可执行文件,因为您将其括在引号中。它不是试图 运行 shell 命令 "export",而是试图找到一个二进制文件,它是包含空格的完整字符串。因此,要克服该错误,您需要取消对 运行 字符串的引用:
RUN export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")
但是,这并不能解决您的根本问题。 RUN
命令的结果是 docker 将对文件系统的更改保存为图像的新层。仅保存对文件系统的更改。您正在 运行ning 的 shell 命令更改 shell 状态,但随后 shell 退出,运行 命令 returns,并且状态其中 shell,包括环境变量,都消失了。
要为您的应用程序解决这个问题,我可以想到两种选择:
选项 A:将构建参数注入到所有 .env 值的构建中,并编写一个脚本来为每个变量使用正确的 --build-arg
标志调用构建。在 Dockerfile 中,每个变量都有两行:
ARG FOO1=default value1
ARG FOO2=default value2
ENV FOO1=${FOO1} \
FOO2=${FOO2}
选项 B:注入您的 .env 文件并使用容器中的入口点对其进行处理。在启动实际应用程序之前,此入口点可以 运行 您的导出命令。在需要这些变量的构建期间,您还需要为每个 RUN
命令执行此操作。我用来将文件内容拉入环境变量的 shorthand 是:
set -a && . .env && set +a
环境变量
如果你想在你的 docker 图像中设置一些环境变量(在容器中使用)你可以简单地在你的 docker 中使用 env_file
配置选项- compose.yml 文件。使用该选项,.env 文件中的所有条目都将被设置为图像中的环境变量,从而进入容器。
构建 ARGS
如果您的要求是仅在 Dockerfile
中使用某些变量,那么您可以按如下方式指定它们
ARG FOO
ARG FOO1
ARG FOO2
等...
并且您必须在 docker-compose.yml
中的 build
键下指定这些参数
build:
context: .
args:
FOO: BAR
FOO1: BAR1
FOO2: BAR2
访问 docker-compose.yml 文件中的 .env 值
如果您正在考虑将一些值从 .env 传递到您的 docker-compose 文件,那么您只需将您的 .env 文件放在与 docker-[=46= 相同的位置] 文件,您可以设置如下配置值;
ports:
- "${HOST_PORT}:80"
因此,例如,您可以通过在 .env 文件中设置服务的主机端口来设置它
我想在我的 Dockerfile 中设置一个环境变量。
我有一个 .env
文件,如下所示:
FOO=bar
。
在我的 Dockerfile 中,我有一个解析该文件内容并将其分配给 FOO 的命令。
RUN 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'
我 运行 遇到的问题是上面的脚本没有 return 我需要的。事实上,它没有 return 任何东西。
当我 运行 docker-compose up --build
时,它失败并出现此错误。
The command '/bin/sh -c 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'' returned a non-zero code: 127
我知道命令 /bin/sh -c 'echo "$(cut -d'=' -f2 <<< $(grep FOO .env))"'
会生成正确的输出,但我不知道如何将该输出分配给环境变量。
对我做错了什么有什么建议吗?
首先,您看到的错误。我怀疑问题中未包含 "not found" 错误消息。如果是这种情况,那么第一个问题是您尝试 运行 一个完整字符串的可执行文件,因为您将其括在引号中。它不是试图 运行 shell 命令 "export",而是试图找到一个二进制文件,它是包含空格的完整字符串。因此,要克服该错误,您需要取消对 运行 字符串的引用:
RUN export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")
但是,这并不能解决您的根本问题。 RUN
命令的结果是 docker 将对文件系统的更改保存为图像的新层。仅保存对文件系统的更改。您正在 运行ning 的 shell 命令更改 shell 状态,但随后 shell 退出,运行 命令 returns,并且状态其中 shell,包括环境变量,都消失了。
要为您的应用程序解决这个问题,我可以想到两种选择:
选项 A:将构建参数注入到所有 .env 值的构建中,并编写一个脚本来为每个变量使用正确的 --build-arg
标志调用构建。在 Dockerfile 中,每个变量都有两行:
ARG FOO1=default value1
ARG FOO2=default value2
ENV FOO1=${FOO1} \
FOO2=${FOO2}
选项 B:注入您的 .env 文件并使用容器中的入口点对其进行处理。在启动实际应用程序之前,此入口点可以 运行 您的导出命令。在需要这些变量的构建期间,您还需要为每个 RUN
命令执行此操作。我用来将文件内容拉入环境变量的 shorthand 是:
set -a && . .env && set +a
环境变量
如果你想在你的 docker 图像中设置一些环境变量(在容器中使用)你可以简单地在你的 docker 中使用 env_file
配置选项- compose.yml 文件。使用该选项,.env 文件中的所有条目都将被设置为图像中的环境变量,从而进入容器。
构建 ARGS
如果您的要求是仅在 Dockerfile
中使用某些变量,那么您可以按如下方式指定它们
ARG FOO
ARG FOO1
ARG FOO2
等...
并且您必须在 docker-compose.yml
build
键下指定这些参数
build:
context: .
args:
FOO: BAR
FOO1: BAR1
FOO2: BAR2
访问 docker-compose.yml 文件中的 .env 值
如果您正在考虑将一些值从 .env 传递到您的 docker-compose 文件,那么您只需将您的 .env 文件放在与 docker-[=46= 相同的位置] 文件,您可以设置如下配置值;
ports:
- "${HOST_PORT}:80"
因此,例如,您可以通过在 .env 文件中设置服务的主机端口来设置它