Running uWSGI behind Nginx

In the 'nginx' directory of the distribution you will find the uwsgi handler for nginx.

Download a 0.7.x (stable) release of nginx (by the way the module works with the 0.8.x too) and untar it at the same level of your uwsgi distribution directory

Move yourself in the nginx-0.7.x directory and ./configure nginx to add the uwsgi handler to its module list:

./configure --add-module=../uwsgi/nginx/

then make and make install it.

If all goes well you can configure nginx to pass requests to the uWSGI server.

First of all add the uwsgi_params file (you will find it in the 'nginx' directory of the distribution) to the nginx conf directory then add to your nginx.conf (in a location directive):

            uwsgi_pass   unix:///tmp/uwsgi.sock;
            include        uwsgi_params;

or if you are using tcp sockets:

            uwsgi_pass   127.0.0.1:3031;
            include        uwsgi_params;

reload nginx and you are ready.

Clustering

Nginx has a beautiful integrated cluster support for all the upstream handlers.

Add an upstream directive out of the server block configuration

        upstream uwsgicluster {
                server unix:///tmp/uwsgi.sock;
                server 192.168.1.235:3031;
                server 10.0.0.17:3017;
        } 

Then modify your uwsgi_pass directive:

    uwsgi_pass   uwsgicluster;

Now your requests will be balanced to the various uWSGI server you have configured.

Dynamic apps

The uWSGI server can load application on demand passing it special vars.

You can launch the server without passing it configuration:

./uwsgi26 -s /tmp/uwsgi.sock -C -M 4 -A 4 -m

If a request set the UWSGI_SCRIPT var , the server will load the specified module:

location / {
            root   html;
            uwsgi_pass   uwsgicluster;
            uwsgi_param UWSGI_SCRIPT testapp;
            include        uwsgi_params;
        }

You can even configure multiple apps:

location / {
            root   html;
            uwsgi_pass   uwsgicluster;
            uwsgi_param UWSGI_SCRIPT testapp;
            include        uwsgi_params;
        }

        location /django {
            uwsgi_pass   uwsgicluster;
            include        uwsgi_params;
            uwsgi_param SCRIPT_NAME /django;
            uwsgi_param UWSGI_SCRIPT django_wsgi;
            uwsgi_modifier1 30;
        }

The WSGI standard says that the SCRIPT_NAME is the var used to select a specific application. The "uwsgi_modifier1 30" option set the UWSGI_MODIFIER_MANAGE_PATH_INFO. This per-request modifier instructs the uWSGI server to rewrite the PATH_INFO value removing the SCRIPT_NAME from it.

Static files

For the best performance, remember to configure nginx to serve static files. For example you can map the django /media directory on an ubuntu system in this way:

        location /media {
                alias /var/lib/python-support/python2.6/django/contrib/admin/media ;
        }

The uWSGI server can serve static files flawlessly but not as fast and efficiently as a webserver like nginx.

Some applications need to pass control to the UWSGI server only if the requested filename does not exists:

if (!-f $request_filename) {
    uwsgi_pass   uwsgicluster;
    include        uwsgi_params;
}

If used incorrecly this could cause security problem, so double check that your application files are outside of the root of the static files.

FastFuncs

You can use FastFuncs with nginx setting the uwsgi modifiers and disabling request headers and body.

The following example will request the fastfunc 11 for /xml uri:

location /xml {
                uwsgi_pass 127.0.0.1:3031;
                uwsgi_modifier1 26;
                uwsgi_modifier2 11;
                uwsgi_pass_request_headers off;
                uwsgi_pass_request_body off;
        }