Ruby/Rack Quickstart
You can compile and install uwsgi with rack support using the "network installer"
curl http://uwsgi.it/install | bash -s rack /tmp/uwsgi
replace /tmp/uwsgi with the absolute path of where you want to install your new uwsgi server binary. Obviously choose a location in which you have write privileges.
To compile uWSGI with rack support you need ruby development files (libruby-dev on debian based distro, ruby-devel on redhat based), gcc (or clang) and python.
OSX users, if you get errors about missing symbols, or wrong architecture, use that trick:
curl http://uwsgi.it/install | CFLAGS="-arch i386 -arch x86_64" bash -s rack /tmp/uwsgi
As we want to use rack applications and middlewares, you need the rack gem too (gem install rack)
If you do not want to compile uWSGI youself, and your distribution is already providing you with a uWSGI stack, you only need to remember to add --plugins http,rack directive to all of the above uWSGI commandline examples.
Your first Rack app
save it to a file named myapp.ru
class RackApp def call(env) [200, {'Content-Type' => 'text/plain'}, ["Hello world!"]] end end run RackApp.new
then run it via uWSGI in http mode:
/tmp/uwsgi --http :8080 --http-modifier1 7 --rack myapp.ru
(remember to replace /tmp/uwsgi with whatever you have used previously)
or if you are using a modular build (like the one of your distro)
uwsgi --plugins http,rack --http :8080 --http-modifier1 7 --rack myapp.ru
What is that '--http-modifier1 7' thing ???
uWSGI supports various languages and platform. When the server receives a request it has to know where to 'route' it.
Each uWSGI plugin has an assigned number (the modifier), the ruby/rack one has the 7. So --http-modifier1 7 means "route to the rack plugin"
Using a full webserver: nginx
The supplied http router, is (yes, incredible) only a router. You can use it as a load balancer or a proxy, but if you need a full webserver (for efficiently serving static files or all of those task a webserver is good at), you can get rid of the uwsgi http router (remember to change --plugins http,rack to --plugins rack if you are using a modular build) and put your app behind nginx.
To communicate with nginx, uWSGI can use various protocol: http,uwsgi,fastcgi...
The most efficient one is the uwsgi one. Nginx includes uwsgi protocol support out of the box.
Run your rack application on a uwsgi socket:
/tmp/uwsgi --socket 127.0.0.1:3031 --rack myapp.ru
then add a location stanza in your nginx config
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
uwsgi_modifier1 7;
}
Reload your nginx server, and it should start proxying requests to your uWSGI instance
Note that you do not need to configure uWSGI to set a specific modifier, nginx will do it using the uwsgi_modifier1 7; directive
Adding concurrency
You can give concurrency to your rack apps via multiprocessing or fibers
To spawn additional processes use the --processes option
/tmp/uwsgi --socket 127.0.0.1:3031 --rack myapp.ru --processes 4
Adding robustness: the master process
It is highly recommended to have the master process always running on productions apps.
It will constantly monitor your processes and will add funny features like the StatsServer
To enable the master simply add --master
/tmp/uwsgi --socket 127.0.0.1:3031 --rack myapp.ru --processes 4 --master
Integration with Bundler
Bundler is very probably the best thing of these days after Diablo III.
If you want to have a dedicated pool of gems for your app simply define a "Gemfile" with the required gems.
source "http://rubygems.org" gem "sinatra" gem "nokigiri"
then run (from the same directory in which you have created the Gemfile)
bundle install --path <path_to_your_gempool>
it will install all of the gems required by your app in <path_to_your_gempool>
Now to use that Gemfile and its just created pool of gems:
/tmp/uwsgi --socket 127.0.0.1:3031 --rack myapp.ru --processes 4 --master --rbrequire rubygems --rbrequire bundler/setup --env BUNDLE_GEMFILE=<path_to_your_Gemfile>
Pretty ugly....
We will use a config file (call it myapp.ini)
[uwsgi] socket = 127.0.0.1:3031 rack = myapp.ru processes = 4 master = true rbrequire = rubygems rbrequire = bundler/setup env = BUNDLE_GEMFILE=<path_to_your_Gemfile>
then
/tmp/uwsgi --ini myapp.ini
Rails 3
Rails 3 is fully bundler-integrated. You can deploy a rails 3 app with
[uwsgi] socket = 127.0.0.1:3031 processes = 4 master = true chdir = <path_to_your_rails_app> rbrequire = rubygems rbrequire = bundler/setup rack = config.ru
This time we have not specified the BUNDLE_GEMFILE env, as by default bundler search for the Gemfile in the current directory, and we have moved to the rails one using chdir
Old Rails app (2.x)
For old rack-based rails app you can use the commodity option --rails
[uwsgi] socket = 127.0.0.1:3031 processes = 4 master = true rails = <path_to_your_rails_app>
Older Rails apps
For non-rack based apps you can use the adapter from the thin project (gem install thin).
uWSGI will automatically set the adapter if it detectes a non-rack rails app.
Going further
Check Rack, RubyOnRails, and rubyDSL for integration with the uWSGI api
