Rails6・PostgreSQLのアプリをEC2にデプロイする際の手順・注意点を解説します。



mysqlのアプリをデプロイした記事はいろいろありますが、postgresqlをデプロイした例はあまりありませんので記録に残します。

手順を解説とか言ってますが、ほぼ有名な記事の通りに作業しました。

##大まかな手順

下記の大まかな手順は[有名なこちらの記事](https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce)と同じです。
・AWSの設定
・Unicorn、Nginxの設定
・[Nginxの起動](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1#nginx%E3%81%AE%E8%B5%B7%E5%8B%95)
##異なる部分

異なるところは[Mysqlの設定](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1#mysql%E3%81%AE%E8%A8%AD%E5%AE%9A)です。私はpostgresqlでデプロイをしました。したがってpostgresqlの設定方法は詳しく書いておりますので、pgでデプロイをしたい人は参考になると思います。

※pgでデプロイをしたい人は当たり前ですがテスト、開発、本番環境がPostgresqlで動いていること、Gemfileにpgがインストールされていることが条件です。



##注意するべきところ


###/tmp/sockets/unicorn.sockは、記載場所によって2種類の意味を持つ。

tmpファイルは2つ存在します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/841ddbf6-facb-3a79-87e4-31aa6653c329.png)

と

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/b3f5d800-302e-a81c-ec2b-a546731c3464.png)

です。

アプリ名.confのapp_name_serverがフルパスによって書かれているか確認しましょう。
とりあえずserver unix:の右側が下記のように書かれていればほぼ大丈夫です。

```アプリ名.conf
server unix:/var/www/rails/アプリ名/tmp/sockets/.unicorn.sock fail_timeout=0; #後々.unicon.sockに苦しめられます。
```

###EC2内のconfig/environment.rbのforce_sslをtrueにしている。

trueにしているとhttpのアクセスは受け付けない設定になってしまいます。falseにしましょう。


###アプリ名.confファイルの.unicorn.sockのピリオドがついている。

エラーはこちら。

```
2020/05/03 15:40:08 [crit] 15773#0: *54 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/.unicorn.sock failed (2: No such file or directory) while connecting to upstream, client: 123.222.30.69, server: 13.115.179.212, request: "GET / HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/.unicorn.sock:/", host: "13.115.179.212"
2020/05/03 15:56:54 [crit] 15773#0: *57 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/.unicorn.sock failed (2: No such file or directory) while connecting to upstream, client: 2.179.120.8, server: 13.115.179.212, request: "GET / HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/.unicorn.sock:/", host: "13.115.179.212:80"
```

アプリ名.confファイルに記述したファイル名と実際に作成されたファイル名があっているか確認しましょう。以下の手順で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/4f3e7dbd-20fb-f818-e4a9-44f5a280e33e.png)
私は画像のようにファイルが```unicorn.sock```となっているのにもかかわらず、```アプリ名.conf```内で```sockets/.unicorn.sock```とピリオドをつけていたのでエラーが出ていました、、、

##エラー111: Connection refused

```
2020/05/07 12:27:29 [error] 3552#0: *1 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 121.3.47.42, server: 13.115.179.212, request: "GET / HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock:/", host: "13.115.179.212"
2020/05/07 13:28:39 [error] 3596#0: *1 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 121.3.47.42, server: 13.115.179.212, request: "GET / HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock:/", host: "13.115.179.212"
2020/05/07 13:29:24 [error] 3634#0: *4 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 121.3.47.42, server: 13.115.179.212, request: "GET / HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock:/", host: "13.115.179.212"
2020/05/07 13:33:59 [error] 3634#0: *7 connect() to unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock failed (111: Connection refused) while connecting to upstream, client: 162.243.138.230, server: 13.115.179.212, request: "GET /ReportServer HTTP/1.1", upstream: "http://unix:/var/www/rails/Portfolio/tmp/sockets/unicorn.sock:/ReportServer", host: "13.115.179.212"
```

原因はsudo systemctl restart postgresql-9.6でDBを起動していなかった。
またはsudo systemctl start postgresql-9.6
あと、capistranoを入れる際に手違いでconfig/database.yml内のproduction環境のportをelasticipにしてしまっていた。
正しくは5432。

##詰まったところ


###rails6だと```rake db:create RAILS_ENV=production```の際にpostgresqlのバージョンが9,3以下だと怒られる？可能性がある。

私は怒られて、EC2内にあるpostgresql9.2をアンインストールし、新しくバージョン9.6をインストールしました。

###EC2のなかでPostgreSQLに入れない。

##Posgresqlのインストール

```
# pgdg96リポジトリを追加する
[root@ip-10-0-0-193 ~] sudo yum install -y https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-redhat96-9.6-3.noarch.rpm

# PostgreSQLサーバーをインストールする
[root@ip-10-0-0-193 ~] sudo yum install -y postgresql96-server postgresql96-contrib

[root@ip-10-0-0-193 ~] psql --version
psql (PostgreSQL) 9.6.3
```



無事9.6をインストールできたものの、

```
[shogo@ip-10-0-0-193 Portfolio]$ psql -U postgres -d postgres
psql: FATAL:  ??? "postgres" ???(peer)?????????
```

postgresqlの中に入ろうとしたらこんなエラーが表示されて入れません。
したがって以下のように解決しました。

```
[shogo@ip-10-0-0-193 ~]$ sudo find / -name pg_hba.conf  #pg_hba.confファイルを探す
/var/lib/pgsql/data/pg_hba.conf
/var/lib/pgsql/9.6/data/pg_hba.conf
/var/www/rails/Portfolio/pgsql-data/pg_hba.conf         #3つ見つかる
[shogo@ip-10-0-0-193 ~]$ sudo vi /var/lib/pgsql/9.6/data/pg_hba.conf
```

そして```/var/lib/pgsql/9.6/data/pg_hba.conf```ファイルを修正します。
pg_hba.confに入ったら下までスクロールしてください。下記のように修正します。

```pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust ←peerになっているのでtrustに変更する
# IPv4 local connections:
host    all             all             127.0.0.1/32            password ←peerになっているのでpasswordに変更する

# IPv6 local connections:
host    all             all             ::1/128                 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                peer
#host    replication     postgres        127.0.0.1/32            ident
#host    replication     postgres        ::1/128                 ident
```
で、su - postgresで入りパスワードを新しく作成します。

```
[shogo@ip-10-0-0-193 Portfolio]$ su - postgres
パスワード:
最終ログイン: 2020/05/05 (火) 09:37:40 UTC日時 pts/0
-bash-4.2$ psql
psql (9.6.17)
"help" でヘルプを表示します.

postgres=# Alter Role postgres with password 'パスワード';
#うまくいかなかったらpasswd postgresmで新しうパスワードを設定する。
ALTER ROLE
postgres=# \q
-bash-4.2$ exit
ログアウト
```

もし上記でパスワードがうまく変更されなかったら、passwd postgresコマンドを入力してください。

で、アプリディレクトリに行き、postgresqlに入れるかチャレンジ。

```
[shogo@ip-10-0-0-193 ~]$ cd /var/www/rails/Portfolio
[shogo@ip-10-0-0-193 Portfolio]$ psql -U postgres -d postgres
psql: FATAL:  ??? "postgres" ???(peer)?????????
```
また入れないので再起動。


```
[shogo@ip-10-0-0-193 Portfolio]$ sudo systemctl restart postgresql-9.6
[shogo@ip-10-0-0-193 Portfolio]$ psql -U postgres -d postgres #ユーザ名はpostgresでログイン。database.ymlにもpostgresと入力。
ユーザ postgres のパスワード:   #database.ymlに書いたパスワード（su - postgresで入った際に設定したやつ）を入力
psql (9.6.17)
"help" でヘルプを表示します.
```

入れました。

##エラー
```
PG::ConnectionBad: could not translate host name "db" to address: Name or service not known
```

EC2内のdatabase.ymlのhost名をdbにしていた。私の場合本来はlocalhostになります。

##DBの再起動を忘れている。
下記を順に入力する。

```
$  sudo service nginx restart
$  sudo systemctl restart  postgresql
$  ps -ef | grep unicorn | grep -v grep
$  bundle exec unicorn_rails -c /var/www/rails/Portfolio/config/unicorn.conf.rb -D -E production
```

データベースを再起動する必要があるのは忘れがち。
たとえ```sudo systemctl status postgresql```で動いていても、データベースの再起動はするべき。

###まとめ
EC2はローカルと違ってマウスでファイルを見にいくことができないのでディレクトリに入る、ファイルを探す、ファイルを確認する、viでファイルを変更する、のようなコマンドを使う機会が多いです。