2017年7月17日月曜日

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出していきたい。





2017年7月6日木曜日

Ruby on rails で動くCMS Refinerycmsをセットアップする


趣味で作っているキンドルセールまとめサイトにブログコンテンツを載せたくなったので、いろいろ調べてRuby on rails で動く Refinerycmsを使用することにした。そのセットアップのメモ

環境構築

サービスがrails 4.2.xにしか対応していないので、その環境構築。現在のメイン環境ruby2.3.1 rails 5.xと共存させたいのでruby 2.7.xを入れてそこにいろいろ入れる。



# ruby 2.2.7 のインストール
rbenv install 2.2.7
rbenv rehash
rbenv global 2.2.7

# 動作に必要なgem install
gem install bundle
gem install refinerycms

# railsのプロジェクト作成
refinerycms blog_test
cd blog_test

# このフォルダは 2.2.7で動かしたいのでversion指定
touch .ruby-version; echo "2.2.7" > .ruby-version

# 開発用サーバ動かす
bundle exec rails s -b 0.0.0.0


ここまでやるとアクセスできるようになる。

この後本番環境で、既存のrailsプロジェクトと共存させたりしたいのでいろいろ設定が必要そうだが、それはまた今度

Pros And Cons

  • rails 4.x系でしか動かない(2017/07/06)
    • ただしrails 5.x系への対応PRは出ている
  • ドキュメントが古い
  • スタイル適応の仕組みがないのでデザイン変えたい時、CSS頑張るしかない。
    • これ自分的には相当面倒なんだが、他の人はどうなんやろ?
  • Rails wayから外れていないので、Rails知っている人には非常にとっつきやすい
  • 未だにメンテされている(活発ではなさそう)