前回はNginxにRails、Passengerを導入する方法について説明しました。今回はPassengerと同様にアプリケーションサーバとして使用されるUnicornを導入する方法について説明します。
目次
実施環境
OS | CentOS8 最小のインストール |
---|---|
Nginx | 1.18.0 |
Ruby | 2.7.1 |
Rails | 6.0.3.2 |
yarn | 1.22.5 |
Node.js | 14.9.0 |
Unicorn | 5.7.0 |
事前準備
初めにRuby用のユーザーの作成、必要なコマンド、develのインストールを行います。
・Rails用ユーザー・railsを作成しパスワードを設定する
# useradd rails
# passwd rails
・git等のコマンドをインストールする
# dnf groupinstall -y "Development Tools"
・Ruby、Railsのインストールに必要なものをインストールする
# dnf -y install openssl-devel readline-devel zlib-devel sqlite-devel libcurl-devel
インストール後、NginxとUnicornの連携後の「403 Forbidden」を回避するためにSELinuxを無効にします。
・SELinuxを無効にする
# vi /etc/selinux/config
■config
-----------------------------------------------------------
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled # enforcingをdisabledにする
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
-----------------------------------------------------------
・SELinux反映のため、端末を再起動する
# reboot
Nginxのインストール
事前準備後、Nginxのインストールをします。今回はリポジトリから安定版をインストールします。
・yum.repo.d配下にNginx用のリポジトリファイルを作成する
# vi /etc/yum.repos.d/nginx.repo
■nginx.repo
-----------------------------------------------------------
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
-----------------------------------------------------------
・Nginxをインストールする
# dnf -y install nginx
・Nginxのバージョンを確認する
# nginx -v
nginx version: nginx/1.18.0
Nginxインストール後、FirewallのHTTPポートを開放します。
・FirewallのHTTPポートを開放
# firewall-cmd --add-service=http --zone=public --permanent
# firewall-cmd --reload
Firewall設定後、Nginxを起動し自動起動の設定を行います。
・Nginxを起動し自動起動の設定をする
# systemctl start nginx
# systemctl enable nginx
Rubyのインストール
Nginxのインストール後、rbenvからRubyをインストールします。Rubyのインストールはrailsユーザーで行います。
初めにrbenv、ruby-buildをgithubからダウンロードし環境変数を設定します。
・Ruby用ユーザーへ切り替え
$ su - rails
・rbenvをダウンロードする
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
・ruby-buildをダウンロードする
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ vi ~/.bash_profile
------------------------------------------------------------
# User specific environment and startup programs
# rbenv setting
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/versions/2.7.1/bin:$PATH"
eval "$(rbenv init -)"
------------------------------------------------------------
・.bash_profileを反映する
$ source ~/.bash_profile
rbenvの設定完了後、Rubyをインストールします。今回はRuby 2.7.1をインストールします。
・Rubyのインストール、今回はバージョン2.7.1をインストールする
$ rbenv install 2.7.1
・Rubyのバージョンを切り替える
$ rbenv global 2.7.1
・Rubyのバージョン確認
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
Node.jsとyarnのインストール
Rubyのインストール後、Rails用にNode.jsとyarnをインストールします。
・Node.jsの最新版をyumリポジトリに追加
# curl --silent --location https://rpm.nodesource.com/setup_14.x | bash -
・yumリポジトリに安定版yarnのリポジトリを追加
# curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
・Node.jsとyarnをインストールする
# dnf -y install yarn nodejs
・yarnとNode.jsのバージョンを確認
# node -v
v14.9.0
# yarn -v
1.22.5
bundlerとRails、Unicornのインストール
Node.jsとyarnのインストール後、RailsとUnicornをインストールします。今回はbundlerを使用しRailsとUnicornをインストールします。RailsとUnicornはRuby用ユーザー・railsでインストールを行うため、事前にRuby用ユーザーに切り替えておいてください。
・bundlerをインストールする
$ gem install bundler
・アプリケーション用のディレクトリの作成
$ mkdir -p ~/projects/sample_app && cd ~/projects/sample_app
・Gemfileを作成する
$ bundle init
・RailsのインストールのためGemfileを編集する
$ vi Gemfile
■Gemfile
------------------------------------------------------------
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
gem 'rails'
------------------------------------------------------------
・Railsをvendor/bundleにインストールする
$ bundle install --path vendor/bundle
・Railsのサンプルアプリケーションを作成する
$ bundle exec rails new .
※Gemfileを上書きするかどうか聞かれるため、Yを入力しEnterを押す
...
Overwrite /home/rails/projects/sample_app/Gemfile? (enter "h" for help) [Ynaqdh] Y
...
・UnicornをインストールするためGemfileを編集する
$ vi Gemfile
■Gemfile
-----------------------------------------------------------
---省略---
gem 'unicorn'
gem 'uglifier'
gem 'coffee-rails'
---省略---
-----------------------------------------------------------
・Unicornをvendor/bundleにインストールする
$ bundle install --path vendor/bundle
Unicornのインストール後、今回表示させるサンプルアプリケーションを作成します。
・サンプルアプリケーション、データベースの作成
$ bundle exec rails generate scaffold board title:string text:string
$ rake db:migrate
・アプリケーションのルーティングを設定する
$ vi ~/projects/sample_app/config/routes.rb
■routes.rb
-----------------------------------------------------------
Rails.application.routes.draw do
resources :boards
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root "boards#index"
end
-----------------------------------------------------------
アプリケーション作成後、Firewallで3000ポートを一時的に開放し、サンプルアプリケーションが表示できるか検証します。
・Firewallの3000ポートを開放する
# firewall-cmd --add-port=3000/tcp --zone=public --permanent
# firewall-cmd --reload
・Railsサーバを起動する
$ bundle exec rails server -b <サーバのIPアドレス>
ポート開放後、ブラウザで「http://<サーバのIPアドレス>:3000」にアクセスし、アプリケーションが表示されれば成功です。

サンプルアプリケーションの検証後、3000ポートを閉じておきます。
・Firewallの3000ポートを閉じる
# firewall-cmd --remove-port=3000/tcp --zone=public --permanent
# firewall-cmd --reload
unicorn.rbの設定
サンプルアプリケーション作成後、Unicornの設定ファイルのunicorn.rbを新規作成します。
・unicorn.rbを作成する
$ vi ~/projects/sample_app/config/unicorn.rb
■unicorn.rb
-----------------------------------------------------------
# -*- coding: utf-8 -*-
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true
# Unicornのsock、pidファイルのパスを指定
listen "/home/rails/projects/sample_app/tmp/unicorn.sock"
pid "/home/rails/projects/sample_app/tmp/unicorn.pid"
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
# Unicornのログのパスを指定
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
-----------------------------------------------------------
Unicornの起動・停止用テンプレートファイルの作成
unicorn.rb作成後、Unicornの起動・停止用のテンプレートファイルを作成します。手動で起動を行うことも可能ですが、Unicornの管理を簡単にするため、今回はテンプレートファイルを作成します。
テンプレートファイルの内容は、以下の記事を参考にしました。
・Rails 4.2 + Unicorn + Nginx でアプリケーションサーバの構築
・テンプレートファイルの作成
$ bundle exec rails generate task unicorn
・テンプレートファイルの編集
$ vi ~/projects/sample_app/lib/tasks/unicorn.rake
■unicorn.rake
-----------------------------------------------------------
namespace :unicorn do
##
# Tasks
##
desc "Start unicorn for development env."
task(:start) {
config = Rails.root.join('config', 'unicorn.rb')
sh "bundle exec unicorn_rails -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
def unicorn_signal signal
Process.kill signal, unicorn_pid
end
def unicorn_pid
begin
File.read("/home/rails/projects/sample_app/tmp/unicorn.pid").to_i
rescue Errno::ENOENT
raise "Unicorn doesn't seem to be running"
end
end
end
-----------------------------------------------------------
テンプレートファイル作成後、Unicornを起動します。
・Unicornの起動
$ bundle exec rake unicorn:start
今回は起動した状態としておきますが、Unicornを停止する場合は以下のコマンドを入力します。
・Unicornの停止
$ bundle exec rake unicorn:stop
Nginxの設定
Unicornのテンプレートファイル作成後、NginxでUnicornを使用する設定を行います。今回はnginx.confファイルに設定を行わず、/etc/nginx/conf.d配下にsample_app.confというファイルを作成し設定を行います。
・default.confからsample_app.confを作成し、default.confをリネームする
# cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/sample_app.conf
# mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
・sample_app.confを編集する
# vi /etc/nginx/conf.d/sample_app.conf
■sample_app.conf
-----------------------------------------------------------
upstream unicorn {
server unix:/home/rails/projects/sample_app/tmp/unicorn.sock;
}
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/sample_app_access.log;
error_log /var/log/nginx/sample_app_error.log;
root /home/rails/projects/sample_app/public;
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 @unicorn {
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;
proxy_pass http://unicorn;
}
}
-----------------------------------------------------------
sample_app.confの編集後、設定ファイルのチェックを行い、問題なければNginxを再起動します。
・Nginxの設定ファイルをチェックする
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
・Nginxを再起動する
# systemctl restart nginx
Nginxの再起動後、今回は/home/rails配下にRuby、Unicorn等を配置しているため、「403 Forbidden」を回避するため/home/railsディレクトリにその他ユーザーの実行権を付与します。
・/home/railsディレクトリにその他ユーザーの実行権を付与する
# chmod o+x /home/rails
動作確認
Nginxの再起動後、ブラウザで「http://<サーバのIPアドレス>」にアクセスし、先程のサンプルアプリケーションが表示されれば成功です。
