如何在不弄乱 Dockerfile 的情况下加载多个环境变量? [英] How to load several environment variables without cluttering the Dockerfile?

查看:129
本文介绍了如何在不弄乱 Dockerfile 的情况下加载多个环境变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个具有大量环境变量的简单 Docker 映像.你能像 docker-compose 一样导入环境变量文件吗?我在 docker 文件文档中找不到任何关于此的信息.

I am working on a simple Docker image that has a large number of environment variables. Are you able to import an environment variable file like with docker-compose? I cannot find anything about this in the docker file documentation.

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.

I guess a good way to rephrase the question would be: how do you efficiently load multiple environment variables in a Dockerfile? If you are not able to load a file, you would not be able to commit a docker file to GitHub.

推荐答案

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

Yes, there are a couple of ways you can do this.

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

In Docker Compose, you can supply environment variables in the file itself, or point to an external env file:

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

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

顺便说一下,一个有点相关的不错的功能是您可以使用多个 Compose 文件,每个后续文件都添加到另一个文件中.因此,如果以上要定义一个基础,那么您可以执行此操作(例如,每个运行时环境):

Incidentally, one nice feature that is somewhat related is that you can use multiple Compose files, with each subsequent one adding to the other. So if the above were to define a base, you can then do this (e.g. per run-time environment):

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

  service-name:
    environment:
    - GREETING=goodbye

然后你可以这样运行它:

You can then run it thus:

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

仅限 Docker

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

Docker only

To do this in Docker only, use your entrypoint or command to run an intermediate script, thus:

#Dockerfile

....

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

然后在您的启动脚本中:

And then in your start script:

#!/bin/sh

source .env

python /manager.py

我过去使用此相关答案作为对自己有用的参考.

I've used this related answer as a helpful reference for myself in the past.

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

To amplify my remark in the comments, if you make your entry point a shell or Python script, it is likely that Unix signals (stop, kill, etc) will not be passed onto your process. This is because that script will become process ID 1, which makes it the parent process of all other processes in the container - in Linux/Unix there is an expectation that this PID will forward signals to its children, but unless you explicitly implement that, it won't happen.

为了解决这个问题,你可以安装一个初始化系统.我使用 Yelp 的 dumb-init.如果您想更好地理解它,该存储库还提供了大量细节,或者如果您只想安装并忘记",则提供简单的安装说明.

To rectify this, you can install an init system. I use dumb-init from Yelp. This repo also features plenty of detail if you want to understand it a bit better, or simple install instructions if you just want to "install and forget".

这篇关于如何在不弄乱 Dockerfile 的情况下加载多个环境变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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