Ubuntu 20.04上でRuby on Railsをnginxで動かす
はじめに_
Ubuntu 20.04 on WSL2上でRuby on Railsをnginxで動かす。実現したい状況は以下のとおり。
- http://locahost:30080 にWindows上のWebブラウザからアクセスするとRailsアプリにアクセスできる
- Webサーバnginxは30080ポートにアクセスがあったら、unicornを通して、Railsアプリを呼び出す
- nginxとunicornはUnixソケットを通じて連携する
参考_
- Webサーバー「Unicorn」の基本情報と実装方法
- WEB/APサーバ構成に応じたNginx設定
- nginxでsites-availableとsites-enabledを用いたバーチャルホストの設定
nginxのインストールと設定_
% sudo apt install -y nginx
デフォルトの設定のままだと以下のようなメッセージがエラーログに表示される。
2021/10/05 15:25:49 [alert] 1532#1532: *2630 768 worker_connections are not enough while connecting to upstream, client: 127.0.0.1, server: , request: "GET / HTTP/1.0", upstream: "http://127.0.0.1:30080/", host: "localhost:30080"
worker_connectionsとworker_rlimit_nofileの値は何がいいのか?に従い、worker_connectionsとworker_rlimit_nofileの値の設定を変える。
Ubuntu 20.04(Debian GNU/Linuxも)は /etc/nginx/nginx.conf で設定されている。まず、設定ファイルのコピーをする。
% cd /etc/nginx % sudo cp -p nginx.conf nginx.conf.org
お好きなエディタで編集する(編集の際はroot権限が必要)。nginx.confのworker_connectionsとworker_rlimit_nofileの値を編集する。
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
## 以下を追記する
worker_rlimit_nofile 83000;
events {
### 以下の値を変更する
#worker_connections 768;
worker_connections 4096;
# multi_accept on;
}
~以下略~
設定が正しいかどうか確かめる。
% sudo nginx -t [sudo] gotoh のパスワード: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
nginxを再起動する。
% sudo service nginx restart
unicornのインストールと設定_
RailsアプリとWebサーバをつなぐミドルウェアとしてunicornを用いる。unicornの役割については以下のページが丁寧に説明してくれている。
動作確認用のRailsアプリの準備_
動作確認用のRailsアプリを作成する。(参考:rbenvを用いたRuby on Rails環境の構築 on Ubuntu 20.04)
% cd % mkdir -p ~/Sandboox/RailsTest % cd ~/Sandboox/RailsTest (Windows Subsystem for Linux上のUbuntuの場合) % rails new demo --skip-bundle -skip-spring --skip-listen % cd demo % bundle install % rails webpacker:install % rails generate scaffold person name:string age:integer % rails db:migrate
Railsアプリの動作確認をする。
% rails server
=> Booting Puma
=> Rails 6.1.4.1 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.4.0 (ruby 3.0.2-p107) ("Super Flight")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 20564
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Webブラウザで、http://localhost:3000/people にアクセスし、アプリが動いていることを確認する。確認したらアプリを Ctrl-cで停止する。
unicornのインストールと設定_
Gemfileに以下を追記する。
gem 'unicorn'
インストールする。
% bundle install
Webサーバー「Unicorn」の基本情報と実装方法に従い config/unicorn.rb を記述する。また、各種ファイルを設置するディレクトリを作成する。
% touch config/unicorn.rb % mkdir -p tmp/pids % mkdir -p tmp/sockets
config/unicorn.rb の中身は以下のようにする。
# Refer to https://www.autovice.jp/articles/146
# Railsアプリのルート
rails_root = File.expand_path('../../', __FILE__)
# Gemfileの場所
ENV['BUNDLE_GEMFILE'] = rails_root + "/Gemfile"
# Unicornの設定
worker_processes 2
timeout 15
working_directory rails_root
pid File.expand_path 'tmp/pids/unicorn.pid', rails_root
listen File.expand_path 'tmp/sockets/.unicorn.sock', rails_root
stdout_path File.expand_path 'log/unicorn.log', rails_root
stderr_path File.expand_path 'log/unicorn.log', rails_root
preload_app true
# フォークが行われる前の処理
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
Process.kill "QUIT", File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
# フォークが行われた後の処理
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
# フォークが行われる前の処理
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
# フォークが行われる前の処理
before_fork do |server, worker|
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
Process.kill "QUIT", File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
続いて、unicornをNginx環境下で動かす時の設定方法に基づいて、unicornを起動するタスクファイルを設定する。
% rails g task unicorn
}}
lib/tasks/unicorn.rakeを以下のように編集する。なお、上述の config/unicorn.rb のPIDファイルの設置場所に合わせて、一部変更している。
{{{
# Refer to https://y-hilite.com/2857/
# Modified above setting according to current config/unicorn.rb
namespace :unicorn do
# Tasks
desc "Start unicorn"
task(:start) {
config = Rails.root.join('config', 'unicorn.rb')
sh "unicorn -c #{config} -E development -D"
}
desc "Stop unicorn"
task(:stop) {
unicorn_signal :QUIT
}
desc "Restart unicorn with USR2"
task(:restart) {
unicorn_signal :USR2
}
desc "Increment number of worker processes"
task(:increment) {
unicorn_signal :TTIN
}
desc "Decrement number of worker processes"
task(:decrement) {
unicorn_signal :TTOU
}
desc "Unicorn pstree (depends on pstree command)"
task(:pstree) do
sh "pstree '#{unicorn_pid}'"
end
# Helpers
def unicorn_signal signal
Process.kill signal, unicorn_pid
end
def unicorn_pid
begin
unicorn_pid = Rails.root.join('tmp', 'pids', 'unicorn.pid')
File.read(unicorn_pid ).to_i
rescue Errno::ENOENT
raise "Unicorn does not seem to be running"
end
end
end
起動確認をする。unicornのプロセスが動いていれば設定OK.
% rails unicorn:start unicorn -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D % ps -ef | grep unicorn | grep -v grep gotoh 2403 12 0 16:02 ? 00:00:00 unicorn master -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2405 2403 0 16:02 ? 00:00:00 unicorn worker[0] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2406 2403 0 16:02 ? 00:00:00 unicorn worker[1] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2407 2403 0 16:02 ? 00:00:00 unicorn worker[2] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2408 2403 0 16:02 ? 00:00:00 unicorn worker[3] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2409 2403 0 16:02 ? 00:00:00 unicorn worker[4] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D gotoh 2410 2403 0 16:02 ? 00:00:00 unicorn worker[5] -c /home/gotoh/Sandbox/RailsTest/demo/config/unicorn.rb -E development -D
停止する。停止したらプロセスも停止していることを確認する。psの実行結果で何も表示されなければ停止している。
% rails unicorn:stop % ps -ef | grep unicorn | grep -v grep
ログは logs/unicorn.log にある。
バーチャルホストの設定_
今回は
Ubuntu 20.04のnginxは /etc/nginx/sites-avaiable 以下にバーチャルホストの設定を置いておくことになっている。今回のRailsアプリのディレクトリ名がdemoなのでバーチャルホストの設定ファイルもdemoとする。
% sudo touch /etc/nginx/sites-avaiable/demo
root権限で/etc/nginx/sites-avaiable/demoの中身を以下のように編集する。
upstream rails_app {
# 注意.unicorn.sockの設置場所のフルパスを記載すること
server unix:/home/gotoh/Sandbox/RailsTest/demo/tmp/sockets/.unicorn.sock fail_timeout=0;
}
server {
# ポート番号は任意。
listen 30080;
server_name _;
# Railsアプリの下にあるpublicディレクトリをrootとする。
root /home/gotoh/Sandbox/RailsTest/demo/public;
# このバーチャルホスト用のログを指定する。ファイル名は任意
access_log /var/log/nginx/demo_access.log;
error_log /var/log/nginx/demo_error.log;
client_max_body_size 100m;
error_page 404 /404.html;
error_page 500 502 503 504 /500.html;
try_files $uri/index.html $uri @unicorn;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# upstreamの部分に記載しているもの(今回はrails_app)を書く
proxy_pass http://rails_app;
}
}
設定ファイルを有効化するためには sites-enabled にシンボリックリンクを作成する。
% sudo ln -s /etc/nginx/sites-available/demo /etc/nginx/sites-enabled/demo
設定ファイルが正しいかどうかを設定する。
% sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
nginxを再起動する。
% sudo service nginx restart * Restarting nginx nginx [ OK ]
Railsアプリの起動手順_
以下の手順でWindows上のWebブラウザからRailsアプリにアクセスできる
- nginxを起動する(以下のようになっていたら起動している)
% ps -ef | grep nginx | grep -v grep root 3356 12 0 16:54 ? 00:00:00 nginx: master process /usr/sbin/nginx www-data 3357 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3358 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3359 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3360 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3362 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3363 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3364 3356 0 16:54 ? 00:00:00 nginx: worker process www-data 3365 3356 0 16:54 ? 00:00:00 nginx: worker process (起動していなければ以下のコマンドを実行する) % sudo service nginx start
- Unicornを起動する。
(今回の例の場合は以下のように起動する) % cd ~/Sandbox/RailsTest/demo % rails unicorn:start (確認する) % ps -ef | grep unicorn | grep -v grep gotoh 3416 12 1 16:59 ? 00:00:00 unicorn master -c /home/gotoh/Sandbox/RailsTest/demo2/config/unicorn.rb -E development -D gotoh 3418 3416 0 16:59 ? 00:00:00 unicorn worker[0] -c /home/gotoh/Sandbox/RailsTest/demo2/config/unicorn.rb -E development -D gotoh 3419 3416 0 16:59 ? 00:00:00 unicorn worker[1] -c /home/gotoh/Sandbox/RailsTest/demo2/config/unicorn.rb -E development -D
- Windows上のWebブラウザから http://localhost:30080/people にアクセスする。
トラブルシューティング_
ログ置き場_
nginxのログは以下にある。500 Internal Server Errorや400 Bad Requestなどが出た場合はnginxのログをみる
- /var/log/nginx/demo_access.log, demo_error.log (バーチャルホストのログ)
unicornのログは以下にある。以下のパスは今回の例のもの。
- ~/Sandbox/RailsTest/demo/log/unicorn.log
Railsアプリのログは以下にある。以下のパスは今回の例のもの。
- ~/Sandbox/RailsTest/demo/log/development.log