Capistranoを使用しAWS EC2デプロイした際に出たPostgreSQLエラーの話

#前提
- Rails6
- AWS
 - VPC,EC2,RDS,S3
- アプリケーションサーバー
 - Puma(Capistrano)
- Webサーバー
 - Nginx
- 使用するデータベース
 - PostgreSQL
- git
- GitHub

Capistranoを使用し自動デプロイの構築をしており、AWS EC２にデプロイしようした際に下記のエラーが出た

```
・PG::ConnectionBad: could not connect to server: No such file or directory
・Is the server running locally and accepting
・connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```

# 解決方法
環境におけるdatabase.ymlを参照できていなかった。今回はcredintialsにdatabase.ymlのデータベースの設定を入れ、参照させることで解消した。

```
EDITOR="vim" bin/rails credentials:edit

db:
  username: (username)
  password: (password)
  host: (database endpoint)
```
config/database.ymlを下記のように編集。（対象がproductionの場合は、production部分だけ）

```config/database.yml
production:
  <<: *default
  database: sample6034_production
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>
  host:     <%= Rails.application.credentials.db[:host] %>
  port:     5432
```
上記設定後、GitHubにpushする。（pushしないと設定が反映されない）

# 解決までにやったこと
エラー文からPostgreSQLが動いてないと考えた
とりあえず、エラー文を一つずつコピぺして検索した。インフラ系は、調べたものを実行して直れば良いけど失敗したらとんでもないことになると思ったのでいくつか記事をみた上で実行した。

#その１

https://make-from-scratch.com/error-connections-on-unix-domain-socket-tmp-s-pgsql-5432/
上記を参考に
PostgreSQLの再起動を実施

```
$ brew services restart postgresql
```
再起動するも解決せず。
これを実行した後に、気づいたのは動かしたいのはEC２内のRDSなのに、ローカルのDBを再起動させていた。
じゃあ、RDSを再起動させれば！と思いAWSコンソールで再起動するも結局変わらず（泣

#その２

```
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```
もう少し調べてると、ポート番号の指定がされてないことや間違っていることがあるとエラーが起きるという記事が多いのでその辺り探すことに。
ターミナルでEC2からRDSにログインできるかの確認（上記の問題解決になっているかは微妙）

```
$psql -l
psql: サーバに接続できませんでした: No such file or directory
                              ローカルにサーバが稼動していますか?
                              Unixドメインソケット"/var/run/postgresql/.s.PGSQL.5432"で通信を受け付けていますか?
```
すると、似たようなエラーが出てきた。ローカルのサーバーは動いているため、一旦放置。
別の方法でログインを試すと

```
$psql -h エンドポイント -U postgres
psql (11.5、サーバ 12.4)
postgres=> \l
                                                データベース一覧
          名前           |  所有者  | エンコーディング |  照合順序   | Ctype(変換演算子) |     アクセス権限
-------------------------+----------+------------------+-------------+-------------------+-----------------------
 ポートフォリオ_production | postgres | UTF8             | en_US.UTF-8 | en_US.UTF-8       |
```
エンドポイントを指定すると、ログインはできた。
今考えると、「エンドポイントを指定するとログインできる。接続できないのはエンドポイントが渡ってない」のが原因だと分かる（泣）

#その３

https://qiita.com/fkana/items/a4b3c4d5d8ca27cd20ec
https://nju33.com/notes/aws/articles/RDS%20%E3%81%AE%20Postgresql%20%E3%81%8C%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E3%81%99%E3%82%8B

RDSとEC2の設定を見直すためAWSコンソールからセキュリティグループのインバウンド設定を確認。
間違っていなかった。なんなら間違えててほしかったです。

#その４
このあたりで挫折仕掛けてたけど、駆け出しエンジニアの差別化差別化・・・と気合い入れてやってました笑
https://www.postgresql.jp/document/
PostgreSQLの公式リファレンスを流し読みしていたら、デフォルトで/tmpに.s.PGSQL.5432があるよというような事を書いていて
/tmpで

```tmp
$ ls -la
total 16
drwxrw  15 root        wheel  480  1 11 21:04 .
drwxr-   6 root        wheel  192  8 31 00:18 ..
drwxrw   2 ~~~~~~~~~~  wheel   64  1  8 15:16 .dca
srwxrw   1 ~~~~~~~~~~  wheel    0  1 11 20:33 .s.PGSQL.5432
```
確かにあった。パスの指定先を変更しようと思ったが、元に戻せる自信がなかったため、/tmpに.s.PGSQL.5432があるのだけ確認して、アクションは起こさず放置した。
この辺りは疲れていて、思考ゼロでした笑

#その５
再度エラーを考える。

```
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```
そもそもrailsがローカルのpostgresqlに接続しようとしている。
接続したいのはRDSなのにUnix domain socketのエラーが出る。
原因はrailsのDB設定だ！と思い

```config/database.yml
production:
  <<: *default
  database: my_portfolio_production
  username: postgres
  password: <%= ENV['MY_PORTFOLIO_DATABASE_PASSWORD'] %>
  host: <%= ENV['MY_PORTFOLIO_DATABASE_HOSTNAME'] %>
```
config/database.yml確認するも大丈夫な気がする・・・
rails consoleでENVの値が取れるか確認しても大丈夫・・・

#その6

```
$ cd /var/www/ポートフォリオ名/releases/(20...)/
$ bundle exec rails db:create RAILS_ENV=production
```
EC2にENVの情報が渡っていないと思い上記コマンドするも

```
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```
挙動変わらず。
config/deploy/production.rbに

```
set :rails_env, 'production'
```
を追加するも挙動かわらず😂

#その７

ENVが使えないなら、credintialsを使って環境変数を渡せば良いかなと思い

```
EDITOR="vim" bin/rails credentials:edit
```
で

```
db:
  username: (username)
  password: (password)
  host: (database endpoint)
```
の記述して

config/database.ymlに

```config/database.yml
production:
  <<: *default
  database: my_portfolio_production
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>
  host:     <%= Rails.application.credentials.db[:host] %>
  port:     5432
```
と渡すも挙動変わらず（泣）
試しにGitHubにプッシュしてデプロイすると・・・

```
 $bundle exec cap production deploy
```
できました！！
この瞬間はすごいうれしかったです。
その後結局ブラウザにアプリが表示されなかったけど、pumaのエラーログ見て
S3のaccess_key_idとsecret_access_keyが渡されてない事を確認。PostgreSQLと似たエラーだったので直ぐ解決できました。

#おわりに
今回の
```
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```
エラーは、productionにおけるENVの読み込みが行われなかったためのエラーだった。
おそらくRailsがデータベースにアクセスしに行ってうまくいかない場合はdevelopmentを参照するのではないかと思いました。
なので、ローカルのpid(Process ID)を探してたのかと。
約３週間戦ったエラーでしたが、お陰で検索・仮説・検証・忍耐力がついた気がします。

## 参考記事
https://make-from-scratch.com/error-connections-on-unix-domain-socket-tmp-s-pgsql-5432/

https://qiita.com/fkana/items/a4b3c4d5d8ca27cd20ec

https://nju33.com/notes/aws/articles/RDS%20%E3%81%AE%20Postgresql%20%E3%81%8C%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E3%81%99%E3%82%8B

https://www.postgresql.jp/document/

https://qiita.com/take18k_tech/items/5710ad9d00ea4c13ce36