Установка Gunicorn + Nginx + Django на Ubuntu

Установка Gunicorn + Nginx + Django на Ubuntu
Сейчас есть широкий выбор серверов, обслуживающих Django[1]. Тесты показывают, что наиболее производительные - это Gunicorn и uWSGI, причем первый развивается и поддерживается более активно.

Нам также понадобится средство для запуска, остановки и перезапуска сервера. В мире Django наиболее популярна система Supervisor, хотя пользователям Ubuntu возможно проще будет воспользоваться Upstart.

Окружение

virtualenv -p /usr/local/bin/python2.7 test
cd test
source bin/activate
pip install gunicorn django
django-admin.py startproject hello
cd hello
$ python manage.py runserver 0.0.0.0:8000
Django работает. Здесь и далее будем полагать, что сервер удаленный, поэтому пишем 0.0.0.0, чтобы иметь возможность подключиться к нему. Разумеется, крайне не рекомендуется тестировать на рабочем сервере. Если же все устанавливаете на локальном, то ip можно не писать, он по умолчанию равен 127.0.0.1:8000. Открываем в браузере http://your_server:8000
Смотрим, выключаем Django Ctrl + D.

Gunicorn

Проверить работу Gunicorn на проекте Django очень просто:
 gunicorn_django -b 0.0.0.0:8000
Опять, указываем адрес 0.0.0.0 только для проверки гуникорна. На рабочем сервере сервере не рекомендуется открывать прямой доступ к gunicorn; желательно запускать его на 127.0.0.1:port и проксировать через веб-сервер (в нашем случае это будет nginx, см. ниже). Открываем севрер в браузере, убеждаемся что гуникорн работает.

Теперь составим конфигурацию для сервера в окружении (вы ведь запускаете проект в виртуальном окружении?). Параметры удобно записать в файле-скрипте:

# script.sh
#!/bin/bash
set -e
LOGFILE=/var/log/gunicorn/hello.log
LOGDIR=$(dirname $LOGFILE)
NUM_WORKERS=3
# user/group to run as
USER=your_unix_user
GROUP=your_unix_group
PORT=8001 # Этот порт будет разным у каждого django-проекта cd /path/to/test/hello source ../bin/activate test -d $LOGDIR || mkdir -p $LOGDIR exec ../bin/gunicorn_django -w $NUM_WORKERS \ --user=$USER --group=$GROUP --log-level=debug \ --log-file=$LOGFILE 2>>$LOGFILE \ --bind 127.0.0.1:$PORT
NUM_WORKERS - это количество процессов, которые будут обслуживать запросы. Минимальное значение: 1. Обычно его устанавливают равным 1 + 2 * количество_CPU на сервере (логично, половина процессоров постоянно будет в ожидании ввода-вывода, например в базе данных). YMMV.

Устанавливаем разрешения на выполнение скрипта chmod ug+x script.sh. И тестируем в командной строке
./script.sh
Еще раз обращаем внимание, что умолчанию Gunicorn работает на локальном адресе 127.0.0.1:8000 (на том же, что и сервер отладки Django), что есть хорошо, если Nginx находится на той же машине – обычно его не открывают для всех, и только Nginx обрабатывает входящие подключения. Мы взяли адрес 0.0.0.0:port только для целей проверки, чтобы была возможность подключиться удаленно, если вы настраиваете удаленный сервер (см. выше).

Чтобы запустить несколько проектов Django на одной машине, всем проектам нужно указать разные порты.

Update: При очередном развертывании, на которое убил целый день, gunicorn_django заводился только без указания пользователя и группы (строку переместить в конец и закомментировать).

Update 2: Можно запустить демона gunicorn и без супервизора с параметром -D:
gunicorn_django ... -D

Supervisor

У Supervisor отличная документация, здесь ее приводить не будем. Конфигурационный файл для запуска сервера - /etc/supervisord.conf), если его нет, нужно создать шаблонный:
echo_supervisord_conf > /etc/supervisord.conf
В нем указать примерно такие параметры:
[program:hello]
directory = /path/to/test/hello/
user = your_unix_user
command = /path/to/test/hello/script.sh
stdout_logfile = /path/to/logfile.log
stderr_logfile = /path/to/logfile.log
Теперь можно проверить:
supervisorctl {start,stop,restart,reload,status} hello
Если мы добавляем новый процесс в конфигурацию, то его надо добавить командой
supervisorctl update
Просмотр процессов:
supervisorctl avail
или
supervisorctl status
Также можно перечитать файл конфигурации
supervisorctl reread
supervisorctl reload
Важно! Это должно запускаться под тем же пользователем, под которым работает supervisord. Если что-то пойдет не так, отлаживать командой
supervisord -n -edebug
(у меня была проблема в том, что при запуске supervisor уже запущен под рутом (вероятно)).

Upstart

В Ubuntu есть альтернативное средство - Upstart, у которого похожий конфигурационный файл (находится /etc/init/hello.conf). Например:
description "Test Django instance"
start on runlevel [2345]
stop on runlevel [06]
respawn
respawn limit 10 5
exec /path/to/test/hello/script.sh
Тестируем:
service hello {start,status,stop}

Nginx

Настроим Nginx в качестве обратного прокси:
server {
listen 80; server_name example.com; # no security problem here, since / is alway passed to upstream root /path/to/test/hello; # serve directly - analogous for static/staticfiles location /media/ { # if asset versioning is used if ($query_string) { expires max; } } location /admin/media/ { # this changes depending on your python version root /home/my/env/lib/python2.7/site-packages/django/contrib; } location / { proxy_pass_header Server; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_connect_timeout 10; proxy_read_timeout 10; proxy_pass http://localhost:8001/; # У каждого django-проекта свой порт (см. script.sh) } # what to serve if upstream is not available or crashes error_page 500 502 503 504 /media/50x.html; }
Для тестирования конфигурации введите nginx -t или nginx -s reload для перезагрузки конфигурации.

Это все. Поскольку сервер установлен изолировано, на одной машине можно запустить множество приложений django с различными окружениями.

Update конец 2014

Обратите внимание на дату поста - статья довольно старая. С тех пор возобновилась активная поддержка uwsgi. Сейчас я большинство проектов перевел на него, здесь о том как настроить django + uwsgi + nginx под Ubuntu