【AWS】nginx + puma で railsアプリ公開する

## はじめに

railsでなんちゃってLINEbotを作成したので、
nginx + puma で railsアプリ公開する設定をしてみる。

## EC2インスタンスを立てる

こちらを参考にEC2インスタンスを立てます。

参考：AWS EC2でWebサーバーを構築してみる
https://qiita.com/Arashi/items/629aaed33401b8f2265c

## gitやrailsなど開発に必要なものは先に設定しておく

## Railsアプリの場所を確認

ホームディレクトリの下にRailsアプリがある場合は
「/opt」の下に移動、またはコピーする。
公開するアプリを置いておく場所として、ホームディレクトリは適切ではないから注意。
※ ホームディレクトリのままだと、パーミッションエラーでハマりやすいよ

```ruby:Railsアプリをコピー
# コピーする場合
$ sudo cp -arf ~/rails/rails_app/opt/
# ファイルを確認
$ ls -al /opt/
drwxr-xr-x  5 root     root     4096  7月 15 13:59 .
dr-xr-xr-x 25 root     root     4096  7月 16 06:02 ..
drwxrwxr-x 13 ec2-user ec2-user 4096  7月 15 13:57 rails_app
```
## Nginxを設定する
まずはインストール

```ruby:Nginxをインストール
$ sudo yum install -y nginx
```

```ruby:バージョン確認
$ nginx -v
nginx version: nginx/1.16.1
```
設定ファイルに設定を書き込む

```ruby:/etc/nginx/conf.d/rails.conf
server {
    listen       80;
    server_name  localhost;

    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    root /opt/rails_app/public;

    # ドキュメントルート配下を以下の先頭から順番に辿る
    try_files $uri @rails_app;

    # 上記の@rails_appが呼び出された場合のみ以下の設定を読み込む
    location @rails_app {
        proxy_pass http://rails_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}
```
一旦動かしてみる

```ruby:起動
$ sudo nginx
```
```ruby:停止
$ sudo nginx -s stop
```
おぉ！！動いた！！

![スクリーンショット 2020-07-16 21.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210436/9ce79cad-eb16-ef9a-3edb-74efbd15a017.png)

## Pumaのソケット通信設定

Rails（Puma）とNginxを連携させるために、Pumaの設定ファイルを修正する
※ホームの下にRailsアプリがあると、NginxはPumaとソケット通信できないので注意

```ruby:/opt/rails_app/config/puma.rb
#ここをコメントアウトする
#port        ENV.fetch("PORT") { 3000 }

#この行を追加
bind "unix:///opt/rails_app/tmp/sockets/puma.sock"
```
rails.confにも連携部分を追記

```ruby:/etc/nginx/conf.d/rails.conf
#下記コード追加
upstream rails_app {
    # UNIXドメインソケット通信の設定
    server unix:///opt/rails_app/tmp/sockets/puma.sock fail_timeout=0;
}

```
railsを実行すると連携される・・・。

```ruby:エラー
Your version of SQLite (3.7.17) is too old. Active Record supports SQLite >= 3.8.
```
わっ！！なにやら怒られた・・・。

Ruby on Rails 6でSQLiteを使う場合、SQLite3.8以上が必要になるみたい。
SQLiteのパッケージは3.7が入っている・・・。
SQLiteの最新版をインストールして解決する。

```
# 3.29をダウンロード
$ wget https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz

$ tar xzvf sqlite-autoconf-3290000.tar.gz

$ cd sqlite-autoconf-3290000

# もとから入っているsqliteと競合しないように /opt/sqlite/sqlite3 にインストールします
$ ./configure --prefix=/opt/sqlite/sqlite3

$ make

$ sudo make install

# バージョン確認
$ /opt/sqlite/sqlite3/bin/sqlite3 --version
3.29.0 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6

# sqlite3のgemを入れ直し
$ gem uninstall sqlite3

# 上記でいれたlibとincludeのパスを指定してinstall
$ gem install sqlite3 -- --with-sqlite3-include=/opt/sqlite/sqlite3/include \
   --with-sqlite3-lib=/opt/sqlite/sqlite3/lib
```

再度railsを動かしてみる・・・。

おぉ！！動いた！！

![スクリーンショット 2020-07-16 21.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210436/21ed5504-9edd-0500-8e16-2c8bb2325e23.png)

## SSL設定！オレオレ証明書を作成

ついでに、SSLも設定しちゃおう

### OpenSSLのインストール

```ruby:OpenSSLの確認とインストール
# opensslのバージョンを確認
$ openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017

# バージョンが表示されなければインストール
$ sudo yum install -y openssl
```

```ruby:ディレクトリ作成
$ sudo mkdir /etc/nginx/ssl
```

### 秘密鍵の作成

```
$ sudo openssl genrsa -out /etc/nginx/ssl/server.key 2048
```

### CSR（証明書署名要求）の作成

秘密鍵から「CSR（証明書署名要求）」を作成する

国コードや住所、会社名などを入力するよう求められますが、自己署名証明書であれば不要なので、何も入力せずに「Enter」でスキップします。

```ruby:CSRを作成
$ sudo openssl req -new -key /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.csr
```

### CRT（SSLサーバ証明書）の作成

本来であれば、さきほどのCSRを認証局に登録して、「CRT（SSLサーバ証明書）」を発行してもらうのですが、今回は「オレオレ（自己署名）証明書」を作ってこのマシン内で完結

```ruby:CRTを作成
# CRT（有効期限10年）を作成
$ sudo openssl x509 -days 3650 -req -signkey /etc/nginx/ssl/server.key -in /etc/nginx/ssl/server.csr -out /etc/nginx/ssl/server.crt

# CRTが生成されたことを確認
$ ls -l /etc/nginx/ssl/
合計 12
-rw-r--r-- 1 root root 1103  7月 14 11:52 server.crt
-rw-r--r-- 1 root root  952  7月 14 11:52 server.csr
-rw-r--r-- 1 root root 1675  7月 14 11:51 server.key
```

### Nginxに証明書を設定

```ruby:/etc/nginx/conf.d/rails.conf
server {
    # 443番ポートを許可し、SSL機能をON
    # listen 80;
    listen 443 ssl;
    server_name  {#server_name};

    # 証明書を設定
    ssl_certificate     /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
         ：
         ：
}

```

```ruby:再起動
$ sudo restart nginx
```
SSL接続できた！！
※オレオレ証明書は、あくまで開発用や勉強用に使うもの

![スクリーンショット 2020-07-16 22.10.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210436/51c44407-529e-4d80-657e-6600a4668159.png)