HttpUwsgiModuleMultipleDynamicApplications
(the previous version will not work because of it bind a UNIX socket,NOT TCP) |
Curtlee2002 (Talk | contribs) m (":" were left out in the python code; uwsgi doesn't have the arg "--no-site"; changed spacings to better match other documentation) |
||
| Line 2: | Line 2: | ||
<geshi lang="nginx"> | <geshi lang="nginx"> | ||
| − | + | 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; | |
| − | + | } | |
| − | + | } | |
| − | + | ||
</geshi> | </geshi> | ||
| Line 64: | Line 57: | ||
app1.py | app1.py | ||
<geshi lang="python"> | <geshi lang="python"> | ||
| − | def app1_handler(environ, start_response) | + | def app1_handler(environ, start_response): |
| − | + | start_response('200 OK', [('Content-Type', 'text/plain')]) | |
| − | + | return b'app1' | |
</geshi> | </geshi> | ||
app2.py | app2.py | ||
<geshi lang="python"> | <geshi lang="python"> | ||
| − | def app2_handler(environ, start_response) | + | def app2_handler(environ, start_response): |
| − | + | start_response('200 OK', [('Content-Type', 'text/plain')]) | |
| − | + | return b'app2' | |
</geshi> | </geshi> | ||
app3.py | app3.py | ||
<geshi lang="python"> | <geshi lang="python"> | ||
| − | def app3_handler(environ, start_response) | + | def app3_handler(environ, start_response): |
| − | + | start_response('200 OK', [('Content-Type', 'text/plain')]) | |
| − | + | return b'app3' | |
</geshi> | </geshi> | ||
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). | 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). | ||
Revision as of 17:58, 17 April 2012
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).










