Ruby on Rails アプリのデプロイ(Puma + Nginx)
『Ruby on Rails』アプリを本番サーバーへデプロイする際は、rbenv で Ruby バージョンを管理し、Bundler で Gem 依存を解決し、Puma をアプリケーションサーバーとして systemd サービスに登録し、Nginx がリバースプロキシとして Unix ソケット経由でリクエストを転送する構成が一般的です。各ツールの役割を理解して順番にセットアップすることで、安定した本番環境を構築できます。
構文
# -----------------------------------------------
# 1. rbenv・ruby-build のインストール
# -----------------------------------------------
# rbenv 本体を git でホームディレクトリ配下にインストールします
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
# rbenv の bin ディレクトリを PATH に追加します
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
# ruby-build プラグインを追加します(Ruby バイナリのビルドに必要です)
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
# インストール可能な Ruby バージョンを確認します
rbenv install --list
# -----------------------------------------------
# 2. Ruby のインストールとグローバル設定
# -----------------------------------------------
# Ruby 3.3.0 をビルドしてインストールします(完了まで数分かかります)
rbenv install 3.3.0
# システム全体で使用する Ruby バージョンを指定します
rbenv global 3.3.0
# 現在の Ruby バージョンを確認します
ruby -v
# rbenv の shim を再生成します(新しい gem を入れた後も必要です)
rbenv rehash
# -----------------------------------------------
# 3. Bundler のインストールとアプリ依存解決
# -----------------------------------------------
# Bundler をインストールします(Rails アプリの Gem 管理ツールです)
gem install bundler
# アプリケーションディレクトリに移動します
cd /var/www/shinji-rails
# Gemfile.lock に従って本番用 Gem をインストールします
# deployment モードでは Gemfile.lock の変更を禁止します
bundle install --deployment --without development test
# -----------------------------------------------
# 4. Rails アプリの本番設定
# -----------------------------------------------
# データベースのマイグレーションを実行します
RAILS_ENV=production bundle exec rails db:migrate
# アセットをプリコンパイルします(CSS・JS を最適化します)
RAILS_ENV=production bundle exec rails assets:precompile
# Rails のマスターキー・秘密鍵を環境変数に設定します
# (/etc/environment または systemd の Environment= に記述します)
# RAILS_MASTER_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# SECRET_KEY_BASE=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# -----------------------------------------------
# 5. Puma の設定ファイル(config/puma.rb)
# -----------------------------------------------
# Puma が使用する Unix ソケットのパスを指定します
# bind 'unix:///var/run/shinji-rails/puma.sock'
# ワーカー数とスレッド数を指定します
# workers 2
# threads 4, 4
# PID ファイルの保存先を指定します
# pidfile '/var/run/shinji-rails/puma.pid'
# -----------------------------------------------
# 6. Puma を systemd サービスとして登録
# -----------------------------------------------
# サービスファイルを作成します(後述の使用例を参照してください)
# sudo vim /etc/systemd/system/shinji-puma.service
# systemd のデーモン定義を再読み込みします
sudo systemctl daemon-reload
# Puma サービスを起動します
sudo systemctl start shinji-puma
# OS 再起動時に自動起動するよう有効化します
sudo systemctl enable shinji-puma
# サービスの稼働状態を確認します
sudo systemctl status shinji-puma
# -----------------------------------------------
# 7. Nginx のリバースプロキシ設定
# -----------------------------------------------
# Nginx の設定ファイルを作成します(後述の使用例を参照してください)
# sudo vim /etc/nginx/sites-available/shinji-rails.conf
# 設定ファイルを sites-enabled にシンボリックリンクします
sudo ln -s /etc/nginx/sites-available/shinji-rails.conf \
/etc/nginx/sites-enabled/shinji-rails.conf
# 設定ファイルの文法を確認します
sudo nginx -t
# Nginx をリロードして設定を反映します
sudo systemctl reload nginx
構文一覧
| 手順 | 説明 |
|---|---|
| rbenv インストール | git clone で ~/.rbenv にインストールし、.bashrc に PATH と rbenv init を追記します。ruby-build プラグインも合わせて追加します。 |
| Ruby のインストール | rbenv install {バージョン} で指定バージョンをビルドします。rbenv global {バージョン} でシステム既定のバージョンを設定します。 |
| Bundler の導入 | gem install bundler でインストールし、bundle install --deployment --without development test で本番用 Gem をプロジェクトに展開します。 |
| DB マイグレーション | RAILS_ENV=production bundle exec rails db:migrate でデータベーススキーマを最新化します。デプロイのたびに実行します。 |
| アセットプリコンパイル | RAILS_ENV=production bundle exec rails assets:precompile で CSS・JS・画像を最適化します。public/assets/ に出力されます。 |
| Puma 設定 | config/puma.rb に Unix ソケットパス・ワーカー数・スレッド数・PID ファイルパスを記述します。 |
| systemd サービス登録 | /etc/systemd/system/{サービス名}.service を作成し、systemctl daemon-reload → systemctl start → systemctl enable の順で有効化します。 |
| Nginx リバースプロキシ設定 | proxy_pass に http://unix:/path/to/puma.sock を指定し、Nginx から Puma の Unix ソケットへ転送します。 |
| Nginx 設定の有効化 | sites-available/ に設定ファイルを作成し、sites-enabled/ にシンボリックリンクを張ります。nginx -t で文法確認後に systemctl reload nginx で反映します。 |
| サービス状態の確認 | systemctl status shinji-puma で Puma の稼働状態を確認します。journalctl -u shinji-puma -f でリアルタイムログを確認できます。 |
使用例
/etc/systemd/system/shinji-puma.service
# ----------------------------------------------- # Puma を systemd サービスとして管理する設定ファイルです # ----------------------------------------------- [Unit] # サービスの説明を記述します Description=Puma HTTP Server for shinji-rails # ネットワークが使用可能になった後に起動します After=network.target [Service] # サービスを実行するユーザーとグループを指定します User=shinji Group=www-data # Rails アプリケーションのルートディレクトリを指定します WorkingDirectory=/var/www/shinji-rails # rbenv 経由で Puma を起動するためのシェル変数を設定します Environment=RAILS_ENV=production Environment=PATH=/home/shinji/.rbenv/shims:/home/shinji/.rbenv/bin:/usr/local/bin:/usr/bin:/bin Environment=RAILS_MASTER_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Puma を bundle exec 経由で起動します # config/puma.rb の設定が読み込まれます ExecStart=/home/shinji/.rbenv/shims/bundle exec puma -C /var/www/shinji-rails/config/puma.rb # サービス停止時は SIGTERM を送って正常終了を待ちます ExecStop=/bin/kill -s SIGTERM $MAINPID # プロセスがクラッシュした場合は自動で再起動します Restart=on-failure RestartSec=5 # 標準出力とエラー出力を journald に記録します StandardOutput=journal StandardError=journal # Unix ソケット用のディレクトリを先に作成しておきます RuntimeDirectory=shinji-rails RuntimeDirectoryMode=0755 [Install] # multi-user.target(通常の起動ターゲット)で自動起動します WantedBy=multi-user.target
/etc/nginx/sites-available/shinji-rails.conf
# -----------------------------------------------
# Nginx が Puma の Unix ソケットへリクエストを転送する設定です
# -----------------------------------------------
# upstream ブロックで Puma ソケットの場所を定義します
upstream shinji_puma {
# Unix ソケット経由で通信します(TCP より低レイテンシです)
server unix:///var/run/shinji-rails/puma.sock fail_timeout=0;
}
server {
# HTTP(ポート 80)でリクエストを受け付けます
listen 80;
# このバーチャルホストが対応するドメイン名を指定します
server_name shinji-rails.example.com;
# Rails の public/ ディレクトリを静的ファイルのルートに指定します
root /var/www/shinji-rails/public;
# アクセスログとエラーログの出力先を指定します
access_log /var/log/nginx/shinji-rails_access.log;
error_log /var/log/nginx/shinji-rails_error.log;
# クライアントからのアップロードサイズの上限を設定します
client_max_body_size 10M;
location / {
# まず public/ 以下に静的ファイルがあれば直接返します
# なければ Puma(@shinji_puma)へ転送します
try_files $uri/index.html $uri @shinji_puma;
}
# 静的ファイルが見つからなかった場合に Puma へ転送します
location @shinji_puma {
# upstream で定義した shinji_puma ソケットへ転送します
proxy_pass http://shinji_puma;
# リクエストヘッダーをアプリに正しく伝えます
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# Nginx 側でリダイレクトの書き換えを行いません
proxy_redirect off;
# WebSocket のバッファリングを無効にします
proxy_buffering off;
}
# Puma の PID ファイルやソケットへの直接アクセスを禁止します
location ~ ^/(\.git|\.env|Gemfile) {
deny all;
}
# アセットファイルには長期キャッシュを設定します
location ~ ^/assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
実行するコマンドは次の通りです。
$ sudo systemctl status shinji-puma
● shinji-puma.service - Puma HTTP Server for shinji-rails
Loaded: loaded (/etc/systemd/system/shinji-puma.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2026-03-25 10:00:00 JST; 2min ago
Main PID: 12345 (ruby)
Tasks: 9 (limit: 4915)
Memory: 128.3M
CPU: 3.241s
CGroup: /system.slice/shinji-puma.service
└─12345 puma 6.4.0 (unix:///var/run/shinji-rails/puma.sock) [shinji-rails]
Mar 25 10:00:00 server shinji-puma[12345]: Puma starting in cluster mode...
Mar 25 10:00:00 server shinji-puma[12345]: * Puma version: 6.4.0
Mar 25 10:00:00 server shinji-puma[12345]: * Workers: 2
Mar 25 10:00:00 server shinji-puma[12345]: * Threads: 4
Mar 25 10:00:00 server shinji-puma[12345]: * Listening on unix:///var/run/shinji-rails/puma.sock
Mar 25 10:00:00 server shinji-puma[12345]: Use Ctrl-C to stop
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx
$ curl -I http://shinji-rails.example.com/
HTTP/1.1 200 OK
Server: nginx/1.24.0
Content-Type: text/html; charset=utf-8
X-Request-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
X-Runtime: 0.042
概要
『Ruby on Rails』のデプロイ構成は「rbenv → Bundler → Puma → systemd → Nginx」という5段階のスタックで成り立っています。rbenv はサーバーに複数の Ruby バージョンを共存させ、プロジェクトごとに異なるバージョンを使い分けられるようにします。Bundler は Gemfile.lock を基準に Gem のバージョンを固定し、開発環境と本番環境の差異を排除します。Puma は Rails アプリをマルチスレッドで処理するアプリケーションサーバーで、Unix ソケットをリッスンすることで TCP より低レイテンシな通信が可能です。systemd サービスとして登録することで、OS 再起動後の自動起動やクラッシュ時の自動リカバリが実現できます(詳細は systemd ユニット を参照してください)。Nginx は静的ファイルを直接返しつつ、動的リクエストのみを Puma ソケットへ転送するリバースプロキシとして動作します。この構成により、静的ファイルの配信は Nginx が高速に処理し、Rails の処理リソースを動的リクエストだけに集中させる効率的な本番環境が完成します。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。