wiki:QuickstartRack

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