I like to use jruby for deploying rails application in production. No need to install additional system packages. You only need java. The only part a little bit complex is when you want to install the application in a subdirectory of your web site.
I develop with ruby MRI. jruby is fast but you still feel some slowness when the jvm is loading.
The first step is to configure the Gemfile to load the appropriate gems for mri ruby and jruby. :platform allow to specify the specific gems for each environment.
Here for jruby :
gem 'activerecord-jdbcsqlite3-adapter', :platform=>:jruby gem 'jruby-openssl', :platform=>:jruby gem 'therubyrhino', :platform=>:jruby gem 'trinidad'
And for ruby :
gem 'sqlite3', :platform=>:ruby gem 'therubyracer', :platform=>:ruby gem "thin", ">= 1.5.0", :platform=>:ruby, :group => [:development, :test] gem "unicorn", ">= 4.3.1", :platform=>:ruby, :group => :production
It’s the minimum gems i modify on a project. Depending on what you use, the list can differ(if you want postgresql or mysql support for example).
It’s a great application server and pretty easy to setup. You only need to create a trinidad.yml configuration file in config directory.
Here my default trinidad.yml :
address: 127.0.0.1 # set to 127.0.0.1 if Trinidad behind a web server such as Apache port: 3000 # port where Trinidad is running http: # HTTP connector setup environment: production jruby_min_runtimes: 1 # min number of JRuby runtimes to use jruby_max_runtimes: 1 # max number of JRuby runtimes to use jruby_compat_version: 2.0 # or 1.8 by default uses the same as trinidad is running context_path: /file_sharer # default context path root_dir: "." # system path where the application is located, by default is PWD rackup: config.ru # rackup script if you are running a (non-Rails) Rack application public: public # system path (relative to root) where your public files are located
I use trinidad behind apache so i am listening only on 127.0.0.1.
context_path is the directive used to specify the sub directory in the web site where the application will be installed. For example, i set it to “file_sharer”
It will strip down this part when sending requests to rails.
With this setting, /file_sharer/home will become /home for rails. So no need to modify routes.rb file for production deployment in sub directory.
With the previous setting, all request will come to rails with the expected route format. But it’s necessary to specify to Rails to generate links including the sub directory part.
Rails provides the following way :
- RAILS_RELATIVE_URL_ROOT environment variable
- config.relative_url_root configuration parameter
- config.action_controller.relative_url_root configuration parameter
I didn’t use the environment variable. It’s used to define the default value for the two other configuration parameters. But i prefer to have the parameters set directly in the application.
It’s possible to set them in config/environments/production.rb :
config.relative_url_root = "/file_sharer" config.action_controller.relative_url_root = "/file_sharer"
So now the controller requests and application links are well processed but trinidad doesn’t process assets. It’s possible to do it but i already proxy requests to trinidad through apache so i want to serve assets with it.
Here the configuration to pass the requests to trinidad :
ProxyPass /file_sharer http://127.0.0.1:3000/file_sharer connectiontimeout=300 timeout=300 ProxyPassReverse /file_sharer http://127.0.0.1/file_sharer
For assets, i need to specify to not proxy the requests with the ProxyPass ! directive :
Alias /file_sharer/assets /data/file_sharer/public/assets <Location /file_sharer/assets> ProxyPass ! </Location> Alias /file_sharer/images /data/file_sharer/public/images <Location /file_sharer/images> ProxyPass ! </Location> Alias /file_sharer/uploads /data/file_sharer/public/uploads <Location /file_sharer/uploads> ProxyPass ! </Location>
And to authorize access :
<Directory /data/file_sharer/public> Order allow,deny Allow from all </Directory>
Honestly, i find it difficult and complex to setup rails in subdirectory. It would be so much better if configuring config.relative_url_root would take care of all. But it’s working, so it’s enough :)