Я пытаюсь заставить flask работать с Apache, используя mod_wsgi, и я уже более семи часов бьюсь головой об этом. Пришло время обратиться за помощью.
Я бегу apache, используя образ httpd docker.
Я начал, следуя инструкциям здесь , чтобы получить Приложение wsgi 'hello world' работает и работает отлично. Если я открою браузер и перейду к 172.17.0.2
, я увижу страницы, которые живут по адресу /usr/local/apache2/htdocs/
В моем httpd.conf у меня есть следующее, чтобы показать эти страницы:
DocumentRoot "/usr/local/apache2/htdocs"
<Directory "/usr/local/apache2/htdocs">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiView
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks
#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# AllowOverride FileInfo AuthConfig Limit
#
AllowOverride None
#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>
Это все по умолчанию из docker изображения.
Затем, на /usr/local/apache2/wsgi-scripts/myapp.wsgi
У меня есть пример hello world на странице инструкций mod_wsgi. В моем httpd.conf у меня есть следующее
WSGIScriptAlias /myapp /usr/local/apache2/wsgi-scripts/myapp.wsgi
<Directory /usr/local/apache2/wsgi-scripts>
<IfVersion < 2.4>
Order allow,deny
Allow from all
</IfVersion>
<IfVersion >= 2.4>
Require all granted
</IfVersion>
</Directory>
Когда я использую свой браузер для перехода к 172.17.0.2/myapp
, все отлично. Я вижу «hello world» и apache печатает следующие журналы:
[Thu Apr 16 02:48:14.678027 2020] [wsgi:info] [pid 1275:tid 140646030583552] mod_wsgi (pid=1275): Create interpreter '172.17.0.2|/myapp'.
[Thu Apr 16 02:48:14.713667 2020] [wsgi:info] [pid 1275:tid 140646030583552] [client 172.17.0.1:38046] mod_wsgi (pid=1275, process='', application='172.17.0.2|/myapp'): Loading Python script file '/usr/local/apache2/wsgi-scripts/myapp.wsgi'.
172.17.0.1 - - [16/Apr/2020:02:48:14 +0000] "GET /myapp HTTP/1.1" 200 12
Теперь я пытаюсь заставить работать мое приложение flask. Вот где что-то не так. Мой скрипт wsgi находится рядом со скриптом myapp.wsgi, описанным выше:
root@423828dd037e:/# ls -l /usr/local/apache2/wsgi-scripts/
total 8
-rw-r--r-- 1 root root 278 Apr 16 02:16 myapp.wsgi
-rw-r--r-- 1 root root 74 Apr 16 02:22 website_api.wsgi
Скрипт очень прост:
root@423828dd037e:/# cat /usr/local/apache2/wsgi-scripts/website_api.wsgi
from website_rest_api import app as application
Я могу запустить точно такую же команду в python интерпретатор, поэтому я знаю, что импорт работает правильно.
У меня есть
WSGIScriptAlias /api /usr/local/apache2/wsgi-scripts/website_api.wsgi
в моем файле httpd.conf
Когда я пытаюсь перейти к 172.17.0.2/api
Я сталкиваюсь с упражнением в полном разочаровании. Журналы apache выглядят так:
[Thu Apr 16 02:52:41.678999 2020] [wsgi:info] [pid 1395:tid 140174394627840] mod_wsgi (pid=1395): Create interpreter '172.17.0.2|/api'.
[Thu Apr 16 02:52:41.683555 2020] [wsgi:info] [pid 1477:tid 140174539728000] mod_wsgi (pid=1477): Python home /usr.
[Thu Apr 16 02:52:41.683649 2020] [wsgi:info] [pid 1477:tid 140174539728000] mod_wsgi (pid=1477): Initializing Python.
[Thu Apr 16 02:52:41.710027 2020] [wsgi:info] [pid 1477:tid 140174539728000] mod_wsgi (pid=1477): Attach interpreter ''.
[Thu Apr 16 02:52:41.714671 2020] [wsgi:info] [pid 1395:tid 140174394627840] [client 172.17.0.1:40228] mod_wsgi (pid=1395, process='', application='172.17.0.2|/api'): Loading Python script file '
/usr/local/apache2/wsgi-scripts/website_api.wsgi'.
[Thu Apr 16 02:52:41.736762 2020] [wsgi:info] [pid 1477:tid 140174539728000] mod_wsgi (pid=1477): Imported 'mod_wsgi'.
172.17.0.1 - - [16/Apr/2020:02:52:41 +0000] "GET /api HTTP/1.1" 404 232
Из этих журналов я знаю, что apache знает, что это вещь mod_wsgi. Кажется, что он загружает скрипт из правильного местоположения, но затем я получаю 404. Я получаю это для всех моих flask URL. Я должен иметь возможность ударить / api, / api / login, / api / logout, / api / projects, / api / tests, но ничего. Все 404, и нет никакой другой ошибки, которую я вижу, чтобы помочь отладке.
Я знаю, что from website_rest_api import app as application
импортирует правильную вещь, потому что я могу go в оболочку python и посмотреть карту URL себя:
>>> from website_rest_api import app as application
>>> application.url_map
Map([<Rule '/api/projects' (OPTIONS, HEAD, GET) -> projects>,
<Rule '/api/logout' (POST, OPTIONS) -> logout>,
<Rule '/api/login' (POST, OPTIONS) -> login>,
<Rule '/api/tests' (OPTIONS, HEAD, GET) -> tests>,
<Rule '/api' (OPTIONS, HEAD, GET) -> hello>,
<Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
Я тоже могу распечатать их, чтобы они отображались в журналах apache:
[Thu Apr 16 04:38:57.162667 2020] [wsgi:info] [pid 2953:tid 139925743146112] mod_wsgi (pid=2953): Imported 'mod_wsgi'.
[Thu Apr 16 04:38:57.396592 2020] [wsgi:error] [pid 2864:tid 139925713024768] Map([<Rule '/api/projects' (GET, OPTIONS, HEAD) -> projects>,
[Thu Apr 16 04:38:57.396634 2020] [wsgi:error] [pid 2864:tid 139925713024768] <Rule '/api/logout' (OPTIONS, POST) -> logout>,
[Thu Apr 16 04:38:57.396642 2020] [wsgi:error] [pid 2864:tid 139925713024768] <Rule '/api/login' (OPTIONS, POST) -> login>,
[Thu Apr 16 04:38:57.396649 2020] [wsgi:error] [pid 2864:tid 139925713024768] <Rule '/api/tests' (GET, OPTIONS, HEAD) -> tests>,
[Thu Apr 16 04:38:57.396657 2020] [wsgi:error] [pid 2864:tid 139925713024768] <Rule '/api' (GET, OPTIONS, HEAD) -> hello>,
[Thu Apr 16 04:38:57.396666 2020] [wsgi:error] [pid 2864:tid 139925713024768] <Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
Я также могу сознательно испортить импорт в website_api.wsgi и я видите, что Apache выдает сообщение об ошибке, поэтому я достаточно уверен, что если импорт был неправильным, он сказал бы мне:
[Thu Apr 16 04:34:27.634313 2020] [wsgi:info] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] mod_wsgi (pid=2743, process='website_api', application=''): Loading Python script file '/usr
/local/apache2/wsgi-scripts/website_api.wsgi'.
[Thu Apr 16 04:34:27.634956 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] mod_wsgi (pid=2743): Failed to exec Python script file '/usr/local/apache2/wsgi-scripts/web
site_api.wsgi'.
[Thu Apr 16 04:34:27.635044 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] mod_wsgi (pid=2743): Exception occurred processing WSGI script '/usr/local/apache2/wsgi-scr
ipts/website_api.wsgi'.
[Thu Apr 16 04:34:27.644848 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] Traceback (most recent call last):
[Thu Apr 16 04:34:27.644905 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] File "/usr/local/apache2/wsgi-scripts/website_api.wsgi", line 1, in <module>
[Thu Apr 16 04:34:27.644917 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] import zarzlefrz
[Thu Apr 16 04:34:27.644943 2020] [wsgi:error] [pid 2743:tid 139796746721024] [remote 172.17.0.1:60664] ModuleNotFoundError: No module named 'zarzlefrz'
172.17.0.1 - - [16/Apr/2020:04:34:27 +0000] "GET /api HTTP/1.1" 500 528
Даже журналы уровня отладки, кажется, не говорят мне ничего о что происходит:
[Thu Apr 16 03:53:52.766115 2020] [core:debug] [pid 2075:tid 140389386400896] log.c(1571): AH02639: Using SO_REUSEPORT: yes (1)
[Thu Apr 16 03:53:52.766422 2020] [wsgi:info] [pid 2079:tid 140389386400896] mod_wsgi (pid=2079): Python home /usr.
[Thu Apr 16 03:53:52.766546 2020] [wsgi:info] [pid 2079:tid 140389386400896] mod_wsgi (pid=2079): Initializing Python.
[Thu Apr 16 03:53:52.769139 2020] [wsgi:info] [pid 2078:tid 140389386400896] mod_wsgi (pid=2078): Python home /usr.
[Thu Apr 16 03:53:52.769300 2020] [wsgi:info] [pid 2078:tid 140389386400896] mod_wsgi (pid=2078): Initializing Python.
[Thu Apr 16 03:53:52.805797 2020] [wsgi:info] [pid 2077:tid 140389386400896] mod_wsgi (pid=2077): Attach interpreter ''.
[Thu Apr 16 03:53:52.806676 2020] [wsgi:info] [pid 2079:tid 140389386400896] mod_wsgi (pid=2079): Attach interpreter ''.
[Thu Apr 16 03:53:52.813314 2020] [wsgi:info] [pid 2078:tid 140389386400896] mod_wsgi (pid=2078): Attach interpreter ''.
[Thu Apr 16 03:53:52.845456 2020] [wsgi:info] [pid 2079:tid 140389386400896] mod_wsgi (pid=2079): Imported 'mod_wsgi'.
[Thu Apr 16 03:53:52.847250 2020] [mpm_event:debug] [pid 2079:tid 140389373064960] event.c(2314): AH02471: start_threads: Using epoll (wakeable)
[Thu Apr 16 03:53:52.859225 2020] [wsgi:info] [pid 2077:tid 140389386400896] mod_wsgi (pid=2077): Imported 'mod_wsgi'.
[Thu Apr 16 03:53:52.860438 2020] [mpm_event:debug] [pid 2077:tid 140389373064960] event.c(2314): AH02471: start_threads: Using epoll (wakeable)
[Thu Apr 16 03:53:52.862762 2020] [wsgi:info] [pid 2078:tid 140389386400896] mod_wsgi (pid=2078): Imported 'mod_wsgi'.
[Thu Apr 16 03:53:52.863600 2020] [mpm_event:debug] [pid 2078:tid 140389373064960] event.c(2314): AH02471: start_threads: Using epoll (wakeable)
[Thu Apr 16 03:54:03.057717 2020] [authz_core:debug] [pid 2079:tid 140389235279616] mod_authz_core.c(818): [client 172.17.0.1:41350] AH01626: authorization result of Require all granted: granted
[Thu Apr 16 03:54:03.057771 2020] [authz_core:debug] [pid 2079:tid 140389235279616] mod_authz_core.c(818): [client 172.17.0.1:41350] AH01626: authorization result of <RequireAny>: granted
[Thu Apr 16 03:54:03.086984 2020] [wsgi:info] [pid 2079:tid 140389235279616] mod_wsgi (pid=2079): Create interpreter '172.17.0.2|/api'.
[Thu Apr 16 03:54:03.128584 2020] [wsgi:info] [pid 2079:tid 140389235279616] [client 172.17.0.1:41350] mod_wsgi (pid=2079, process='', application='172.17.0.2|/api'): Loading Python script file '
/usr/local/apache2/wsgi-scripts/website_api.wsgi'.
172.17.0.1 - - [16/Apr/2020:03:54:03 +0000] "GET /api HTTP/1.1" 404 232
Мой вопрос:
Как, черт возьми, я должен отлаживать это дальше? Есть ли какое-то место, которое извергает секретные flask ошибок, которые я не вижу?