Долгое время по старинке использовал fastcgi c django, на давно пора было перейти на более совершенный uwsgi. Основные преимущества - более производительный, graceful reload.

Устанавливаем uwsgi в окружение проекта:

pip install uwsgi

Создаём конфиг для него - wsgi.ini:

[uwsgi]
home=/home/project/env
chdir=/home/project
master=True
disable-logging=True
vacuum=True
pidfile=/tmp/project.pid
max-requests=5000
socket=127.0.0.1:49001
processes=2

pythonpath=/home/sites/project
env=DJANGO_SETTINGS_MODULE=settings
module = django.core.handlers.wsgi:WSGIHandler()
touch-reload=/tmp/project.txt

home - путь к виртуальному окружению, если вы его используете. Об остальных настройках можно подробнее почитать тут.
touch-reload - механизм плавного рестарта(graceful reload) проекта - все запросы будут обработаны при перезапуске, никто из клиентов не увидит 502. Для перезапуска нужно изменить файл по указанному пути, выполнив, например, touch /tmp/project.txt. Нормально перезапустить через supervisor к сожалению пока не получается, есть даже тикет на эту тему. Поэтому будем использовать эту фичу. Кстати о supervisor, через который я запускаю всякие процессы, вы можете почитать в соседнем посте.

Добавляем процесс в supervisord.conf:

[program:project]
command=/home/project/env/bin/uwsgi /home/project/wsgi.ini
stdout_logfile=/home/project/logs/wsgi.log
stderr_logfile=/home/project/logs/wsgi_err.log
autostart=true
autorestart=true
redirect_stderr=true
stopwaitsecs = 60
stopsignal=INT

Выполняем команду:

supervisorctl update

Конфиг перечитывается и uwsgi запускается. Теперь можно настраивать nginx, пример конфига:

server {
        listen       80;
        server_name site.com;
        access_log  /var/log/nginx/access.log  main;
        error_log   /var/log/nginx/error.log info;


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

        location /media/ {
                alias /home/project/media/;
                expires 30d;
        }

        location /static/ {
                alias /home/project/static/;
                expires 30d;
        }
}

Перезапускаем nginx и всё готово. Теперь настроим fabric для удобного обновления нашего проекта. Установим его в систему:

pip install fabric

Создаём файл fabfile.py в проекте. Я использую git и выглядит он у меня так:

# -*- coding: utf-8 -*-
from __future__ import with_statement

from fabric.api import *
from fabric.contrib.console import confirm


env.hosts = ['root@host']


def deploy():
    local('git push')
    code_dir = '/home/project'
    with cd(code_dir):
        run('git pull')
        #run('./manage.py compress')

    run('touch /tmp/project.txt')


def celery():
    run('supervisorctl restart project_celery')


def status():
    run('supervisorctl status')


def uptime():
    run('uptime')

Теперь находясь в проекте выполняем команду:

fab deploy

и все обновления из локального репозитория проекта перетекают на сервер и приложение перезапускается. По аналогии используем команды status и uptime(через него смотрю за la). Это намного удобнее чем вручную заходить на сервер, делать pull и тп.

./manage.py compress - это django-compressor, про него, наверное, расскажу в следующем посте.