我尝试加载正在使用的Django网站时遇到的问题 mod_wsgi,python 2.7和virtualenv,是我在浏览器中访问该站点时出现500错误。什么时候 我查看在我的apache日志中创建的错误,我得到以下内容......
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] mod_wsgi (pid=69270): Exception occurred processing WSGI script '/Volumes/Ontario/Sites/emails/config/apache/dev.emails.wenatcheeworld.com.wsgi'.
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] Traceback (most recent call last):
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] File "/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg/django/core/handlers/wsgi.py", line 230, in __call__
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] self.load_middleware()
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] File "/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg/django/core/handlers/base.py", line 33, in load_middleware
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] for middleware_path in settings.MIDDLEWARE_CLASSES:
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] File "/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg/django/utils/functional.py", line 276, in __getattr__
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] self._setup()
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] File "/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg/django/conf/__init__.py", line 40, in _setup
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] self._wrapped = Settings(settings_module)
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] File "/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg/django/conf/__init__.py", line 75, in __init__
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] raise ImportError("Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e))
[Tue Oct 11 09:32:30 2011] [error] [client 206.130.131.226] ImportError: Could not import settings 'config.settings' (Is it on sys.path? Does it have syntax errors?): No module named config.settings
回溯没有意义,因为加载的文件来自全局python 2.5库。
我在运行OS X 10.5.8的OS X Server上安装了python 2.7。一世 使用安装python Python 2.7.2 Mac OS X 32-bit i386/PPC Installer。服务器目前安装了virtualenv 1.6.4。
我使用以下
设置我的virtualenv用于新网站$ cd /usr/local/virtualenvs
$ virtualenv --no-site-packages -p /usr/local/bin/python2.7 dev.emails
然后我安装所有必要的python包。当我运行pip freeze
时,这是我的输出
$ pip freeze
Django==1.3
PIL==1.1.7
South==0.7.3
amqplib==1.0.2
anyjson==0.3.1
boto==2.0
celery==2.2.7
django-celery==2.2.4
django-compressor==0.9.2
django-grappelli==2.3.4
django-picklefield==0.1.9
feedparser==5.0.1
html2text==3.02
kombu==1.4.1
lxml==2.2.2
psycopg2==2.4.2
pyparsing==1.5.6
python-dateutil==1.5
python-sendgrid==0.2.0dev
redis==2.4.9
requests==0.6.2
wsgiref==0.1.2
我创建了一个名为path_test.py
的脚本,以测试我的virtualenv路径......
import os
import sys
# Activate Python Virtual Enviroment
activate_this = '/usr/local/virtualenvs/dev.emails/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
# start django
import django.core.handlers.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings'
for p in sys.path:
print p
application = django.core.handlers.wsgi.WSGIHandler()
当我使用python path_test.py
运行脚本时,我得到以下输出:
/usr/local/virtualenvs/dev.emails/lib/python2.5/site-packages
/Volumes/Ontario/Sites/emails/bin
/Library/Python/2.5/site-packages/MySQL_python-1.2.2-py2.5-macosx-10.5-i386.egg
/Library/Python/2.5/site-packages/paramiko-1.7.4-py2.5.egg
/Library/Python/2.5/site-packages/simplejson-2.0.7-py2.5-macosx-10.5-i386.egg
/Library/Python/2.5/site-packages/python_ldap-2.3.7-py2.5-macosx-10.5-i386.egg
/Library/Python/2.5/site-packages/lxml-2.2.2-py2.5-macosx-10.5-i386.egg
/Library/Python/2.5/site-packages/pytz-2010h-py2.5.egg
/Library/Python/2.5/site-packages/python_openid-2.2.4-py2.5.egg
/Library/Python/2.5/site-packages/Markdown-2.0.3-py2.5.egg
/Library/Python/2.5/site-packages/django_authopenid-1.0.1-py2.5.egg
/Library/Python/2.5/site-packages/Django-1.2.1-py2.5.egg
/Library/Python/2.5/site-packages/django_profiles-0.2-py2.5.egg
/Library/Python/2.5/site-packages/django_openid_consumer-0.1.1-py2.5.egg
/Library/Python/2.5/site-packages/setuptools-0.6c11-py2.5.egg
/Library/Python/2.5/site-packages/ipython-0.10-py2.5.egg
/Library/Python/2.5/site-packages/httplib2-0.6.0-py2.5.egg
/Library/Python/2.5/site-packages/guess_language-0.2-py2.5.egg
/Library/Python/2.5/site-packages/django_ratings-0.3.4-py2.5.egg
/Library/Python/2.5/site-packages/pip-0.8.1-py2.5.egg
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python25.zip
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-darwin
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/plat-mac/lib-scriptpackages
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-tk
/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-dynload
/Library/Python/2.5/site-packages
/Library/Python/2.5/site-packages/PIL
/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC
如果我首先使用source /path/to/virtualenv/bin/activate
激活virtualenv,然后运行python path_test.py
,我会得到以下输出:
/usr/local/virtualenvs/dev.emails/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
/usr/local/virtualenvs/dev.emails/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg
/usr/local/virtualenvs/dev.emails/lib/python2.7/site-packages/lxml-2.2.2-py2.7-macosx-10.3-intel.egg
/usr/local/virtualenvs/dev.emails/lib/python2.7/site-packages
/usr/local/virtualenvs/dev.emails/lib/python2.7/site-packages/PIL
/Volumes/Ontario/Sites/emails/bin
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/site-packages/pip-1.0.2-py2.7.egg
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/site-packages/lxml-2.2.2-py2.7-macosx-10.3-intel.egg
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python27.zip
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/plat-darwin
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/plat-mac
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/plat-mac/lib-scriptpackages
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/lib-tk
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/lib-old
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/lib-dynload
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/site-packages
/Volumes/Ontario/local/virtualenvs/dev.emails/lib/python2.7/site-packages/PIL
/Volumes/Ontario/Sites/emails
此时我很确定问题是virtualenv中的activate_this.py
没有设置正确的sys.path
。
答案 0 :(得分:2)
正如我在回答我自己的问题时指出的那样,并且正如其他人所回答的那样,不可能在mod_wsgi中使用不同版本的python。我的解决方案是为我需要不同版本的python的特定站点安装和设置gunicorn。
首先我安装了gunicorn ......
$ /usr/local/virtualenvs/my.examplesite/bin/activate
$ pip install gunicorn
然后我设置了一个launchd.plist来在/Library/LaunchDaemons/my.examplesite.com.plist
中运行gunicorn:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>my.examplesite.com</string>
<key>EnvironmentVariables</key>
<dict>
<key>DJANGO_SETTINGS_MODULE</key><string>config.settings</string>
</dict>
<key>UserName</key><string>_www</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/virtualenvs/my.examplesite/bin/gunicorn_django</string>
<string>--bind=127.0.0.1:8001</string>
</array>
<key>RunAtLoad</key><true/>
<key>StandardErrorPath</key><string>/var/log/gunicorn/my.examplesite.com.error.log</string>
<key>StandardOutPath</key><string>/var/log/gunicorn/my.examplesite.com.access.log</string>
</dict>
</plist>
接下来,我将nginx设置为服务器媒体并代理我的gunicorn服务器:
server {
listen 80;
server_name my.examplesite.com;
access_log /var/log/nginx/my.examplesite.com.access.log;
error_log /var/log/nginx/my.examplesite.com.error.log;
location = /favicon.ico {
return 404;
}
location /static/ {
root /path/to/site/root/;
}
location /media/ {
root /path/to/site/root/;
}
location / {
proxy_pass http://127.0.0.1:8001/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
}
}
答案 1 :(得分:1)
你有几个问题。
首先,activate_this.py工作正常。问题出在你的设置上。你正试图激活virtualenv,但是你使用系统的默认2.5 python而不是virtualenv的2.7 python。这就是你看到系统站点包的原因; '' - no-site-packages“仅适用于virtualenv创建的python二进制文件。这也是它添加”/usr/local/virtualenvs/dev.emails/lib/python2.5/site-packages“的原因。 activate_this.py脚本使用执行脚本的python版本来确定要使用的site-packages目录:
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
当您激活virtualenv时,它使用正确的2.7二进制文件。
其次,你的mod_wsgi版本是针对系统的2.5 python构建的,所以它遇到了你在virtualenv未激活时看到的同样问题。 “activate_this.py”脚本实际上没有强制执行“--no-site-packages”选项,它依赖于virtualenv创建的python二进制文件,因此mod_wsgi永远不会强制执行“--no-site-packages”。这就是为什么当它在virtualenv中找不到2.5 site-packages目录时,它会回到系统上安装的Django版本。
第三,Apache在10.5上以64位运行并且你安装了一个只有32位的python二进制文件,所以即使你在2.7版本上重建了mod_wsgi,Apache也会在尝试加载它时崩溃。当然,所有2.5个站点都会遇到2.7个站点现在遇到的问题。你最好的选择是将你的2.7网站放在像gunicorn这样的地方。
答案 2 :(得分:0)
看起来mod_wsgi默认为Python 2.5。你编译得对吗?看看http://code.google.com/p/modwsgi/wiki/InstallationIssues#Multiple%5FPython%5FVersions。
来自virtualenv和mod_wsgi [1]的页面:
请注意,创建此基准环境的Python版本必须相同 编译mod_wsgi的Python版本。基于的混合环境是不可能的 不同的主要/次要版本的Python。
[1] http://code.google.com/p/modwsgi/wiki/VirtualEnvironments
答案 3 :(得分:0)
如果您已经针对Python 2.7从源代码构建了mod_wsgi,但发现它拾取了Python 2.5框架(并且由于某种原因没有崩溃),请尝试使用:
--disable-framework
使用Python 2.7从源代码构建mod_wsgi时来'配置'。
如果你甚至没有针对Python 2.7重建mod_wsgi,那么先做。