Deploying Django
By Rayed
Django is a web framework written in Python language, my favourite computer programming language.
Python a language is really great language, easy to read and understand, and very easy to learn, but for me I always found setting up Python for web development as a challenge, socially if compare it to PHP, which almost works out of the box, actually most people think PHP works only in the web server and can’t work as stand alone application, search for PHP CLI if you are interested.
I will try here to document an easy Django deployment for my future reference and hopefully it will help others:
Step 1: Install virtualenv
virtualenv is a tool to create isolated Python environments, by default if you install a new Python package it will be install under /usr/lib/python2.6/site-packages
, but what happen if you don’t have root access in a shared environment for example, or what if you want to install 2 versions of the same package, may be try a newer version. For these cases you need virtualenv, it will allow you to create your own unique Python environment (or many if you want) where you have your own packages, binaries, and scripts. You can even have multiple environments, wach one with its own packages and versions. So let’s install it (this step need root access, ask your admin to install it for you if you don’t have root):
$ sudo pip install virtualenv
# or ...
$ sudo aptitude install python-virtualenv
Next we will create a new virtual environment “myenv”:
$ virtualenv myenv
To activate it type:
$ source myenv/bin/activate
(myenv)$
You will notice that the prompt changed now to include “(myenv)”, this mean you are now inside the virtual enviroument, any thing you install from now on will be install inside it (it is just a directory called “myenv” feel free to explore it), to leave the environment use the command “deactivate”.
Step 2: Installing Django
Make sure you the “myvirt” is active (from the prompt) and install Django using the following command:
(myenv)$ pip install Django
That is it, we’ve installed Django … Thank you for your attention 🙂 Next we will setup a new Django website, I will use the following directory structure:
$ /home/rayed # my home directory
$ /home/rayed/site1 # my website files and directories
$ /home/rayed/site1/myenv # virtual environment created from previous step
$ /home/rayed/site1/mysite # Django created project
$ /home/rayed/site1/www # Static files, images, css, js, etc ...
So here are the commands for easy reference:
$ cd ~
$ mkdir -p site1/www
$ cd site1
site1$ virtualenv myenv
site1$ source myenv/bin/activate
(myenv)site1$ pip install Django
(myenv)site1$ django-admin.py startproject mysite
(myenv)site1$ cd mysite
(myenv)site1/mysite$ python manage.py runserver 0.0.0.0:8000
:
this will start dev server CTRL+C to stop
you can access it http://localhost:8000/
:
(myenv)site1/mysite$ vi mysite/settings.py # this will setup the database
(myenv)site1/mysite$ python manage.py syncdb # this will install basic DB tables
Step 3: GUnicorn
For production website you will not use Django development web server, we will use gunicorn, a Python WSGI HTTP Server, it will responsible for running all Django code.
# while inside "myenv" install guincorn
(myenv)$ pip install gunicorn
# and run Django
(myenv)$ cd ~/site1/mysite
(myenv) site1/mysite$ gunicorn apps.wsgi:application -b 0.0.0.0:8000
Try it out http://localhost:8000/
# NOTE: to run gunicorn on UNIX socket use:
gunicorn apps.wsgi:application -b unix:/tmp/gunicorn.sock
Step 4: Install supervisor (optional)
We will use supervisor to keep an eye on “gunicorn”, and restart it automatically if it fails, it will also start it automatically when you restart the machine.
$ sudo aptitude install supervisor
$ cat > /etc/supervisor/conf.d/gunicorn.conf
[program:gunicorn]
directory=/home/rayed/site1/mysite/
command=/home/rayed/site1/myenv/bin/gunicorn apps.wsgi:application -b 127.0.0.1:8000
user=nobody
autostart=true
autorestart=true
redirect_stderr=True
[EOF]
$ sudo supervisorctl update
$ sudo supervisorctl restart gunicorn
Step 5: Integrating gunicorn with Apache
gunicorn is a web server, so why do we need Apache? you ask, two reasons:
1- It can’t handle slow clients (browsers). 2- It can’t handle static files (images, css, js).
The basic idea is to serve static files directly from (img|css|js|media) and proxy everything else to “gunicorn”, here is how:
$ sudo a2enmod proxy_http # enable Apache HTTP proxy module (Ubuntu & Debian)
$ sudo apache2ctl restart
$ cd ~site1/www
$ site1/www$ cat > .htaccess
RewriteEngine on
RewriteCond $1 !^(img|css|js|robots\.txt|media)
RewriteRule ^(.*) http://localhost:8000/$1 [P]
[EOF]
Make sure only “www” directory is accessible from the web, and not “mysite”! your Django code and settings, including the DB username and password will be exposed.
A sample Apache virtual host configuration: `
<virtualhost *:80>
ServerName site1.rayed.com
DocumentRoot /home/rayed/site1/www
</virtualhost>
You can also replace Apache with Nginx which is usually faster with static files, here is a sample file:
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
# For a TCP configuration:
# server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80 ;
server_name site1.rayed.com;
location ~ /(css|js|media|static)/ { # Static content
root /home/rayed/site1/www/;
expires 30d;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}