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

Webpy using Nginx and GUnicorn


Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX, light on server resources, and fairly speedy.



  • nginx
  • gunicorn
  • web2py



  • greenlet and eventlet or geventlet to use gunicorn's async workers


The idea is to configure NGINX as a proxy to redirect all http request to Gunicorn server who handle the WSGI.


Gunicorn configuration


    # 'mode': 'wsgi',
    'working_dir': '/var/www/web2py',
    # 'python': '/usr/bin/python',
    'args': (
        '--user=www-data', '--group=www-data',
        #'--worker-class=eventlet', # choose a worker class, here i'm using eventlet


Nginx configuration


upstream gunicorn {
        #server unix:/tmp/gunicorn.sock fail_timeout=0;
        # For a TCP configuration:
        server fail_timeout=0;

server {
        listen 80 default;
        client_max_body_size 4G;
        server_name $hostname;

        keepalive_timeout 5;

        location ~* /(\w+)/static/ {
                root /var/www/web2py/applications/;

        ## gunicorn
        location / {
                # checks for static file, if not found proxy to app
                try_files $uri @proxy_to_gunicorn;

        location @proxy_to_gunicorn {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;

                proxy_pass   http://gunicorn;
server {
        listen 443 default_server ssl;
        server_name $hostname;

        ssl_certificate /etc/nginx/ssl/web2py.crt;
        ssl_certificate_key /etc/nginx/ssl/web2py.key;

        location / {
                # checks for static file, if not found proxy to app
                try_files $uri @proxy_to_gunicorn;

        location @proxy_to_gunicorn {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Ssl on;
                proxy_set_header Host $http_host;
                proxy_redirect off;

                proxy_pass   http://gunicorn;

Fine, now nginx and GUnicorn are configured to work together, but two things are missing to enable SSL and web2py remote access :

  • nginx's SSL certificates
  • web2py administration password


From a shell theses commands will create SSL certificates:

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
openssl genrsa -out web2py.key 1024
openssl req -batch -new -key web2py.key -out web2py.csr
openssl x509 -req -days 1780 -in web2py.csr -signkey web2py.key -out web2py.crt

Should be ok for nginx and SSL access, now the simple part : the web2Py administration password. In my exemple the web2py installation is in /var/www/web2py, so from a shell :

cd /var/www/web2py
sudo -u www-data
python -c "from gluon.main import save_password; save_password('MySecurePassword',443)"


Restart gunicorn, and nginx !


  • use unix socket instead of tcp (gunicorn can do that ?),
  • tweak nginx/gunicorn workers, memory and other things ?


Sources :

Related slices

Comments (1)

  • Login to post

  • 0
    cmj 10 years ago

    What is the advantage of using nginx and gunicorn together?  It seems like one or the other would do.  Sure I'm missing something -- how is this better than just nginx, or just gunicorn?  Thanks --

    replies (1)
    • ezka 10 years ago

      Well, in most case using Gunicorn will be enough but Gunicorn cannot listen on multiple networks addresses so if you need a proxy this example use Ngnix. When I was setting up my server, Nginx was already in used, and I've read some advise to NOT use the wsgi provided with Nginx. So Gunicorn seems to be a good replacement but, may be now, uwsgi is a better choice =). It's all matter of situations.

      It's still a way to deploy your web2py application, and it's a quite versatile solution based on an improved proxy, and a python dedicated WSGI HTTP server.

Hosting graciously provided by:
Python Anywhere