WSGIDaemonProcess 不影响 python 站点
WSGIDaemonProcess does not affect python site
我想在一台 CentOS 服务器上管理多个 Django 应用程序,每个域一个,使用虚拟主机和 virtualenvs(每个应用程序都有自己的虚拟环境)。
我将在这里展示我的配置、生成的日志并解释我期望(但未能)看到的内容。
我正在使用 mod_wsgi 4.4 和软件集合 rh-python34 和 httpd24。
我的虚拟主机是这样配置的:
全局配置
Define RROOT "/opt/rh/httpd24/root"
Define RDOCROOT "/opt/rh/httpd24/root/var/www"
WSGIScriptAlias /wsgi "${RDOCROOT}/wsgi-bin"
WSGIProcessGroup localhost
<Directory "${RDOCROOT}/wsgi-bin">
Order allow,deny
Allow from all
</Directory>
通过上面的配置,我想处理通过IP访问的服务器,例如去 123.123.123.123:80/wsgi/
应该 运行 RDOCROOT/wsgi-bin 中的脚本。它不起作用,实际上对IP地址的请求是由第一个虚拟主机处理的。但这是一个附带问题。
每个虚拟主机配置(DOMAIN.COM 更改,例如 example1.com、example2.com)
<VirtualHost *:80>
ServerName DOMAIN.COM
ServerAdmin webmaster@DOMAIN.COM
DocumentRoot "${RDOCROOT}/DOMAIN.COM/html"
ErrorLog "${RDOCROOT}/DOMAIN.COM/error.log"
CustomLog "${RDOCROOT}/DOMAIN.COM/access.log" combined
<Directory "${RDOCROOT}/DOMAIN.COM/html">
Options FollowSymLinks
AllowOverride All
Require all granted
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://DOMAIN.COM"
</IfModule>
</Directory>
ScriptAlias /cgi/ "${RDOCROOT}/DOMAIN.COM/cgi-bin/"
<Directory "${RDOCROOT}/DOMAIN.COM/cgi-bin">
AllowOverride None
Options None
Require all granted
AddDefaultCharset utf-8
</Directory>
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
WSGIProcessGroup DOMAIN.COM
WSGIScriptAlias /wsgi/ "${RDOCROOT}/DOMAIN.COM/wsgi-bin/"
<Directory "${RDOCROOT}/DOMAIN.COM/wsgi-bin">
Require all granted
</Directory>
</VirtualHost>
因此,虚拟主机应该在 DOMAIN.COM/
中包含 html 页面,在 DOMAIN.COM/cgi/
中包含 /cgi-bin/
脚本,在 DOMAIN.COM/wsgi/
中包含 /wsgi-bin/
脚本=],它们都有效。
问题是虚拟环境无效:无法加载来自该虚拟环境的包。为了进行调试,我将日志级别设置为 info
并创建了一个无法打印站点包目录的测试脚本:
$ cat wsgi-bin/app.py
import site
raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))
当我访问 DOMAIN.COM/wsgi/app.py
时,error.log 包含以下内容(没有前缀、时间戳和 pids):
mod_wsgi (pid=20267): Attach interpreter ''.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
mod_wsgi (pid=20267): Create interpreter 'WWW.DOMAIN.COM:80|/wsgi/app.py'.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
[remote SOMEIP] mod_wsgi (pid=20267, process='WWW.DOMAIN.COM', application='WWW.DOMAIN.COM:80|/wsgi/app.py'): Loading WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] mod_wsgi (pid=20267): Target WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py' cannot be loaded as Python module.
[remote SOMEIP] mod_wsgi (pid=20267): Exception occurred processing WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] Traceback (most recent call last):
[remote SOMEIP] File "/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py", line 5, in <module>
[remote SOMEIP] raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))
[remote SOMEIP] RuntimeError: Site /usr/share/httpd/.local ['/opt/rh/rh-python34/root/usr/lib64/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/site-python']
从日志的第三行来看,virtualenv 似乎已正确添加到站点,但从脚本生成的最后一行来看,似乎使用了系统范围的站点包。
目录正确,已仔细检查。
我哪里失败了?
WSGIPythonHome
对于 virtualenv
安装,您可能需要专门使用 WSGIPythonHome
。
WSGIPythonHome ${RDOCROOT}/DOMAIN.COM/django-venv/
配置 WSGIDaemonProcess
和 python-path
您可能需要更改您提供的路径:
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
只使用其中之一(另请参阅 mod_wsgi 4.4.15 的发行说明)
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
正在为其他 python
重新编译
在某些情况下,除了 WSGIPythonHome
或 python-path
技巧之外,您可能还需要 recompile mod_wsgi
for that particular python version。
直接在 wsgi 应用程序中配置 site
作为最后的手段,您可以在 wsgi app.py
:
中配置站点包
import site
site.addsitedir('/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages')
mod_wsgi
WSGIPythonPath
的已知问题
来自release notes for mod_wsgi 4.4.15:
- When specifying multiple directories for the Python module search path using the
WSGIPythonPath
directive, or the python-path
option to WSGIDaemonProcess
, it was failing under Python 3 due to incorrect logging. It was therefore only possible to add a single directory.
我想在一台 CentOS 服务器上管理多个 Django 应用程序,每个域一个,使用虚拟主机和 virtualenvs(每个应用程序都有自己的虚拟环境)。
我将在这里展示我的配置、生成的日志并解释我期望(但未能)看到的内容。
我正在使用 mod_wsgi 4.4 和软件集合 rh-python34 和 httpd24。
我的虚拟主机是这样配置的:
全局配置
Define RROOT "/opt/rh/httpd24/root"
Define RDOCROOT "/opt/rh/httpd24/root/var/www"
WSGIScriptAlias /wsgi "${RDOCROOT}/wsgi-bin"
WSGIProcessGroup localhost
<Directory "${RDOCROOT}/wsgi-bin">
Order allow,deny
Allow from all
</Directory>
通过上面的配置,我想处理通过IP访问的服务器,例如去 123.123.123.123:80/wsgi/
应该 运行 RDOCROOT/wsgi-bin 中的脚本。它不起作用,实际上对IP地址的请求是由第一个虚拟主机处理的。但这是一个附带问题。
每个虚拟主机配置(DOMAIN.COM 更改,例如 example1.com、example2.com)
<VirtualHost *:80>
ServerName DOMAIN.COM
ServerAdmin webmaster@DOMAIN.COM
DocumentRoot "${RDOCROOT}/DOMAIN.COM/html"
ErrorLog "${RDOCROOT}/DOMAIN.COM/error.log"
CustomLog "${RDOCROOT}/DOMAIN.COM/access.log" combined
<Directory "${RDOCROOT}/DOMAIN.COM/html">
Options FollowSymLinks
AllowOverride All
Require all granted
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://DOMAIN.COM"
</IfModule>
</Directory>
ScriptAlias /cgi/ "${RDOCROOT}/DOMAIN.COM/cgi-bin/"
<Directory "${RDOCROOT}/DOMAIN.COM/cgi-bin">
AllowOverride None
Options None
Require all granted
AddDefaultCharset utf-8
</Directory>
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
WSGIProcessGroup DOMAIN.COM
WSGIScriptAlias /wsgi/ "${RDOCROOT}/DOMAIN.COM/wsgi-bin/"
<Directory "${RDOCROOT}/DOMAIN.COM/wsgi-bin">
Require all granted
</Directory>
</VirtualHost>
因此,虚拟主机应该在 DOMAIN.COM/
中包含 html 页面,在 DOMAIN.COM/cgi/
中包含 /cgi-bin/
脚本,在 DOMAIN.COM/wsgi/
中包含 /wsgi-bin/
脚本=],它们都有效。
问题是虚拟环境无效:无法加载来自该虚拟环境的包。为了进行调试,我将日志级别设置为 info
并创建了一个无法打印站点包目录的测试脚本:
$ cat wsgi-bin/app.py
import site
raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))
当我访问 DOMAIN.COM/wsgi/app.py
时,error.log 包含以下内容(没有前缀、时间戳和 pids):
mod_wsgi (pid=20267): Attach interpreter ''.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
mod_wsgi (pid=20267): Create interpreter 'WWW.DOMAIN.COM:80|/wsgi/app.py'.
mod_wsgi (pid=20267): Adding '(null)' to path.
mod_wsgi (pid=20267): Adding '/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages/' to path.
[remote SOMEIP] mod_wsgi (pid=20267, process='WWW.DOMAIN.COM', application='WWW.DOMAIN.COM:80|/wsgi/app.py'): Loading WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] mod_wsgi (pid=20267): Target WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py' cannot be loaded as Python module.
[remote SOMEIP] mod_wsgi (pid=20267): Exception occurred processing WSGI script '/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py'.
[remote SOMEIP] Traceback (most recent call last):
[remote SOMEIP] File "/opt/rh/httpd24/root/var/www/DOMAIN.COM/wsgi-bin/app.py", line 5, in <module>
[remote SOMEIP] raise RuntimeError('Site {} {}'.format(site.getuserbase(), site.getsitepackages()))
[remote SOMEIP] RuntimeError: Site /usr/share/httpd/.local ['/opt/rh/rh-python34/root/usr/lib64/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/python3.4/site-packages', '/opt/rh/rh-python34/root/usr/lib/site-python']
从日志的第三行来看,virtualenv 似乎已正确添加到站点,但从脚本生成的最后一行来看,似乎使用了系统范围的站点包。
目录正确,已仔细检查。
我哪里失败了?
WSGIPythonHome
对于 virtualenv
安装,您可能需要专门使用 WSGIPythonHome
。
WSGIPythonHome ${RDOCROOT}/DOMAIN.COM/django-venv/
配置 WSGIDaemonProcess
和 python-path
您可能需要更改您提供的路径:
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/wsgi:${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
只使用其中之一(另请参阅 mod_wsgi 4.4.15 的发行说明)
WSGIDaemonProcess DOMAIN.COM python-path=${RDOCROOT}/DOMAIN.COM/django-venv/lib/python3.4/site-packages/
正在为其他 python
重新编译在某些情况下,除了 WSGIPythonHome
或 python-path
技巧之外,您可能还需要 recompile mod_wsgi
for that particular python version。
直接在 wsgi 应用程序中配置 site
作为最后的手段,您可以在 wsgi app.py
:
import site
site.addsitedir('/opt/rh/httpd24/root/var/www/DOMAIN.COM/django-venv/lib/python3.4/site-packages')
mod_wsgi
WSGIPythonPath
的已知问题
来自release notes for mod_wsgi 4.4.15:
- When specifying multiple directories for the Python module search path using the
WSGIPythonPath
directive, or thepython-path
option toWSGIDaemonProcess
, it was failing under Python 3 due to incorrect logging. It was therefore only possible to add a single directory.