Ashigaruコンピューター道

ソフトウェアの話とか、キャリアの話とか

1つのサーバに2つのrailsアプリを共存させる方法

個人で作成しているKindleセール本まとめサイトで、railsアプリを1サーバに共存させる必要が出てきたのでその方法。

概要

http://kinsume.infoにアクセスした時はrails5.0.1のアプリに飛ばして、http://kinsume.info/kinsume_blogにアクセスされた時は、rails4.2.7のアプリに飛ばしたい。
kinsume_blogで動くアプリはオープンソースCMS refinery-cmsを使用したかったのだが、rails4.x系にしか対応していなかったので、苦肉の策ではある。

環境はUbuntu, Nginx, Unicorn

手順

まず、すでに動いているrails5.x系, ruby 2.3.xの環境には影響を与えたくなかったので、ruby 2.2.7をインストールして、ruby周りの環境を整える。


cd ~/repos/kinsume_blog
rbenv local install 2.2.7
gem install bundler
bundle install

Unicornの設定ファイルを作成

新しく設定したいアプリの下で、vim config/unicorn.rbでファイルを新規作成。


app_path = File.expand_path(File.dirname(FILE) + '/..')$
$
# workerをいくつ立ち上げるか。ここではCMSであまりアクセスないことを$
# 想定していて、メモリの空きもないので1にしている。$
worker_processes 1$
$
# どのソケットで連携するかNginxの設定ファイルにも書くので覚えておく$
listen app_path + '/tmp/kinsume_blog.sock', backlog: 64$
timeout 300$
working_directory app_path$
$
# この辺もすでに動いているアプリと被らないようにする$
pid app_path + '/tmp/kinsume_blog.pid'$
stderr_path app_path + '/log/kinsume_blog.log'$
stdout_path app_path + '/log/kinsume_blog.log'$
$
preload_app true$
$
GC.respond_to?(:copy_on_write_friendly=) &&$
GC.copy_on_write_friendly = true$
$
before_fork do |server, worker|$
defined?(ActiveRecord::Base) &&$
ActiveRecord::Base.connection.disconnect!$
end$
$
after_fork do |server, worker|$
defined?(ActiveRecord::Base) &&$
ActiveRecord::Base.establish_connection$
end$

railsアプリのルートパスを変える。refinery-cmsのパスを変えるには下記ファイルを変更。

vim config/initializers/refinery/core.rb


  # Specify a different Refinery::Core::Engine mount path than the default of "/".$
# Make sure you clear the tmp/cache directory after changing this setting.$
config.mounted_path = "/kinsume_blog"$


わかりやすくなるように、静的ファイルのパスを元のアプリと変える。

vim config/environments/production.rb


  config.assets.prefix = '/static'$

Nginxの設定ファイルは以下


upstream tagosaku{$
server unix:/home/ishioka/repos/tagosaku/tmp/tagosaku.sock fail_timeout=0;$
}$

# 先ほど作成したアプリのソケットファイルをここで指定
upstream kinsume_blog{$
server unix:/home/ishioka/repos/kinsume_blog/tmp/kinsume_blog.sock fail_timeout=0;$
}$
$
server {$
error_log /var/log/nginx/error.log debug;$
listen 80;$
$
root /home/ishioka/repos/tagosaku;$
index index.html index.htm;$
$
keepalive_timeout 300;$
client_max_body_size 4G;$

 # kinsume_blogないで使っているgemから走るアクセスパスをどうしても変えられなかったので悲しみのrewriteで対応
rewrite ^/wymiframe$ /kinsume_blog/wymiframe last;$
$
# ここでもkinsume_blogないのgemから走るアクセスを変えられなかったので、いったんassetsを見てふぁいるがなければ/static/を見に行くように変更
location ~ ^/assets/(.*) {$
root /home/ishioka/repos/tagosaku/public/;$
try_files $uri /static/$1 =404;$
}$
$
 # staticへのアクセスはkinsume_blogの静的ファイルへのアクセスなのでロケーションを変更
location /static/ {$
root /home/ishioka/repos/kinsume_blog/public/;$
}$

location / {$
# First attempt to serve request as file, then$
# as directory, then fall back to displaying a 404.$
#try_files $uri $uri/ =404;$
$
# Uncomment to enable naxsi on this location$
# include /etc/nginx/naxsi.rules$
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;$
proxy_set_header Host $http_host;$
proxy_set_header X-Forwarded_Proto $scheme;$
proxy_redirect off;$
$
# This passes requests to unicorn, as defined in /etc/nginx/nginx.conf$
proxy_set_header Host $http_host;$
proxy_pass http://tagosaku;$
proxy_read_timeout 300s;$
proxy_send_timeout 300s;$
}$
$
location /kinsume_blog {$
# First attempt to serve request as file, then$
# as directory, then fall back to displaying a 404.$
#try_files $uri $uri/ =404;$
$
# Uncomment to enable naxsi on this location$
# include /etc/nginx/naxsi.rules$
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;$
proxy_set_header Host $http_host;$
proxy_set_header X-Forwarded_Proto $scheme;$
proxy_redirect off;$
$
# This passes requests to unicorn, as defined in /etc/nginx/nginx.conf$
proxy_set_header Host $http_host;$
proxy_pass http://kinsume_blog;$
proxy_read_timeout 300s;$
proxy_send_timeout 300s;$
}$
$
error_page 500 502 503 504 /500.html;$
$
location = /500.html {$
root /home/ishioka/repos/tagosaku/public;$
}$
}


refinery-cmsのpluginからリクエストされる静的ファイルのパスを/から/kinsume_blogへ変更することができなかったので、nginxのrewriteを駆使して対応。 

あまりアクセスパスを変更されることを想定されてない作りっぽいので、PR出していきたい。