Deploying Django projects
Posted on March 16, 2011
Nothing of this would have been easy without a modern and decent environment. I have found it in Ubuntu. Also, let me assume you can run django-admin.py runserver in the virtualenv and it works.
Requirements
- dedicated hosting (or VPS) with root access
- Ubuntu 10.10 Maverick (do not use 10.04 if you can)
- virtualenv with your project, able to run runserver
Tools of the trade
Seriously, forget about Apache for its complicated configuration. Supervisord is a much better option for managing Django projects than uwsgi init scripts found in Ubuntu.
add-apt-repository ppa:nginx/development add-apt-repository ppa:chris-lea/uwsgi apt-get install ubuntu uwsgi-python2.6 supervisor
Configure the Django project
Let me assume
- your username is uvar
- your home directory is /home/uvar
- your virtualenvs are located in /home/uvar/envs
- your virtualenv for the project is in /home/uvar/envs/uvar
- your project has been checked out to /home/uvar/uvar.si
Create the following directories which will hold logs, sockets, and static files in your virtualenv:
mkdir /home/uvar/envs/uvar/{logs,run,static}
chown -R uvar. /home/uvar/envs/uvar
Configure Nginx
Look at how easy is to set up a site in Nginx. Put this to your /etc/nginx/sites-enabled/<domain>. I will configure the site http://uvar.si:
server {
server_name *.uvar.si;
rewrite ^ http://uvar.si$request_uri permanent;
}
server {
server_name uvar.si;
location / {
uwsgi_pass unix:/home/uvar/envs/uvar/run/uwsgi.sock;
include /etc/nginx/uwsgi_params;
}
location /static {
root /home/uvar/envs/uvar;
}
}
The first section redirects everything to uvar.si (like www.uvar.si to uvar.si).
Next, location / is passing everything to our Django project via socket.
Last, location /static serves everything from the directory which has collected media using the command django-admin.py collectstatic some time earlier.
Configure uwsgi/supervisord
Put the following config file into /etc/supervisor/conf.d/uvar.si.conf:
[program:uvar.si]
command=uwsgi-python2.6
--socket /home/uvar/envs/uvar/run/uwsgi.sock
--chmod-socket
--processes 2
--master
--home /home/uvar/envs/uvar
--module django.core.handlers.wsgi:WSGIHandler()
environment=DJANGO_SETTINGS_MODULE='cookbook.settings'
user=uvar
autostart=true
autorestart=true
stdout_logfile=/home/uvar/envs/uvar/log/uwsgi.log
stderr_logfile=/home/uvar/envs/uvar/log/uwsgi.err
stopsignal=QUIT
Restart (start or stop) with supervisorctl restart uvar.si. That's it! Your site should be up and running now. Easy, wasn't it?
Bonus: deploying with Fabric
Allow access to everyone in supervisord in /etc/supervisor/supervisord.conf:
chmod=0777
Restart supervisord. Activate the virtualenvwrapper in your .bashrc on the hosting. Put the following two lines somewhere at the beginning of .bashrc, before the line [ -z "$PS1" ] && return:
export WORKON_HOME=~/envs . /usr/local/bin/virtualenvwrapper.sh
Install the fresh fabric into your ordinary (development system) with pip:
pip install fabric
Now, create the fabfile.py:
from fabric.operations import run
from fabric.decorators import hosts
from fabric.context_managers import cd, prefix
@hosts('uvar@uvar.si')
def deploy():
with cd('~/uvar.si'):
run('git pull')
with prefix('workon uvar'):
run('django-admin.py syncdb')
run('django-admin.py collectstatic --noinput')
run('supervisorctl restart uvar.si')
Now you can deploy your project with
fab deploy