FAQ

Page Discussion History

HttpUwsgiModuleMultipleDynamicApplications

Revision as of 12:21, 27 May 2011 by Shiny (Talk)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

There is a way to have a single uWSGI instance to provide backend for multiple hosts and/or applications per host:

   upstream uwsgi_host
   {
      server 127.0.0.1:1088;
   }
 
   include uwsgi_params;
   uwsgi_param SCRIPT_NAME   $app;        
   uwsgi_param UWSGI_MODULE   $app;
   uwsgi_param UWSGI_CALLABLE   "${app}_handler";
   uwsgi_param UWSGI_PYHOME   $document_root;
   uwsgi_param UWSGI_CHDIR   $document_root;
   uwsgi_modifier1   30;   #properly sets PATH_INFO variable
 
   server
   {
      server_name   foo;
      root   /var/www/foo;
 
      location /app1/ 
      {
         set   $app   app1;
         uwsgi_pass   127.0.0.1:1088;
      }
 
      location /app2/ 
      {
         set   $app   app2;
         uwsgi_pass   127.0.0.1:1088;
      }
   }
 
   server
   {
      server_name   bar;
      root   /var/www/bar;
 
      location /app1/ 
      {
         set   $app   app1;
         uwsgi_pass   uwsgi_host;
      }
 
      location /app3/ 
      {
         set   $app   app3;
         uwsgi_pass   uwsgi_host;
      }
   }

The key aspect of this setup is providing 2 uwsgi protocol parameters: SCRIPT_NAME and SERVER_NAME. While later is handled automatically, since it is mapped in stock /etc/nginx/uwsgi_params file, SCRIPT_NAME variable needs to be passed to backend explicitly because uWSGI roster of vhost applications is keyed on "host|script" and having same host and same script name (which will be blank unless defined) would yield same application handling all requests, whichever was first initialized. Please note the UWSGI_MODULE and UWSGI_CALLABLE variables, first one provides module which is used as entry point of the WSGI application (found by providing UWSGI_PYHOME, which adds parameter to the Python path) and the second variable states the name of class to be instanced.

Minimal set of params of uWSGI in this case would be:

uwsgi -s 127.0.0.1:1088 -M --no-site --vhost

And Python modules -

app1.py

def app1_handler(environ, start_response)   
   start_response('200 OK', [('Content-Type', 'text/plain')])
   return b'app1'

app2.py

def app2_handler(environ, start_response)   
   start_response('200 OK', [('Content-Type', 'text/plain')])
   return b'app2'

app3.py

def app3_handler(environ, start_response)   
   start_response('200 OK', [('Content-Type', 'text/plain')])
   return b'app3'

In this setup uWSGI will have two distinct app1 instances (one for host foo based on /var/www/foo/app1.py and one for host bar - /var/www/bar/app1.py), one app2 for foo (/var/www/foo/app2.py) and app3 for bar (/var/www/bar/app3.py).