はじめに
Docker Composeでアプリを起動していると、こんな経験をしたことはありませんか?
docker compose up
を実行して、
Ctrl + C
を押したのにコンテナがすぐ停止しない。
さらにもう一度
Ctrl + C
を押したら停止した。
私は初めてこの挙動を見たとき、
- Ctrl+Cが効いていない?
- Dockerがフリーズした?
- 何か設定を間違えた?
と思いました。
しかし実は、これはDocker Composeでよく見られる正常な挙動だそうです。
この記事では、なぜCtrl+Cを2回押すことがあるのか、その理由と対処法を解説します。
※筆者の使用しているパソコンはWindows11になります
結論
先に結論です。
Ctrl+Cを2回押さないと停止しないことは珍しくありません。
多くの場合は異常ではなく、
Docker Composeがコンテナを安全に停止しようとしているため
に発生します。
Docker Composeは何をしているのか
まずは docker compose up の動作を理解することから。。
docker compose up
を実行すると、Docker Composeは次の2つを行います。
- コンテナを起動する
- コンテナのログを表示する
例えばRailsアプリとMySQLを起動している場合、
Railsのログ
MySQLのログ
Railsのログ
MySQLのログ
のように複数のコンテナのログがまとめて表示されます。
つまり、
Docker Composeは複数のコンテナに接続(attach)しながらログを表示している状態
になっています。
Ctrl+Cを押すと何が起きるのか?
docker compose up 実行中にCtrl+Cを押すと、Docker Composeはすぐにコンテナを強制終了するわけではありません!
まずはコンテナに対して、
安全に終了してください
という停止要求を送ります。
この状態を 「Graceful Stop(正常終了)」 と呼びます。
実際には次のようなメッセージが表示されることがあります。
Gracefully stopping... (press Ctrl+C again to force)
⚠️ このメッセージの意味
表示を日本語にすると、
正常に停止しようとしています
もう一度Ctrl+Cを押すと強制終了します
という意味です。
つまり、
1回目のCtrl+C
安全に停止してね
というお願い
2回目のCtrl+C
待てないので強制終了する
という指示になります。
なぜ安全停止が必要なのか?
例えばRailsアプリがデータベースに書き込みをしている途中で突然停止すると、以下のような問題が起きる可能性があります。
- データの保存に失敗する
- 接続が中途半端に切れる
- ファイル書き込みが途中で終わる
そのためDockerは、以下のような設計になっています
まず正常終了を試みる
2回押しが発生しやすいケース
以下のような構成では比較的よく見られます。
① Rails + MySQL
services:
web:
db:
RailsコンテナとDBコンテナの両方を停止する必要があります。
② 複数コンテナ構成
例えば
- Rails
- MySQL
- Redis
など複数のサービスを起動しているケースです。
停止対象が増えるため、終了処理に時間がかかることがあります。
③ アプリの終了処理が重い場合
アプリケーションによっては、
- 接続を閉じる
- ファイルを保存する
- ジョブを終了する
といった処理を行ってから終了します。
そのため停止に数秒かかることがあります。
対処法・回避方法
① 気にしない
正常終了を待っているだけなので、基本的には問題ありません。
数秒待てば停止するケースがほとんどです。
② docker compose down を使う
明示的に停止したい場合は、
docker compose down
を利用します。
このコマンドは、
- コンテナ停止
- ネットワーク削除
までまとめて実行してくれます。
開発環境では最もよく使う停止方法です。
③ バックグラウンド起動する
docker compose up -d
を利用する方法です。
バックグラウンドで起動するため、
Ctrl + Cで停止する
という操作自体が不要になります。
④ ログだけ確認する
ログを見たいだけなら、
docker compose logs -f
がおすすめです。
ログ表示を終了するだけなら、
Ctrl + C
を1回押すだけで済みます。
コンテナは停止しません。
停止に時間がかかりすぎる場合
毎回かなり長い時間待たされる場合は、
コンテナが正常終了を待っている可能性があります。
Composeでは次のような設定も可能です。
stop_grace_period: 10s
これは
正常終了を10秒待つ
↓
終わらなければ強制停止
という設定です。
まとめ
今回のポイントを整理します。
- Ctrl+Cを2回押すことがあるのは異常ではない
- Docker Composeはまず安全停止を試みる
- 「Gracefully stopping...」は正常なメッセージ
- 2回目のCtrl+Cは強制終了
- RailsやMySQLなど複数コンテナ構成で発生しやすい
- 停止には
docker compose downを使うのがおすすめ
最初は「Ctrl+Cが効いていない」と思いがちですが、実際にはDockerがコンテナを安全に終了させるための仕組みです。
この挙動を理解しておくと、Docker Composeの停止処理で慌てることがなくなるでしょう。
