web-dev-qa-db-ja.com

Dockerに「待機」スクリプトを作成させると、元のコンテナENTRYPOINTまたはCMDを呼び出すことができますか?

Composeでの起動順序の制御 によると、 Docker Compose がコンテナを起動する順序を制御するには、「 wait-for-it "脚本。スクリプト wait-for-it.sh は、Host:port引数と、ポートが使用可能なときにスクリプトが実行するコマンドの両方を想定しています。ドキュメントでは、Docker Composeがentrypoint:オプションを使用してこのスクリプトを呼び出すことを推奨しています。ただし、このオプションを使用すると、entrypoint:がデフォルトを上書きするため、コンテナはデフォルトのENTRYPOINTまたはCMDを実行しなくなります。

待機する条件が満たされたときにスクリプトがデフォルトのENTRYPOINTまたはCMDを呼び出すことができるように、このデフォルトコマンドをwait-for-it.shに提供するにはどうすればよいでしょうか。

私の場合、ファイルが存在するのを待ってポーリングするスクリプトwait-for-file.shを実装しました。

#!/bin/bash

set -e

waitFile="$1"
shift
cmd="$@"

until test -e $waitFile
do
  >&2 echo "Waiting for file [$waitFile]."
  sleep 1
done

>&2 echo "Found file [$waitFile]."
exec $cmd

Docker Composeはwait-for-file.shを、 Tomcat:8-jre8 から派生したわずかにカスタム化されたコンテナへのエントリポイントとして呼び出します。

  platinum-oms:
    image: opes/platinum-oms
    ports:
      - "8080:8080"
    volumes_from:
      - liquibase
    links:
      - postgres:postgres
      - activemq:activemq
    depends_on:
      - liquibase
      - activemq
    entrypoint: /wait-for-file.sh /var/run/liquibase/done

正常に終了する前に、別のカスタムコンテナliquibase/var/run/liquibase/doneを作成するため、platinum-omsはコンテナliquibaseの完了を効果的に待ちます。

コンテナliquibaseがファイル/var/run/liquibase/doneを作成すると、wait-for-file.shFound file [/var/run/liquibase/done].を出力しますが、ベースコンテナのデフォルトコマンド catalina.sh run の呼び出しに失敗しますTomcat:8-jre8。どうして?

テストシナリオ

簡単なテストシナリオ docker-compose-wait-for-file を作成して、問題を実証しました。コンテナubuntu-wait-for-fileは、コンテナubuntu-create-fileがファイル/wait/doneを作成するのを待ってから、Iexpectcontainer ubuntu-wait-for-fileデフォルトのubuntuコンテナコマンド/bin/bashを呼び出しますが、代わりに終了します。なぜ期待どおりに機能しないのですか?

20
Derek Mahar

ただし、このオプションを使用すると、entrypoint:がデフォルトを上書きするため、コンテナはデフォルトのENTRYPOINTまたはCMDコマンドを実行しなくなります。

それが予想されるため、 wait-for-itwrapperスクリプトとして表示されます。
ただし、「サブコマンド」を実行できます。

wait-for-it.sh Host:port [-s] [-t timeout] [-- command args]
                                               ^^^^^^^^^^^^

サブコマンドは、サービスが稼働しているかどうかに関係なく実行されます。
サービスが起動している場合にのみサブコマンドを実行する場合は、--strict引数を追加します。

つまり、そのパラメーターはCMDコマンドにパラメーターで渡されるため、イメージのENTRYPOINT部分を実際のコンテナーコマンドに使用できます。

entrypoint: wait-for-it.sh Host:port --
cmd: mycmd myargs

これは動作するはずです... docker-compose issue 314コメントOP Derek Mahar で言及)

docker-compose.ymlで定義されたエントリポイントは、Dockerfileで定義されたCMDを消去します

8
VonC