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