docker-composeでコンテナを起動して、コンテナの中に入ろうとすると「Exit (0)」が原因で入れなかったときの対応方法。
【事象】Exited(0)でコンテナが起動しない
docker-composeでコンテナを立ち上げ後、以下コマンドを実行してコンテナ内に入ろうとすると入れなかった。
docker compose exec サービス名 bash
// 実行結果
// service "サービス名" is not running
実行結果で「service is not running」と表示されているので、どうやらコンテナが稼働していないようです。
念のため、「docker ps -a」コマンドを実行し、コンテナの稼働状況を確認してみる。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c0e3f7d179c docker-dev-app "docker-php-entrypoi…" 20 minutes ago Exited (0) 7 minutes ago docker-dev-app-1
ステータスを確認すると、「Exited (0)」と表示されていました。
Exitのステータスコードは「0」なので、コンテナが起動してそのまま正常終了しています。
【原因】 コンテナを起動させ続けるプロセスがない
色々調べてみると、原因はdocker側の仕様で、ポート待受をしていないコンテナを起動した場合、コンテナを起動させ続けるためのプロセスを実行させておかないと、そのまま正常終了するようになっているからでした。
そのため、特にエラーもなく、正常終了しているのはdockerの仕様上では間違っていないということです。
原因がわかったので、コンテナを起動させ続けるための何らかのプロセスを入れることで解決できそうです。
【対策】 コンテナとホストマシンの標準入出力を繋げる
コンテナ起動後にフォアグラウンドで動作するプロセスを実行させることで解決できます。
フォアグラウンドとは、実行する処理(プロセス)の完了を待ち、それが完了するまで次のプロセスが実行できない状態のことを意味します。
dockerには、コンテナとホストマシンの標準入出力を繋げる設定があるので、それをに有効にすることでコンテナを起動させ続けることができます。
docker composeを用いる場合、docker-compose.ymlの設定項目の、「stdin_open」と「tty」をtrueにすることで設定を有効にできます。
services:
サービス名:
images: xxxxx
container_name: xxxxx
(省略)
stdin_open: true
tty: true
- 「stdin_open」は、ホストマシンの標準入力とコンテナを繋ぐオプションで、trueにするとホストマシンでの入力がコンテナに伝えることができるようになる。
- 「tty」は、ホストマシンの標準出力とコンテナを繋ぐオプションで、trueにするとコンテナの出力をホストマシンで確認できるようになる。
ちなみに、docker composeを用いずに、docker runコマンドでイメージファイルからコンテナを起動させたい場合は、「-itdオプション」をつけると同じ設定でコンテナを起動させ続けることができます。
docker run -itd イメージ名
まとめ
Exited (0)でコンテナが起動せずにそのまま終了してしまう原因は、コンテナ起動後にフォアグラウンドで動作するプロセスが存在しないため。
コンテナとホストマシンの標準入出力を繋げる設定を有効にすることで、コンテナを起動し続けることができる。
- docker composeで起動する場合は、docker-compose.ymlの 「stdin_open」と 「tty」をtrueにしておく
- docker runで起動する場合は、「-itd」オプションを付与しておく
「Exited (0)」でコンテナが起動できないときは、この辺りの設定を忘れていないか注意しておきたいです。
参考サイト
docker-compose で exit with status 0 の解決法
Dockerコンテナをずっと起動しておく