Установка Django + uWSGI + Nginx на Ubuntu 14.04 LTS

Установка Django + uWSGI + Nginx на Ubuntu 14.04 LTS
Внимание!
Возможно, это статья устарела и вас заинтересует новая версия Установка uWSGI + Nginx для Django на Ubuntu 16.04 LTS
К большому удивлению не нашел в рунете понятной и работающей step-by-step инструкции по установке uWSGI, хотя это очень популярный набор. Почитал документацию на нескольких сайтах – вообще-то все гораздо проще, чем об этом пишут.

1. Установка ПО
2. Настройка конфигурации uwsgi
3. Запуск службы

1. Установка

Версии на момент публикации поста (время от времени обновляю эту инструкцию и версии тоже):
  • Ubuntu 14.04
  • Django 1.8.4
  • uWSGI 2.0.11
  • Nginx 1.4.6
Принцип установки следующий: uWSGI работает глобально в режиме emperor (император), который загружает конфигурацию для каждого проекта.

Предварительно устанавливаем необходимые пакеты:
sudo apt-get install build-essential python-dev libpcre3 libpcre3-dev
Допустим, все Django-проекты лежат в каталоге /home/django, в том числе наш проект myproj со следующей структурой каталогов (на иллюстрации показан путь /Users/ вместо /home/, но структура та же):

Виртуальное окружение установите в директорию venv. Конфигурации nginx и uwsgi, а также логи помещаем в deploy. В myproj находятся файлы проекта – так Django располагает файлы проекта (командой startproject), начиная с версии 1.4.

Глобально устанавливаем uwsgi (не в виртуальное окружение!):
sudo pip install uwsgi

2. Настройка конфигурации uwsgi

В каталоге /home/django/myproj/deploy создаем файл uwsgi.ini (расширение файла важно, т.к. uwsgi читает конфигурацию только из файлов с расширением .ini или .conf) со следующим содержанием:
[uwsgi]
socket = /tmp/uwsgi.sock
pidfile = /tmp/myproj.pid
chmod-socket = 666
chdir = /home/django/myproj/myproj/
pythonpath = ..
virtualenv = /home/django/myproj/venv
module = myproj.wsgi:application
master = true
processes = 4
threads = 2
logto = /home/django/myproj/deploy/logs/uwsgi.log
Параметров может быть больше, я указал лишь критически важные.

Примечание: Если вы запускаете только один проект (без emperor), то вместо logto указывайте daemonize с тем же значением.

Создаем ссылку на эту конфигурацию в папке, которую будет "слушать" император:
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
sudo ln -s /home/django/myproj/uwsgi.ini /etc/uwsgi/vassals/myproj.ini # так легче будет различать разные проекты
Подсказка:
В конфигурации можно использовать шаблон %n – при обработке император вместо него подставляет часть имени файла или символьной ссылки (symlink) до расширения. Это удобно, если у вас несколько типовых проектов с одинаковой конфигурацией, только в разных каталогах.

Называя каталоги соответствующим образом, можно "myproj" в конфигурации заменить на "%n" (все без кавычек). Тогда шаблон может храниться, например, в файле /etc/uwsgi/vassals/_skeleton, а для проектов в той же папке создадим символьные ссылки на этот шаблон, например myproj1.ini, myproj2.ini, и т.д. (обратите внимание, uwsgi читает конфигурацию только из файлов .conf и .ini).

cd /etc/uwsgi/vassals
sudo ln -s _skeleton myproj1.ini
sudo ln -s _skeleton myproj2.ini
В итоге в каталоге /etc/uwsgi/vassals/ будут следующие файлы:
/etc/uwsgi/vassals/
┝────_skeleton
┝────@myproj1.ini
┝────@myproj2.ini
Теперь, если нужно будет поменять типовую конфигурацию, вы изменяете только _skeleton. При этом перезагрузятся все проекты, конфигурации которых ссылаются на этот шаблон. Не знаю, понятно ли объяснил, если что, спрашивайте в комментариях.

3. Запуск службы

Запускаем uwsgi в режиме императора:
uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
Чтобы служба запускалась при старте системы вставим в файл /etc/init/uwsgi.conf следующие строки
# Emperor uWSGI script

description "uWSGI Emperor"
start on runlevel [2345]
stop on runlevel [06]

respawn

exec uwsgi --emperor /etc/uwsgi/vassals
Настраиваем Nginx:
server {
    server_name myproj.com;
    access_log /home/django/myproj/deploy/logs/nginx_acc.log;
    error_log /home/django/myproj/deploy/logs/nginx_err.log;

    location / {
        uwsgi_pass      unix:///tmp/uwsgi.sock;
        include         uwsgi_params;
    }

    location ~ ^/(static|media)/ {
      root /home/django/myproj/myproj;
      expires max;
      log_not_found off;
    }
}
Здесь снова указываю только самое необходимое. Остальные параметры nginx настраиваем по необходимости, перезапускаем и пробуем.
sudo service nginx reload
Теперь можно пробовать открыть в браузере ваш сервер myproj.com - он уже должен работать.

Чтобы перезагрузить uwsgi для отдельного проекта,

просто обновите файл (или символьную ссылку) конфигурации этого проекта:
sudo touch /etc/uwsgi/vassals/myproj2.ini
Подсказка:
На каждый проект создайте псевдоним в файле ~/.bash_aliases, например
alias res2='sudo touch /etc/uwsgi/vassals/myproj2.ini'
Тогда вы сможете рестартовать проект из shell командой res2