使用与系统默认版本不同的 virtualenv 或 Python 运行 mod_wsgi

Posted

技术标签:

【中文标题】使用与系统默认版本不同的 virtualenv 或 Python 运行 mod_wsgi【英文标题】:Run mod_wsgi with virtualenv or Python with version different that system default 【发布时间】:2015-02-11 14:21:38 【问题描述】:

我正在尝试让我的 Flask 应用程序在 CentOS 服务器上运行。基本上问题是我在/usr/bin 中安装了Python 2.6,这是系统默认值,而在/usr/local/bin 中安装了Python 3.4。我想为 mod_wsgi 使用 Python 3.4 virtualenv 或至少 Python 3.4 解释器来运行我的应用程序。

我在~/virtualenvs/flask 中创建了 virtualenv。

我有这个 WSGI 脚本:

import os
import sys
from logging import Formatter, FileHandler

APP_HOME = r"/home/fenikso/Album"


activate_this = os.path.join("/home/fenikso/virtualenvs/flask/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))

sys.path.insert(0, APP_HOME)
os.chdir(APP_HOME)

from app import app

handler = FileHandler("app.log")
handler.setFormatter(Formatter("[%(asctime)s | %(levelname)s] %(message)s"))
app.logger.addHandler(handler)
application = app

并在 Apache 中进行以下配置:

<VirtualHost *:80>
        ServerName album2.site.cz
        Alias /static "/home/fenikso/Album/static"
        Alias /photos "/home/fenikso/Album/photos"
        Alias /thumbs "/home/fenikso/Album/thumbs"
        WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
        <Directory "/home/fenikso/Album">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/static">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/photos">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/thumbs">
            AllowOverride None
            Allow from all
        </Directory>
</VirtualHost>

但是,在尝试运行应用程序时,我收到错误消息:

Apache/2.2.15 (Unix) DAV/2 mod_wsgi/3.2 Python/2.6.6 mod_fcgid/2.3.7 php/5.3.3 mod_ssl/2.2.15 OpenSSL/1.0.1e-fips SVN/1.6.11 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations
mod_wsgi (pid=14627): Target WSGI script '/home/fenikso/Album/wsgi.py' cannot be loaded as Python module.
mod_wsgi (pid=14627): Exception occurred processing WSGI script '/home/fenikso/Album/wsgi.py'.
Traceback (most recent call last):
   File "/home/fenikso/Album/wsgi.py", line 15, in <module>
     from app import app
   File "/home/fenikso/Album/app.py", line 1, in <module>
     from flask import Flask
 ImportError: No module named flask

我注意到 Python 2.6 正在运行并且我的 virtualenv 未激活。什么是让它工作的正确方法,并且仍然将 Python 2.6 作为系统默认值?

【问题讨论】:

【参考方案1】:

我认为另一个更简洁、合乎逻辑和灵活的选择是在 wsgi 文件的开头简单地从 venv 引用 python 解释器。这样,它很容易更改(无需摆弄系统配置文件)并为多个应用程序在不同的 python 环境中运行提供了可能性,如下所示:

#!/path/to/your/venv/bin/python

【讨论】:

【参考方案2】:

您必须在 apache.conf 中添加以下行,以便提供正确的可执行文件和 virtualenv 的路径。

WSGIPythonHome /usr/local/bin
WSGIPythonPath /home/fenikso/virtualenv/lib/python3.4/site-packages

你会发现这两个命令in the mod_wsgi documentation的所有选项

请注意,您的 mod_wsgi 版本必须与 python 可执行文件兼容。在您的情况下,您可能必须安装 mod_wsgi3.4 并配置 apache 以使用它而不是标准的 mod_wsgi 模块。

整个配置文件应该是:

WSGIPythonHome "/usr/local/bin"
WSGIPythonPath "/home/fenikso/virtualenv/lib/python3.4/site-packages"

<VirtualHost *:80>
        ServerName album2.site.cz
        Alias /static "/home/fenikso/Album/static"
        Alias /photos "/home/fenikso/Album/photos"
        Alias /thumbs "/home/fenikso/Album/thumbs"
        WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
        <Directory "/home/fenikso/Album">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/static">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/photos">
            AllowOverride None
            Allow from all
        </Directory>
        <Directory "/home/fenikso/Album/thumbs">
            AllowOverride None
            Allow from all
        </Directory>
</VirtualHost>

【讨论】:

我认为这是正确的方法。但是我无法让它在我的环境中工作。太多的东西破碎和凌乱,所以我放弃并尝试了另一种方式。 但是,WSGIPythonHomeWSGIPythonPath 不应该在 &lt;VirtualHost&gt; 之外吗? 您说的很对,这些选项必须在&lt;VirtualHost&gt; 块之外。我的错。如果您必须为每个 &lt;VirtualHost&gt; 使用不同的 virtualenv,您可以通过设置 python-path 选项来使用 WSGIDaemonProcessWSGIProcessGroup 指令。【参考方案3】:

查看WSGIPythonHome and WSGIPythonPath 指令。您也可能安装了 python2.6 mod_wsgi,mod_wsgi 必须为预期的 python 版本和does not support multiple python versions 编译。所以检查你的 mod_wsgi 是否兼容 py3.4 并设置上面的指令。

或者,您可以使用诸如 gunicorn 之类的 python 服务器和从 apache 到 gunicorn 的 proxypass 运行烧瓶应用程序。

【讨论】:

感谢您的建议。我试图研究 WSGIPythonHome 和 WSGIPythonPath,但我不知道如何正确使用它们,因为我没有找到任何示例。另外,如何检查 mod_wsgi “类型”?我刚刚做了yum install mod_wsgi @Fenikso ,@afrancais 有一个使用指令的更完整示例,请参阅他的答案。您可以通过在 lib 上执行 ldd 来检查为哪个 python mod_wsgi 编译,可能是ldd /usr/lib,lib64/httpd/modules/mod_wsgi.so 感谢您提供有关 ldd 的宝贵信息并建议 Gunicorn。最后我选择了 uWSGI + nginx。有用的是 uWSGI 可以用 pip 安装,所以我可以直接安装所需的 Python 版本。

以上是关于使用与系统默认版本不同的 virtualenv 或 Python 运行 mod_wsgi的主要内容,如果未能解决你的问题,请参考以下文章

在virtualenv中使用不同的Python版本

在windows下使用VirtualEnv

在 virtualenv 中控制 pip 版本

用pyenv和virtualenv搭建单机多版本python虚拟开发环境

Linux下使用 virtualenv 虚拟独立 Python 环境

pyenv & virtualenv 的安装与使用