воскресенье, 16 июня 2013 г.

Настройка mod_wsgi (Apache) для Flask

Перевод статьи: mod_wsgi (Apache)

Если вы используете веб-сервер Apache и задумались об использовании mod_wsgi.

Предварительная проверка

Удостоверьтесь, что вызовы app.run() в файле приложения находятся внутри блока if __name__ == '__main__': или вынесены в отдельный файл. Просто убедитесь в отсутствии подобных вызовов, потому что если вы решили воспользоваться mod_wsgi для запуска приложения, то запускать локальный сервер WSGI не нужно.

Установка mod_wsgi

Если mod_wsgi ещё не установлен, его можно установить с помощью менеджера пакетов или собрать самостоятельно. В инструкции по установке mod_wsgi описывается установка из исходных текстов в UNIX-системах.

Если вы используете Ubuntu/Debian, можно воспользоваться apt-get:
# apt-get install libapache2-mod-wsgi
На FreeBSD mod_wsgi можно установить сборкой из порта www/mod_wsgi или при помощи pkg_add:
# pkg_add -r mod_wsgi
Если используется pkgsrc, можно установить mod_wsgi, собрав из пакета www/ap2-wsgi.

Если случится ошибка сегментации дочернего процесса после первой перезагрузки apache, можно спокойно проигнорировать её. Просто перезапустите сервер.

Создание файла .wsgi

Для запуска приложения нужен файл yourapplication.wsgi. Этот файл содержит код, выполняемый mod_wsgi для получения объекта приложения. Объект с именем application в этом файле будет использоваться в качестве приложения.

Для большинства приложений будет достаточно такого файла:
from yourapplication import app as application
Если у вас нет фабричной функции для создания приложений, но есть экземпляр-одиночка, можно просто импортировать его как приложение.

Сохраните этот файл где-нибудь, где сможете его найти (например, в /var/www/yourapplication) и удостоверьтесь, что yourapplication и все используемые им библиотеки находятся в списке путей загрузки python. Если вы не хотите делать его общедоступным для всей системы, воспользуйтесь виртуальным экземпляром python. Помните, что при этом вам нужно будет установить ваше приложение внутрь virtualenv. Или можно отредактировать переменную path внутри .wsgi перед импортом:
import sys
sys.path.insert(0, '/path/to/the/application')
Настройка Apache

Наконец, нужно создать файл с настройками Apache для запуска приложения. В следующем примере мы говорим mod_wsgi выполнить приложение от имени отдельного пользователя в целях безопасности:
<VirtualHost *>
    ServerName example.com
    WSGIDaemonProcess yourapplication user=user1 group=group1 threads=5
    WSGIScriptAlias / /var/www/yourapplication/yourapplication.wsgi
    <Directory /var/www/yourapplication>
        WSGIProcessGroup yourapplication
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>
Замечание: WSGIDaemonProcess не реализован в Windows и Apache не запустится с указанной выше конфигурацией. В системе Windows эти строки нужно удалить:
<VirtualHost *>
    ServerName example.com
    WSGIScriptAlias / C:\yourdir\yourapp.wsgi
    <Directory C:\yourdir>
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>
За более подробной информацией обратитесь к wiki-странице mod_wsgi.

Решение проблем

Если приложение не запускается, попробуйте следующие решения:
  • Проблема: приложение не запускается, в журнале ошибок появляется сообщение SystemExit ignored

    Произошёл вызов app.run() в файле вашего приложения, в котором не было предохранительного условия if __name__ == '__main__'. Либо удалите из файла этот вызов run(), либо поместите его в отдельный файл run.py, либо поместите его в подобный блок if.
  • Проблема: приложение сообщает об ошибках доступа

    Возможно это вызвано тем, что ваше приложение работает от неправильного пользователя. Проверьте, что каталоги, к которым необходим доступ из приложения, имеют правильные разрешения, а приложение запущено от правильного пользователя (параметры user и group в директиве WSGIDaemonProcess).
  • Проблема: приложение завершается с выводом сообщения об ошибке

    Помните, что mod_wsgi запрещает делать что-либо с sys.stdout и sys.stderr. Можно выключить эту защиту, прописав в конфигурации следующую настройку:
    WSGIRestrictStdout Off
    Или можно заменить стандартный вывод в файле .wsgi на другой поток:
    import sys
    sys.stdout = sys.stderr
  • Проблема: доступ к ресурсам приводит к ошибкам ввода-вывода

    Возможно ваше приложение является символической ссылкой на один из файлов .py, находящихся в каталоге пакетов сайта. Такой приём не работает, поэтому удостоверьтесь, что поместили каталог в пути поиска python или преобразуйте ваше приложение в пакет.

    Причина заключается в том, что имя файла модуля используется для поиска ресурсов, а в случае символической ссылки будет использоваться неправильное имя файла.
Поддержка автоматической перезагрузки

Чтобы облегчить работу инструментов установки, можно включить поддержку автоматической перезагрузки. Когда файл .wsgi изменится, mod_wsgi перезагрузит все процессы демона.

Для этого просто добавьте следующие директивы в раздел Directory:
WSGIScriptReloading On
Работа с виртуальными окружениями

Польза от виртуальных окружений заключается в том, что они позволяют не устанавливать необходимые зависимости на уровне всей системы, что позволяет достичь большего контроля над используемыми пакетами. Если вы решили воспользоваться виртуальным окружением совместно с mod_wsgi, нужно слегка изменить файл .wsgi.

Добавьте следующие строки в начало файла .wsgi:
activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
Эти строки настроят пути загрузки в соответствии с настройками виртуального окружения. Помните, что это должен быть абсолютный путь.

Примечания переводчика

Этот и другие переводы можно найти на сайте проекта перевода документации по Flask. Автор проекта - Виталий Кузьмин aka ferm32.

Комментариев нет: