FastCGI
FastCGI — это вариант развертывания на серверах, таких как nginx, lighttpd и cherokee; см. uWSGI и Контейнеры WSGI по умолчанию для других вариантов. Для использования вашего приложения 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 прослойки.
Убедитесь, что вы применяете это только в том случае, если вы устанавливаете приложение в корне URL. Также, смотрите документацию Lighttpd для получения дополнительной информации о FastCGI и Python (обратите внимание, что явное передача сокета для запуска больше не требуется).
Настройка 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.0.x/deploying/fastcgi/