2017-08-03 30 views
0

我是docker-compose的新手。
我想了解如何通過docker-compose傳遞環境變量以在Dockerfile的構建階段填充配置文件中的缺失變量值,因此在運行階段,我將運行帶有其配置的service-rabbitmq用env變量值填充。如何使用docker-compose環境變量來填充配置文件

在docker-compose yml文件我有一個env_file:environment:,問題我怎麼能通過它們來填充配置文件。

任何幫助,一個想法將不勝感激與一個簡單的例子 當然。

實施例的RabbitMQ配置文件(與需要被填充有其爲$ SSL_PORT值ENV變量):

[{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

看看這篇文章是否有助於http://tarunlalwani.com/post/simple-parameterized-config-files-docker/ –

+0

@TarunLalwani:你如何傳遞來自'env_file:'或'environment:'部分的環境變量到docker構建階段的配置文件? – JavaSa

+0

如果你在構建過程中傳遞它,那麼你需要使用構建參數。 https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg –

回答

2

問題可以分爲2部分:

  1. 注入容器內的配置值
  2. 讓目標軟件使用這種配置值

的第一個問題是通過使用環境變量來解決:如你所說,你可以指示搬運工人到使用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 [email protected] 

這樣修改配置文件可能是危險的,容易出錯所以寫這樣的腳本時要小心。

更新

如果你想要做的是之前的原始入口點開始,你可以按照這個簡單的模式進行一些預處理:比方說,原來的入口點被稱爲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 [email protected] 

如果您在使用新的入口點建立一個碼頭工人形象,與開始的容器:

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

將會發生什麼是docker-entrypoint-pre.sh將被調用與參數echoThis 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 .從包含Dockerfiledocker-entrypoint-pre.sh目錄建立你的形象。

在這一點上,你有一個新的圖像myrabbit:latest與你的預處理邏輯。

+0

請你指定翻譯波紋管bash腳本命令,另外我怎麼能不重寫我現有的rabbitmq'docker-entrypoint.sh',只是用我自己的腳本來擴展它,然後才能運行它。 Docker-entrypoint.sh正在使用該配置,因此我需要在啓動前進行一些修改 – JavaSa

+1

作爲示例發佈的bash腳本只是使用sed將每個出現的$ SSL_PORT替換爲該環境變量的值。這是我的goto方法,因爲'sed'存在於許多基本圖像中。入口點腳本的最後一行是啓動軟件的實際調用。 Docker會用最終命令(及其參數)作爲參數調用入口點腳本。鑑於這種情況,如果你想做一些預處理,你可以讓你的入口點調用原來的入口點。爲了提供一個例子,我會更新答案。 – nivox

+0

好吧,我有一個新的腳本與預處理,我如何重寫這個dockerfile首先啓動我的預處理,然後所有其他說明:https://github.com/docker-library/rabbitmq/blob/79277042564875d55e4b05a60c65b6eb46651a94/3.6/debian/Dockerfile – JavaSa

0

假設你的配置文件(一個或多個)使用的是可變$SSL_PORT內部容器,並且您想要通過主機機器上的環境變量來構建,可以在您的docker-compose.yml中完成。 YAML支持使用環境變量,因此,您可以使用environment:,後跟您想在運行時傳遞給容器的變量數組。

例如:

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

麻煩拍攝,並確保您的變量實際上你的容器運行在內部分配:

docker exec -it <container_name_or_id> printenv

這應當列出所有內部的環境變量您的貨櫃

+0

我需要它建立時間不運行時間,這意味着在'dockerfile'如果我做printenv我沒有看到環境變量.. – JavaSa

相關問題