Docker Stack DeployはDocker Composeのようにデフォルト値で環境変数を解決しません。

Docker Stack DeployはDocker Composeのようにデフォルト値で環境変数を解決しません。

以下のサンプルファイルがあります

docker-compose.yml

version: '3'
services:
  web:
    image: webapp:${VARIABLE_A:-${VARIABLE_B}}

env.conf

VARIABLE_B=123

VARIABLE_A意図的に設定されていないので、VARIABLE_B

Docker Composeは環境変数のデフォルト値を解決できますが、docker stack deploy同じ解決を行うことはできません。

user@laptop:~$ docker compose --env-file ./env.conf convert

name: dockercomposetest
services:
  web:
    image: webapp:123
    networks:
      default: null
networks:
  default:
    name: dockercomposetest_default
user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack

Creating service stack_web
failed to create service stack_web: 
  Error response from daemon: 
  rpc error: 
    code = InvalidArgument desc = ContainerSpec: "webapp:${VARIABLE_B}" is not a valid repository/tag

ご覧のとおり、docker stack deployこれを使用すると、検出される${VARIABLE_A:-${VARIABLE_B}}環境変数がVARIABLE_A設定されていないため、デフォルトで になるはずです${VARIABLE_B}が、その値が解決されないため、123

明らかに、webappは存在しません。これは単なる例ですが、上記のエラー出力は代わりに次のようになります。

user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack

Creating service stack_web
failed to create service stack_web: 
  Error response from daemon: 
  rpc error: 
    code = InvalidArgument desc = ContainerSpec: "webapp:123" is not a valid repository/tag

なぜこのようなことが起こるのでしょうか? 回避策はありますか?

答え1

参考としてmobyを参照1.13のdocker stack deployはdocker-compose upのように.envファイルをロードしません。 具体的にはkinghuangからのコメント

「私の開発者は、docker-compose config を使用して、Docker Compose プロジェクトを docker stack deploy に渡す前に前処理するようにしています。これは、次の 1 行で実行できます。

docker stack deploy -c <(docker-compose config) stack-name-here

こうすることで、.env 処理を含むすべての Docker Compose 機能が完全に適用されます。"

答え2

私が最終的に行った回避策は、env varsを置き換えるためにdocker stack deploy使用することですenvsubst

user@laptop:~$ env $(cat ./env.conf | xargs) envsubst < ./docker-compose.yml | docker stack deploy --compose-file - stack

ドキュメントによると、--compose-file -これを使用するとstdindocker composeファイルとして取得されるため、基本的にこれはまずすべての変数を解決し、docker-compose.yml次にパイプを使用して結果を渡すことになります。docker stack deploy

答え3

この問題を克服する別の良い方法があります。環境に追加するすべての変数を含む「.env」ファイルを作成する必要があります。たとえば、APP_NAME=Example次のようになります。次に、stack-compose.yml で次のように宣言します。

version: "3.9" 
services: 
  myservice: 
    env_file: 
      - .env

その後、次のコマンドを実行する必要があります。

docker stack config -c stack-compose.yml | docker stack deploy -c - mystackname

これにより、.env ファイルで宣言した変数が次のように stack_compose.yml に挿入されます。

version: "3.9"
services:
  myservice:
    environment:
      APP_NAME: "Example"

このリンクでdocker swarm スタックで環境変数を渡す方法

これを行う方法についての非常に良い説明が見つかります。私も同じ問題を抱えていましたが、この方法で克服しました。よろしくお願いいたします

関連情報