.. _deploying-fastcgi:
FastCGI
=======
FastCGI - это один из вариантов развёртывания приложения на таких серверах,
как `nginx`_, `lighttpd`_ и `cherokee`_; за описанием других опций обратитесь
к разделам :ref:`deploying-uwsgi` и :ref:`deploying-wsgi-standalone`. Для
использования приложения WSGI с любым из этих серверов необходимо сначала
настроить сервер FastCGI. Наиболее популярен `flup`_, который будет
использоваться в этом руководстве. Убедитесь в том, что установили его,
Прежде чем продолжить чтение убедитесь, что он установлен.
.. admonition:: Предварительная проверка
Удостоверьтесь, что вызовы ``app.run()`` в файле приложения находятся
внутри блока ``if __name__ == '__main__':`` или вынесены в отдельный
файл. Просто убедитесь в отсутствии подобных вызовов, потому что если
вы решили воспользоваться FastCGI для запуска приложения, то запускать
локальный сервер WSGI не нужно.
Создание файла `.fcgi`
----------------------
Для начала нужно создать файл сервера FastCGI. Давайте назовём его
`yourapplication.fcgi`::
#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app
if __name__ == '__main__':
WSGIServer(app).run()
Этого достаточно для работы Apache, однако nginx и старые версии lighttpd
требуют явного указания сокетов для связи с сервером FastCGI. Для этого
нужно передать путь к сокет-файлу в :class:`~flup.server.fcgi.WSGIServer`::
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
Этот путь должен быть точно таким же, какой был указан в настройках
сервера.
Сохраните файл `yourapplication.fcgi` где-нибудь, где вы сможете потом
найти его. Неплохо положить его в `/var/www/yourapplication` или в
какое-то другое подходящее место.
Убедитесь, что у этого файла установлен флаг выполнения, чтобы сервер
мог его выполнить:
.. sourcecode:: text
# chmod +x /var/www/yourapplication/yourapplication.fcgi
Настройка Apache
----------------
Приведённый выше пример достаточно хорош для того, чтобы использовать его
при развёртывании с Apache, однако файл `.fcgi` будет встречаться в URL
приложения, например: example.com/yourapplication.fcgi/news/. Есть
несколько способов настройки приложения для того, чтобы убрать
yourapplication.fcgi из URL. Предпочтительный способ - это использование
директивы конфигурации ScriptAlias::
ServerName example.com
ScriptAlias / /path/to/yourapplication.fcgi/
Если задать ScriptAlias нельзя, например на веб-узле, настроенном для нескольких
пользователей, то можно воспользоваться промежуточным приложением WSGI для
удаления yourapplication.fcgi из URL. Настройте .htaccess::
AddHandler fcgid-script .fcgi
SetHandler fcgid-script
Options +FollowSymLinks +ExecCGI
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
Теперь настроим yourapplication.fcgi::
#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '/lib/python2.6/site-packages')
from flup.server.fcgi import WSGIServer
from yourapplication import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
app = ScriptNameStripper(app)
if __name__ == '__main__':
WSGIServer(app).run()
Настройка lighttpd
------------------
Базовая настройка FastCGI для lighttpd выглядит следующим образом::
fastcgi.server = ("/yourapplication.fcgi" =>
((
"socket" => "/tmp/yourapplication-fcgi.sock",
"bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
"check-local" => "disable",
"max-procs" => 1
))
)
alias.url = (
"/static/" => "/path/to/your/static"
)
url.rewrite-once = (
"^(/static($|/.*))$" => "$1",
"^(/.*)$" => "/yourapplication.fcgi$1"
Не забудьте включить модули FastCGI, alias и rewrite. Эта настройка закрепит
приложение за `/yourapplication`. Если нужно, чтобы приложение работало в
корне URL, понадобится обойти недоработку lighttpd при помощи промежуточного
приложения :class:`~werkzeug.contrib.fixers.LighttpdCGIRootFix`.
Убедитесь, что применяете его лишь в том случае, если подключили приложение
к корню URL. А также, обратитесь к документации Lighttpd за более подробной
информацией сюда `FastCGI and Python
`_ (отметим, что
явная передача сокет-файла в run() больше не требуется).
Настройка nginx
---------------
Установка приложений FastCGI в nginx немного отличается, потому что по
умолчанию программе не передаются параметры FastCGI.
Базовая конфигурация FastCGI nginx для flask выглядит следующим образом::
location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
include fastcgi_params;
fastcgi_split_path_info ^(/yourapplication)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}
Эта конфигурация привязывает приложение к `/yourapplication`. Привязать
приложение к корню URL несколько проще, потому что не нужно думать о том,
какие значения использовать в `PATH_INFO` и `SCRIPT_NAME`::
location / { try_files $uri @yourapplication; }
location @yourapplication {
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SCRIPT_NAME "";
fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}
Запуск процессов FastCGI
------------------------
Поскольку Nginx и другие серверы не загружают приложения FastCGI, это нужно
сделать самостоятельно. `Процессами FastCGI может управлять программа
Supervisor
`_.
Можно поискать другие диспетчеры процессов FastCGI или написать сценарий
для запуска файла `.fcgi` во время загрузки, например, с помощью сценария
SysV ``init.d``. В качестве временного решения может подойти запуск
сценария `.fcgi` из программы GNU screen. Обратитесь к странице
руководства screen за более подробной информацией, однако стоит заметить,
что после перезагрузки системы запуск придётся повторять вручную::
$ screen
$ /var/www/yourapplication/yourapplication.fcgi
Отладка
-------
На большинстве веб-серверов становится всё труднее отлаживать приложения
FastCGI. Довольно часто единственное, о чём сообщают журналы сервера
- это о неожиданном окончании заголовков. Для отладки приложения
единственное подходящее средство диагностики - это переключиться на
нужного пользователя и запустить приложение вручную.
В следующем примере предполагается, что приложение называется
`application.fcgi`, а веб-сервер работает от имени пользователя
`www-data`::
$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
File "yourapplication.fcgi", line 4, in
ImportError: No module named yourapplication
In this case the error seems to be "yourapplication" not being on the
python path. Common problems are:
- Relative paths being used. Don't rely on the current working directory
- The code depending on environment variables that are not set by the
web server.
- Different python interpreters being used.
В данном случае ошибка вызвана тем, что "yourapplication" не найден в путях
поиска python. Обычно это происходит по одной из следующих причин:
- Указаны относительные пути, которые не работают относительно текущего
каталога.
- Выполнение программы зависит от переменных окружения, которые не заданы
для веб-сервера.
- Используется интерпретатор python другой версии.
.. _nginx: http://nginx.org/
.. _lighttpd: http://www.lighttpd.net/
.. _cherokee: http://www.cherokee-project.com/
.. _flup: http://trac.saddi.com/flup
Примечания переводчика
``````````````````````
В случае настройки Lighttpd не нужно писать никаких сценариев SysV `init.d`,
потому что:
1. Lighttpd может сам управлять FastCGI-процессами на локальном компьютере,
самостоятельно порождая необходимое их количество (с учётом настроенного
лимита),
2. в рамках проекта Lighttpd разрабатывается собственный диспетчер
процессов FastCGI - `spawn-fcgi`, который не настолько продвинут, чтобы
регулировать количество необходимых процессов, но по крайней мере
указанное количество процессов запустить и поддерживать сможет.
Обычно `spawn-fcgi` применяется в тех случаях, когда приложение FastCGI
работает на отдельном от веб-сервера компьютере или нужно запустить
приложение от имени другого пользователя, например, для изоляции друг от
друга приложений разных пользователей, работающих на одном сервере.
Например, так: `Настройка FastCGI и PHP с индивидуальными правами
пользователей `_.
И, наконец, никто не мешает использовать spawn-fcgi совместно с nginx.