Перевод статьи: FastCGI
Автор: Армин Роначер (Armin Ronacher)
FastCGI - это один из вариантов развёртывания приложения на серверах nginx, lighttpd и cherokee; за описанием других опций обратитесь к разделам uWSGI и Самостоятельные контейнеры WSGI. Для использования приложения WSGI с любым из этих серверов необходимо сначала настроить сервер FastCGI. Наиболее популярен flup, который будет использоваться в этом руководстве. Убедитесь в том, что установили его, прежде чем продолжить чтение.
Удостоверьтесь, что вызовы app.run() в файле приложения находятся внутри блока if __name__ == '__main__': или вынесены в отдельный файл. Просто убедитесь в отсутствии подобных вызовов, потому что если вы решили воспользоваться FastCGI для запуска приложения, то запускать локальный сервер WSGI не нужно.
Для начала нужно создать файл сервера 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. Для этого нужно передать путь к сокет-файлу в WSGIServer:
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
Этот путь должен быть точно таким же, какой был указан в настройках сервера.
Сохраните файл yourapplication.fcgi где-нибудь, где вы сможете потом найти его. Неплохо положить его в /var/www/yourapplication или в какое-то другое подходящее место.
Убедитесь, что у этого файла установлен флаг выполнения, чтобы сервер мог его выполнить:
# chmod +x /var/www/yourapplication/yourapplication.fcgi
Приведённый выше пример достаточно хорош для того, чтобы использовать его при развёртывании с Apache, однако файл .fcgi будет встречаться в URL приложения, например: example.com/yourapplication.fcgi/news/. Есть несколько способов настройки приложения для того, чтобы убрать yourapplication.fcgi из URL. Предпочтительный способ - это использование директивы ScriptAlias:
<VirtualHost *> ServerName example.com ScriptAlias / /path/to/yourapplication.fcgi/ </VirtualHost>
Если задать ScriptAlias нельзя, например на веб-узле, настроенном для нескольких пользователей, то можно воспользоваться промежуточным приложением WSGI для удаления yourapplication.fcgi из URL. Настройте .htaccess:
<IfModule mod_fcgid.c> AddHandler fcgid-script .fcgi <Files ~ (\.fcgi)> SetHandler fcgid-script Options +FollowSymLinks +ExecCGI </Files> </IfModule> <IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L] </IfModule>
Теперь настроим yourapplication.fcgi:
#!/usr/bin/python #: не обязательный путь к каталогу с локальными пакетами python 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()
Базовая настройка 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 при помощи промежуточного приложения LighttpdCGIRootFix.
Убедитесь, что применяете его лишь в том случае, если подключили приложение к корню URL. А также, обратитесь к документации Lighttpd за более подробной информацией о FastCGI и Python (отметим, что явная передача сокет-файла в run() больше не требуется).
Установка приложений 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; }
Поскольку 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 <module> ImportError: No module named yourapplication
В данном случае ошибка вызвана тем, что yourapplication не найден в путях поиска python. Обычно это происходит по одной из следующих причин:
В случае настройки Lighttpd не нужно писать никаких сценариев SysV init.d, потому что:
Обычно spawn-fcgi применяется в тех случаях, когда приложение FastCGI работает на отдельном от веб-сервера компьютере или нужно запустить приложение от имени другого пользователя, например, для изоляции друг от друга приложений разных пользователей, работающих на одном сервере. Например, так: Настройка FastCGI и PHP с индивидуальными правами пользователей.
И, наконец, никто не мешает использовать spawn-fcgi совместно с nginx.
Этот и другие переводы можно найти на сайте проекта перевода документации по Flask. Автор проекта - Виталий Кузьмин aka ferm32.