Monday, January 20, 2014

Setting up Web2py + Gunicorn + Nginx + SSL

Deploying web2py applications is not so hard if you've already deployed Django apps. It's just the same.


1. Prepare folders and download web2py source code, install nginx, install gunicorn:

* Create project folder:

$ mkdir /home/www-data/
$ cd /home/www-data

* Clone web2py source code:

$ git clone https://github.com/web2py/web2py.git

* Install nginx:

$ sudo apt-get install nginx-full

* Install gunicorn:

$ sudo apt-get install python-pip
$ sudo pip install gunicorn


2. Create self-signed ssl certificate:

$ sudo mkdir /etc/nginx/ssl
$ cd /etc/nginx/ssl

$ openssl genrsa 1024 > web2py.key
$ sudo chmod 400 web2py.key
$ openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt
$ openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info


3. Configure nginx:

* Create a configuration file names /etc/nginx/sites-available/we2py:

upstream gunicorn {
        server 127.0.0.1:8000 fail_timeout=0;
}

server {
        listen 80 default;
        client_max_body_size 4G;
        server_name 192.168.7.2;

        keepalive_timeout 5;

        location ~* /(\w+)/static/ {
                root /home/www-data/web2py/applications/;
        }

        location / {
                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 192.168.7.2;
                proxy_redirect off;

                proxy_pass http://gunicorn;
        }
}

server {
        listen 443 default_server ssl;
        server_name 192.168.7.2;

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

        location / {
                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 192.168.7.2;
                proxy_redirect off;

                proxy_pass http://gunicorn;
        }
}

* Create a symlink of the above file to /etc/nginx/sites-enable/:

$ sudo ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enable/web2py


4. Start nginx:

$ sudo service nginx start


5. Run gunicorn:

$ cd /home/www-data/web2py
$ gunicorn wsgihandler:application


Now, I will have these following service running on my server:

tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      28198/nginx     
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      28076/python    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      28198/nginx