Dockerで起動したRails(DB:postgres)のDBにDBeaverで接続する

# はじめに
Dockerで作り始めたRailsアプリのデータベースをpostgresにしたので
Sequel Proよろしく中身を見に行くか〜！と思って簡単に考えていたら
思ったよりも大変だったのでまとめておく。
~~というより[前の記事](https://qiita.com/krile136/items/24a16cd9d598e75ecc01)のせいで苦労した~~

# 環境
- MacOS Mojave 10.14.5
- Rails 5.2.3
- ruby 2.5.7
- postgres 11

# 設定
ここでの設定は[DockerでRailsの環境構築してHerokuへデプロイする](https://qiita.com/fuku_tech/items/dc6b568f7f34df10cae7#docker%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)で紹介されている内容と一緒になります。
### Docker-compose.yml
```yml: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
```yml:config/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のインストール
[こちらの記事](https://qiita.com/Ryooota/items/755e249f5241d2c964e6)を参考にインストールしてください。

## DBeaverを使ってpostgresへ接続
- dockerでRailsアプリの起動

```
$ docker-compose start
```
- DBeaverを起動して設定する
<img width="876" alt="新しい接続を作成する.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/f87761b8-b1ca-1fa6-861a-1ef9e54645b0.png">
<img width="876" alt="新しい接続を作成する-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/386c150f-5132-c146-e5fd-df7076db8827.png">

テスト接続に成功すると
<img width="881" alt="Connection_Test_と_新しい接続を作成する.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/8222d4bc-7efa-ace9-9127-2e40e02b46d4.png">

こんな感じになる。
接続が完了したら、終了を押して完了させる。

## データベースの情報を表示させる
無事にデータベースへの接続が完了したら
<img width="1490" alt="DBeaver_6_2_3_-_myapp_development.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/5d4ff5c2-39be-9ec6-5be4-a90bf6cf5b04.png">
<img width="1149" alt="DBeaver_6_2_3_-_public.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/2d5443bc-2c94-14ed-1fb7-e7eb45520b55.png">
<img width="1147" alt="DBeaver_6_2_3_-_users.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/43d4c3bc-8e2e-df42-ee06-2f849a02dbba.png">
これでデータベースに保存されているカラムの内容が表示されます。
もちろん書き換えもできます。

## FATAL:  role “postgres” does not exist　と出る時
結論は、「他のpostgresサーバーが5432ポートで起動している」ため
postgresのコンテナサーバーへの接続にエラーが出ているようです。

まずは基本に立ち返って、エラー文に書いてあることを解消していきます。
[こちらの記事](https://qiita.com/Ksk8358/items/6629f597ddf7f4ccd97c)を参考に、データベースに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インスタンスが動いていた
[こちらの記事](https://stackoverflow.com/questions/48593016/postgresql-docker-role-does-not-exist)では、同じような問題に対して
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で動かしているデータベースのコンテナのようですが
他に２つ動いているようです。（実際にはPIDが419で同じなので１つです）
先ほどの記事では、他の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でなんとかした
[こちらの記事](http://b0npu.hatenablog.com/entry/2016/05/15/164551)で紹介されているコマンドでpostgresインスタンスの削除を試みます。

```
$ launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

$ pg_ctl status
pg_ctl: no server running
```
やりました！postgresインスタンスを削除できたようです！
これでもう一度、コンテナを立ち上げ直してDBeaverから接続を試すと、成功するはずです！

## 立ち上がっていたインスタンスは何者か？
[前の記事](https://qiita.com/krile136/items/24a16cd9d598e75ecc01)でサーバーを建てて放置していたのが原因っぽいです。
終わったら片付けることは大事ですね・・・