Запуск django и других python проектов при помощи uwsgi+nginx
Содержание:
Note
Редакция от 11/11/2011
Note
Статья описывает развертывание python-проектов на linux сервере с использованием nginx, supervisor, uwsgi. В интернете уже есть множество материалов на эту тему, ниже находится небольшая систематизация моего опыта.
Практически в каждом веб-проекте используется легковесный веб-сервер (nginx, lighthttpd и тд), как минимум для генерации статики. При этом довольно часто для динамической части проекта применяют apache + модули. В один момент мне надоело ставить nginx и apache одновременно и теперь я использую связку nginx + uwsgi из-за простоты развертывания, удобства обслуживания и быстродействия.
UWSGI — быстрый, легко настраиваемый сервер для WSGI приложений, написанный на C.
Далее я покажу как настроить и запустить python WSGI приложение (в том числе и с использованием Django).
Note
Сравнение производительности WSGI серверов: http://nichol.as/benchmark-of-python-web-servers
Установка зависимостей
Для начала необходимо установить nginx, uwsgi. Последние версии nginx уже содержат поддержку WSGI, поэтому вручную собирать ничего не надо.
Note
Рассмотрено для debian-based дистрибутивов. Права суперпользователя.
# nginx и uwsgi устанавливаем прямо из репозиториев
# для последних версий uwsgi неоюходимо дополнительно
# установить пакет: uwsgi-plugin-python
apt-get install nginx uwsgi uwsgi-plugin-python
Для управления uwsgi и множеством других процессов, я использую supervisor:
apt-get install supervisor
Note
Если вы получите ошибку ImportError поставьте python-модуль elementtree и повторите установку supervisor.
Конфигурирование и запуск
Note
Файлы с исходным кодом для данной статьи можно найти по адресу: https://github.com/klen/klen.github.com/tree/master/_code/uwsgi
Предположим у нас есть python-проект расположенный состоящий из очень простого WSGI приложения (wsgi.py):
def application(environ, start_response):
status = '200 OK'
output = 'Pong!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Note
Здесь и далее предполагается, что корневой путь для проекта /home/klen/Projects/klen.github.com/_code/uwsgi
Создадим конфигурационный файл с настройками uwsgi для запуска нашего приложения: uwsgi.xml
Note
В данном примере рассмотрен XML формат, но можно использовать INI или параметры строки запуска
<!-- UWSGI XML Configuration File -->
<uwsgi>
<!-- Сокет для передачи данных -->
<socket>/home/klen/Projects/klen.github.com/_code/uwsgi/uwsgi.sock</socket>
<!-- Путь к виртуальному окружению -->
<!-- <home>/home/klen/Projects/klen.github.com/_code/uwsgi/.virtualenv</home> -->
<!-- Нам понадобится включенный python плагин -->
<plugins>python</plugins>
<!-- Дополнительный python-путь -->
<pythonpath>/home/klen/Projects/klen.github.com/_code/uwsgi</pythonpath>
<!-- Модуль python с определением wsgi приложения -->
<module>wsgi</module>
<!-- Количество процессов -->
<processes>10</processes>
<!-- Максимальное количество соединений для каждого процесса -->
<max-requests>5000</max-requests>
<!-- Максимальный размер запроса -->
<buffer-size>32768</buffer-size>
<!-- Убивать каждое соединение требующее больше 30 сек для обработки -->
<harakiri>30</harakiri>
<reload-mercy>8</reload-mercy>
<master />
<no-orphans />
</uwsgi>
Создадим конфигурационный файл с настройками для supervisor: supervisor.conf
[program:example]
command=/usr/bin/uwsgi -x /home/klen/Projects/klen.github.com/_code/uwsgi/uwsgi.xml
user=www-data
stdout_logfile=/home/klen/Projects/klen.github.com/_code/uwsgi/logs/uwsgi.log
stderr_logfile=/home/klen/Projects/klen.github.com/_code/uwsgi/logs/uwsgi_err.log
directory=/home/klen/Projects/klen.github.com/_code/uwsgi
autostart=true
autorestart=true
redirect_stderr=true
stopsignal=QUIT
Note
Обычно я держу конфигурацию supervisor в проекте и создаю на нее симлинки в /etc/supervisor/conf.d
Настроим server в nginx:
upstream example.proxy {
ip_hash;
server unix:///home/klen/Projects/klen.github.com/_code/uwsgi/uwsgi.sock;
}
server {
listen 4444;
# В продакшен добавьте сюда свой домен
# server_name example.com;
access_log /home/klen/Projects/klen.github.com/_code/uwsgi/logs/nginx_access.log;
error_log /home/klen/Projects/klen.github.com/_code/uwsgi/logs/nginx_error.log;
# Статика у нас будет хранится в папк static в корне проекта
location ^~ /static/ {
root /var/www/example;
expires max;
}
location = /favicon.ico {
rewrite (.*) /static/favicon.ico;
}
location = /robots.txt {
rewrite (.*) /static/robots.txt;
}
location / {
uwsgi_pass example.proxy;
include uwsgi_params;
}
}
Запуск
Создадим ссылку на файлы конфигурации проекта для nginx и supervisor:
# создадим папку для логов
mkdir logs
# nginx
ln -s /home/klen/Projects/klen.github.com/_code/uwsgi/nginx.conf /etc/nginx/sites-enabled/uwsgi-example.conf
# supervisor
ln -s /home/klen/Projects/klen.github.com/_code/uwsgi/supervisor.conf /etc/supervisor/conf.d/uwsgi-example.conf
Дадим права на запись всем пользователям:
Note
По хорошему надо просто изменить владельца проекта на www-data.
chmod a+w -R /home/klen/Projects/klen.github.com/_code/uwsgi
Перезапустим nginx и supervisor:
/etc/init.d/nginx restart
/etc/init.d/supervisor stop
/etc/init.d/supervisor start
Если все прошло успешно, то перейдя по адресу: http://localhost:4444/ вы должны увидеть наше работающее приложение.
Настройка django-проекта
Для Django проекта вам необходимо просто изменить wsgi.py:
#!/usr/bin/env python
import os
from django.core.handlers.wsgi import WSGIHandler
os.environ['DJANGO_SETTINGS_MODULE'] = os.environ.get(
'DJANGO_SETTINGS_MODULE', 'settings')
application = WSGIHandler()
Note
Предпологается, что проект находится в той же директории, в противном случае добавьте необходимые пути в sys.path
Управление
# Старт проекта
supervisorctl start example
# Перезапуск проекта
supervisorctl restart example
# Останов проекта
supervisorctl stop example
# Статус проекта
supervisorctl status example
Note
Также вы можете использовать параметр uwsgi touch-reload
Данный способ успешно применяется мной в боевой и девелоперской среде. Например так работают сайты http://intaxi.ru и http://venturebrothers.ru.