在 Django/mod_wsgi 虚拟环境中配置 WSGIPythonHome 的问题

Posted

技术标签:

【中文标题】在 Django/mod_wsgi 虚拟环境中配置 WSGIPythonHome 的问题【英文标题】:An issue configuring WSGIPythonHome in a Django/mod_wsgi virtual environment 【发布时间】:2020-01-29 05:38:17 【问题描述】:

我在 Windows 10 上运行 Python 3.7.1 和 Apache 2.4.38。我已经设置了一个虚拟环境,其中包含通过“pip”安装的 Django 2.2.5 和 mod_wsgi 4.6.5。在“httpd.conf”中,我根据几条指令将 WSGIPythonHome 设置为指向我的虚拟环境的根目录。但是,当我启动 Apache 时,它​​会失败并显示:“没有名为 'encodings' 的模块”。 Apache 似乎需要访问系统范围的 Python。

我在“C:\Program Files\Python3.7.1”中有系统范围的 Python。 虚拟环境位于:“D:\PROJ\PYTHON\VEnv\django”。

这是我添加到“httpd.conf”的内容:

LoadModule wsgi_module "D:/PROJ/PYTHON/VEnv/django/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"

WSGIScriptAlias / "D:/PROJ/PYTHON/VEnv/django/Shipkaliev/wsgi.py"

WSGIPythonHome "D:/PROJ/PYTHON/VEnv/django"

WSGIPythonPath "D:/PROJ/PYTHON/VEnv/django/Shipkaliev"

<Directory "D:/PROJ/PYTHON/VEnv/django/Shipkaliev">
<Files wsgi.py>
    Require all granted
</Files>
</Directory>

根据:https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html 和:https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/modwsgi/ 需要这样设置。

因此,使用此配置,Apache 无法找到虚拟环境中不存在的所有原生 Python 模块,例如“encodings”、“codecs”、“io”等。

当我注释掉“WSGIPythonHome”指令时,Apache 会初始化 Python,但是如果我尝试在“wsgi.py”脚本中导入 Django,它会找不到它。

让一切正常的方法是,我将“WSGIPythonHome”更改为指向系统范围的 Python,并将虚拟环境的“站点包”添加到路径中:

WSGIPythonHome "C:/Program Files/Python3.7.1"

WSGIPythonPath "D:/PROJ/PYTHON/VEnv/django/Lib/site-packages;D:/PROJ/PYTHON/VEnv/django/Shipkaliev"

但这不是它的预期工作方式。 “WSGIPythonHome”有什么意义?难道我做错了什么?我的解决方案可以接受吗?

非常感谢!

【问题讨论】:

【参考方案1】:

我找到了!由于 "D:/PROJ/PYTHON/VEnv/django" 是虚拟环境的根目录,所以那里找不到 Python 标准库。标准库位于“C:/Program Files/Python3.7.1/Lib”中。这就是为什么:“没有名为 'encodings' 的模块”。

“WSGIPythonHome - 用于在 Python 初始化时向 Python 指示其库文件的安装位置。...使用此指令时,应为包含平台无关和系统相关 Python 库文件的目录提供前缀。 " - 感谢:https://code.google.com/archive/p/modwsgi/wikis/ConfigurationDirectives.wiki#WSGIPythonHome

这是我最后的 Apache conf:

LoadModule wsgi_module "D:/PROJ/PYTHON/VEnv/django/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp37-win_amd64.pyd"

WSGIScriptAlias / "D:/PROJ/PYTHON/VEnv/django/Shipkaliev/wsgi.py"

WSGIPythonHome "D:/PROJ/PYTHON/VEnv/django;C:/Program Files/Python3.7.1"

WSGIPythonPath "D:/PROJ/PYTHON/VEnv/django/Lib/site-packages;D:/PROJ/PYTHON/VEnv/django/Shipkaliev"

<Directory "D:/PROJ/PYTHON/VEnv/django/Shipkaliev">
<Files wsgi.py>
    Require all granted
</Files>
</Directory>

这在 Django 和 mod_wsgi 文档中都没有明确说明。希望对你有帮助。

【讨论】:

这救了我... tysm【参考方案2】:

我能够让我的工作类似于 Shipkaliev 的回答,但对 WSGIPythonHome 和 WSGIPythonPath 的配置最少:

将 WSGIPythonHome 设置为你的 python 可执行文件,并将 WSGIPythonPath 设置为你的 env 包的安装位置。


例如:

cd C:/xampp/htdocs/django_app
python -m venv env
env/Scripts/activate
python -m pip install -r your_dependencies.txt

env 文件位于:

C:/xampp/htdocs/django_app/env/

python 可执行文件是您安装 python 的位置。我的在

C:/Users/Yi/Python/python.exe

所以对于我的 apache 配置文件:

LoadModule wsgi_module modules/mod_wsgi.so
<IfModule wsgi_module>

    ## Set WSGIPythonHome to this your python executable.
    WSGIPythonHome "C:/Users/Yi/Python"
    ## Set WSGIPythonPath to where your env packages are installed.
    WSGIPythonPath "C:/xampp/htdocs/django_app/env/Lib/site-packages"
    
    <VirtualHost *:443>
        WSGIScriptAlias / "C:/xampp/htdocs/django_app/django_app/wsgi.py"

        <Directory "C:/xampp/htdocs/django_app">
            <Files wsgi.py>
                Require all granted
            </Files>
        </Directory>

        Alias /static/ "C:/xampp/htdocs/django_app/static/"

        <Directory "C:/xampp/htdocs/django_app/static/">
            Require all granted
        </Directory>
    </VirtualHost>
</IfModule>

【讨论】:

以上是关于在 Django/mod_wsgi 虚拟环境中配置 WSGIPythonHome 的问题的主要内容,如果未能解决你的问题,请参考以下文章

centos+apache+python34+django+mod_wsgi 开发环境搭建

Django + mod_wsgi。从 Apache 的 SetEnv 设置操作系统环境变量

Django,mod_wsgi,psycopg2 配置不当:加载 psycopg2 模块时出错:没有名为 _psycopg 的模块

python看门狗模块在redhat服务器下不能与django/mod_wsgi一起使用

Django/mod_wsgi/Apache - mod_wsgi 没有使用为其编译的 Python 版本 - “ModuleNotFoundError: No module named 'math'

Django + mod_wsgi + apache:ImportError at / No module named djproj.urls