[ElevenBits]

Welcome!

Howto on nginx, uWSGI and Django

Monday, 17th December 2012, 1939hrs

In the beginning there was Cherokee...

Previously, Cherokee powered this website. Cherokee is a fast server with lots of interesting features. But it lacks a clean, text based configuration file; the full configuration is web based.

Fab is used to deploy this website. It makes it possible to deploy locally (on my laptop), on a staging server (a server I've running) and on production (the server you're connected to now). But it is quite a nuisance to update the configuration parameters of Cherokee on all these environments using a fabfile. So I decided a move from Cherokee was required.

First I've checked several servers, like lighttpd, litespeed and nginx. After trying and checking some reviews and benchmarks I stuck with nginx.

...and FastCGI

When deploying a Django project on a webserver, the server needs to be able to forward the Python requests to a Python environment. There are many gateway protocols, like CGI or FastCGI which do this, but they do have performance drawbacks.

The Python community came up with a standard interface between web servers and a Python environment. It is called WSGI. See PEP 333 and (for Python 3) PEP 3333 for a detailed technical explanation.

There are many implementations of this interface, but after some research I chose for uWSGI.

Then we went for nginx and uWSGI!

In this entry I'll explain how my nginx and uwgsi servers are installed. Hope it is handy for you.

Install nginx and uwsgi

To install nginx on a debian based system:

user@box:~$ sudo apt-get install nginx

To start it and to get its status:

user@box:~$ sudo service nginx start
Starting nginx: nginx.
user@box:~$ sudo service nginx status
* nginx is running

To install uwsgi (and its python plugin) also is very simple process:

user@box:~$ sudo apt-get install uwsgi uwsgi-plugin-python
Configure nginx

To configure nginx to handle your Django website and the related STATIC_ROOT, STATIC_URL, MEDIA_ROOT and URL directories, create this configuration file in /etc/nginx/sites-available.

server {

    listen 80;
    server_name elevenbits.com, www.elevenbits.com, elevenbits.org, www.elevenbits.org;

    access_log /var/log/nginx/elevenbits.access.log;
    error_log /var/log/nginx/elevenbits.error.log;

    location /static/ { # STATIC_URL
        alias /var/www/elevenbits/static/; # STATIC_ROOT
        expires 30d;
    }

    location /media/ { # MEDIA_URL
        alias /var/www/elevenbits/static/; # MEDIA_ROOT
        expires 30d;
    }

    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:3031;
    }

}

You can name file as you like; I use localhost.conf when nginx runs on my local machine, elevenbits.conf when it runs on production.

I guess you'll understand the configuration file. The only hard part is the "location /" section where a link is given to uWSGI:

Configure uwsgi

The uWSGI starts one (or more) severs which will handle requests from nginx. The interface to these uWSGI servers is specified in the "location /" section of the nginx configuration.

The uWSGI configuration is very simple. This file needs to be placed in /etc/uwsgi/apps-available:

[uwsgi]
socket = 127.0.0.1:3031
uid = www-data
gid = www-data
chdir = /var/www/elevenbits
module = elevenbits.uwsgi

You can call this file whatever you like. I just called it django.ini.

Note that you can also specify this file in xml format, or yaml format. See the documentation for detailed information.

Lastly create some symbolic links and restart both servers
user@box:~$ ln -sf /etc/nginx/sites-available/elevenbits.conf /etc/nginx/sites-enabled/elevenbits.conf
user@box:~$ ln -sf /etc/uwsgi/apps-available/django.ini /etc/uwsgi/apps-enabled/django.ini

Best to make sure that the default site is removed from the nginx enabled folder. Now, when you restart uwsgi and nginx, your system will be online!

IntelliJ IDEA and pycharm are the best editors ever!

Tuesday, 4th December 2012, 2021hrs

IntelliJ IDEA and pycharm are the best editors in the world. Plain and simple.

Python easter eggs

Saturday, 25th August 2012, 0847hrs

Zen of Python

This is in fact PEP20.

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Braces are for old languages

Braces are for old languages, like C, C# and Java ;-)

>>> from __future__ import braces
SyntaxError: not a chance

How to access cherokee-admin from a remote machine

Wednesday, 15th August 2012, 0835hrs

The cherokee-admin binds only to local loopback by default. There are some workarounds:

Tunneling

Create an SSH tunnel. This is the recommended way. In order to do so you must issue the following command:

user@box:~$ ssh -L 9090:localhost:9090 remote_IP

After that your terminal will be logged in the remote machine. There you can start the admin. From then on you can access this remote interface through http://localhost:9090. Every request will be forwarded to the remote IP running cherokee-admin.

The -b parameter

Launch cherokee-admin with the -b parameter in order to force it to listen to all the network interfaces.

Copy and paste

Finally you could always install cherokee on your local host, configure it there and then copy the generated cherokee.conf file to the device running the cherokee instance you wanted to set up.