今天准备正式部署将自己的个人博客部署到云服务器上,结果怎么配置都无法连接上我的站点。起初我怀疑是服务器因为某些原因而无法连接,然而在开放了80端口之后,apache的默认000站点可以正常访问,ping测试也很正常。我又去检查了所有的配置文件,连一个标点符号都不放过,也没发现有错误。去查看apache错误日志后发现一直报这个错误
[Thu Sep 24 11:37:43.769231 2020] [wsgi:error] [pid 1206:tid 139625453172480] [remote 14.23.253.69:14394] Traceback (most recent call last):
[Thu Sep 24 11:37:43.769267 2020] [wsgi:error] [pid 1206:tid 139625453172480] [remote 14.23.253.69:14394] File "/home/ranger/site/ranger/ranger/wsgi.py", line 13, in <module>
[Thu Sep 24 11:37:43.769273 2020] [wsgi:error] [pid 1206:tid 139625453172480] [remote 14.23.253.69:14394] from django.core.wsgi import get_wsgi_application
[Thu Sep 24 11:37:43.769290 2020] [wsgi:error] [pid 1206:tid 139625453172480] [remote 14.23.253.69:14394] ModuleNotFoundError: No module named 'django'
看着这段错误,我在想,难道是因为我的虚拟环境路径没配置正确吗?我又去检查了配置文件中的虚拟环境路径,然而没发现任何错误。可为什么我明明已经配置好的虚拟环境会找不到django?
我又在虚拟环境中打开python并导入django,发现一些正常。我懵了。
在网上疯狂的找解决办法和相似的问题时,我读到了这篇文章:uwsgi遇到ImportError: No module named django.core.wsgi问题
看完之后突然想到会不会我也是因为路径问题呢?而且我又看到了错误日志中记录的ModuleNotFoundError异常,所以我想到了一个办法——写一个异常捕获代码,让它抛出更加明了的提示
我把django的wsgi.py文件改成了这样:
import os, sys
try:
from django.core.wsgi import get_wsgi_application
except ModuleNotFoundError:
path = sys.path
version = sys.version
info = '{} | {}'.format(path, version)
raise ModuleNotFoundError(info)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ranger.settings')
application = get_wsgi_application()
然后错误信息变成了下面这段
[Thu Sep 24 12:43:38.139075 2020] [wsgi:error] [pid 1412:tid 139625570760448] [remote 20.51.210.251:63801] Traceback (most recent call last):
[Thu Sep 24 12:43:38.139086 2020] [wsgi:error] [pid 1412:tid 139625570760448] [remote 20.51.210.251:63801] File "/home/ranger/site/ranger/ranger/wsgi.py", line 18, in <module>
[Thu Sep 24 12:43:38.139090 2020] [wsgi:error] [pid 1412:tid 139625570760448] [remote 20.51.210.251:63801] raise ModuleNotFoundError(info)[Thu Sep 24 12:43:38.139112 2020] [wsgi:error] [pid 1412:tid 139625570760448] [remote 20.51.210.251:63801]
ModuleNotFoundError: ['/home/ranger/site/ranger', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload'] | 3.6.9 (default, Jul 17 2020, 12:50:27)
[Thu Sep 24 12:43:38.139116 2020] [wsgi:error] [pid 1412:tid 139625570760448] [remote 20.51.210.251:63801] [GCC 8.4.0]
可以看到它将程序运行的搜索模块的路径列了出来,还有运行程序的Python版本。奇怪!我的虚拟环境是Python3.8的,为什么它这儿是3.6?而且路径中根本就没有包含虚拟环境所在路径!难道是我的配置文件有问题??但是我坚持过N遍了,应该不是那个。
于是我去查阅Django的部署指南,看看是不是我漏了什么配置从而导致apache没有进入到虚拟环境下的Python中

然后又去看了mod_wsgi模块的官方文档,终于找到了一下这段说明了一切原因的话

我一开始安装mod_wsgi模块时用的方法是直接从apt中安装libapache2-mod-wsgi-py3。而这会直接使用系统默认的python3.6,但我的python虚拟环境却是python3.8从而导致最终apache调用的实际上python3.6。
到了这一步,能解决问题的办法也就出来了,要么使用回python3.6的环境,要么重新通过源码编译的方式安装mod_wsgi,我感觉还是不太一样放弃python的一些新特性的,所以重新安装mod_wsgi啦!
在卸载了原来由apt安装的libapache2-mod-wsgi-py3之后,重新编译安装了mod_wsgi,成功了!!
总结:
这篇文章写得并不怎么像一个指南,或者解决方案。这篇文章更像是我这折腾了半天的回顾,从思考错误到排除错误到最后找出真正的问题所在,并且解决问题。
虽然很折腾,但也算是学会了一些东西。
——2020.09.24
Apache+Python虚拟环境配置陷阱:mod_wsgi与Python版本不匹配
在部署个人博客到云服务器时,遇到Apache无法连接到Django站点的问题。经过排查发现,mod_wsgi模块使用的是系统默认的Python3.6,而非虚拟环境的Python3.8。通过修改wsgi.py引发更详细的错误信息,揭示问题根源在于mod_wsgi安装方式。解决方法是卸载apt安装的mod_wsgi,重新编译安装与虚拟环境匹配的版本,问题得以解决。
3万+

被折叠的 条评论
为什么被折叠?



