Compose: docker-compose.ymlでシェルコマンドを使用する

作成日 2016年10月27日  ·  41コメント  ·  ソース: docker/compose

こんにちは、 docker-compose.ymlファイルでシェルコマンドを使用する方法はありますか?
これが私のユースケースです:

 version: '2'
 services:
   ci:
     image: jenkins
     volumes:
       - ./data:/var/jenkins_home
       - /var/run/docker.sock:/var/run/docker.sock
       - $(command -v docker):/usr/bin/docker
     groupadd:
       - $(stat -c %g /var/run/docker.sock)
     ports:
       - "8080:8080"
       - "50000:50000"

現在、このエラーが発生しています。

ERROR: Invalid interpolation format for "volumes" option in service "ci": "${command -v docker}:/usr/bin/docker"
kinquestion

最も参考になるコメント

これは非常に便利です...。

全てのコメント41件

こんにちは@zkanda

申し訳ありませんが、これはサポートされていません。 通常、これは、環境変数を設定し、代わりにComposeファイル内で変数置換を使用することによって行われます。

@ shin-ありがとう、環境変数を回避できます。 また、 .envも非常に便利なようです。
関連するドキュメント: https ://docs.docker.com/compose/environment-variables/#/the -env-file

@zkandaこれを機能させることはありましたか? .envファイルで試しました

DOCKER_BIN=`which docker`

そしてdocker-compose.ymlで

jenkinsmaster:
  build: jenkins-master
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ${DOCKER_BIN}:/usr/bin/docker
  ports:
    - "50000:50000"

しかし、私は取得し続けます

Cannot create container for service jenkinsmaster: create `which docker`: "`which docker`" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.

それで、コマンドは.envファイルの文字列として解釈されるように見えますか?

コマンドは、 .envまたは他の場所でComposeによって展開されません。

これは非常に便利です...。

+1

これがユースケースです。 Kafkaを設定するときは、ホストマシンのIPが必要です。 私はそれを取得するために次のスクリプトを持っています:

DOCKER_HOST_IP=$(ifconfig | grep 'inet .*br' | sed -E 's/.*inet (.*) netmask.*/\1/')

私は環境でそのIPを参照します。 事前に実行する必要があるため、 docker-compose up実行することはできません。 そして、私はこれをチームの他の開発者に知らせる必要があります。

+1

次のように、現在のユーザーを取得すると便利です。

services:
  foo:
    image: bar:latest
    user: ${CURRENT_USER-$(id -u):$(id -g)}

他のユースケースもあるはずです...

ちなみに、残りのBash機能を実行できない場合、 ${BAZ-default}がComposeで機能するという事実はわかりません...(私が知る限り、 -は、Bashの変数操作機能の1つであり、たとえば${VAR/search/replace}での置換として)

はい@ davi5e ...私が試していたもの:

version: "3.7"

services:
  orchestrator:
    build: .
    ports:
      - "2000:2000"
    # Use type host until we can test link
    network_mode: "host"
    environment:
      - NODE_ENV=development
      - LOCAL_USER_ID=${id -u}

@ davi5e別のユースケースは、

+1
Plzは問題を再開します

+1
私のユースケースでは、「ベース」ポートの関数として決定されるポートの範囲を公開します

これは、開発環境でDockerを使用するための要件であるため(スクリプトを使用してこれを.envファイルに設定する必要がないため)、UID / GID変数を設定する場合に非常に役立ちます。

+1

これを使用して、dockercomposeによって生成された画像にgitタグとコミットハッシュでラベル付け/タグ付けできます。

.env

GIT_VERSION=$(git describe --always --dirty --abbrev)
OUTER_PORT=6970

docer-complse.yml

version: '3'
services:
  nginx:
    restart: always
    build:
        context: ./nginx
        labels:
          org.label-schema.schema-version: "1.0"
          org.label-schema.version: "${GIT_VERSION}"
          org.lavel.schema.url: "https://mydocu-server.company.com/vcs/${GIT_VERSION}"
    ports:
      - ${OUTER_PORT}:8080

開発でこれを行う場合、シェルがUID変数を設定すると、ローカル開発イメージを構築するときにそれを渡すことができます。 ローカル開発イメージは共有されないため、同僚とのuidの競合について心配する必要はありません。

+1

@ con-f-useテストの結果ではなく、実際のコマンドを送信するだけです。これまでに成功した唯一のハックは、環境変数を設定するdockercomposeをラップするスクリプトを作成することです。

+1

TL; DRこれらの変数を.envファイルからエクスポートする場合:

# set the path of .env file here
ENV_FILE="${ENV_FILE:-local.env}"
while IFS= read -r line; do
  export "$line"
done < <( grep --color=never -E -v -e '^#' -e '^[[:space:]]*$' "${ENV_FILE}" )

使い方:

  • コマンドラインで入力し、Enterキーを押して、現在のシェル環境を変更します

または

  • bashスクリプトとして保存し、ソースを設定します

警告:

  • これをスクリプトとして保存して実行しても、現在のシェル環境でこれらの変数が魔法のようにエクスポートされることはありません。 あなたはそれをevalするか、いくつかの派手な
  • (たぶん良いことですか?) $ENV_FILE内の同じ名前の既存の変数を上書きします

説明:ここ

https://direnv.net/をすべて自動化するためにdirenvを見て

金、2019年6月28日には、午前12時57分PM Sudarshan Wadkar [email protected]
書きました:

これらの変数を.envファイルからエクスポートする場合はTL; DR:

ここで.envファイルのパスを設定します

ENV_FILE = "$ {ENV_ FILE:-local.env }" while IFS = read -r line; 行う
export "$ line" done <<(grep --color = never -E -v -e '^#' -e '^ [[:space:]] * $' "$ {ENV_FILE}")

使い方:

  • コマンドラインで入力します
  • bashスクリプトとして保存し、ソースを設定します

警告:

  • これをスクリプトとして保存して実行しても、魔法のようにそれらがエクスポートされることはありません
    現在のシェル環境の変数。 あなたはそれを調達するか、する必要があります
    いくつかの派手な評価。
  • (多分良いことですか?)それは既存の変数を同じもので上書きします
    $ ENV_FILEの名前

説明:ここ
https://explainshell.com/explain?cmd=while+IFS%3D+read+-r+line%3B+do+export+%22%24line%22%3B+done+%3C+%3C%28grep+--color%3Dno+ -v + -e +%27%5E%23%27 + -e +%27%5E%5B%5B%3Aspace%3A%5D%5D *%24%27 +%24%7BENV_FILE%7D%29


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDBQXQZTC5FXTOFL6UTP4XOBJA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2Z
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AACHRDGJ6FAQBEDLBSRVS6TP4XOBJANCNFSM4CUISSSA

ええ、 direnvは素晴らしいですが、単純なVAR=VAL構文の単純な行があるDockerの.envファイルで役立つかどうかはわかりません(このリンクのとおり)。 .envファイルであるという考えはリポジトリにコミットされ、ビルドスクリプトはそれをローカルで実行するか、 docker-composeはステージング/デプロイで実行できます。

実際には環境変数はありません
https://en.wikipedia.org/wiki/Environment_variable(の一部である場合)
コードベースであり、環境の一部ではありません。

14:04 Sudarshan Wadkarで金、2019年6月28日には[email protected]
書きました:

ええ、direnvは素晴らしいですが、Dockerで役立つかどうかはわかりません
単純なVAR = VAL構文の単純な行を持つ.envファイル(これによる)
https://docs.docker.com/compose/env-file/#syntax-rulesリンク。)アイデア
.envファイルであることはリポジトリにコミットされ、ビルドスクリプトは
ローカルまたはdockerで実行します-composeはステージング/デプロイで実行できます。


このスレッドにサブスクライブしているため、これを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDCEKOMK2VI3A43QBC3P4XV5BA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AACHRDF3Q3YOZPHUIUZYEPTP4XV5BANCNFSM4CUISSSA

ああ、大丈夫。

docker-compose upを実行すると、 .envファイルが環境変数に変わると思います。

私のユースケースは、信頼できる情報源と同じ.envファイルを使用してローカル開発インスタンスを実行することdocker-compose (おそらく.envファイル内のこれらの行は実際には環境変数ではないかもしれませんが、デプロイすると確実に1つになります。

その場合、 direnvがどのように役立つかはまだわかりません。

別の使用例は、パスワードを生成するコマンドをコンテナのenvvarに割り当てることです。
このように、パスワードは実際には.envまたはdocker-compose.ymlファイルに書き込まれません。

これは、多くのセキュリティ関連のユースケースにとって大きなメリットになると思います。

+1

+1

+1は、ソリューションを過度に複雑にすることなく、 uidgidを設定するのに非常に役立ちます。

`` `
/ _ / \
(oo)

^ <`` `

+1上記のユースケースでgitブランチを追加し、composeファイルにコミットします。これは最終的にdockerfileに入り、マルチステージdockerビルドプロセスのステージでビルドされたjarのマニフェストにバージョンとして追加されます。 。

  gateway:
    image: name
    build:
      context: ./project
      dockerfile: build/Dockerfile
      args:
        - GIT_COMMIT=${$(git rev-list -1 HEAD):-unspecified}
        - GIT_DATE=${$(git log -1 --date=short --pretty=format:%ct):-unspecified}

したがって、現在、作成ファイル内の7つのプロジェクトに対して、7x2環境を設定する必要があります。 悲しい。

@ shin-これを機能リクエストとして再度開いていただけませんか? それは良い回避策によって解決されていないようであり、それに対するいくつかの確かな必要性があります。

+1おそらくこれは別の方法で実現できたかもしれませんが、隣接するコンテナーを再起動するには、コンテナー内からDockerエンジンを使用する必要がありました。 Letsencrypt証明書の有効期限が切れているが、更新後にNGinxコンテナを再起動する必要がある場合。 問題は、コンテナ内のdocker-composeに、このコンテナグループのプロジェクト名をどのように伝えるかです。 PROJECT=(basedir ~+) 。 今のところ手動でコーディングされています:(

その機能リクエストに+1
もう1つの使用例は、cli / http(vault、1Passwordなど)からシークレットを取得し、環境にプラグインすることです。
すなわち

...
    environment:
      - SERVICE_USERNAME=$(vault kv get -field=username kv/service/credentials)
      - SERVICE_PASSWORD=$(vault kv get -field=password kv/service/credentials)
...

私はlastpassを使用していることを除いて、

...
     environment:
         - TRPASSWD=$(lpass show --password Transmission)
....

+1

+1

@ shin-これを機能リクエストとして再度開いていただけませんか? それは良い回避策によって解決されていないようであり、それに対するいくつかの確かな必要性があります。

@ four43 、多分@ shin-または他の人はクローズされた問題に関するコメントを読んでいませんか? 注意を引くために別のものを開きましょうか。

docker-composeファイルの変数展開は、非常に便利な機能です...

+1

@ esale-ええ、それはちょっと依存していると思います。 この場合、範囲外であることがわかりました。 一部のDSLではやりすぎないでください。 その時点で、他のツールを使用してdocker-composeファイルをテンプレート化しますか? 懸念を超えすぎていませんか?

.envファイルを使用している場合は、シェル出力を次のようなコマンドで置き換えることができます。

eval "echo \"$(cat .env.example)\"" > .env

.env.exampleファイルの例

DOCKER_BIN=$(which docker)
DOCKER_COMPOSE_BIN=$(which docker-compose)

.envファイルを作成します

DOCKER_BIN=/snap/bin/docker
DOCKER_COMPOSE_BIN=/snap/bin/docker-compose
このページは役に立ちましたか?
0 / 5 - 0 評価