If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

The configuration we introduce here is useful for heavy loaded production sites. SCGI is a light protocol that is similar in scope to FCGI, but designed to be much simpler and lighter on the network.

To make web2py work with SCGI we have to consider that web2py is by all means a WSGI application. There are a lot of examples on how to make WSGI talk SCGI, but of course web2py has already a small SCGI<->WSGI server included. Before we can start using it we must choose a SCGI implementation for python. We suggest wsgitools. We can install the python package:

# pip install wsgitools

or

# easy_install wsgitools

now we can start web2py as a SCGI server:

$ cd <web2py installation root>

$ python scgihandler.py & #start the server in background

$ disown $! #detach the server from the terminal.  You can close the terminal afterwards.

Now we would like to serve the pages through HTTP not SCGI! So what we need is a web server that can speak to SCGI backends. We need a fast one and easy to configure, so we choose nginx. Since nginx comes with a nice SCGI module we need only to write a little piece of configuration in nginx.conf (usually under /etc/nginx). In a server section of choice put the following

    set $web2pyroot <web2py root folder>;

            #serve static content without web2py intervention
    location ~ ^/(.*)/static/(.*) {
         alias $web2pyroot/applications/$1/static/$2;
    }

            # use port 4000 the default definend in scgihandler.py
    location / { 
         include /etc/nginx/scgi_params;
         scgi_pass 127.0.0.1:4000;
    }

If you have a recent version of nginx you can take advantage of HTTP keep-alive conection even when requesting data from the upstream SCGI server (i.e. web2py).  Older versions of nginx supported keep-alive connections only when serving static content. The setup is the same above, but we introduce an upstream block in the http section of nginx.conf

upstream scgi_web2py {
         server 127.0.0.1:4000;
         keepalive 512;
}


And the above configuration then becomes:

   set $web2pyroot <web2py root folder>;

    #serve static content without web2py intervention
    location ~ ^/(.*)/static/(.*) {
         alias $web2pyroot/applications/$1/static/$2;
    }

            # use port 4000 the default definend in scgihandler.py
    location / { 
         include /etc/nginx/scgi_params;
         scgi_pass scgi_web2py;
    }

Start nginx and we are done. Was that fast? See it running!

If you need to finetune the number of web2py processes you can edit last line of the scgihandler.py file.  For instance the following sets a maximum of 7 processes and a minimum of 2:

SCGIServer(application, port=4000, minworkers=2, maxworkers=7).enable_sighandler().run()

Kill the SCGI server and restart it as usual.  The suggestion is to have no more than 2 web2py/SCGI processes per each core.


 


[Update: 2012-03-10]

 

Now scgihandler is faster since supports gzip compression when the browser sends the appropriate HTTP header:

Accept-Encoding: gzip

 


[Update: 2012-05-16]

To enable succesful detection of https scheme by web2py you can pass the HTTPS environment variable to the SCGI server by adding the following statement in the location / block:

                         scgi_param HTTPS yes;

 

 

 


[Update: 2012-06-13]

Robust way to daemonize scgiserver.py and have it run forever with little resources.

 

 

 

Related slices

Comments (5)

  • Login to post



  • 0
    matt-gorecki-10806 12 years ago

    You can also add a uwsgi_param to your location to force uwsgi to see the connection as https.

    Here's what part of my nginx config looks like, UWSGI_SCHEME is the param that needs set.

            location / {
    
                    include        uwsgi_params;
                    root   /opt/www/managesite/htdocs;
                    uwsgi_param UWSGI_SCHEME https;
                    uwsgi_pass 127.0.0.1:3031;
            }
    replies (1)
    • michelecomitini 12 years ago

      This is not a uwsgi but a *SCGI* setup. Anyway your suggestion has been applied to the tutorial above. tnx


  • 0
    michelecomitini 12 years ago

    To avoid the "Admin is disabled because insecure channel" you have some options I use two:

    1. Setup the nginx to serve over TLS/SSL (see nginx docs);
    2. connect to the server via ssh like this:
    ssh root@your.server -L 1880:localhost:80

    browse to http://localhost:1880/admin

     

     


  • 0
    francis-kayiwa-11134 12 years ago

    Thanks! This worked. Thanks for pointers on how to use this and avoid "Admin is disabled because insecure channel".

     

    Cheers

    replies (1)
    • michelecomitini 12 years ago

      See my last comment above for a possible solution. Thanks!


  • 0
    rochacbruno 13 years ago
    I am running some web2py instances under NGINX+UWSGI on Ubuntu Linode. Do you recommend moving my apps to SCGI?

  • 0
    michelecomitini 13 years ago
    Give it a try! If it works well , you can go back to uwsgi if you need some of its features or more fine tuning... The proposed configuration works very well on multicores due to multiprocessing. Let me know how it goes! Mic

Hosting graciously provided by:
Python Anywhere