HttpUwsgiModuleMultipleDynamicApplications

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 --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).