よくある質問と回答¶
あなたの質問がここになければ、freenode IRC の #docker-compose
にあるコミュニティに、質問を気軽に投げてください。
サービスが停止するのに10秒かかるのはどうして?¶
Compose の停止(stop)とはコンテナに SIGTERM
を送信して停止することです。 デフォルトのタイムアウトは 10 秒間です 。タイムアウトしたら、コンテナを強制停止するために SIGKILL
を送信します。タイムアウトで待っているとは、つまり、コンテナが SIGTERM
シグナルを受信しても停止しないのを意味します。
これはコンテナが プロセスのシグナルをどう扱うか(英語) の問題で言及されています。
この問題を解決するには、以下のことを試してください。
- Dockerfile の
CMD
とENTRYPOINT
命令で JSON 形式を使用する。
例えば、 ["program", "arg1", "arg2"]
の形式を使うのであり、 "program arg1 arg2"
の形式を使いません。後者の文字列で指定すると、Docker はプロセスの実行に bash
を使います。すると Docker は適切にシグナルを扱えません。 Compose では常に JSON 形式を使っていれば、Compose ファイル上のコマンドやエントリを書き換える心配は不要です。
- 可能であれば、アプリケーションが
SIGTERM
シグナルを確実に扱えるように書き換えます。
同一ホスト上で Compose ファイルをコピーして、複数実行するには?¶
Compose での作成時は、プロジェクト名をユニークな識別子として使います。これはプロジェクト内の全てのコンテナや他のリソースに使います。プロジェクトをコピーして複数実行するには、 -p
コマンドライン・オプション を使って任意のプロジェクト名を指定するか、あるいは COMPOSE_PROJECT_NAME
環境変数 を使います。
up
・ run
・ start
の違いは何ですか?¶
一般的には docker-compose up
が使われるでしょう。 up
を使うと docker-compose.yml
ファイル中で定義したサービスの開始または再起動を行います。デフォルトは「アタッチド」モードであり、全てのコンテナのログが画面上に表示されます。「デタッチド」モード( -d
)では、Compose はコンテナを実行すると終了しますが、コンテナは後ろで動き続けます。
docker-compose run
コマンドは「ワンオフ」(one-off;1つだけ、偶発的) または「アドホック」(adhoc;臨時)なタスクの実行に使います。実行するにはサービス名の指定が必要であり、特定のサービス用のコンテナを起動し、かつ依存関係のあるコンテナも起動します。 run
の利用心は、テストの実行であったり、データ・ボリューム・コンテナに対するデータの追加・削除といった管理タスクです。 run
コマンドは実際には docker run -ti
を処理しており、コンテナに対してインタラクティブなターミナルを開き、コンテナのプロセスが終了すると、その時点の該当する終了コードを返します。
docker-compose start
コマンドは既に作成済みのコンテナの再起動には便利です。しかし止まっているコンテナを起動するだけであり、新しいコンテナは作成しません。
Compose ファイルには、YAML の代わりに JSON を使えますか?¶
はい、 YAML は JSON のスーパーセットです 。そのため、あらゆる JSON ファイルは有効な YAML でもあります。Compose ファイルに JSON を使いたい場合は、ファイル名で( .json
を )指定します。実行例:
docker-compose -f docker-compose.json up
データベースが起動するのを待ってからアプリケーションを起動するには?¶
残念ながら、正統な理由がなければ Compose はそのように処理できません。
データベースが準備するまで待たせることにより、分散システムにおいて非常に大きな問題となる可能性があります。プロダクション環境においては、データベースが使えなくなるか、あるいは他のホストに移動する場合があるでしょう。アプリケーションは、この種の障害に対する回復力を必要とします。
そのためには、アプリケーションがデータベースとの通信ができなくなっても、再度接続を試みるでしょう。もしアプリケーションのリトライが失敗したら、データベースに対する接続性は失われたと考えるべきです。
アプリケーションが正常になるまで待つためには、ヘルスチェックを実装する必要があります。ヘルスチェックはアプリケーションに対してリクエストを送り、ステータス・コードの応答が正常化どうかを確認します。もし成功しなければ、短時間待った後、再試行します。何度もタイムアウトをするようであれば、チェックを停止し、失敗を報告します。
もしアプリケーションに対する実行テストが必要であれば、ヘルスチェックを実行できます。ヘルスチェックの応答が正常であれば、テストを実行可能になります。
コードを入れるには COPY
か ADD
ですか、それともボリュームですか?¶
コードをイメージにコピーするには、 Dockerfile
の COPY
または ADD
命令が使えます。これは Docker イメージのコードを置き換える場合に便利です。例えば、コードを別の環境(プロダクション、CI 、等)に送りたい場合です。
コードを変更したい場合、すぐに反映したい場合は volume
を使うべきでしょう。例えば、コードをデプロイする場面で、サーバがホット・コード・リロードやライブ・リロードをサポートしている場合です。
両方の命令を使いたい場合があるかもしれません。開発環境上において、イメージに対してコードを追加する場合は COPY
を使い、Compose ファイルにコードを含める場合は volume
を使えます。ボリュームを使えばイメージの中にあるディレクトリの情報を上書きします。