如何在不弄乱 Dockerfile 的情况下加载多个环境变量?

新手上路,请多包涵

我正在开发一个包含大量环境变量的简单 Docker 映像。你能像 docker-compose 一样导入环境变量文件吗?我在 docker 文件文档中找不到任何关于此的内容。

Dockerfile

 FROM python:3.6

ENV ENV1 9.3
ENV ENV2 9.3.4
...

ADD . /

RUN pip install -r requirements.txt

CMD [ "python", "./manager.py" ]

我想改写这个问题的一个好方法是:如何有效地在 Dockerfile 中加载多个环境变量?如果您无法加载文件,您将无法将 docker 文件提交到 GitHub。

原文由 hY8vVpf3tyR57Xib 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 616
2 个回答

是的,有几种方法可以做到这一点。

码头工人撰写

在 Docker Compose 中,您可以在文件本身中提供环境变量,或者指向外部 env 文件:

 # docker-compose.yml
version: '2'
services:

  service-name:
    image: service-app
    environment:
    - GREETING=hello
    env_file:
    - .env

顺便说一句,一个与此相关的不错的功能是您可以使用多个 Compose 文件,每个后续文件都可以添加到另一个文件中。因此,如果上面要定义一个基础,那么您可以这样做(例如,每个运行时环境):

 # docker-compose-dev.yml
version: '2'
services:

  service-name:
    environment:
    - GREETING=goodbye

然后你可以这样运行它:

 docker-compose -f docker-compose.yml -f docker-compose-dev.yml up

仅 Docker

要仅在 Docker 中执行此操作,请使用您的入口点或命令来运行中间脚本,因此:

 #Dockerfile

....

ENTRYPOINT ["sh", "bin/start.sh"]

然后在您的启动脚本中:

 #!/bin/sh

source .env

python /manager.py

过去,我曾 将此相关答案 用作对自己有用的参考。

PID 1 更新

为了放大我在评论中的评论,如果您将入口点设置为 shell 或 Python 脚本,则 Unix 信号(停止、终止等)很可能不会传递到您的进程。这是因为该脚本将成为 进程 ID 1 ,这使其成为容器中所有其他进程的父进程 - 在 Linux/Unix 中,期望此 PID 会将信号转发给其子进程,但除非您明确实现,它不会发生。

为了解决这个问题,您可以安装一个 init 系统。我使用 来自 Yelp 的哑初始化。如果您想更好地理解它,这个 repo 还包含大量细节,或者如果您只想“安装并忘记”,则可以使用简单的安装说明。

原文由 halfer 发布,翻译遵循 CC BY-SA 4.0 许可协议

我真的很喜欢@halfers 方法,但这也可以。 docker run 采用一个名为 --env-file 的可选参数,这非常有用。

所以你的 docker 文件可能看起来像这样。

 COPY .env .env

然后在构建脚本中使用:

 docker build -t my_docker_image . && docker run --env-file .env my_docker_image

原文由 Justin Rice 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进