【Rails, Docker】コンテナが起動後すぐに落ちてしまうトラブルの原因とその対処法

概要

DockerでRails環境を構築すると, コンテナが起動しないトラブルに見舞われることがあります. その原因と対処法を説明します.

トラブルケース

以下のようなコマンドでRails Serverが稼働しているコンテナに入ったとします.

docker-compose exec <Rails container> bash

一通り作業を終え, コンテナから出る際に

Ctrl+D

で抜けるとコンテナが停止してしまいます. そこであわてて

docker-compose up -d

としても, ほんの一瞬起動するだけで, すぐコンテナが停止してしまいます.

対処法

原因よりも大事であろう対処法を先に書きます. 以下のファイルを削除してください.

application_root/tmp/pids/server.pid

普通applicaion_rootはローカルマシンにマウントしているでしょうから, コンテナが起動できなくても削除できるはずです. 削除し終わったら, いつも通り起動させれば問題なく動きます.

docker-compose up -d

原因のヒント

ここから原因について述べていきましょう. まずは原因のヒントとなるログメッセージを見ます.

この症状が見られた際, -dをつけずに起動を試みると, 起動中のログメッセージが表示されます.

docker-compose up

ログメッセージを見ると, このように書かれた行が見つかります.

web_1  | => Rails 5.2.0 application starting in development 
web_1  | => Run `rails server -h` for more startup options
web_1  | A server is already running. Check /myapp/tmp/pids/server.pid.
web_1  | Exiting
micropost_web_1 exited with code 1

起動しようと頑張っていますが, 最終的にはExitしていますね. その理由がまさにこれです.

A server is already running.

つまり原因は, 「すでにサーバーが起動しているんだし, 俺の出番は無ぇな」とRailsが判断してしまっていることにあります. Rails Serverが起動しているものと, Railsが勘違いしてしまったわけですね.

その勘違いの原因となっているのが, tmp/pids/server.pidというファイルです. 中身を見てみましょう.

$ cat tmp/pids/server.pid
1

ひとつだけ書かれた数字はRails ServerのPIDです. 大学で数学を専攻していた方は単項イデアル整域だと勘違いするかもしれませんが, これはProcess IDの略です.

Linuxでは各プロセスにIDをつけて管理しています. またDockerでは, プロセスIDが1であるプロセスが終了した場合, コンテナも終了するようになっています.

これでトラブルが発生した流れが見えてきましたね.

トラブル発生の流れ

Ctrl+Dで強制終了してしまったことにより, tmp/pids/server.pidが残ったままになってしまいました. docker-compose downで終了したならば, これらの一時ファイルやネットワーク, コンテナを自動で消去してくれるはずでした.

この状態で起動を試みると, Railstmp/pids/内の消去されなかったファイルを見て, Rails Serverが起動していると勘違いを起こします.

するとRails Serverは起動を中止します.

プロセスIDが1であるプロセスが終了したため, コンテナも停止します.

まとめ

  • 正しいコマンドで終了しましょう.
  • トラブルが起きたら落ち着いて対処しましょう.