docker composeで環境変数を使用する方法


217

docker-compose.yml内でenv変数を使用できるようにしたいのですが、Docker-composeの実行時に値が渡されます。これは例です。今日は、基本的なdocker runコマンドでこれを行っています。これは、自分のスクリプトにラップされています。そのようなbashラッパーなしで、composeでそれを達成する方法はありますか?

proxy:
  hostname: $hostname
  volumes:
    - /mnt/data/logs/$hostname:/logs
    - /mnt/data/$hostname:/data

2
さまざまなオプションについては、docs.docker.com
compose /

2
これはcomposeの前のバージョンで解決されており、サンプルはそのまま動作します。変数の置換については、docs.docker.com / compose / compose-file /# variable-substitutionを確認してください。
natbusa

1
docker

回答:


93
  1. with環境変数template.ymlであるを作成しdocker-compose.ymlます。
  2. 環境変数がファイル「env.sh」にあると仮定します
  3. 以下のコードをshファイルに入れて実行します。

ソースenv.sh; rm -rf docker-compose.yml; envsubst <"template.yml"> "docker-compose.yml";

新しいファイルdocker-compose.ymlが、環境変数の正しい値で生成されます。

template.ymlファイルの例:

oracledb:
        image: ${ORACLE_DB_IMAGE}
        privileged: true
        cpuset: "0"
        ports:
                - "${ORACLE_DB_PORT}:${ORACLE_DB_PORT}"
        command: /bin/sh -c "chmod 777 /tmp/start; /tmp/start"
        container_name: ${ORACLE_DB_CONTAINER_NAME}

env.shファイルの例:

#!/bin/bash 
export ORACLE_DB_IMAGE=<image-name> 
export ORACLE_DB_PORT=<port to be exposed> 
export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER

@Meetこの「BASHソリューション」の下にある私の回答を確認してください。このアプローチの概要をもう少し詳しく説明します。
modulitos

7
現時点ではまだ良い解決策はありませんか?
lvthillo 2016年

13
なぜファイルを再帰的に削除するのですか?(rm -rf
docker

@ lorenzvth7以下の私の回答を確認できます。これはもう少し詳細だと思います:stackoverflow.com/a/33186458/1884158
modulitos

5
-1このソリューションは物事を複雑にするだけなので、docker
Efrat Levitan

239

DOCKERソリューション:

docker-compose 1.5+で変数置換が有効になっているようです:https : //github.com/docker/compose/releases

最新のDocker Composeでは、構成ファイルから環境変数にアクセスできます。したがって、環境変数を取得してから、次のようにComposeを実行できます。

set -a
source .my-env
docker-compose up -d

次に、次のように$ {VARIABLE}を使用してdocker-compose.ymlの変数を参照できます。

db:
  image: "postgres:${POSTGRES_VERSION}"

そして、ここにここから取られたドキュメントの詳細情報があります:https : //docs.docker.com/compose/compose-file/#variable-substitution

この設定でdocker-compose upを実行すると、ComposeはシェルでPOSTGRES_VERSION環境変数を探し、その値を代入します。この例では、Composeは設定を実行する前にイメージをpostgres:9.3に解決します。

環境変数が設定されていない場合、Composeは空の文字列に置き換えます。上記の例では、POSTGRES_VERSIONが設定されていない場合、imageオプションの値はpostgres:です。

$ VARIABLE構文と$ {VARIABLE}構文の両方がサポートされています。$ {VARIABLE-default}や$ {VARIABLE / foo / bar}などの拡張シェルスタイルの機能はサポートされていません。

構成値にリテラルドル記号を配置する必要がある場合は、二重ドル記号($$)を使用します。

そして、私はこの機能がこのプルリクエストに追加されたと思います:https : //github.com/docker/compose/pull/1765

BASHソリューション:

Dockerの環境変数のサポートに問題があることに気づきました。Dockerで環境変数を扱う代わりに、bashなどの基本に戻りましょう!以下は、bashスクリプトと.envファイルを使用したより柔軟な方法です。

.envファイルの例:

EXAMPLE_URL=http://example.com
# Note that the variable below is commented out and will not be used:
# EXAMPLE_URL=http://example2.com 
SECRET_KEY=ABDFWEDFSADFWWEFSFSDFM

# You can even define the compose file in an env variable like so:
COMPOSE_CONFIG=my-compose-file.yml
# You can define other compose files, and just comment them out
# when not needed:
# COMPOSE_CONFIG=another-compose-file.yml

次に、同じbashスクリプトを同じディレクトリで実行します。これにより、すべてが適切に展開されます。

#!/bin/bash

docker rm -f `docker ps -aq -f name=myproject_*`
set -a
source .env
cat ${COMPOSE_CONFIG} | envsubst | docker-compose -f - -p "myproject" up -d

通常のbash構文(つまり、ファイルから${SECRET_KEY}を挿入する)を使用して、構成ファイル内の環境変数を参照するだけです。SECRET_KEY.env

なお、COMPOSE_CONFIG私の中で定義され.envたファイルと私のbashスクリプトで使用されるが、あなただけで簡単に交換することができ{$COMPOSE_CONFIG}my-compose-file.ymlbashスクリプトで。

また、すべてのコンテナに「myproject」という接頭辞を付けて、このデプロイメントにラベルを付けたことにも注意してください。任意の名前を使用できますが、後で簡単に参照できるようにコンテナーを識別するのに役立ちます。コンテナーがステートレスであると想定すると、このスクリプトは、.envファイルのパラメーターと構成YAMLファイルに従って、コンテナーをすばやく削除して再デプロイします。

更新 この回答はかなり人気があるようですので、私のDockerデプロイメントワークフローをより深く説明するブログ投稿を書きました:http : //lukeswart.net/2016/03/lets-deploy-part-1/これは、 nginx configs、LetsEncrypt証明書、リンクされたコンテナなど、デプロイメント構成がより複雑になります。


2
grep foo file.text代わりに単にできcat file.text | grep fooます。私の場合、私はしなければなりませんでしたexport $(grep "^[^#]" .config | xargs) && cat docker-compose.yml | envsubst
ホルヘラビン

「Dockerの環境変数のサポートに問題があることに気づきました」-詳細やチケットへのリンクはありますか?
tleyden 2016

申し訳ありませんが、発生していた特定の問題はログに記録していませんでした。また、かなり前(約6か月)であり、まだ関連性があるかどうかはわかりません。しかし、はい、Docker環境変数サポートの一部の機能にはバグがあり、複数のユーザーから報告されました。私はそれが今よりずっと良いと信じています。しかし、デプロイメント構成が非常に複雑になると、bashを使用して構成ロジックを処理し、コンテナーオーケストレーションのDocker Composeを使用してモジュールをモジュール化することを好みます。
modulitos

8
PSA:これはでのみ機能しdocker-compose up、では機能しませんdocker-compose run
Kriegslustig 2016

5
このソリューションdocs.docker.com/compose/compose-file/#envfileがあり、環境変数を.envunder から追加する場所で使用していますenv_file。次に、docker-compose.yml使用中の変数を参照できます${VARIABLE}
Musale

111

docker-composeがfileのデフォルトの環境変数をネイティブでサポートしているようです

名前を付けたファイルで変数を宣言するだけで、.envdocker-compose.ymlで使用できます。

たとえば、.env内容のあるファイルの場合:

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

内部で変数にアクセスしたり、変数をdocker-compose.ymlコンテナに転送したりできます。

my-service:
  image: ${IMAGE_NAME}
  environment:
    MY_SECRET_KEY: ${MY_SECRET_KEY}

4
これが最善の解決策です!
Ladenkov Vladislav

4
これも私にとってはうまくいきました。理由はわかりませんが、ファイル名は文字どおり.envにする必要がありますconfig.env。たとえば、うまくいきませんでした。
HBat

1
@HBat "。" 隠しファイルを意味します-これはローカル構成ファイルの通常の手順です
Jeremy Hajek

2
最良のソリューション。そして、/ etc / environment propsを追加し、.envを使用してそれらを環境として使用できます。より安全になります。
チンタカディナダサ

24

以下はdocker-compose 3.xに適用されますコンテナー内の環境変数を設定します

メソッド-1 ストレートメソッド

web:
  environment:
    - DEBUG=1
      POSTGRES_PASSWORD: 'postgres'
      POSTGRES_USER: 'postgres'

メソッド-2 「.env」ファイル

docker-compose.ymlと同じ場所に.envファイルを作成します

$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: 'postgres'

あなたの作成ファイルは次のようになります

$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"
    postgres_password: "${POSTGRES_PASSWORD}"

ソース


2
方法1の完全な例を見たいのですが、これを機能させることができなかったため、.envファイルを使用することになりました(これは正常に機能しました)。
BobHy

20

必要なボリュームの環境変数を使用する場合:

  1. ファイルを含む同じフォルダに.envファイルを作成しdocker-compose.yaml ます

  2. .envファイルで変数を宣言します。

    HOSTNAME=your_hostname
    
  3. 変更$hostnameすること${HOSTNAME}で、docker-compose.yaml ファイル

    proxy:
      hostname: ${HOSTNAME}
      volumes:
        - /mnt/data/logs/${HOSTNAME}:/logs
        - /mnt/data/${HOSTNAME}:/data
    

もちろん、ビルドごとに次のように動的に行うことができます。

echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up

9
ドキュメントによると、注意:The .env file feature only works when you use the docker-compose up command and does not work with docker stack deploy.
ジェームズgensの複数形

19

最善の方法は、docker-compose.ymlファイルの外部で環境変数を指定することです。env_file設定を使用して、同じ行内で環境ファイルを定義できます。次に、もう一度docker-composeを実行すると、新しい環境変数でコンテナーが再作成されます。

これが私のdocker-compose.ymlがどのように見えるかです:

services:
  web:
    env_file: variables.env

注:docker-composeは、envファイルの各行がVAR=VALフォーマットであると想定しています。ファイルexport内での使用は避けてください.env。また、.envファイルはdocker-composeコマンドが実行されるフォルダーに配置する必要があります。


2
確かに最善の方法
ダニー

番号。Dockerコンテナー内で環境変数を自動的に使用可能にすることはありません。これらについては、環境セクションで明示的に言及する必要があります。
kta

6

あなたはまだできません... しかし、これは代替手段であり、docker-composer.ymlジェネレーターのように考えます。

https://gist.github.com/Vad1mo/9ab63f28239515d4dafd

基本的に、変数を置き換えるシェルスクリプト。また、Gruntタスクを使用して、CIプロセスの最後にdocker composeファイルを構築できます。


4

私はこれのために作成した単純なbashスクリプトがあります。これは、使用する前にファイルで実行することを意味します。https//github.com/antonosmond/subber

基本的に、環境変数を示すために二重中括弧を使用して作成ファイルを作成します。例:

app:
    build: "{{APP_PATH}}"
ports:
    - "{{APP_PORT_MAP}}"

二重中括弧内のものはすべて同じ名前の環境変数で置き換えられるため、次の環境変数を設定した場合:

APP_PATH=~/my_app/build
APP_PORT_MAP=5000:5000

subber docker-compose.yml結果のファイルを実行すると、次のようになります。

app:
    build: "~/my_app/build"
ports:
    - "5000:5000"

2

私の知る限り、これは進行中の作業です。彼らはそれをしたいのですが、まだリリースされていません。1377(「新しい」495)を参照してください @Andyによって言及されを。

@Thomasによって提案された「CIの一部として.ymlを生成する」アプローチを実装することになりました。


1

envを.envファイルに追加する

といった

VERSION=1.0.0

それを保存します deploy.sh

INPUTFILE=docker-compose.yml
RESULT_NAME=docker-compose.product.yml
NAME=test

prepare() {
        local inFile=$(pwd)/$INPUTFILE
        local outFile=$(pwd)/$RESULT_NAME
        cp $inFile $outFile
        while read -r line; do
            OLD_IFS="$IFS"
            IFS="="
            pair=($line)
            IFS="$OLD_IFS"
               sed -i -e "s/\${${pair[0]}}/${pair[1]}/g" $outFile
            done <.env
     }
       
deploy() {
        docker stack deploy -c $outFile $NAME
}

        
prepare
deploy
    

1

.envファイルを使用して、docker-compse.ymlで動的な値を定義します。ポートまたはその他の値である。

docker-composeのサンプル:

testcore.web:
       image: xxxxxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/testcore:latest
       volumes: 
            - c:/logs:c:/logs
       ports:
            - ${TEST_CORE_PORT}:80
       environment:
            - CONSUL_URL=http://${CONSUL_IP}:8500 
            - HOST=${HOST_ADDRESS}:${TEST_CORE_PORT}

.envファイル内で、これらの変数の値を定義できます。

CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002

1
env SOME_VAR="I am some var" OTHER_VAR="I am other var" docker stack deploy -c docker-compose.yml

バージョン3.6を使用します。

version: "3.6"
services:
  one:
    image: "nginx:alpine"
    environment:
      foo: "bar"
      SOME_VAR:
      baz: "${OTHER_VAR}"
    labels:
      some-label: "$SOME_VAR"
  two:
    image: "nginx:alpine"
    environment:
      hello: "world"
      world: "${SOME_VAR}"
    labels:
      some-label: "$OTHER_VAR"

私はこのリンクからそれを得ました https://github.com/docker/cli/issues/939


1

1.25.4以降、docker-composeは--env-file変数を含むファイルを指定できるオプションをサポートしています。

これは次のようになります。

hostname=my-host-name

そしてコマンド:

docker-compose --env-file /path/to/my-env-file config
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.