Ruby
passenger
RubyOnRails

Ruby on Railsのアプリをサブディレクトリで動かす場合のメモ

More than 3 years have passed since last update.

たまにRuby on Railsでアプリを作るのだけれどいつも忘れてしまうのでメモ。いろいろな人がすでに書いてるけど自分がよく使う環境に関連したマトメ。Ruby on Rails v4.2.0での動作確認も兼ねて。


Ajax関連

AjaxでアクセスするURLをJavaScriptでハードコーディングするとサブディレクトリで動かしたときに404になって困るのでファイルの拡張子をjs.erbとかjs.coffee.erbとかにしてRailsの機能でURLを生成するようにする。

例えばこんな感じ?


app/assets/javascripts/application.js.coffee.erb

<%= Rails.application.config.relative_url_root %><%= Rails.application.routes.url_helpers.search_people_path(format:'json') %>


なんか一発で取れるメソッドとかありそうな気もするし文字列連結してるのもちょっと嫌な感じもするけど、とりあえずこれで。

で、このRails.application.config.relative_url_rootについては当該ソースコードを見れば以下のように環境変数RAILS_RELATIVE_URL_ROOTの値が代入されていることがわかる。


railties-4.2.0/lib/rails/application/configuration.rb

@relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]   


ちなみにActionController::Base.relative_url_rootでも取得できる。当該ソースコードは以下のような感じなので、結局はRails.application.config.relative_url_root経由でRAILS_RELATIVE_URL_ROOT由来の値。


actionpack-4.2.0/lib/action_controller/railtie.rb

options.relative_url_root ||= app.config.relative_url_root


Rails.application.config.relative_url_rootActionController::Base.relative_url_rootの使い分けはよく分からないが、より上流にある前者の方が良い気もするし、コントローラ的には後者の方が良い気もするけど、私は元気です。


開発環境

Rails With Relative URL Rootの「結局おすすめは」を参考にして設定すると変更箇所も少なくうまくいった。

config.ruを以下のように書く。ここはRails.application.config.relative_url_rootの方がしっくりくる感ある。うむ。


config.ru

require ::File.expand_path('../config/environment', __FILE__)

map Rails.application.config.relative_url_root || '/' do
run Rails.application
end

サーバの起動時には環境変数RAILS_RELATIVE_URL_ROOTに値を指定する。

$ RAILS_RELATIVE_URL_ROOT=/piyo rails server

あ、最近はspringを使うのかい。インスタンスを再利用してくれて叩き直しが早いらしい。bundleとか使ってもう少ししつこく書くとこう。あと--bind=0.0.0.0すると他のマシンからでもアクセスできるよ。

$ RAILS_RELATIVE_URL_ROOT=/piyo bundle exec spring rails server -p 3000 --bind=0.0.0.0

ウェブブラウザからは以下のURLでアクセスできる。

http://localhost:3000/piyo/


本番環境


アセットのプリコンパイル

production環境だとデフォルトではassetsは動的にコンパイルされないのであらかじめコンパイルしておくのがたぶん普通。こっちの方がはやいもんね。でrake assets:precompileがそのプリコンパイルするRakeタスク。初心者はこれで泣きながら1日くらいさまよう罠。この時に環境変数RAILS_RELATIVE_URL_ROOTを指定して実行するのを忘れちゃいけない。

うちはDebianなので以下のような感じで実行する。rake assets:precompileを実行するとpublic/assets以下へ色々とコンパイルの成果物が配置されるわけだけどwww-dataってユーザでファイルを生成しとくのがたぶん普通。

sudo -u www-data -H bundle exec rake assets:precompile RAILS_ENV=production RAILS_RELATIVE_URL_ROOT=/piyo


Passengerの設定

Apache2の設定ファイルは以下な感じにする。PassengerBaseURIの値が環境変数RAILS_RELATIVE_URL_ROOTにセットされる。この辺は公式サイト参照。あと、PassengerRubyで実行させたいRubyの実行ファイルを指定できるので、色んなバージョンのアプリを動かすときに助かる。なお、Passengerは公式マニュアルをよく読んでから使ったほうが良い気がする。急がば回れ。


/etc/apache2/sites-enabled/000-default

Alias /piyo /srv/rails/piyo/public

<Location /piyo>
SetEnv SECRET_KEY_BASE 秘密の文字列
PassengerEnabled on
PassengerRuby /usr/local/bin/ruby
PassengerBaseURI /piyo
PassengerAppRoot /srv/rails/piyo
PassengerUser www-data
</Location>
<Directory /srv/rails/piyo/public>
Options -MultiViews
</Directory>

あと、DebianだとPassengerのモジュールの読込設定は/etc/apache2/httpd.confに書くんじゃあない。/etc/apache2/mods-availableの中を参考に然るべきファイルを設置してa2enmodで有効化する。この辺りはDebian流。