なぜrails sでサーバーが動くのか〜MacでRails + puma + Nginxでサーバー構築〜

#はじめに
皆さん、なんとなく"rails s"をして、実際はrailsでどのようにサーバーが立ち上がっているか知らずに開発をしていませんか？ 恥ずかしながら、私は最近まで内部の処理を深くまで知ることなく開発を行ってきていました。
そこで、今回は"rails s"を実行したときにどのようにサーバーが立てられているのかについてとよくRailsのサーバーの構成として使われているRails + puma + Nginxについてを調べてみました。


#結論
結論から言うと、rails sするとRackというサーバーが立ち上がり、RailsはRackアプリケーションとして起動しています。

#Rackとは
Rackの入門によると
https://leahneukirchen.org/blog/archive/2007/02/introducing-rack.html
> Rack aims to provide a minimal API for connecting web servers and web frameworks.

つまり、RackはWebサーバとWebフレームワークを繋ぐ役割を果たしているということです。

#なぜRails + puma + Nginxの構成？
Railsは先ほど述べたように、RackというWebサーバとRubyのフレームワークを繋ぐ役割を果たすインターフェイスを用いてサーバーを立ち上げています。

**では、なぜRackとNginxの間にあるpumaが必要なのでしょうか？**

**結論から言うと、RackとNginxは直接繋ぐことができないからです**

**では、どのようにRackとNginxを繋具のでしょうか？**

**ここで、用いられるのがpumaです！！**
#pumaとは
pumaとは、Railsで標準的に指定されているアプリケーションサーバーのことです。

開発時は、pumaをWebサーバとして使用しても問題がありません。しかし、pumaはRubyで書かれているため、C言語で書かれているNginxと比べると言語の性質上、処理が遅くなってしまいます。

そのため、開発環境では問題なく動作しているアプリケーションでも本番環境にて大量のアクセスが集中した際には、処理が遅くなってしまいます。

**したがって、Railsを用いたWebアプリケーション開発において、NginxなどのWebサーバーと連携して開発を進める必要があります。**

#Nginxとは

wikipediaより
https://ja.wikipedia.org/wiki/Nginx

> nginx（「エンジンエックス」のように発音[1][2]）は、フリーかつオープンソースなWebサーバである。処理性能・高い並行性・メモリ使用量の小ささに焦点を当てて開発されており、HTTP, HTTPS, SMTP, POP3, IMAPのリバースプロキシの機能や、ロードバランサ、HTTPキャッシュなどの機能も持つ。

実際に、Nginxは世界中で最も高い稼働率を誇るサイトのうち66%が利用しています
(Nginxの公式サイトより https://www.nginx.co.jp/)

WebサーバーといえばNginx！！

最後に、実際にMacでRails + puma + Nginxでサーバーを構築してみようと思います。
# MacでのRails + puma + Nginxでのサーバーを構築
### 1. Nginxのインストール
```
# インストール
$ brew install nginx

# バージョン確認
$ nginx -v
nginx version: nginx/1.21.4
```

### 2. Nginxのアクセス確認
```
# nginx起動
$ sudo nginx

# nginx停止
sudo nginx -s stop
```
### 3. Nginxバーチャルホスト設定

nginxのコンフィグファイルを修正します。
nginxのコンフィグファイルは、Macの場合/usr/local/etc/nginx/nginx.confになります。

```/usr/local/etc/nginx/nginx.conf
user  nobody;
worker_processes  auto;
error_log  /usr/local/var/log/nginx/error.log;
pid        /usr/local/var/run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections  1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /usr/local/var/log/nginx/access.log  main;

    sendfile           on;
    tcp_nopush         on;
    tcp_nodelay        on;
    keepalive_timeout  65;
    types_hash_max_size 2048;

    include            mime.types;
    default_type       application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
```

バーチャルホスト設定ファイル配置ディレクトリを用意する

```
$ mkdir /etc/nginx/sites-available
$ mkdir /etc/nginx/sites-enabled
```
バーチャルホスト設定ファイルを作成する

```
nano /etc/nginx/sites-available/{アプリ名}
```

/usr/local/etc/nginx/sites-available/{アプリ名}のファイルに以下のコードを書きます。

```
upstream Nginx-test-app {
  server unix:/Users/{ユーザー名}/Desktop/work/Nginx-test-app/tmp/sockets/puma.sock;
}

server {
  listen 80;
  server_name .*;

  root /Users/{ユーザー名}/Desktop/work/Nginx-test-app/public;

  location / {
    try_files $uri @app;
  }

  location @app {
    proxy_set_header    Host                $http_host;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-Host    $host;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   $scheme;
    proxy_pass http://backend;
  }
}

```

/usr/local/etc/nginx/sites-enabledディレクトリにバーチャルホスト設定ファイルをコピーする

```
$ ln -s /etc/nginx/sites-available/{アプリ名} /etc/nginx/sites-enabled/{アプリ名}
```

### 4. Railsアプリケーションのpuma設定
作ったRailsアプリケーションの/config/puma.rbの一番下に以下を追記してください。

```/config/puma.rb
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
```

### 5. Nginx→Railsアクセス確認
```
#nginxの立ち上げ
$ sudo nginx

#railsサーバーの立ち上げ
$ rails s
=> Booting Puma
=> Rails 6.0.3.4 application starting in development 
=> Run `rails server --help` for more startup options
warning ../../../package.json: No license field                                                                                                                                                         
Puma starting in single mode...
* Version 4.3.6 (ruby 2.6.3-p62), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
* Listening on unix:///Users/{ユーザー名}/Desktop/work/{アプリ名}/tmp/sockets/puma.sock
Use Ctrl-C to stop
```

このようになったら成功です！！

RailsアプリケーションのWebサーバーをNginxにすることができました！！

```
#railsサーバーの停止
Ctrl + C

#nginxの停止
$ sudo nginx　-s stop
```

# 最後に
このように、普段開発で使っているフレームワークがどのようにしてサーバーを立てて動いているのかを知ることで個人的にはサーバについての理解が深まり、興味を持ちました。それと同時に、サーバーの奥深さも感じました笑

私もサーバーについての知識はまだまだ浅いので、もし、この記事で間違えているところがありましたら気軽にコメントでご指摘お願いいたします。
これからも地道にサーバについて勉強していきます。

最後に、この記事がみなさんのサーバについて興味を持つきっかけになれば幸いです。

# 参考記事

https://qiita.com/NaokiIshimura/items/888d77f924877e5dc5e0
https://blog.mothule.com/web/nginx/web-nginx-getting-started-step3-on-mac#web%E3%82%B5%E3%83%BC%E3%83%90%E3%81%A8ap%E3%82%B5%E3%83%BC%E3%83%90%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E9%81%95%E3%81%84
https://qiita.com/kamohicokamo/items/3ec26ccb8e16b8ba9adb