Docker ComposeでのDB接続エラー内容
Docker Compose環境(Rails + PostgreSQL)の構築中、backend (Rails)コンテナ起動時に以下のデータベース接続エラーが発生しました。
ActiveRecord::DatabaseConnectionError
There is an issue connecting to your database with your username/password, username: postgres.
Please check your database configuration to ensure the username/password are valid.
解決方法:DATABASE_PASSWORDの修正
今回のケースでは、.envファイル内のDATABASE_PASSWORDを、既に永続化されていたPOSTGRES_PASSWORDと同じ値に修正し、再起動することで無事エラーを解消し、コンテナを接続できました。
-
DATABASE_PASSWORDは、backendコンテナ(Rails)がdbコンテナ(PostgreSQL)に接続する時に使うパスワード。.envに記載されていて、Rails内のconfig/database.ymlで読み込んで使用します。 -
POSTGRES_PASSWORDは、PostgreSQL初期化時に使われ、volumeに永続化されているパスワード。
実行した手順
1. .envファイルを修正
- すでに
dbコンテナ(PostgreSQL)の初期化に使われ、Volumeに永続化されているPOSTGRES_PASSWORDの値を確認します。 -
backendコンテナ(Rails)が接続時に利用するDATABASE_PASSWORDの値を、上記のPOSTGRES_PASSWORDと一致するように修正しました。
# .env ファイルの例
# PostgreSQL初期化時に使われ、volumeに永続化されているパスワード
POSTGRES_PASSWORD=password_a
# Railsが接続時に使うパスワード(ここを修正)
-DATABASE_PASSWORD=password_b
+DATABASE_PASSWORD=password_a
2. コンテナを再起動
POSTGRES_PASSWORDの設定自体(PostgreSQLコンテナの初期化設定)は変更していないため、-vオプション(Volume削除)は付けずに再起動します。
# 停止
docker-compose down
# 再ビルド・起動
docker-compose up --build
これで dbコンテナ(PostgreSQL)に接続完了。
無事エラー解決!
なぜこれで解決できたのか?:永続化の仕組みの気づき
今回の解決手順から、どの設定が永続化され、どの設定が永続化されないのかという重要な気づきが得られました。
1. POSTGRES_PASSWORDは永続化されていた(Volumeに保存)
-
POSTGRES_PASSWORDは、PostgreSQLコンテナが初めて起動する際に内部のpostgresユーザーのパスワードを設定するために使われます。 - このパスワード情報は、データベースのデータと共にDocker Volumeに永続化されます(
docker-compose-ymlにvolumeの記述をしています)。 - そのため、もし最初に
POSTGRES_PASSWORD=password_aでDBが構築された場合、後から.envファイルのPOSTGRES_PASSWORDをpassword_cに変更してdocker-compose upしても、既存のVolumeが使われ続ける限り、DB内のパスワードはpassword_aのままです。
2. DATABASE_PASSWORDは永続化されていなかった(Volumeに保存されていない)
- 一方で、
DATABASE_PASSWORDはRailsアプリケーション(backendコンテナ)がDBに接続する際に使用するただの環境変数です(Rails内のconfig/database.ymlで.envのDATABASE_PASSWORDを読み込みます)。 - これは、DBコンテナの内部設定やVolumeに保存される情報ではありません。
backendコンテナが起動するたびに、.envファイルから読み込まれる一時的な接続情報です。
結論
-
POSTGRES_PASSWORDでDB初期化時に設定されたパスワードが、Volumeによって永続化されていた。 -
DATABASE_PASSWORDは永続化されておらず、.envファイルを修正して再起動すれば、すぐに新しい値でRailsコンテナに適用された。
今回のエラーは、永続化されたPOSTGRES_PASSWORD (password_a) と、非永続化のDATABASE_PASSWORD (password_b) の値が異なっていたために発生しました。
そのため、永続化されていない側のDATABASE_PASSWORDを、永続化されている側のPOSTGRES_PASSWORDに合わせて修正することで、Railsからの接続が可能となり、エラーが解消されました。
もしDATABASE_PASSWORDも永続化されていたら?
もし仮にDATABASE_PASSWORDもDB内部や何らかの形でVolumeに永続化されていた場合、以下の事態になっていました。
- 最初に誤った
DATABASE_PASSWORD(password_b) でVolumeが作成される。 -
.envでDATABASE_PASSWORDを修正し、docker-compose up --buildを実行。 - しかし、Volumeが残っているため、依然として誤った古いパスワードが使われ続け、接続は失敗。
この場合、docker-compose down -vで古いVolumeを完全に削除し、DBの初期化とコンテナの環境変数の設定をゼロからやり直さないと、解決は不可能でした。今回のケースでは、DATABASE_PASSWORDが永続化されていなかったおかげで、簡単な修正で済みました。
参考
volumeについてわかりやすく解説されている記事
https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
https://frkz.jp/study/infra/docker/volume-bind-mount
PostgreSQL公式イメージDoc
https://hub.docker.com/_/postgres?utm_source=chatgpt.com