遭遇したエラーの対応について備忘録としてまとめます。
1. 環境
- macOS Tahoe 26.4
- PostgreSQL 18
- Docker
2. 現象
docker compose up -d を実行した際、コマンド自体は正常に終了したように見える(その場ではエラーが表示されない / 空振りの挙動)が、実際には PostgreSQL コンテナが起動に失敗し、バックグラウンドで停止または再起動を繰り返す。
発生時のログ
FATAL: bogus data in lock file postmaster.pid
PostgreSQL Database directory appears to contain a database; Skipping initialization
3. 原因
3-1. 不正なロックファイルの残留(根本原因)
PostgreSQL は、二重起動を防止するために起動時に postmaster.pid というロックファイルを作成します。通常は正常停止時に自動削除されますが、PCの強制終了、Docker の強制停止、コンテナのクラッシュ などが発生すると、ファイルが破損した状態(中身が空など)で残ってしまいます。
次回起動時に PostgreSQL がこの破損ファイルを読み込み、「不正なデータがある(bogus data)」と検知して安全のために起動を強制停止します。
この内容については、18.3. データベースサーバーの起動 (日本PostgreSQLユーザー会)で以下のように説明されています。
サーバが実行している間は、そのPIDはデータディレクトリの中のpostmaster.pidファイルに記述されています。 これは同じデータディレクトリで複数のサーバインスタンスが実行されるのを防止し、また、サーバの停止にも使うことができます。
3-2. なぜコマンド実行時にエラーが出ず「空振り」に見えるのか?
docker compose up -d の -d(バックグラウンド起動)オプションは、「コンテナの作成と起動処理の開始」 までしか追いません。
起動した「直後」にコンテナの内部(PostgreSQL プロセス)がエラーで即死した場合、Docker コマンド自体は正常終了したように見えてしまいます。そのため、docker compose logs を見ないと気付けない現象が発生します。
4. 解決手順
本プロジェクトでは PostgreSQL のデータ領域を名前付きボリューム(例: postgres_data)で管理し、/var/lib/postgresql にマウントしているため、ホストマシンから直接ファイルを削除できません。
そのため、一時的なコンテナを立ち上げてボリューム内のファイルを操作します。
ステップ 1. コンテナの完全停止
まず、中途半端に起動を繰り返しているコンテナを確実に停止させます。
docker compose down
ステップ 2. 原因ファイルの探索と削除
PostgreSQL のバージョンやベースイメージの仕様変更により、ボリューム内の階層(パス)が変わることがあります。まずは find コマンドでファイルの正確な位置を特定してから削除します。
ステップ 2-1. ファイルの場所を探索する
使い捨てコンテナ ( --rm )を起動し、マウントされたディレクトリ以下から -name オプションで postmaster.pid を検索します。
docker compose run --rm db find /var/lib/postgresql -name postmaster.pid
※ 実行すると /var/lib/postgresql/18/docker/postmaster.pid のようなヒットしたパスが画面に出力されます。
ステップ 2-2. 特定したファイルを削除する
出力されたパスを指定して、ファイルを削除します。
※ 必ず PostgreSQL が停止していることを確認してから削除してください。
docker compose run --rm db rm [確認したファイルパス]
(例: docker compose run --rm db rm /var/lib/postgresql/18/docker/postmaster.pid)
ステップ 3: 再起動と確認
通常通りコンテナをバックグラウンドで起動し、ログで正常に起動したか確認します。
起動
docker compose up -d
ログ確認
docker compose logs db
ログが普段通り正常に流れていたら、復旧は完了です。
5. 予防策・注意点
Docker コンテナを停止する際は、PCの電源をいきなり切ったり、ターミナルを強制終了したりせず、可能な限り docker compose down または docker compose stop を実行して安全に停止させてください。
今後、同様に「コマンドは成功するのにコンテナが動いていない」状態になった場合は、まず -d を付けずに docker compose up を実行するか、すぐに docker compose logs を確認する習慣をつけると原因特定が早くなります。
6. 今回のケースにおける発生原因 (参考)
大規模データ処理に伴うローカルストレージの枯渇によって PostgreSQL が強制終了し、正常なシャットダウン処理が行われなかったためにこのファイルが残った、というのが今回の根本的な原因である可能性が高いです。内部のデータ自体は無事でした。
ストレージの容量には気をつけましょう。