【Puma】Rails 5.2 + Puma + Nginx のデプロイ設定
先日、【EC2】Rails5 環境構築(Ruby + MySQL5.7 + Node.js + Nginx) について書いた。そして、今回は、アプリケーションサーバーである Puma について色々と調べて設定したので、備忘録を残しておく。(以前、Rails を使っていた時は、Unicorn が主流だったのに、Rails5 からは標準サーバーも Puma に変わったこともあり、今回は Puma を採用してみた。)
Pumaとは
Puma is a simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications.
Puma は、シンプル、高速、マルチスレッドで多数の並列処理を実現できる Ruby/Rack アプリケーションの HTTP 1.1 サーバーである。
ここで、「マルチスレッド」、「Ruby/Rack アプリケーション」という言葉に注目してみる。
マルチスレッド
Puma はマルチスレッドで動いていることが大きな特徴である。対照的に、Unicorn は マルチプロセスで動いている。CPU は一度に1つのプロセスしか実行できず、マルチプロセスの場合、CPU のコア数に応じて並列処理できる数に制限がある。しかしながら、マルチスレッドの場合は、1つのプロセスに複数のスレッドが存在し、並行して処理を行うため、CPU のリソースが少ない中でも効率的に処理を行うことができる。
Ruby/Rack アプリケーション
Rack とは、Rubyにおけるサーバとアプリケーション/フレームワーク間のインターフェースの役割を果たすライブラリである。Python の WSGI に影響されて開発されたらしく、WebサーバとWebアプリケーション/フレームワーク間の標準インターフェースを定める「仕様」である。
rails serverコマンドは、Rack::Serverのオブジェクトを作成し、Webサーバーを起動している。
Railsガイド 参照
簡単な概略図はこのような形になる。
HTTP リクエストを web サーバーである Nginx や Apache で受け取り、Nginx はそのリクエストを Puma に Socket 通信で渡し、Puma はそのリクエストを Rack::Server に渡し、最終的に Rails の router に渡される。
インストールに関して
Rails5 以上であれば、標準Webサーバーなので、最初に生成された Gemfile に含まれているので、新規にインストールをする必要はないが、インストールする場合は、以下の通りである。
$ gem install puma $ puma
Rails で開発をする場合に、rails server
をすることで、Puma が起動している。
$ rails server Puma starting in single mode... * Version 3.9.1 (ruby 2.4.0-p0), codename: Private Caller * Min threads: 5, max threads: 5 * Environment: production * Listening on tcp://0.0.0.0:3000 Use Ctrl-C to stop
設定に関して
Puma は、Railsの場合、config/puma.rb
で詳細な設定をすることができる。もちろん、オプションコマンドで設定も可能であるが、毎回コマンドを打つのが面倒なので、設定ファイルに用いる。
開発時は、Default の設定で問題ないので以下の通りである。
# Puma can serve each request in a thread from an internal thread pool. # The `threads` method setting takes two numbers: a minimum and maximum. threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } threads threads_count, threads_count # Specifies the `port` that Puma will listen on to receive requests; default is 3000. port ENV.fetch("PORT") { 3000 } # Specifies the `environment` that Puma will run in. environment ENV.fetch("RAILS_ENV") { "development" } # Specifies the `pidfile` that Puma will use. pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } # Specifies the number of `workers` to boot in clustered mode. # workers ENV.fetch("WEB_CONCURRENCY") { 2 } # Use the `preload_app!` method when specifying a `workers` number. # preload_app! # Allow puma to be restarted by `rails restart` command. plugin :tmp_restart
本番環境では、Nginx をリバースプロキシとして Puma の前段におき、UNIXドメインソケットを経由して Nginx とPuma が通信を行う。
Puma 側では、Pumaを起動した時に、「puma.sock」を生成するようにする。
#port ENV.fetch("PORT") { 3000 } #portの設置の部分はコメントアウトしておく。そうでないと、puma.sockを参照しないことがある模様。 bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
Nginx 側では、/etc/nginx/conf.d/
に新規に設定ファイルを作成する。
upstream app_server { # for UNIX domain socket setups # 上記で設定したpuma.sockファイルの絶対パスを指定する server unix:///app/sample-app/tmp/sockets/puma.sock; } server { #ポート80番を許可する listen 80; #ホスト名を指定する server_name _; #静的ファイルのパスをドキュメントルートに設定する root /app/sample-app/public; # ドキュメントルート配下を以下の順番で検索する try_files $uri/index.html $uri.html $uri @app; # @appの場合は、以下の設定を読み込ませる location @app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; #upstreamで指定した名前で設定する } # エラーページの参照先を設定する error_page 500 502 503 504 /500.html; location = /500.html { root /app/sample-app/public; } }
Nginx の設定ファイルの修正が完了したら、設定に問題がないか確認を行う(successful が表示されれば、OK.)
$ sudo nginx -t nginx: [warn] conflicting server name "_" on 0.0.0.0:80, ignored nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Nginxの設定を書き換えたので、再起動する
$ sudo systemctl reload nginx
Pumaを起動する(どのコマンドでも起動することができる)
$ bundle exec rails s $ bundle exec puma $ bundle exec pumactl start
これで設定は完了である。
http://<---IP address->:80
にアクセスすると、Railsアプリケーションが表示される。
コマンドに関して
Puma には、上記でも示したように、3つの制御方法が存在する。(個人的には、pumactl
が使いやすいと思っている。)
- rails sの場合
- pumaコマンドの場合
- pumactlの場合
rails sの場合
Railsアプリケーションの起動と同時に、Pumaも起動する
$ bundle exec rails s -e production
Puma ではデフォルトの設定ファイル config/puma.rb
以外にも、実行環境に応じたconfig/puma/[実行環境].rb
という設定ファイルを参照させることができる。
-e production
の場合、config/puma/production.rb
参照する。(なかった場合は、デフォルトを参照する。)
停止する場合は、以下のように Puma のプロセスを確認して、kill
する
# process IDの確認をする $ ps aux | grep puma # プロセスを停止させる $ kill -9 <--process ID-->
pumaコマンドの場合
設定ファイルを指定して、起動する(-Cのオプションがない場合は、デフォルトを参照するが、設定することをオススメする)
$ bundle exec puma -C config/puma.rb
停止する場合は、rails s 同様に、プロセスを確認して、kill
する
pumactlの場合
pumactl
を使う場合は、オプションコマンドなどで設定をすることができないので、config/puma.rb
にきちんと設定を書いておく必要がある。
# 起動する $ bundle exec pumactl start # 状態を確認する $ bundle exec pumactl status # 停止する $ bundle exec pumactl stop # 再起動する $ bundle exec pumactl restart
まとめ
今回は、アプリケーションサーバーである Puma についてまとめを行った。
それでは、ステキな開発ライフを。