TOP > カテゴリ > Ruby・Ruby on Rails >

Nginx + Unicornで複数のRailsプロジェクトを実行する [CentOS]

Nginx/Unicornで1つのドメイン(IPアドレス)で複数のRuby on Railsのプロジェクトを実行する方法です。

やること

http://IPアドレス/aaa/Ruby on Railsプロジェクト
実際のパス:/home/ユーザー名/myapp1
http://IPアドレス/bbb/Ruby on Railsプロジェクト
実際のパス:/home/ユーザー名/myapp2

※サブディレクトリを切って実行させています。

実行例

http://IPアドレス/aaa/

http://IPアドレス/bbb/

既存のユニコーンのオフ (任意)

上記の関連記事を進めた方は既にunicornの自動起動の設定がされています。今回はそれをオフにしてから進みます。

// サービスの確認
sudo chkconfig --list

// unicornの自動起動のオフ
sudo chkconfig unicorn off

// 必要であればunicornファイルも削除する
sudo rm /etc/init.d/unicorn

// ココでOSを再起動します。

1. Railsプロジェクトの作成

[myapp1]

// Railsプロジェクト
cd ~/
mkdir myapp1
cd myapp1
rails new . -d postgresql
 
※/home/ユーザー名/myapp1にプロジェクトが生成される
 
// データベースの生成
bin/rails db:create
 
// モデルの作成(モデル/マイグレーションファイルの生成)
bin/rails g model Cat name:string description:text
 
// マイグレーションの実行(テーブルの生成)
bin/rails db:migrate
 
// コントローラーの作成(コントローラー/ビューの生成)
bin/rails g controller cats index show new edit
 
// Gemfileファイルの編集
vi /home/ユーザー名/myapp1/Gemfile
※/home/ユーザー名/myapp1/Gemfileの末尾を次のようにする
 
#gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'unicorn'
 
// Gemfileファイルを元に各Gemをインストール
bundle

[myapp2]

// Railsプロジェクト
cd ~/
mkdir myapp2
cd myapp2
rails new . -d postgresql
 
※/home/ユーザー名/myapp2にプロジェクトが生成される
 
// データベースの生成
bin/rails db:create
 
// モデルの作成(モデル/マイグレーションファイルの生成)
bin/rails g model Dog name:string description:text
 
// マイグレーションの実行(テーブルの生成)
bin/rails db:migrate
 
// コントローラーの作成(コントローラー/ビューの生成)
bin/rails g controller dogs index show new edit
 
// Gemfileファイルの編集
vi /home/ユーザー名/myapp2/Gemfile
※/home/ユーザー名/myapp2/Gemfileの末尾を次のようにする
 
#gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'unicorn'
 
// Gemfileファイルを元に各Gemをインストール
bundle

2. config/routes.rbの編集

// myapp1/config/routes.rb
Rails.application.routes.draw do
  get 'cats/index'
  get 'cats/show'
  get 'cats/new'
  get 'cats/edit'

  root to: 'cats#index'
end

// myapp2/config/routes.rb
Rails.application.routes.draw do
  get 'dogs/index'
  get 'dogs/show'
  get 'dogs/new'
  get 'dogs/edit'
  
  root to: 'dogs#index'
end

3. プロジェクト名/config.ruの編集

[myapp1]

RAILS_RELATIVE_URL_ROOT='/aaa'
 
require_relative 'config/environment'
 
if RAILS_RELATIVE_URL_ROOT then
  map RAILS_RELATIVE_URL_ROOT do
    run Rails.application
  end
else
  run Rails.application
end
 
# 元のコード
# require_relative 'config/environment'
# run Rails.application

[myapp2]

RAILS_RELATIVE_URL_ROOT='/bbb'
 
require_relative 'config/environment'
 
if RAILS_RELATIVE_URL_ROOT then
  map RAILS_RELATIVE_URL_ROOT do
    run Rails.application
  end
else
  run Rails.application
end
 
# 元のコード
# require_relative 'config/environment'
# run Rails.application

4. config/unicorn.rbを作成する

myapp1/myapp2にそれぞれ作成します。

worker_processes Integer(ENV["WEB_CONCURRENCY"] || 4)
timeout 15
preload_app true
 
listen '/home/ユーザー名/プロジェクト名/tmp/unicorn.sock'
pid    '/home/ユーザー名/プロジェクト名/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
 
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

5. Unicornの起動/停止スクリプトを作成する

[myapp1]

cd /home/ユーザー名/myapp1
bin/rails g task unicorn

[myapp1/lib/tasks/unicorn.rake]

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
      File.read("/home/ユーザー名/プロジェクト名/tmp/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn does not seem to be running"
    end
  end
end

※myapp2も同様な操作を行います。

6. Nginxの設定ファイル(nginx.conf)の編集

sudo vi /etc/nginx/nginx.conf

user ユーザー名;

worker_processes auto;

events {
    worker_connections  1024;
}

http {
    server_tokens off;
    
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

※/*.confからコメントの緑色になっていますが、全て必要です。

Nginxのバージョンが1.12より新しい場合は「/etc/nginx/conf.d/default.conf」が存在する場合があります。その場合は正常に動作しないので「sudo rm /etc/nginx/conf.d/default.conf」でdefault.confを削除して下さい。

7. myapp.confを作成する

sudo vi /etc/nginx/conf.d/myapp.conf

upstream unicorn_myapp1 {
    server  unix:/home/ユーザー名/myapp1/tmp/unicorn.sock;
}

upstream unicorn_myapp2 {
    server  unix:/home/ユーザー名/myapp2/tmp/unicorn.sock;
}
 
server {
    listen       80;
    server_name  IPアドレス; 
    
    client_max_body_size 100m;
    error_page   404              /404.html;
    error_page   500 502 503 504  /50x.html;          
    
    
    # /home/ユーザー名/プロジェクト名/publicの各ファイルにアクセス可能にする
    location ~ ^/aaa/assets/(.*) {
        alias /home/ユーザー名/myapp1/public/assets/$1;
    }        
    location ~ ^/bbb/assets/(.*) {
        alias /home/ユーザー名/myapp2/public/assets/$1;
    }        
    
    # myapp1
    location /aaa/ {
        alias /home/ユーザー名/myapp1/public;  
        try_files $uri @unicorn_myapp1;    
    }
    location @unicorn_myapp1 {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_pass http://unicorn_myapp1;
    }    
    
    # myapp2
    location /bbb/ {
        alias /home/ユーザー名/myapp2/public;  
        try_files $uri @unicorn_myapp2;    
    }
    location @unicorn_myapp2 {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_pass http://unicorn_myapp2;
    }  
}

8. 動作確認

// myapp1のユニコーン起動
cd /home/ユーザー名/myapp1
// bundle exec rake unicorn:stop ※これは停止
bundle exec rake unicorn:start

// myapp2のユニコーン起動
cd /home/ユーザー名/myapp2
// bundle exec rake unicorn:stop ※これは停止
bundle exec rake unicorn:start

// ユニコーンの起動確認
ps -ef | grep unicorn | grep -v grep 

// Nginxのリスタート
sudo systemctl restart nginx

9. ユニコーンの自動起動

Unicornの自動起動を参考にして下さい。

関連

Nginx + Pumaで複数のRailsプロジェクトを実行する





掲示板

ソフトウェア、ハードウェアのプログラミング用の掲示板を作成しました。質問やわからない事は@掲示板でユーザー同士で情報を共有して下さい。

関連記事



公開日:2019年09月16日 最終更新日:2019年10月04日
記事NO:02769