【问题标题】:Django/Apache/mod_wsgi not using virtualenv's Python binaryDjango/Apache/mod_wsgi 不使用 virtualenv 的 Python 二进制文件
【发布时间】:2011-08-13 14:58:29
【问题描述】:

我在 /opt/webapps/ff/ 有一个带有自己的 Python 安装的 virtualenv。我在我的 Apache 配置文件中将 WSGIPythonHome 设置为 /opt/webapps/ff (这肯定会以某种方式使用,因为如果我将其设置为稍微不同的现有目录并重新启动 Apache,我会得到 504)。但是如果我例如assert False 在某个视图中显示 Django 调试页面,我看到 settings.PYTHON_BIN 是 /usr/bin 而不是 /opt/webapps/ff/bin。

如何让 Apache/mod_wsgi 使用我的虚拟环境的 Python 二进制文件?我认为设置 WSGIPythonHome 是这样做的方法,但它似乎只影响使用哪个站点包目录,而不影响使用哪个二进制文件。谢谢。

【问题讨论】:

  • 你能解决这个问题吗?

标签: python django apache mod-wsgi wsgi


【解决方案1】:

我在 virtualenv 中安装 modoboa(基于 django)时遇到了同样的问题。

我花了很多时间才找到一个明确的答案,所以我会在这里发布。

我需要做的只是在通用 apache conf 文件(CentOS 中的 /etc/httpd/conf/httpd.conf)中添加两行:

WSGISocketPrefix /var/run/wsgi ## (location for the PID)
WSGIPythonHome /path/to/virtualenv 

然后重启 Apache

【讨论】:

    【解决方案2】:

    这些是我使用的说明,似乎效果很好。

    http://code.google.com/p/modwsgi/wiki/VirtualEnvironments

    使用 'site.addsitedir()' 有点 不同于简单地添加 目录到 'sys.path' 作为 函数将打开任何“.pth”文件 位于目录和进程中 他们。这是必要的,以确保 任何相关的特殊目录 Python 鸡蛋会自动添加到 'sys.path'。

    请注意,虽然 virtualenv 包括 脚本“activate_this.py”,其中 virtualenv 文档声称 应该使用 'execfile()' 调用 在 mod_wsgi 的上下文中,您可以 想谨慎使用它。这是 因为脚本修改 'sys.prefix' 这实际上可能导致 操作的问题 mod_wsgi 或 Python 模块已经 加载到 Python 解释器中,如果 代码取决于 'sys.prefix' 没有改变。这 WSGIPythonHome 指令已经 描述应该改为使用,如果 想要将 Python 作为一个整体关联起来 与虚拟环境。

    尽管如此,'activate_this.py' 脚本是试图解决一个 'site.addsitedir()'的问题 作品。那就是任何新的 添加到的目录 'site.addsitedir()' 的 'sys.path' 是 实际上附加到最后。这 在这种情况下的问题 mod_wsgi 是如果 WSGIPythonHome 是 不用于将 mod_wsgi 与 处女基线环境,然后任何 主 Python 中的包/模块 安装仍然需要 优先于那些在虚拟 环境。

    要解决这个问题,什么 'activate_this.py' 确实是调用 'site.addsitedir()' 但也 重新排序 'sys.path' 所以任何新添加的 目录被移到前面 'sys.path'。这将确保 有不同的地方 虚拟包的版本 他们优先的环境 超过主要 Python 中的那些 安装。

    如上所述,因为 'activate_this.py' 正在做其他事情 可能不适合的事情 mod_wsgi 的上下文,如果不能 将 WSGIPythonHome 设置为指向 mod_wsgi 在原始基线环境中, 而不仅仅是打电话 'site.addsitedir()' 你应该使用 代码:

    ALLDIRS = ['usr/local/pythonenv/PYLONS-1/lib/python2.5/site-packages']
    
    import sys 
    import site 
    
    # Remember original sys.path.
    prev_sys_path = list(sys.path) 
    
    # Add each new site-packages directory.
    for directory in ALLDIRS:
      site.addsitedir(directory)
    
    # Reorder sys.path so new directories at the front.
    new_sys_path = [] 
    for item in list(sys.path): 
        if item not in prev_sys_path: 
            new_sys_path.append(item) 
            sys.path.remove(item) 
    sys.path[:0] = new_sys_path 
    

    如果您仍想使用 来自 virtualenv 的激活脚本, 然后使用:

    activate_this = '/usr/local/pythonenv/PYLONS-1/bin/activate_this.py' 
    execfile(activate_this, dict(__file__=activate_this))
    

    如果 'sys.prefix' 已被 修改后没有问题,那么 伟大的。如果你看到微妙的无法解释的 可能与 更改为“sys.prefix”,然后使用 上面更长期的方法 其中使用了“site.addsitedir()” 直接和“sys.path”重新排序 随后。

    这里也有关于这个问题的讨论

    http://groups.google.com/group/modwsgi/browse_thread/thread/466823f087070b5f?pli=1

    【讨论】:

    • 谢谢,这实际上并没有解决问题,信不信由你……但当我读到它时,这似乎是一个很好的建议。
    【解决方案3】:

    如果您使用的是 virtualenv,则需要确保在 WSGI 脚本中激活它。

    venv_path = "/opt/webapps/ff"
    activate_this = os.path.join(venv_path, "bin/activate_this.py")
    execfile(activate_this, dict(__file__=activate_this))
    

    【讨论】:

    • 谢谢 - 我以为这会解决问题,但当我回到家尝试时,它实际上并没有。当我有一个错字('opt/webapps/ff',缺少第一个斜杠)时,我得到了一个 Apache 错误,当我修复它时它就消失了......所以它正在被读取,但它不影响使用哪个 python 二进制文件。
    【解决方案4】:

    我在 Pylons 应用程序中遇到了同样的情况,最终改用了 /usr/bin binary plus virtualenv site-packages 目录。

    当然是同一个python版本……

    【讨论】:

    • 谢谢,是的,该网站可以像这样正常服务...直到它没有。我正在努力让事情变得更便携。
    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 2012-06-09
    • 2011-06-04
    • 2016-08-23
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    相关资源
    最近更新 更多