Статья описывает один из способов развертывания Django-проектов, в связке Nginx + uWSGI на Unix-подобных операционных системах. Тестирование, а так же дальнейшая рабочая эксплуатация производилась на FreeBSD, однако на Linux процесс будет схож, за исключением некоторых незначительных моментов.
В один из дней, на месте работы возникла необходимость запуска Web-приложений написанных на Django (Python). В ходе поиска, было найдено большое количество схожих статей, описывающих запуск Django-проектов с использованием Nginx + uWSGI. Авторы рассматривали запуск конкретно одного Django-проекта, у которого был свой конфигурационный xml-файл для uWSGI-воркера(ов), а так же отдельный сокет/порт для взаимодействия с Nginx'ом. В следствие чего, при добавлении нового Django-проекта, возникнет необходимость заново производить настройку uWSGI-воркера(ов) уже для этого приложения (пускай даже копипастом, но все же). К сожалению, данный метод не универсален и при такой конфигурации нет единого, привычногоFreeBSD'шнику мне средства контроля работающего демона, единой точки управления. Вследствие чего, после поисков в Internet и изучения официальной wiki uWSGI-проекта, был выработан следующий метод запуска (принципиальные отличия):
Предполагается использование единого каталога, в котором будет развернут конгломерат Django-проектов, в моем случае это /usr/local/www. Например, содержимое каталога будет примерно следующим:
Настройка location'ов производится исходя из принципа, один Django-проект — один location.
nginx.conf:
В данной конфигурации location'ов:
Конфигурационный xml-файл для uWSGI-воркера(ов) webapp.xml размещается в каталоге /usr/local/www.
webapp.xml:
Важно чтоб в каталоге каждого приложения app1, app2, appN находился файл webapp, представляющий собой точку входа в Django-проект. uWSGI-воркер запускает webapp, а webapp в свою очередь запускает WSGI-обработчик в Django-проекте.
Вот так выглядит webapp для проекта app1:
На этом настройка заканчивается. Теперь, для запуска uWSGI-воркера(ов) обслуживающих все Django-проекты, достаточно выполнить следующую команду:
# uwsgi -s /tmp/uwsgi.sock -x /usr/local/www/webapp.xml
На FreeBSD запуск можно организовать более красиво нежели в Linux:
/etc/rc.conf:
uwsgi_enable=«YES»
uwsgi_flags="-x /usr/local/www/webapp.xml"
# /usr/local/etc/uwsgi start
При такой конфигурации, достаточно распаковать в рабочий каталог Django-проект, добавить шаблонный location в Nginx и сделать рестарт Nginx- и uWSGI-демонам.
Используемые
projects.unbit.it/uwsgi/wiki/RunOnNginx
projects.unbit.it/uwsgi/wiki/Example
projects.unbit.it/uwsgi/wiki/Emperor
http://wiki.diphost.ru/Category:WSGI
blog.zacharyvoase.com/2010/03/05/django-uwsgi-nginx
www.westphahl.net/blog/2010/4/8/running-django-nginx-and-uwsgi
posterous.adambard.com/start-to-finish-serving-mysql-backed-django-w
brandonkonkle.com/blog/2010/sep/14/django-uwsgi-and-nginx
www.jeremybowers.com/blog/post/5/django-nginx-and-uwsgi-production-serving-millions-page-views
www.cherokee-project.com/doc/cookbook_uwsgi.html
Введение
В один из дней, на месте работы возникла необходимость запуска Web-приложений написанных на Django (Python). В ходе поиска, было найдено большое количество схожих статей, описывающих запуск Django-проектов с использованием Nginx + uWSGI. Авторы рассматривали запуск конкретно одного Django-проекта, у которого был свой конфигурационный xml-файл для uWSGI-воркера(ов), а так же отдельный сокет/порт для взаимодействия с Nginx'ом. В следствие чего, при добавлении нового Django-проекта, возникнет необходимость заново производить настройку uWSGI-воркера(ов) уже для этого приложения (пускай даже копипастом, но все же). К сожалению, данный метод не универсален и при такой конфигурации нет единого, привычного
- Единый, обобщенный конфигурационный xml-файл для uWSGI-воркера(ов);
- Специфичные параметры, описываемые для каждого Django-проекта в конфигурационном xml-файле для uWSGI-воркера(ов) переносятся в location'ы Nginx'а и передаются uWSGI-воркеру из Nginx'а.
Каталог размещения приложений
Предполагается использование единого каталога, в котором будет развернут конгломерат Django-проектов, в моем случае это /usr/local/www. Например, содержимое каталога будет примерно следующим:
# ls -la /usr/local/www/
...
drwxr-xr-x ... app1
drwxr-xr-x ... app2
drwxr-xr-x ... appN
-rw-r--r-- ... webapp.xml
Настройка Nginx
Настройка location'ов производится исходя из принципа, один Django-проект — один location.
nginx.conf:
location / { uwsgi_pass unix:///tmp/uwsgi.sock; include uwsgi_params; uwsgi_param UWSGI_SCRIPT webapp; uwsgi_param UWSGI_CHDIR /usr/local/www/app1; } location /app2 { uwsgi_pass unix:///tmp/uwsgi.sock; include uwsgi_params; uwsgi_param SCRIPT_NAME /app2; uwsgi_param UWSGI_SCRIPT webapp; uwsgi_param UWSGI_CHDIR /usr/local/www/app2; } location /appN { uwsgi_pass unix:///tmp/uwsgi.sock; include uwsgi_params; uwsgi_param SCRIPT_NAME /appN; uwsgi_param UWSGI_SCRIPT webapp; uwsgi_param UWSGI_CHDIR /usr/local/www/appN; }
В данной конфигурации location'ов:
- Параметр «SCRIPT_NAME /appN» соответствует параметру конфигурационного xml-файла uWSGI-воркера(ов) «
<app mountpoint="/appN">...</app>
» и обозначает контекст Django-проекта; - Параметр «UWSGI_SCRIPT webapp» соответствует параметру webapp и обозначает точку входа в Django-проект (о точке входа в приложение чуть ниже);
- Параметр «UWSGI_CHDIR /usr/local/www/appN» соответствует параметру /usr/local/www/appN и обозначает каталог с Django-проект.
Конфигурационный файл webapp.xml
Конфигурационный xml-файл для uWSGI-воркера(ов) webapp.xml размещается в каталоге /usr/local/www.
webapp.xml:
<uwsgi> <socket>/tmp/uwsgi.sock</socket> <process>1</process> <master/> <enable-threads/> <uid>80</uid> <gid>80</gid> <pidfile>/var/run/uwsgi.pid</pidfile> </uwsgi>
Точка входа в Django-проект
Важно чтоб в каталоге каждого приложения app1, app2, appN находился файл webapp, представляющий собой точку входа в Django-проект. uWSGI-воркер запускает webapp, а webapp в свою очередь запускает WSGI-обработчик в Django-проекте.
Вот так выглядит webapp для проекта app1:
# -*- coding: iso-8859-1 -*- import sys, os import django.core.handlers.wsgi sys.path.insert(0, '/usr/local/www/app1') os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' application = django.core.handlers.wsgi.WSGIHandler()
Вместо заключения
На этом настройка заканчивается. Теперь, для запуска uWSGI-воркера(ов) обслуживающих все Django-проекты, достаточно выполнить следующую команду:
# uwsgi -s /tmp/uwsgi.sock -x /usr/local/www/webapp.xml
На FreeBSD запуск можно организовать более красиво нежели в Linux:
/etc/rc.conf:
uwsgi_enable=«YES»
uwsgi_flags="-x /usr/local/www/webapp.xml"
# /usr/local/etc/uwsgi start
При такой конфигурации, достаточно распаковать в рабочий каталог Django-проект, добавить шаблонный location в Nginx и сделать рестарт Nginx- и uWSGI-демонам.
Используемые литература блоги
projects.unbit.it/uwsgi/wiki/RunOnNginx
projects.unbit.it/uwsgi/wiki/Example
projects.unbit.it/uwsgi/wiki/Emperor
http://wiki.diphost.ru/Category:WSGI
blog.zacharyvoase.com/2010/03/05/django-uwsgi-nginx
www.westphahl.net/blog/2010/4/8/running-django-nginx-and-uwsgi
posterous.adambard.com/start-to-finish-serving-mysql-backed-django-w
brandonkonkle.com/blog/2010/sep/14/django-uwsgi-and-nginx
www.jeremybowers.com/blog/post/5/django-nginx-and-uwsgi-production-serving-millions-page-views
www.cherokee-project.com/doc/cookbook_uwsgi.html