如何使用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}]} ]} ].
问题可以分为两部分:
- 注入容器内的configuration值
- 让目标软件使用这样的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
将被调用参数echo
和This 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 .
从包含Dockerfile
和docker-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