はじめに
Dockerで作り始めたRailsアプリのデータベースをpostgresにしたので
Sequel Proよろしく中身を見に行くか〜!と思って簡単に考えていたら
思ったよりも大変だったのでまとめておく。
というより前の記事のせいで苦労した
環境
- MacOS Mojave 10.14.5
- Rails 5.2.3
- ruby 2.5.7
- postgres 11
設定
ここでの設定はDockerでRailsの環境構築してHerokuへデプロイするで紹介されている内容と一緒になります。
Docker-compose.yml
version: '3'
services:
db:
image: postgres:11
ports:
- '5432:5432'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test_db
volumes:
- postgresql-data:/var/lib/postgresql/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
volumes:
postgresql-data:
driver: local
database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password:
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: myapp
password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
DBeaverのインストール
こちらの記事を参考にインストールしてください。
DBeaverを使ってpostgresへ接続
- dockerでRailsアプリの起動
$ docker-compose start
- DBeaverを起動して設定する
こんな感じになる。
接続が完了したら、終了を押して完了させる。
データベースの情報を表示させる
無事にデータベースへの接続が完了したら
これでデータベースに保存されているカラムの内容が表示されます。
もちろん書き換えもできます。
FATAL: role “postgres” does not exist と出る時
結論は、「他のpostgresサーバーが5432ポートで起動している」ため
postgresのコンテナサーバーへの接続にエラーが出ているようです。
まずは基本に立ち返って、エラー文に書いてあることを解消していきます。
こちらの記事を参考に、データベースにrole postgresがあるか確認しにいきます。
- 稼働しているコンテナの状況を確認
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c920fadb8d27 application_web "entrypoint.sh bash …" 30 hours ago Up 55 minutes 0.0.0.0:3000->3000/tcp application_web_1
2479f579d66e postgres:11 "docker-entrypoint.s…" 30 hours ago Up 55 minutes 0.0.0.0:5432->5432/tcp application_db_1
データベースのコンテナの名前は"application_db_1"のようですね。
(名前はそれぞれの環境によって異なります)
- データベースのコンテナに入る
$ docker exec -it application_db_1 bash
root@2479f579d66e:/# ここでコマンド待ちの状態になる
- データベースにアクセスする
psql -U postres を実行する
root@2479f579d66e:/# psql -U postgres
psql (11.5 (Debian 11.5-3.pgdg90+1))
Type "help" for help.
postgres=# ここでコマンド待ちの状態になる
- roleの状態を確認する
\du を実行する
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
postgres=#
どうやら、postgresは存在するようです。
原因は他にあるようですが・・・?
他のpostgreインスタンスが動いていた
こちらの記事では、同じような問題に対して
The problem was simple enough that my computer was already running an instance of Postgres that I was not aware was still running (not inside Docker) on :5432, checked with:
と説明されています。コマンドも示されているので試してみましょう。
(ターミナルで実行してください)
$ lsof -n -i:5432 | grep LISTEN
postgres 419 user_name 5u IPv6 0xe1a2b61a846df097 0t0 TCP [::1]:postgresql (LISTEN)
postgres 419 user_name 6u IPv4 0xe1a2b61a8514b617 0t0 TCP 127.0.0.1:postgresql (LISTEN)
com.docke 594 user_name 18u IPv6 0xe1a2b61a96bd6f57 0t0 TCP *:postgresql (LISTEN)
一番下のcom.dockeがdockerで動かしているデータベースのコンテナのようですが
他に2つ動いているようです。(実際にはPIDが419で同じなので1つです)
先ほどの記事では、他のposgresインスタンスをストップさせれば接続できるようなので
早速ストップさせてみます。
- postgresインスタンスの状態を確認する
$ pg_ctl status
pg_ctl: server is running (PID: 419)
/usr/local/Cellar/postgresql/11.5/bin/postgres "-D" "/usr/local/var/postgres"
先ほどと同じPIDのサーバーが動いていることが確認できました。
こいつをストップさせましょう。
- postgresインスタンスをストップさせる
$ pg_ctl stop -D "/usr/local/var/postgres" -m s
waiting for server to shut down.... done
server stopped
止まったようですね!本当に止まっているか、念の為確認しておきましょう
$ pg_ctl status
pg_ctl: server is running (PID: 76742)
/usr/local/Cellar/postgresql/11.5/bin/postgres "-D" "/usr/local/var/postgres"
新たに生まれ落ちているようですね・・・自動再起動しているようです。
とりあえずもう一度削除を試みますが・・・
$ pg_ctl stop -D "/usr/local/var/postgres" -m s
waiting for server to shut down............................................................... failed
pg_ctl: server does not shut down
HINT: The "-m fast" option immediately disconnects sessions rather than
waiting for session-initiated disconnection.
$ pg_ctl stop -D "/usr/local/var/postgres" -m fast
waiting for server to shut down............................................................... failed
pg_ctl: server does not shut down
$ pg_ctl stop -D "/usr/local/var/postgres" -m i
waiting for server to shut down............................................................... failed
pg_ctl: server does not shut down
stopのオプションたちを全て試してみるも、posgresインスタンが止まらないようです。
これは困った。
lanchctlでなんとかした
こちらの記事で紹介されているコマンドでpostgresインスタンスの削除を試みます。
$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
$ pg_ctl status
pg_ctl: no server running
やりました!postgresインスタンスを削除できたようです!
これでもう一度、コンテナを立ち上げ直してDBeaverから接続を試すと、成功するはずです!
立ち上がっていたインスタンスは何者か?
前の記事でサーバーを建てて放置していたのが原因っぽいです。
終わったら片付けることは大事ですね・・・