如何使用docker-compose环境变量来填充配置文件

时间:2017-08-03 17:47:19

标签: bash docker rabbitmq docker-compose

我是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}]}
  ]}
].

2 个答案:

答案 0 :(得分:3)

问题可以分为两部分:

  1. 在容器中注入配置值
  2. 让目标软件使用此类配置值
  3. 第一个问题是通过使用环境变量解决的:正如您所说,您可以指示docker使用env文件(--env-file file.env)或指定单个环境变量(--env VARIABLE=value)并且docker将使它们在容器内可用。

    第二个问题根据使用的配置框架有不同的解决方案。

    例如,如果您使用Typesafe configSpring之类的内容,则只需在配置本身内部引用环境变量,配置框架就会自动扩展它。

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

    这通常是通过使用自定义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.shecho调用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