如何使用docker-compose环境variables来填充configuration文件

我是新来的docker写作。
我试图了解如何通过docker-compose传递环境variables来在Dockerfile的构build阶段填充configuration文件中缺less的variables值,所以在运行阶段,我将运行service- rabbitmq ,其configuration填充envvariables值。

env_file: -compose yml文件中,我有一个env_file:以及environment: ,问题如何将它们传递给填充configuration文件。

任何帮助,一个想法将不胜感激,当然一个简单的例子。

示例rabbitmqconfiguration文件(需要用$ SSL_PORT的值填充envvariables):

 [{rabbit, [ {loopback_users, []}, {ssl_listeners, [$SSL_PORT]}, {ssl_options, [{cacertfile,"/etc/rabbitmq/ca/cacert.pem"}, {certfile,"/etc/rabbitmq/server/cert.pem"}, {keyfile,"/etc/rabbitmq/server/key.pem"}, {verify,verify_none}, {fail_if_no_peer_cert,false}]} ]} ]. 

问题可以分为两部分:

  1. 注入容器内的configuration值
  2. 让目标软件使用这样的configuration值

第一个问题是通过使用环境variables来解决的:正如你所说的,你可以指示--env-file file.env使用env文件( --env-file file.env )或者指定单个环境variables( --env VARIABLE=value ), --env VARIABLE=value会使它们在容器内可用。

第二个问题根据所使用的configuration框架有不同的解决scheme。

例如,如果你正在使用types安全configuration或者Spring这样的东西,你可以在configuration本身中放一个对环境variables的引用,configuration框架会自动扩展它。

如果您正在configuration不支持环境variables扩展的第三方软件,则需要在目标软件执行之前进行一些预处理。

这通常通过使用自定义入口点创build泊坞窗图像来完成。 此入口点负责修改扩展已知环境variables的目标软件的configuration,然后启动软件。

这样的入口点脚本的例子可以是:

 #!/bin/sh sed -i "s/\$SSL_PORT/$SSL_PORT/g" /etc/software.conf exec $@ 

以这种方式修改configuration文件可能是危险的,容易出错,所以在编写这样的脚本时要小心。

更新

如果您只想在原始入口点开始之前执行一些预处理,则可以遵循以下简单模式:假设原始入口点称为docker-entrypoint.sh ,您只需创builddocker-entrypoint-pre.sh与这个内容:

 #!/bin/bash # Perfom all the needed preprocessing here... # Invoke the original entrypoint passing the command and arguments exec /docker-entrypoint.sh $@ 

如果您使用新的入口点构build泊坞窗图像,并使用以下命令启动容器:

docker run --rm test-image echo "This is a test"

会发生什么是docker-entrypoint-pre.sh将被调用参数echoThis is a test 。 预处理完成后,原始入口点docker-entrypoint.sh将被调用相同的参数,从而保持原始图像的行为。

Update2:为了添加新的入口点,您必须创build一个从原来的inheritance的新Docker镜像。 让我们说,原始图像是rabbit:latest ,你需要创build一个Dockerfile与以下内容:

 FROM rabbit:latest COPY docker-entrypoint-pre.sh /docker-entrypoint-pre.sh ENTRYPOINT ["/docker-entrypoint-pre.sh"] 

然后用docker build -t myrabbit:latest .创build你的镜像docker build -t myrabbit:latest . 从包含Dockerfiledocker-entrypoint-pre.sh的目录中。

在这一点上,你有一个新的图像myrabbit:latest的预处理逻辑。

假设你的configuration文件在容器中使用variables$SSL_PORT ,并且你想从主机上传递环境variables来在build上使用,这可以在你docker-compose.yml 。 YAML支持使用环境variables,因此,您可以使用environment:后跟一个您希望在运行时传递给容器的variables数组。

例如:

 version: '3' services: your-app: build: context: . dockerfile: Dockerfile environment: - "SSL_PORT=${PORT_VARIABLE_FROM_HOST}" 

为了排除故障并确保您的variables实际上是在您的容器运行中分配的:

docker exec -it <container_name_or_id> printenv

这应该列出容器内的所有环境variables