我是docker-compose的新手
我试图了解如何通过docker-compose传递环境变量,以便在Dockerfile
的构建阶段填充配置文件中缺少的变量值,因此在运行阶段,我将运行service- rabbitmq
,其配置填充了env变量值。
在docker-compose yml文件中,我有env_file:
和environment:
,请问如何将它们传递给填充配置文件。
任何帮助,一个简单的例子都会非常感激 当然。
示例rabbitmq配置文件(带有env变量,需要用$ SSL_PORT的值填充):
[{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}]}
]}
].
答案 0 :(得分:3)
问题可以分为两部分:
第一个问题是通过使用环境变量解决的:正如您所说,您可以指示docker使用env文件(--env-file file.env
)或指定单个环境变量(--env VARIABLE=value
)并且docker将使它们在容器内可用。
第二个问题根据使用的配置框架有不同的解决方案。
例如,如果您使用Typesafe config或Spring之类的内容,则只需在配置本身内部引用环境变量,配置框架就会自动扩展它。
如果您正在配置不支持环境变量扩展的第三方软件,则需要在执行目标软件之前执行一些预处理。
这通常是通过使用自定义entrypoint创建泊坞窗图片来完成的。此入口点负责修改扩展已知环境变量的目标软件的配置,然后启动软件。
此类入口点脚本的示例可能是:
#!/bin/sh
sed -i "s/\$SSL_PORT/$SSL_PORT/g" /etc/software.conf
exec $@
以这种方式修改配置文件可能很危险且容易出错,因此在编写此类脚本时要小心。
<强>更新强>:
如果您要做的只是在原始入口点开始之前执行一些预处理,您可以遵循以下简单模式:假设原始入口点被称为docker-entrypoint.sh
,您需要做的就是创建docker-entrypoint-pre.sh
有此内容:
#!/bin/bash
# Perfom all the needed preprocessing here...
# Invoke the original entrypoint passing the command and arguments
exec /docker-entrypoint.sh $@
如果使用新的入口点构建docker镜像并使用以下命令启动容器:
docker run --rm test-image echo "This is a test"
将会使用参数docker-entrypoint-pre.sh
和echo
调用This is a test
。完成预处理后,将使用相同的参数调用原始入口点docker-entrypoint.sh
,从而保持原始图像的行为。
<强> UPDATE2:强>
为了添加新的入口点,您必须创建一个从原始入口继承的新Docker镜像。假设原始图片为rabbit:latest
,您需要创建一个包含以下内容的Dockerfile
:
FROM rabbit:latest
COPY docker-entrypoint-pre.sh /docker-entrypoint-pre.sh
ENTRYPOINT ["/docker-entrypoint-pre.sh"]
然后从包含docker build -t myrabbit:latest .
和Dockerfile
的目录中使用docker-entrypoint-pre.sh
构建您的图片。
此时,您有一个带有预处理逻辑的新图像myrabbit:latest
。
答案 1 :(得分:0)
Assuming that your config file(s) are using the variable $SSL_PORT
inside the container, and you want to pass environment variables from the host machine to be used on build, this can be done in your docker-compose.yml
. YAML supports the use of environment variables, therefore, you can use environment:
followed by an array of variables you wish to pass to the container during runtime.
For example:
version: '3'
services:
your-app:
build:
context: .
dockerfile: Dockerfile
environment:
- "SSL_PORT=${PORT_VARIABLE_FROM_HOST}"
To trouble shoot and make sure that your variables are in fact assigned inside your container run:
docker exec -it <container_name_or_id> printenv
This should list all of the environment variables inside your container