Puma は、Ruby/Rack アプリケーション用の、シンプル、高速、マルチスレッド、並列性の高い HTTP 1.1 サーバーです。
Puma は、Ruby で書かれた Rack-powered HTTP アプリケーション用のサーバーです。それは次のとおりです。
もともと Rubinius 用のサーバーとして設計された Puma は、Ruby (MRI) および JRuby ともうまく動作します。
MRI には、一度に 1 つのスレッドだけが Ruby コードを実行できるようにする Global VM Lock (GVL) があります。ただし、大量のブロック IO (Twitter などの外部 API への HTTP 呼び出しなど) を実行している場合でも、Puma は IO 待機を並行して実行できるようにすることで MRI のスループットを向上させます。真の並列 Ruby 実装 (TruffleRuby、JRuby) にはこの制限はありません。
$ gem install puma
$ puma
引数を指定しないと、puma はconfig.ru
という作業ディレクトリでラックアップ (.ru) ファイルを探します。
Puma は、OpenSSL 開発ファイルがシステムにインストールされていると仮定して、SSL ソケットをサポートしてインストール/コンパイルします。
システムに OpenSSL 開発ファイルがインストールされていない場合、Puma はインストール/コンパイルしますが、SSL 接続は許可されません。
Puma は Rails のデフォルトのサーバーであり、生成された Gemfile に含まれています。
rails
コマンドを使用してサーバーを起動します。
$ rails server
rails server
を使用する場合、多くの構成オプションと Puma 機能は使用できません。代わりに Puma の実行可能ファイルを使用することをお勧めします。
$ bundle exec puma
次のようにコマンドラインから Puma を使用して Sinatra アプリケーションを実行できます。
$ ruby app.rb -s Puma
ただし、 puma.rb
などの構成ファイルを使用して実際に Puma を構成するには、 puma
実行可能ファイルを使用する必要があります。これを行うには、Sinatra アプリにラックアップ ファイルを追加する必要があります。
# config.ru
require './app'
run Sinatra :: Application
その後、以下を使用してアプリケーションを起動できます。
$ bundle exec puma
Puma は多数のオプションを提供します。 CLI オプションの完全なリストについてはpuma -h
(またはpuma --help
) を参照するか、 Puma::DSL
または dsl.rb を参照してください。
テスト スイートの一部として、いくつかの構成例を見つけることもできます。
デバッグの目的で、環境変数PUMA_LOG_CONFIG
に値を設定すると、ロードされた構成がブート プロセスの一部として出力されます。
Puma はスレッド プールを使用します。 -t
(または--threads
) フラグを使用して、プール内で使用可能なスレッドの最小数と最大数を設定できます。
$ puma -t 8:32
Puma は、存在するトラフィックの量に基づいて、スレッド数を最小値から最大値に達するまで自動的にスケーリングします。現在のデフォルトは0:16
で、MRI では0:5
です。自由に実験してください。ただし、最大スレッド数を大きな値に設定しないように注意してください。システム上のリソースが使い果たされる可能性があります (または、MRI を使用する場合はグローバル VM ロックの競合が発生する可能性があります)。
さらに、Puma は内部目的 (遅いクライアントの処理など) のために独自にスレッドを作成することに注意してください。したがって、-t 1:1 を指定した場合でも、アプリケーションで約 7 つのスレッドが作成されることが予想されます。
Puma は「クラスター化モード」も提供します。クラスター化モードは、マスター プロセスからワーカーをfork
。各子プロセスには依然として独自のスレッド プールがあります。 -w
(または--workers
) フラグを使用してワーカーの数を調整できます。
$ puma -t 8:32 -w 3
または、 WEB_CONCURRENCY
環境変数を使用します。
$ WEB_CONCURRENCY=3 puma -t 8:32
スレッドは引き続きクラスター化モードで使用され、 -t
スレッド フラグの設定はワーカーごとに設定されるため、 -w 2 -t 16:16
、各ワーカー プロセスに 16 個ずつ、合計 32 個のスレッドを生成することに注意してください。
WEB_CONCURRENCY
環境変数が"auto"
に設定されており、アプリケーションでconcurrent-ruby
gem が利用可能な場合、Puma はワーカー プロセス数を利用可能なプロセッサの結果に設定します。
スレッドとプロセス数の設定のトレードオフの詳細については、ドキュメントを参照してください。
クラスター化モードでは、Puma はアプリケーションを「プリロード」できます。これにより、フォークする前にすべてのアプリケーション コードがロードされます。プリロードは、コピーオンライトと呼ばれるオペレーティング システム機能を通じてアプリケーションの合計メモリ使用量を削減します。
WEB_CONCURRENCY
環境変数が 1 より大きい値に設定されている場合 (および--prune-bundler
指定されていない場合)、プリロードはデフォルトで有効になります。それ以外の場合は、コマンド ラインから--preload
フラグを使用できます。
$ puma -w 3 --preload
または、構成ファイルを使用している場合は、 preload_app!
使用できます。方法:
# config/puma.rb
workers 3
preload_app!
段階的再起動ではワーカーを 1 つずつ強制終了して再起動し、プリロードではマスターのコードがワーカーにコピーされるため、段階的再起動ではプリロードを使用できません。
クラスター化モードを使用する場合、Puma の構成 DSL は、マスター プロセスのフォークと子ワーカーがそれぞれ起動されるときにコードを実行するbefore_fork
とon_worker_boot
フックを提供します。
これらのフックはpreload_app!
そうでない場合、アプリケーション ( Rails
など) によってロードされた定数はフック内で使用できなくなります。
# config/puma.rb
before_fork do
# Add code to run inside the Puma master process before it forks a worker child.
end
on_worker_boot do
# Add code to run inside the Puma worker process after forking.
end
さらに、ワーカー 0 の子プロセスが孫ワーカーをフォークするときに、 fork_worker
モードでのみ使用されるon_refork
フックがあります。
on_refork do
# Used only when fork_worker mode is enabled. Add code to run inside the Puma worker 0
# child process before it forks a grandchild worker.
end
重要なことに、Ruby が子プロセスをフォークするときは、次の考慮事項に注意してください。
SocketError
、 Errno::EPIPE
、 EOFError
などの I/O 競合が発生します。したがって、次のことをお勧めします。
before_fork
とon_refork
使用して親のソケット接続を切断し、誤って子プロセスにコピーされないようにします。on_worker_boot
使用して、フォークされた子上のバックグラウンド スレッドを再起動します。 Puma の設定 DSL は、各イベントで実行するコード ブロックを指定するために使用できるマスター プロセス ライフサイクル フックon_booted
、 on_restart
、およびon_stopped
提供します。
# config/puma.rb
on_booted do
# Add code to run in the Puma master process after it boots,
# and also after a phased restart completes.
end
on_restart do
# Add code to run in the Puma master process when it receives
# a restart command but before it restarts.
end
on_stopped do
# Add code to run in the Puma master process when it receives
# a stop command but before it shuts down.
end
Puma がアプリケーションのコンテキスト外でエラーに遭遇した場合、400/500 および単純なテキストのエラー メッセージで応答します ( Puma::Server#lowlevel_error
または server.rb を参照)。このシナリオのカスタム動作を指定できます。たとえば、サードパーティのエラー追跡サービス (この例ではロールバー) にエラーを報告できます。
lowlevel_error_handler do | e , env , status |
if status == 400
message = "The server could not process the request due to an error, such as an incorrectly typed URL, malformed syntax, or a URL that contains illegal characters. n "
else
message = "An error has occurred, and engineers have been informed. Please reload the page. If you continue to have problems, contact [email protected] n "
Rollbar . critical ( e )
end
[ status , { } , [ message ] ]
end
-b
(または--bind
) フラグを使用して Puma をソケットにバインドします。
$ puma -b tcp://127.0.0.1:9292
TCP の代わりに UNIX ソケットを使用するには:
$ puma -b unix:///var/run/puma.sock
UNIX ソケットの権限を変更する必要がある場合は、umask パラメータを追加するだけです。
$ puma -b 'unix:///var/run/puma.sock?umask=0111'
多少のセキュリティが必要ですか? SSL ソケットを使用します。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
localhost
gem 経由、開発用): Puma は、自己署名証明書のlocalhost
gem をサポートしています。これは、ローカルで SSL を使用して Puma を使用する場合に特に便利で、自己署名証明書はユースケースで機能します。現在、この統合は MRI でのみ使用できます。
localhost
gem がdevelopment
環境にロードされると、Puma は自動的に SSL を設定します。
gem を Gemfile に追加します。
group ( :development ) do
gem 'localhost'
end
そして、バンドラーを使用して暗黙的にそれを要求します。
require "bundler"
Bundler . require ( :default , ENV [ "RACK_ENV" ] . to_sym )
あるいは、構成ファイルconfig/puma/development.rb
、 config/puma.rb
) で gem を要求するか、 -C
cli オプションで設定することもできます。
require 'localhost'
# configuration methods (from Puma::DSL) as needed
さらに、Puma は SSL ソケットをリッスンする必要があります。
$ puma -b ' ssl://localhost:9292 ' -C config/use_local_host.rb
# The following options allow you to reach Puma over HTTP as well:
$ puma -b ssl://localhost:9292 -b tcp://localhost:9393 -C config/use_local_host.rb
TLSv1.2 以前の特定の SSL 暗号を使用または回避するには、 ssl_cipher_filter
またはssl_cipher_list
オプションを使用します。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA'
$ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore_password&ssl_cipher_list=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA'
利用可能な TLSv1.3 暗号スイートを設定するには、 ssl_ciphersuites
オプションを使用します (JRuby では使用できません)。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256'
暗号フィルターの形式と暗号スイートの完全なリストについては、https://www.openssl.org/docs/man1.1.1/man1/ciphers.html を参照してください。
no_tlsv1
オプションを使用して TLS v1 を無効にします。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true'
OpenSSL によって提供される検証フラグを有効にするには、 verification_flags
を使用します (JRuby では使用できません)。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN'
複数の検証フラグを設定することもできます (カンマで区切ります)。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN,CRL_CHECK'
使用可能なフラグのリスト: USE_CHECK_TIME
、 CRL_CHECK
、 CRL_CHECK_ALL
、 IGNORE_CRITICAL
、 X509_STRICT
、 ALLOW_PROXY_CERTS
、 POLICY_CHECK
、 EXPLICIT_POLICY
、 INHIBIT_ANY
、 INHIBIT_MAP
、 NOTIFY_POLICY
、 EXTENDED_CRL_SUPPORT
、 USE_DELTAS
、 CHECK_SS_SIGNATURE
、 TRUSTED_FIRST
、 SUITEB_128_LOS_ONLY
、 SUITEB_192_LOS
、 SUITEB_128_LOS
、 PARTIAL_CHAIN
、 NO_ALT_CHAINS
、 NO_CHECK_TIME
(「」を参照) https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_hostflags.html#VERIFICATION-FLAGS)。
暗号化された SSL キー (JRuby では使用できません) のランタイム復号化を有効にするには、 key_password_command
を使用します。
$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&key_password_command=/path/to/command.sh'
key_password_command
次のことを行う必要があります。
例えば:
#! /bin/sh
echo " this is my password "
key_password_command
key
またはkey_pem
と一緒に使用できます。キーが暗号化されていない場合、実行可能ファイルは呼び出されません。
Puma には、Puma のクエリと制御に使用できるステータスおよび制御アプリが組み込まれています。
$ puma --control-url tcp://127.0.0.1:9293 --control-token foo
Puma はローカルホスト ポート 9293 でコントロール サーバーを起動します。コントロール サーバーへのすべてのリクエストには、コントロール トークン (この場合はtoken=foo
) をクエリ パラメーターとして含める必要があります。これにより、簡単な認証が可能になります。 Puma::App::Status
または status.rb をチェックして、ステータス アプリで利用可能なものを確認してください。
pumactl
を介してコントロール サーバーと対話することもできます。このコマンドは Puma を再起動します。
$ pumactl --control-url 'tcp://127.0.0.1:9293' --control-token foo restart
pumactl
オプションのリストを表示するには、 pumactl --help
を使用します。
-C
(または--config
) フラグを使用して構成ファイルを指定することもできます。
$ puma -C /path/to/config
設定ファイルが指定されていない場合、Puma はconfig/puma.rb
で設定ファイルを検索します。環境が指定されている場合 ( --environment
フラグ、またはAPP_ENV
、 RACK_ENV
、またはRAILS_ENV
環境変数を介して)、Puma はconfig/puma/<environment_name>.rb
で設定ファイルを検索し、 config/puma.rb
にフォールバックします。 。
Puma がこれらの場所で構成ファイルを検索しないようにするには、 --no-config
フラグを含めます。
$ puma --no-config
# or
$ puma -C "-"
環境設定のその他の副作用は、( development
またはtest
で) スタック トレースを表示するかどうかです。また、 RACK_ENV の設定は、動作を変更するためにこの値を探しているミドルウェアに影響を与える可能性があります。デフォルトの puma RACK_ENV 値は、 development
です。すべての設定のデフォルト値はPuma::Configuration#puma_default_options
またはconfiguration.rbで確認できます。
利用可能なすべてのオプションを確認するには、 Puma::DSL
または dsl.rb をチェックしてください。
Puma には自身を再起動する機能が含まれています。利用可能な場合 (MRI、Rubinius、JRuby)、Puma は「ホット リスタート」を実行します。これは、 UnicornおよびNGINXで利用できる機能と同じで、再起動の間にサーバー ソケットを開いたままにします。これにより、再起動中に保留中のリクエストがドロップされなくなります。
詳細については、再起動のドキュメントを参照してください。
プーマはいくつかの信号に反応します。 Puma で UNIX シグナルを使用するための詳細なガイドは、シグナルのドキュメントに記載されています。
一部のプラットフォームでは、Puma のすべての機能がサポートされません。
MRI バージョン 2.2.7、2.2.8、2.2.9、2.2.10、2.3.4、および 2.4.1 では、 stream closed in another thread (IOError)
が表示される場合があります。 Ruby のバグが原因である可能性があります。これは gem https://rubygems.org/gems/stopgap_13632 で修正できます。
if %w( 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1 ) . include? RUBY_VERSION
begin
require 'stopgap_13632'
rescue LoadError
end
end
Puma は外部 gem を使用して Capistrano をサポートしています。
さらに、Puma は puma-daemon Ruby gem による組み込みデーモン化をサポートしています。この gem は、バージョン 5 以降の Puma から削除されたdaemonize
オプションを復元しますが、これは MRI Ruby に対してのみです。
Puma ではプロセス モニターを使用するのが一般的です。 systemd や rc.d などの最新のプロセス モニターは、継続的な監視と再起動を提供して、運用環境の信頼性を向上させます。
コミュニティガイド:
貢献の詳細については、貢献ガイドをご覧ください。
Puma の著作権は Evan Phoenix および寄稿者にあり、BSD 3 条項ライセンスに基づいてライセンスされています。詳細については、同梱の LICENSE ファイルを参照してください。