FAQ

Page Discussion History

Difference between revisions of "HttpUwsgiModuleMultipleDynamicApplications"

(the previous version will not work because of it bind a UNIX socket,NOT TCP)
 
m (":" were left out in the python code; uwsgi doesn't have the arg "--no-site"; changed spacings to better match other documentation)
 
(One intermediate revision by one user not shown)
Line 2: Line 2:
  
 
<geshi lang="nginx">
 
<geshi lang="nginx">
  upstream uwsgi_host
+
upstream uwsgi_host {
  {
+
    server 127.0.0.1:1088;
      server 127.0.0.1:1088;
+
}
  }
+
  
  include uwsgi_params;
+
include uwsgi_params;
  uwsgi_param SCRIPT_NAME  $app;         
+
uwsgi_param SCRIPT_NAME  $app;         
  uwsgi_param UWSGI_MODULE  $app;
+
uwsgi_param UWSGI_MODULE  $app;
  uwsgi_param UWSGI_CALLABLE  "${app}_handler";
+
uwsgi_param UWSGI_CALLABLE  "${app}_handler";
  uwsgi_param UWSGI_PYHOME  $document_root;
+
uwsgi_param UWSGI_PYHOME  $document_root;
  uwsgi_param UWSGI_CHDIR  $document_root;
+
uwsgi_param UWSGI_CHDIR  $document_root;
  uwsgi_modifier1  30;  #properly sets PATH_INFO variable
+
uwsgi_modifier1  30;  #properly sets PATH_INFO variable
  
  server
+
server {
  {
+
    server_name  foo;
      server_name  foo;
+
    root  /var/www/foo;
      root  /var/www/foo;
+
  
      location /app1/  
+
    location /app1/ {
      {
+
        set  $app  app1;
        set  $app  app1;
+
        uwsgi_pass  127.0.0.1:1088;
        uwsgi_pass  127.0.0.1:1088;
+
    }
      }
+
  
      location /app2/  
+
    location /app2/ {
      {
+
        set  $app  app2;
        set  $app  app2;
+
        uwsgi_pass  127.0.0.1:1088;
        uwsgi_pass  127.0.0.1:1088;
+
    }
      }
+
}
  }
+
  
  server
+
server {
  {
+
    server_name  bar;
      server_name  bar;
+
    root  /var/www/bar;
      root  /var/www/bar;
+
  
      location /app1/  
+
    location /app1/ {
      {
+
        set  $app  app1;
        set  $app  app1;
+
        uwsgi_pass  uwsgi_host;
        uwsgi_pass  uwsgi_host;
+
    }
      }
+
  
      location /app3/  
+
    location /app3/ {
      {
+
        set  $app  app3;
        set  $app  app3;
+
        uwsgi_pass  uwsgi_host;
        uwsgi_pass  uwsgi_host;
+
    }
      }
+
}
  }
+
 
</geshi>
 
</geshi>
  
Line 57: Line 50:
 
Minimal set of params of uWSGI in this case would be:
 
Minimal set of params of uWSGI in this case would be:
 
<geshi lang="bash">
 
<geshi lang="bash">
uwsgi -s 127.0.0.1:1088 -M --no-site --vhost
+
uwsgi -s 127.0.0.1:1088 -M --vhost
 
</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')])
+
    start_response('200 OK', [('Content-Type', 'text/plain')])
  return b'app1'
+
    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')])
+
    start_response('200 OK', [('Content-Type', 'text/plain')])
  return b'app2'
+
    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')])
+
    start_response('200 OK', [('Content-Type', 'text/plain')])
  return b'app3'
+
    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).

Latest revision as of 17:59, 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 --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).