【问题标题】:Why `sys.path` differs when executed in mod_wsgi and normal interpreter mode?为什么在 mod_wsgi 和普通解释器模式下执行时 `sys.path` 不同?
【发布时间】:2017-10-30 11:50:09
【问题描述】:

环境: MAC OS 10.10.4 python 2.7.12 with pyenv mod_wsgi 3.4 Apache/2.4.10 (Unix)

我有一个打印 sys.path 的 wsgi.py:

import sys
print sys.path
sys.path.insert(0, '...')

from app import app as application

我确认在安装mod_wsgi 的过程中,它配置了正确的python 版本(/Users/forever/.pyenv/shims/python:由pyenv 安装):

checking for apxs2... no
checking for apxs... /usr/sbin/apxs
checking Apache version... 2.4.10
checking for python... /Users/forever/.pyenv/shims/python
configure: creating ./config.status
config.status: creating Makefile

然后使用以下内容配置 Apache:

<VirtualHost *:5000>
    ServerName loyal.jms.tw

    # WSGIPythonHome /Users/forever/.pyenv/shims
    WSGIDaemonProcess test user=forever group=admin threads=5
    WSGIScriptAlias / /Users/forever/git/test/app/wsgi.py

    <Directory /Users/forever/git/test/app>
        WSGIProcessGroup test
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

Apache 日志显示 mod_wsgi 信息,其中配置了正确的 python 版本:

[Tue May 30 13:59:28.658723 2017] [mpm_prefork:notice] [pid 4843] AH00163: Apache/2.4.10 (Unix) PHP/5.5.24 mod_wsgi/3.4 Python/2.7.12 configured -- resuming normal operations

然后奇怪的部分是 Apache 日志中的 sys.path 输出:

['/usr/lib/python27.zip', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-darwin', '/usr/lib/python2.7/plat-mac', '/usr/lib/python2.7/plat-mac/lib-scriptpackages', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/Library/Python/2.7/site-packages']

好像是系统默认python的python路径,不是我pyenv安装的python。然后我用pyenv安装的python解释器检查sys.path是什么,它显示:

Python 2.7.12 (default, May 26 2017, 21:30:36)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/Users/forever/.pyenv/versions/2.7.12/lib/python27.zip', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/plat-darwin', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/plat-mac', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/lib-tk', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/lib-old', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/lib-dynload', '/Users/forever/.pyenv/versions/2.7.12/lib/python2.7/site-packages']

,这是不同的。

我想知道这怎么会发生?以及如何更正 mod_wsgi 使用的 python 路径?

【问题讨论】:

  • 你还没有配置 WSGI 来使用你的 virtualenv,见modwsgi.readthedocs.io/en/develop/user-guides/…
  • 你为什么用 mod_wsgi 3.4,那个版本很古老。您是否尝试使用来自Server.app 的版本?建议您不要这样做。无论哪种方式,如果 mod_wsgi 是为不同的 Python 安装编译的,你不能强制它使用基于另一个的 Python 虚拟环境。请参阅pip install 方法。 pypi.python.org/pypi/mod_wsgi
  • 另外,pyenv 生成的 Python 安装默认情况下已损坏,无法用于嵌入式系统。见github.com/pyenv/pyenv/issues/392

标签: python apache python-2.7 mod-wsgi


【解决方案1】:

WSGI 尚未配置为使用您的 virtualenv Python。见documentation on WSGI and virtualenv;您需要配置守护进程组以使用正确的二进制文件:

# add the python-home argument here
WSGIDaemonProcess test python-home=/Users/forever/.pyenv/shims user=forever group=admin threads=5

否则,如文档所述:

由于在守护进程组中仅运行单个应用程序,因此还使用了WSGIApplicationGroup 指令。 当它与 %{GLOBAL} 值一起使用时,它会强制 WSGI 应用程序在每个进程的主要 Python 解释器上下文中运行。

我的大胆强调。

WSGIPythonHome 只能在嵌入模式下使用(没有WSGIDaemonProcessWSGIProcessGroup 指令)。

【讨论】:

  • 添加python-home=/Users/forever/.pyenv/shim重启后,Apache err log中有很多行ImportError: No module named site
  • @LucasYang:听起来像是Python版本不兼容,见Django Apache and Virtualenv ImportError: No module named site
  • @LucasYang:还有一些其他关于使用 WSGI 和 virtualenv 抛出异常的帖子,我建议快速谷歌搜索,看看是否有任何匹配。
  • 谢谢,我已经阅读了那篇文章,但是我使用相同的 python 版本来编译 mod_wsgi 并在 Apache 中配置虚拟主机。我不知道为什么它不起作用。
  • 这就是我建议进一步谷歌搜索的原因;可能是Python home设置错了?
猜你喜欢
  • 2021-11-01
  • 1970-01-01
  • 2013-10-31
  • 2016-05-29
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多