FastCGI
FastCGI — это вариант развертывания на серверах, таких как nginx, lighttpd и cherokee; см. uWSGI и Контейнеры WSGI Standalone для других вариантов. Чтобы использовать ваше WSGI-приложение с любым из них, вам сначала потребуется сервер FastCGI. Наиболее популярным из них является flup, который мы будем использовать в этом руководстве. Убедитесь, что он установлен, чтобы следовать инструкциям.
Обратите внимание
Пожалуйста, убедитесь заранее, что все app.run() вызовы, которые могут быть в вашем файле приложения, находятся внутри блока if __name__ ==
'__main__': или перемещены в отдельный файл. Просто убедитесь, что он не вызывается, так как это всегда запускает локальный сервер WSGI, чего мы не хотим, если развернём это приложение в FastCGI.
Создание файла .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. Для этого вам нужно передать путь к сокету в WSGIServer.
WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()
Путь должен быть точно таким же, как вы определили в конфигурации сервера.
Сохраните файл yourapplication.fcgi в месте, где вы сможете его снова найти. Логично разместить его в /var/www/yourapplication или что-то подобное.
Убедитесь, что на этом файле установлен исполняемый бит, чтобы серверы могли его выполнить:
$ chmod +x /var/www/yourapplication/yourapplication.fcgi
Настройка Apache
Приведённый выше пример подходит для базового развертывания в Apache, но ваш файл .fcgi будет отображаться в вашем URL-адресе приложения, например, example.com/yourapplication.fcgi/news/. Существует несколько способов настроить ваше приложение, чтобы yourapplication.fcgi не отображался в URL-адресе. Предпочтительный способ — использовать директивы конфигурации ScriptAlias и SetHandler для перенаправления запросов на сервер FastCGI. В следующем примере используется FastCgiServer для запуска 5 экземпляров приложения, которые будут обрабатывать все входящие запросы:
LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so
FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5
<VirtualHost *>
ServerName webapp1.mydomain.com
DocumentRoot /var/www/html/yourapplication
AddHandler fastcgi-script fcgi
ScriptAlias / /var/www/html/yourapplication/app.fcgi/
<Location />
SetHandler fastcgi-script
</Location>
</VirtualHost>
Эти процессы будут управляться Apache. Если вы используете отдельный сервер FastCGI, вместо этого можно использовать директиву FastCgiExternalServer. Обратите внимание, что в следующем примере путь не является реальным, он просто используется в качестве идентификатора для других директив, таких как AliasMatch:
FastCgiServer /var/www/html/yourapplication -host 127.0.0.1:3000
Если вы не можете установить 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
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '<your_local_path>/lib/python<your_python_version>/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 с помощью LighttpdCGIRootFix middleware.
Убедитесь, что применяете это только в том случае, если вы монтируете приложение на корневой URL-адрес. Также см. документацию Lighty для получения дополнительной информации о FastCGI и Python (обратите внимание, что явное передача сокета для выполнения run() больше не требуется).
Настройка nginx
Установка приложений FastCGI на nginx немного отличается, так как по умолчанию параметры FastCGI не передаются.
Базовая конфигурация Flask FastCGI для nginx выглядит следующим образом:
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, вам нужно сделать это самостоятельно. Supervisor может управлять процессами FastCGI. Вы можете поискать другие менеджеры процессов FastCGI или написать скрипт для запуска вашего файла .fcgi при загрузке, например, используя скрипт SysV init.d. Для временного решения вы всегда можете запустить скрипт .fcgi внутри GNU screen. Подробнее см. man 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. Распространённые проблемы:
- Использование относительных путей. Не полагайтесь на текущую рабочую директорию.
- Код зависит от переменных среды, которые не установлены веб-сервером.
- Использование разных интерпретаторов Python.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.1.x/deploying/fastcgi/