Skip Navigation
Show nav
Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • ドキュメント
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku のアーキテクチャ
    • Dyno (アプリコンテナ)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • Developer Tools
    • コマンドライン
    • Heroku VS Code Extension
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリーとインテグレーション
    • 継続的統合
  • 言語サポート
    • Node.js
      • Working with Node.js
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails のサポート
      • Bundler の使用
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Python でのバックグランドジョブ
      • Python Behavior in Heroku
      • Django の使用
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Maven の使用
      • Spring Boot の使用
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres スターターガイド
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
      • Migrating to Heroku Postgres
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • その他のデータストア
  • AI
    • Working with AI
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Vector Database
    • Model Context Protocol
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
      • シングルサインオン (SSO)
    • Private Space
      • インフラストラクチャネットワーキング
    • コンプライアンス
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
      • Heroku Connect の管理
      • Heroku Connect のリファレンス
      • Heroku Connect のトラブルシューティング
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • Salesforce とのインテグレーション
  • 言語サポート
  • Ruby
  • Rails のサポート
  • Unicorn を使用した Rails アプリケーションのデプロイ

Unicorn を使用した Rails アプリケーションのデプロイ

日本語 — Switch to English

この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。

最終更新日 2024年03月12日(火)

Table of Contents

  • Unicorn サーバー
  • アプリケーションへの Unicorn の追加
  • 注意

Heroku では、Unicorn の代わりに Puma Web サーバー​を使用することをお勧めします。Unicorn を使用している場合は、アプリケーションがスロークライアント攻撃から保護されません。

リクエストを並列に処理する Web アプリケーションの方が、一度に 1 つのリクエストしか処理しない Web アプリケーションよりはるかに効率的に dyno リソースを使用します。そのため、本番環境のサービスを開発および実行する場合は常に、並列リクエスト処理を使用することをお勧めします。

Rails フレームワークは最初、一度に 1 つのリクエストを処理するように設計されました。このフレームワークは、この設計から、1 つの Ruby プロセスでのリクエストの並列処理を可能にするスレッドセーフ実装に徐々に移行しています。ただし、これは現在ほとんどの Ruby アプリケーションでサポートされていません。

Unicorn Web サーバーを使用すると、1 つの dyno で複数の Ruby プロセスを実行することにより、すべての Rails アプリケーションを並列に実行できます。

このガイドでは、Unicorn Web サーバーを使用して、新しい Rails アプリケーションを Heroku にデプロイする方法について説明します。基本的な Rails のセットアップについては、Rails スターターガイド​を参照してください。

新しいデプロイは、必ずステージング環境でテストしてから本番環境アプリケーションにデプロイしてください。詳細は、「Managing Multiple Environments for an App​」(アプリの複数の環境の管理) を参照してください。

Unicorn サーバー

Unicorn​ は、フォークされたプロセスを使用して複数の受信リクエストを並列に処理する Rack HTTP サーバーです。

アプリケーションへの Unicorn の追加

Gemfile

最初に、Unicorn をアプリの Gemfile に追加します。

 gem 'unicorn'

bundle install​ を実行して、バンドルをローカルに設定します。

設定

Unicorn の設定ファイルを config/unicorn.rb​、または好きなパスに作成します。単純な Rails アプリケーションでは、次の基本設定を推奨します。

# config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

上記では、監視に ActiveRecord と New Relic を使用する標準の Rails アプリを前提としています。その他の使用可能な設定操作については、Unicorn のドキュメント​を参照してください。

同時実行数の値を手動で設定するには、heroku config:set WEB_CONCURRENCY​ を使用します。アプリケーションの負荷テストを実行して​、アプリに適切な値を見つけます。

Unicorn ワーカープロセス

worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)

Unicorn は各 dyno 内で複数の OS プロセスをフォークして、Rails アプリがスレッドセーフでなくても複数の並列リクエストをサポートできるようにします。Unicorn の用語では、これらはワーカープロセスと呼ばれます (独自の dyno で実行される Heroku ワーカープロセスと混同しないようにしてください)。

フォークされた各 OS プロセスが追加のメモリを消費します。これにより、1 つの dyno で実行できるプロセスの数が制限されます。一般的な Rails メモリフットプリントでは、2 ~ 4 個の Unicorn ワーカープロセスが実行されることが想定されます。アプリケーションで許可されるプロセスの数は、具体的なメモリフットプリントに応じて増減します。アプリケーションの高速チューニングを可能にするために、この数を環境設定で指定することをお勧めします。アプリケーションログの R14 エラー​ (メモリ割り当ての超過) をロギングアドオン​または heroku logs​ のいずれかで監視します。

アプリの事前ロード

preload_app true
# ...
before_fork do |server, worker|
  # ...
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  # ...
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

アプリケーションを事前ロードすると、個々の Unicorn worker_processes​ の起動時間が短縮されると共に、before_fork​ および after_fork​ 呼び出しを使用して個々のワーカーの外部接続を管理できるようになります。上記の設定では、これらの呼び出しはワーカープロセスごとの Postgres 接続を正しく確立するために使用されます。

New Relic ではまた、Unicorn アプリでのより正確なデータ収集のために preload_app true​ も推奨しています。preload_app true​での New Relic の使用については、New Relic のドキュメント​を参照してください。

シグナルの処理

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end
  # ...
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end
  # ...
end

POSIX シグナル​は、特定のイベントまたは状態の変化を示すプロセス間通信の形式です。従来、QUIT​ は、ただちに終了してコアダンプを生成するようプロセスに指示するために使用されています。TERM​は、終了するようプロセスに指示するが、その後プロセスがクリーンアップできるようにするために使用されます。

Unicorn は、グレースフルシャットダウンを示すために QUIT​ シグナルを使用します。マスタープロセスは、このシグナルを受信すると、処理中のリクエストをすべて完了した後にグレースフルシャットダウンするすべてのワーカーに QUIT​ シグナルを送信します。これらのワーカープロセスがシャットダウンすると、マスタープロセスは終了します。

Heroku は、dyno 内のすべてのプロセスに、その dyno がシャットダウンされることを示すために TERM​ シグナルを使用します。上記の設定により、この TERM​ シグナルは確実に、ワーカーがシグナルを捕捉して無視するという Unicorn モデルに正しく変換されます。マスターは、QUIT​ シグナルを捕捉して自身に送信することにより、グレースフルシャットダウンプロセスを起動します。

Heroku は、プロセスがグレースフルシャットダウンするまで 10 秒間待ちます。その後、強制シャットダウンのためにすべてのプロセスに KILL​ シグナルが送信されます。個々のリクエストが 10 秒より長くかかった場合、そのリクエストは中断されます。グレースフルシャットダウンの失敗を示すアプリケーションログ内のエントリに注意してください。

タイムアウト

Heroku のルーターは、リクエストタイムアウト​が発生する前に 30 秒間の期間を適用します。リクエストがルーター経由で dyno に配信された後、dyno はレスポンスを返すまでに 30 秒の余裕があります。それを過ぎると、ルーターはカスタマイズ可能なエラーページ​を返します。これは、ハングアップしたリクエストがリソースを停止させないようにするために行われます。ルーターはクライアントにレスポンスを返しますが、クライアントがレスポンスを受信しても、Unicorn ワーカーは引き続きそのリクエストを処理しようとします。つまり、ハングアップしたリクエストのために、ワーカーはいつまでも停止する可能性があります。アプリケーションのリクエストがリクエストタイムアウトを超えて dyno を停止させないようにするには、Rack::Timeout​ gem と Unicorn のタイムアウト設定の両方を使用することをお勧めします。

Unicorn のタイムアウト

Unicorn には、設定可能なタイムアウト設定があります。Unicorn でのタイムアウトのカウントダウンは、リクエストがアプリケーションによって処理されるときに開始され、そこからレスポンスが返されたときに終了します。リクエストの処理が指定された時間を超えた場合、マスターはリクエストを処理しているワーカーに SIGKILL を送信します。

timeout 15

15 秒のタイムアウトをお勧めします。15 秒のタイムアウトでは、リクエストの処理が 15 秒を超えた場合、マスタープロセスはワーカープロセスに SIGKILL​ を送信します。これにより H13​ エラーコードが生成され、それがログに表示されます。デバッグに役立つスタックトレースが生成されるわけではありません。

Rack::Timeout

Rack::Timeout​ の制限が設定されている場合は、リクエストが閉じられ、長時間実行されるコードの将来のデバッグに使用できるスタックトレースがログに生成されます。最初に、gem をインストールする必要があります。

# Gemfile
gem 'rack-timeout'
$ bundle install

その後、タイムアウトを設定できます。

# config/initializers/timeout.rb
Rack::Timeout.timeout = 10  # seconds

Ruby 1.9/2.0 の Rack::Timeout​ では、信頼できない可能性がある Ruby の stdlib Timeout​ ライブラリが使用されます。Heroku では、Rack::Timeout を使用し、Unicorn のタイムアウトを設定することをお勧めします。両方のタイムアウトシステムを使用しているとき、Rack::Timeout によって生成されるスタックトレースをデバッグに使用する予定がある場合は、Rack::Timeout 値を Unicorn のタイムアウトより小さくする必要があります。

Procfile

Procfile​ で Unicorn を Web プロセスのサーバーとして設定し、その設定ファイルを指します。

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

注意

事前ロードとその他の外部サービス

他の外部接続に注意して、それらが Unicorn のフォーキングモデルと適切に動作することを確認してください。上記のサンプル設定で確認できるように、このアプリはその ActiveRecord 接続を before_fork​ ブロックで削除し、ワーカープロセスの after_fork​ で再接続します。その他のサービスも同様のパターンに従います。たとえば、Unicorn アプリで Resque を使用するための設定ブロックを次に示します。

before_fork do |server, worker|
  # ...

  # If you are using Redis but not Resque, change this
  if defined?(Resque)
    Resque.redis.quit
    Rails.logger.info('Disconnected from Redis')
  end
end

after_fork do |server, worker|
  # ...

  # If you are using Redis but not Resque, change this
  if defined?(Resque)
    Resque.redis = ENV['<REDIS_URL>']
    Rails.logger.info('Connected to Redis')
  end
end

REDIS_URL​ 環境設定を Redis プロバイダーからのものに対応するように変更します。

dalli memcache クライアント​などの多くの一般的な gem では、Unicorn のワーカープロセスモデルとの互換性をドキュメントで説明しています。問題が発生している場合は、詳細について gem のドキュメントを確認してください。

アセット

最適なパフォーマンスを得るには、アセットを CDN の背後で​ホストして、Web dyno を動的コンテンツにのみサービスを提供するように解放します。

Database connections

並列 Web サーバーを本番環境で実行すると、各 dyno には複数のデータベース接続が必要になります。並列 Web サーバーで多数の Rails アプリを実行するには、Active Record がこれらの接続を接続プール内に作成して管理する方法や、開発データベースに関する接続制限を理解する必要があります。これらのトピックについての詳細は、DevCenter の記事「Concurrency and Database Connections​」(並列性とデータベース接続) を参照してください。

スロークライアント

アプリケーションとワークロードの特定の組み合わせでは、Unicorn が最適な選択肢ではない場合があります。特に、アプリケーションが大きな本文ペイロードを含むリクエストをスロークライアントから受信する場合は、別の Web サーバーを使用する方が適している可能性があります。その例として、WiFi、4G、またはその他の高速ネットワーク上にない携帯電話からユーザーによってアップロードされた画像を受信するアプリがあります。

この問題は、クライアントから低速で送信されるリクエストの受信中に Unicorn ワーカーが停止することによって発生します。すべての Unicorn ワーカーが停止すると、新しいリクエストはキューに入れられ、アプリでは、通常より長いリクエストのキューイング時間や、場合によっては H12 エラー が発生する可能性があります。

Puma、Thin、または Rainbows! は、スロークライアントによって生成された負荷の下でより適切に動作する可能性のある代替の Web サーバーです。Heroku でアプリを実行している Web サーバーを変更するには、Procfile​ で web​ プロセスタイプの別のコマンドを指定するだけです。

関連カテゴリー

  • Rails のサポート

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices