はじめに
ローカル開発環境でDockerを使ってPostgreSQLを立ち上げた際、ポート設定のすれ違いとMacローカルのDBが引き起こした「意図しないDBへの接続トラブル」にガッツリとハマってしまいました。
自分への戒めと備忘録を兼ねて、トラブルの顛末と解決策を残しておきます。同じように「謎のDBエラー」に悩まされている方の参考になれば幸いです。
1. 起きた現象(発端):データが保存されない!?
ローカル環境にて、Goアプリ用のPostgreSQLをDockerで立ち上げました。
すでにローカルで他のDBが動いている可能性を考慮し、ポート競合を避けるために docker-compose.yml ではホスト側の 5433 をコンテナの 5432 に繋ぐよう設定しました。
# docker-compose.ymlの一部
ports:
- "5433:5432"
コンテナは無事に起動したように見えましたが、アプリからPOSTリクエストを送っても、なぜか原因不明のエラーが多発。
Docker上で直接クエリを発行しても、アプリから送ったはずのデータがテーブルに登録されておらず、かなり焦りました。
docker-compose.yml を何度見直しても、設定に誤りはありません。
サーバーの再起動などを繰り返すうちに、ハッと気がつきました。アプリ側(.env)で設定しているDBの接続ポートが 5432 のままだったのです。
2. トラップの正体:killしても復活するゾンビプロセス
「なんだ、.envのポート番号を変え忘れていただけか」と安心し、.env のポートを 5433 に修正しました。
しかし、状況は改善しません。それどころか、まだアプリが 5432 へ繋ぎに行こうとしてエラーを吐き、さらに混乱に陥りました。
実は今回のトラブル発生当初から、GitHub Copilotを壁打ち相手にして状況の整理を行っていました。
一向に改善しない状況を前に、「もしかして古いプロセスの残骸がポートを握って邪魔をしているのでは?」 と直感し、以下のコマンドで現在動いているプロセスを確認しました。
lsof -i :8080
lsof -i :5432
lsof -i :5433
確認後、怪しいプロセスを見つけて kill 2743 のように終了させてみたものの、なぜかすぐに新しいプロセスが出現して復活してしまいます。
マイグレーションやテーブルの整合性もメチャクチャになっている状況で、「設定は合っているはずなのに、なぜkillしても別のプロセスが立ち上がるのか?」と、自分なりに原因を絞り込みながらCopilotとの壁打ちを続けていました。
そのやり取りの中で、ある衝撃の事実にたどり着きます。
過去に MacのHomebrewでインストールしていたPostgreSQL(5432ポート)が、バックグラウンドで自動起動・常駐していた のです。
つまり、アプリはDockerのDB(5433)ではなく、たまたま常駐していたMacローカルのDB(5432)に繋がりに行ってしまっていたのが、一連のトラブルの根本的な原因でした。
3. 解決への道のり(ここでの気づき)
このトラブルを通して、以下の3つの重要な気づきを得ました。
-
Dockerのポートフォワーディングの正しい認識
ports: "5433:5432"は、「ホスト(Mac)の5433へのアクセスを、コンテナ内の5432に転送する」という意味です。Goアプリから見たら 「5433に繋がないといけない」 ということをしっかり意識し、.envを正しく設定し直す必要がありました。 -
古いプロセスの残骸を疑う
.envを直した後も上手く動かない場合、古いプロセスがポートを握ったままになっているケースを疑う視点は間違っていませんでした。 -
ローカルDBの適切な管理
Homebrew版のDBが勝手に立ち上がらないように、サービス自体を停止させる必要がありました。
最終的にbrew services stop postgresql@14を実行し、lsof -iTCP:5432で該当プロセスが「0件」になったことを確認して、ようやく無事にDocker側のDBへ接続できるようになりました。
4. 【備忘録】Homebrew版 PostgreSQLのコマンドまとめ
今後の個人開発でローカルのDBを使いたくなった時のために、Homebrewでの起動・停止コマンドを残しておきます。
-
今だけ停止したい(自動起動をオフにする)
brew services stop postgresql@14 -
今すぐ起動したい(バックグラウンドで自動起動させる)
brew services start postgresql@14 -
再起動したい
brew services restart postgresql@14 -
一時停止したいが、PC再起動時の自動起動は残したい場合
brew services kill postgresql@14
5. まとめ(今回の教訓)
今回の事件からの教訓です。
- Dockerでポートをずらしたら、アプリ側の環境変数(
.envなど)も必ずずらしたポート番号(今回は5433)に合わせる! - 謎のDBエラーが起きたら、想定していないローカルDBに繋がっていないか疑う!
- プロセスをkillしても復活する場合は、Homebrewなどのサービス管理ツールが自動起動させていないか確認する!
開発環境の構築では思わぬ落とし穴がありますが、同じような状況になった際は、AIを壁打ち相手に使いつつ、ローカルで常駐しているサービスを疑ってみてください。