0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQLコンテナが起動しない・繋がらない時の切り分け

0
Posted at

Docker公式イメージでPostgreSQLを立ち上げたのにコンテナが即Exitする、ホストのpsqlから接続できない、docker compose downを実行したらデータが消えた。この手の症状は原因のパターンが限られています。前回の起動で作られたボリュームが残っているか、接続先のホスト名とポートを取り違えているか、だいたいこの2つに収まります。

この記事は要約版です。エラーメッセージ別の対処手順、shm_sizeやチェックポイント設定の調整、ヘルスチェックまで含めた壊れにくいcompose構成例は、ブログの完全版にまとめています: PostgreSQL Docker起動エラー切り分け手順

結論は「残ったボリューム」と「接続先の指定」

公式postgresイメージのエントリポイントは、PGDATAが空のときだけinitdbを実行します。つまりPOSTGRES_PASSWORD、POSTGRES_USER、POSTGRES_DB、/docker-entrypoint-initdb.d/配下のスクリプトが有効になるのは初回起動時だけです。ボリュームが残った状態でdocker-compose.ymlのパスワードやDB名を書き換えても、既存クラスタの中身は変わりません。その結果、password authentication failed for user "app"やdatabase "app" does not existが出たり、初期化SQLが実行されないままになります。

接続系は、どこから繋ごうとしているかで指定が変わります。ホストOSのpsqlやGUIツールからはlocalhostとports:の左側の番号、同じCompose内の別コンテナからはサービス名とコンテナ側の5432、コンテナ内のpsqlはホスト指定なしでUNIXドメインソケットを使います。アプリコンテナからlocalhost:5432を指定するとアプリ自身のコンテナを見にいくため、Connection refusedになります。

切り分けの順番はログ、ボリューム、ネットワークです。推測で設定を書き換える前にdocker compose logs --tail=50 dbで終了理由を読み、database system is ready to accept connectionsが出ているならPostgreSQL本体は起動済みと判断してネットワーク側へ進みます。

先に確認したいボリュームの状態

データディレクトリの実体は、使い捨てコンテナでマウントすると手早く確認できます。

# データディレクトリが初期化済みか、どのメジャーバージョンで作られたか
docker run --rm -v pgdata:/v alpine sh -c 'ls -A /v | head; cat /v/PG_VERSION 2>/dev/null'

ls -Aが空なら未初期化なので、環境変数と初期化SQLが効きます。PG_VERSIONの値とイメージタグのメジャーバージョンが食い違っていれば、データファイルの非互換で起動しません。

完全版で扱っている内容

  • 原因の切り分け手順として、ExitCode: 1と137/OOMKilledの読み分け、初期化フェーズと起動フェーズのログの区別、コンテナ内ソケット→コンテナ内TCP→別コンテナ→ホスト公開ポートの4段階テストと、どこで失敗したかに応じた原因の特定
  • エラーメッセージ別の対処として、Database is uninitialized and superuser password is not specified、directory ... exists but is not empty、has invalid permissions、database files are incompatible with server、incorrect checksum in control fileへの具体的な対応
  • 起動はするが遅い・不安定なケースとして、/dev/shmが既定64MBであることと動的共有メモリのエラー、shm_sizeの指定、Docker Desktopでのバインドマウントと名前付きボリュームの使い分け、max_wal_sizeやlog_min_duration_statementをcommandで渡す方法
  • よくある質問として、初期化SQLが実行されない4つの条件、pg_dumpallとpg_upgradeによるメジャーバージョン移行の手順、本番でコンテナ運用する場合に自分側へ残る責務、停止時と稼働時それぞれのバックアップ手順
  • 再発防止の構成例として、パッチバージョンまでのタグ固定、127.0.0.1:付きのポート公開、healthcheckとdepends_onのcondition: service_healthyの組み合わせ

PostgreSQL Docker起動エラー切り分け手順

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?