EC2上でRailsアプリをnginx + pumaで動作させる

表題の通り、RailsアプリをEC2にデプロイするところまで何とか漕ぎつけたようなのでメモも兼ねて
書いてみた。といっても、参考にしたサイトを載せていくだけになりそう。はじめは[この記事](https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce)を参考に
Railsチュートリアルのhello_appが動作することを確認後、自分のアプリを配置するという流れでやった。
一気にやろうとすると大変だからね、それでも四苦八苦したけど。

##VPC ~ EC2インスタンス作成
[Udemyの動画](https://www.udemy.com/course/aws-and-infra/)で予習後、上記Qiitaの記事と併用しながら作っていく。AWSを初めて勉強するにあたって
書籍よりまずは動画を見て大まかな内容を知りたいという方は、[無料の教材](https://www.udemy.com/course/aws-for-beginner/)もあったりするので試しに
観てみるのもいいかも。

- VPC作成
- サブネット：　publicとprivateの作成、privateは今回使わなかったけど後々RDSに切り分けたい……
- インターネットゲートウェイの作成
- ルートテーブルの作成：　publicのルートテーブルを作成(サブネットの関連付けとIGWとの紐づけを行う)
- EC2インスタンスの作成：　AMIはLinux2、インスタンスタイプやストレージは全て無料枠
- セキュリティグループ：　上記インスタンス作成時に併せて出来たセキュリティグループにインバウンドルール(HTTP：任意の場所）を設定
- ターミナルから`ssh -i <pemキーファイル名> ec2-user@<ElasticIPもしくは自動割り当てIP>`でEC2へログイン
- `sudo yum update -y`が完了すれば、最初のQiita記事の[ここくらい](https://qiita.com/naoki_mochizuki/items/814e0979217b1a25aa3e#ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89)までは進んだことになる。

##EC2環境構築
作業を進めるとNode.jsのインストール時にepelが無いゾと言われ、何だろうと調べてたら[この記事](https://qiita.com/s_tatsuki/items/288ed809e87864f03f86)がヒットした。
(多分AMIをLinuxではなくLinux2にしたのが原因？)　コマンドだけで言うと
`sudo amazon-linux-extras install epel`の後に再度`sudo yum install nodejs npm --enablerepo=epel`を実行

そこからはgit cloneできるようになるまで順調に進んでいく。その次のwebサーバーやアプリケーションサーバー辺りから
人によってやることが変わってくると思う。自分は「nginx」 + 「puma」 + 「postgresql」で構築するので

###・nginx
`etc/nginx/conf.d`にて
[このサイト](https://ryo10leo.hatenablog.com/entry/2020/01/18/123631)と[この記事](https://qiita.com/KONTA2019/items/2a519f18b204dea9a771)を参考にconfファイルを作成、現状こんな仕上がり。

```/etc/nginx/conf.d/proto-status.conf
upstream puma {
    server unix:///var/www/rails/proto-status/tmp/sockets/puma.sock;
}

server {
    client_max_body_size 20M;
    listen       80;
    server_name  54.187.69.116;
    root /var/www/rails/proto-status/public;

    location ^~ /assets/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
    }

    location / {
        proxy_pass http://puma;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_connect_timeout 30;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /var/www/rails/proto-status/public;
    }
}
```

***

###・puma
git cloneしたrailsアプリのディレクトリにて`gem install bundler`でバンドラーを取得し、`bundle install`
自分はここで`The "libcurl" package isn't available.`というエラーメッセージが出たので[この記事](https://qiita.com/pieroplus/items/a9a7b2d1bf1674bdc622)を
参考に、`sudo yum -y install libcurl libcurl-devel`を行い、再度`bundle install`

DBにsqliteとpostgresの環境が必要だったので
`sudo yum install sqlite-devel`
`sudo yum install postgresql-server postgresql-devel postgresql-contrib`
をそれぞれ実行。

`touch tmp/sockets/puma.sock`の実行と`config/puma.rb`に以下を追記

```
# 最初の二行だけでも一応、動作する
app_dir = File.expand_path("../..", __FILE__)
bind "unix://#{app_dir}/tmp/sockets/puma.sock"

pidfile "#{app_dir}/tmp/pids/puma.pid"
state_path "#{app_dir}/tmp/pids/puma.state"
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
```

プリコンパイルされていないので`rake assets:precompile RAILS_ENV=production`を実行

railsコマンドが使えなかったので、[このサイト](https://arakaji.hatenablog.com/entry/2015/08/03/200502)のようにbundle exec pumaとしても
よかったが`gem update --system`でとりあえず解決

***

###・postgresql
[このサイト](https://ryo10leo.hatenablog.com/entry/2020/01/16/214742)を参考に設定していく。万が一、サイトがなくなったら困るので簡単に箇条書き

1. `sudo service postgresql initdb`で初期化
1. `sudo service postgresql start`で起動(restartにすれば再起動)
1. `service postgresql status`で状態確認

```
# EC2インスタンス起動に合わせて、PostgreSQLも起動するよう設定
$ sudo chkconfig postgresql on 

# 設定確認
$ systemctl list-unit-files -t service | grep postgres
postgresql.service                            enabled
```

>エンコードの変更
>`sudo -u postgres psql`でpostgresqlにログイン
>`\l`コマンドを打つとEncodingの欄がSQL_ASCIIになっているのでUTF-8に対応するよう設定
>
>```
>postgres=# UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';
># DROP DATABASE template1;
># CREATE DATABASE template1 WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'ja_JP.UTF-8' LC_CTYPE = 'ja_JP.UTF-8';
># UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';
>```
***
>認証関連（[参考サイト](https://ryotatake.hatenablog.com/entry/2019/05/03/postgresql_peer_authentication_failed)）
>postgresのユーザーやパスワードの設定が間違っていないのに、`rake db:create RAILS_ENV=production`
>などで認証エラーが出るときは`/var/lib/pgsql/data/pg_hba.conf`のpeerをmd5に変える必要がある。
>
>```/var/lib/pgsql/data/pg_hba.conf
># TYPE  DATABASE  USER  ADDRESS   METHOD
>#local   all       all             peer
>```

##その他
これは結構役に立つんじゃないかなと思う。
[【rails】本番環境でもエラー文を表示させる](https://qiita.com/hirouch/items/35bbf4b49e566cf66d5a)
***

最後に今までの参考サイト一覧を載せようかなと思ったけど、逆に見辛そうだったからやめました。
AWS関連をもう少しいじったら、次はDocker、そしてCircleCIか。先は長いなー:sweat_smile: