Skip to content

Latest commit

 

History

History
229 lines (157 loc) · 6.8 KB

Nginx.rst

File metadata and controls

229 lines (157 loc) · 6.8 KB

Nginx support

Nginx natively includes support for upstream servers speaking the :doc:`uwsgi protocol<Protocol>` since version 0.8.40.

If you are unfortunate enough to use an older version (that nevertheless is 0.7.63 or newer), you can find a module in the nginx directory of the uWSGI distribution.

Building the module (Nginx 0.8.39 and older)

Download a >=0.7.63 release of nginx and untar it at the same level of your uWSGI distribution directory. Move yourself into 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 now configure Nginx to pass requests to the uWSGI server.

Configuring Nginx

First of all copy the uwsgi_params file (available in the nginx directory of the uWSGI distribution) into your Nginx configuration directory, then in a location directive in your Nginx configuration add:

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;

Then simply reload Nginx and you are ready to rock your uWSGI powered applications through Nginx.

What is the uwsgi_params file?

It's convenience, nothing more! For your reading pleasure, the contents of the file as of uWSGI 1.3:

uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_ADDR $server_addr;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
.. seealso:: :doc:`Vars`

Clustering

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

Add an upstream directive outside the server configuration block:

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;

Your requests will be balanced between the uWSGI servers configured.

Dynamic apps

The uWSGI server can load applications on demand when passed special vars.

uWSGI can be launched without passing it any application configuration:

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

If a request sets 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 per-location:

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

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

The WSGI standard dictates that SCRIPT_NAME is the variable used to select a specific application.

The uwsgi_modifier1 30 option sets the uWSGI modifier 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 best performance and security, remember to configure Nginx to serve static files instead of letting your poor application handle that instead.

The uWSGI server can serve static files flawlessly but not as quickly and efficiently as a dedicated web server like Nginx.

For example you can the Django /media path could be mapped like this:

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

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

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

Virtual Hosting

You can use Nginx's virtual hosting without particular problems.

If you run "untrusted" web apps (such as those of your clients if you happen to be an ISP) you should limit their memory/address space usage and use a different uid for each host/application:

server {
  listen 80;
  server_name customersite1.com;
  access_log /var/log/customersite1/access_log;
  location / {
    root /var/www/customersite1;
    uwsgi_pass 127.0.0.1:3031;
    include uwsgi_params;
  }
}

server {
  listen 80;
  server_name customersite2.it;
  access_log /var/log/customersite2/access_log;
  location / {
    root /var/www/customersite2;
    uwsgi_pass 127.0.0.1:3032;
    include uwsgi_params;
  }
}

server {
  listen 80;
  server_name sivusto3.fi;
  access_log /var/log/customersite3/access_log;
  location / {
    root /var/www/customersite3;
    uwsgi_pass 127.0.0.1:3033;
    include uwsgi_params;
  }
}

The customers' applications can now be run (using the process manager of your choice, such as rc.local, :doc:`Upstart`, Supervisord or whatever strikes your fancy) with a different uid and a limited (if you want) address space for each socket:

uwsgi --uid 1001 -w customer1app --limit-as 128 -p 3 -M -s 127.0.0.1:3031
uwsgi --uid 1002 -w customer2app --limit-as 128 -p 3 -M -s 127.0.0.1:3032
uwsgi --uid 1003 -w django3app --limit-as 96 -p 6 -M -s 127.0.0.1:3033

FastFuncs

You can use :doc:`FastFuncs` with Nginx by setting the uwsgi modifiers and disabling request headers and body.

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

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;
 }

Eval modifier

Note

Available since 0.9.5.1.

:doc:`Modifier<Modifiers>` 22 allows you to directly pass Python code to uWSGI that will be evaluated. An example:

uwsgi_pass 127.0.0.1:3031;
uwsgi_pass_request_headers off;
uwsgi_pass_request_body off;
uwsgi_string "
import uwsgi
uwsgi.start_response('200 OK', [('Content-type','text/plain')])
total = 30+22
uwsgi.send("30 + 22 = %d" % total)
";
uwsgi_modifier1 22;
uwsgi_modifier2 0;