Running RubyOnRails apps on uWSGI >=0.9.7-dev (stable from 0.9.9)
Starting from version 0.9.7-dev a Rack/ruby/rails plugin is officially available.
The official modifier is 7, so remember to set it in your webserver configuration
Ruby 1.8 and ruby 1.9 are supported.
You can build it embedded in the uWSGI core or as a plugin.
Embedding in the uWSGI core
In the buildconf directory there is already a rack.ini config that will build a uWSGI server with a ruby interpreter embedded.
(obviously you need the ruby headers)
python uwsgiconfig.py --build rack
Now your uwsgi binary can run rails app.
Typo and nginx
Install the typo gem and create a new instance
sudo gem install typo typo install /tmp/mytypo
Now run the uwsgi server with the process manager, 4 workers, memory report and post buffering (this is needed by Rack specification):
./uwsgi -s :3031 -M -p 4 -m --rails /tmp/mytypo --post-buffering 4096 --env RAILS_ENV=production
or use an xml file (we will call it typo.xml)
<uwsgi> <socket>:3031</socket> <master/> <processes>4</processes> <rails>/tmp/mytypo</rails> <post-buffering>4096</post-buffering> <env>RAILS_ENV=production</env> </uwsgi>
./uwsgi -x typo.xml
or a .ini one ( typo.ini )
[uwsgi] socket = :3031 master = true processes = 4 rails = /tmp/mytypo post-buffering = 4096 env = RAILS_ENV=production
./uwsgi --ini typo.ini
Now configure nginx location
location / {
root "/tmp/mytypo/public";
include "uwsgi_params";
uwsgi_modifier1 7;
if (!-f $request_filename) {
uwsgi_pass 127.0.0.1:3031;
}
}
Go to your browser and you should see you new shining typo instance running
Radiant and apache2
Install the radiant gem and create a new radiant instance
sudo gem install radiant radiant /tmp/myradiant cd /tmp/myradiant
edit your config/database.yml then fill it
rake production db:bootstrap
now run uwsgi server
./uwsgi -s :3031 -M -p 2 -m --rails /tmp/myradiant --post-buffering 4096 --env RAILS_ENV=production
and finally the apache configuration. This time we will map static file hardcoded in apache configuration (instead of checking for file existance at every request)
DocumentRoot /tmp/myradiant/public
<Directory /tmp/myradiant/public>
Allow from all
</Directory>
<Location />
uWSGISocket 127.0.0.1:3032
SetHandler uwsgi-handler
uWSGIForceScriptName /
uWSGImodifier1 7
</Location>
<Location /images>
SetHandler default-handler
</Location>
<Location /stylesheets>
SetHandler default-handler
</Location>
<Location /javascripts>
SetHandler default-handler
</Location>
Rack/Rails support as a plugin
A rackp.ini file is included in the buildconf directory. This will build the uWSGI core and the rack plugin as a shared library
python uwsgiconfig --build rackp
Now you can follow the same rules of the embedded one, but you must remember to load the plugin.
It is simple as adding the '--plugins rack' as the first option (it is not real necessary, the general rule is that a plugin must be loaded before specifying a related option)
./uwsgi --plugins rack -s :3031 -M -p 4 -m --rails /tmp/mytypo --post-buffering 4096 --env RAILS_ENV=production
or
[uwsgi] plugins = rack socket = :3031 master = true processes = 4 rails = /tmp/mytypo post-buffering = 4096 env = RAILS_ENV=production
Status and notes
By default the memory management of this plugin is very aggressive (as Ruby is a real memory devourer). After every request the GC is called. This can hurt a bit if your app create a lot of objects at every request. You can set the frequency at wich GC run using the --ruby-gc-freq <n> option. There is no a one-fit-for-all value so experiment a bit.
If your apps leaks memory without control, consider limiting the number of requests a worker can manage before being restarted (you can use the --max-requests options). Using the --limit-as can be a good choice too.
A bunch of uWSGI standard feature are missing in the plugin:
udp request management
SharedArea (already working on it)
see rubyDSL for list of currently supported features
A special note on threading
Adding threading support in ruby 1.8 is out of discussion. Thread support in this versions is pratically useless in a server like uWSGI. Ruby 1.9 has a threading mode very similar to the Python one, so adding it will be very simple (and super fast). Expect an update soon.
Ruby 1.9 Fiber
Fibers are a new feature of ruby 1.9. They are an implementation of coroutine/green-thread/stop-resume (or whatever you want to call those funny technlogies). See Fiber
SSL
For nginx you can use the following options to pass along the protocol used:
If serving a rails 2.x application over SSL:
uwsgi_param HTTPS on;
Or for a rails 3.x application:
uwsgi_param UWSGI_SCHEME https;
Post scriptum
You may wish to look at this Rack
