梦幻女团
53.79M · 2026-02-05
作为一名运维兼阿里西西小编开发,本地跑通Django项目不算难,但部署到服务器(CentOS 7)、搭配Nginx+Gunicorn时,总会遇到各种奇奇怪怪的报错——相信很多新手和我一样,从“网页无法访问”到“500 Internal Server Error”,一步步踩坑,一步步排查,最终才找到问题根源。
今天就把我这次完整的排错经历记录下来,还原每一个报错场景、实操命令和排查思路,希望能帮到正在被Django部署折磨的你(全程基于Python 3.6、Django 2.2/3.2、Nginx 1.20、Gunicorn 20.1.0)。
先交代下我的部署架构,经典组合:
本地开发环境一切正常,代码上传到服务器、配置好Nginx和Gunicorn后,访问网页只显示“500 Internal Server Error”,用curl访问也提示异常——这就是我排错的开始。
排错的核心思路:从外向内,逐步缩小范围——先确认Nginx是否正常,再验证Gunicorn是否能接收请求,最后排查Django应用内部错误,避免盲目修改配置。
最开始,我用curl本地访问Gunicorn的8000端口,直接报错:
[root@server ~]# curl -v http://127.0.0.1:8000
* About to connect() to 127.0.0.1 port 8000 (#0)
* Trying 127.0.0.1...
* 拒绝连接
* Failed connect to 127.0.0.1:8000; 拒绝连接
* Closing connection 0
curl: (7) Failed connect to 127.0.0.1:8000; 拒绝连接
第一反应:Gunicorn没启动?或者端口没?
用ss命令查看8000端口状态,发现没有任何输出(说明无进程8000端口):
[root@server ~]# ss -lntp | grep 8000
再查看Gunicorn进程,发现进程存在,但端口就是没——这时候才意识到,进程存在≠正常,大概率是Gunicorn启动后隐性闪退了。
查看Gunicorn的错误日志(路径/var/log/gunicorn/error.log),发现了关键报错:
ModuleNotFoundError: No module named 'HealthForum'
原来!我启动Gunicorn时,没切换到Django项目根目录 (项目根目录是/code/HealthForum/,里面有manage.py和HealthForum子文件夹),导致Python无法识别项目模块,Gunicorn启动后立刻闪退,端口自然无法。
# 1. 清理残留的Gunicorn进程
kill -9 $(ps -ef | grep gunicorn | grep -v grep | awk '{print $2}')
# 2. 切换到Django项目根目录
cd /code/HealthForum/
# 3. 重启Gunicorn(后台启动,保留日志)
gunicorn -w 4 -b 127.0.0.1:8000 HealthForum.wsgi
--error-logfile /var/log/gunicorn/error.log
--access-logfile /var/log/gunicorn/access.log
重启后,查看进程和端口,终于看到Gunicorn正常8000端口了——本以为问题解决,结果新的报错又来了。
这次用curl访问8000端口,不再拒绝连接,而是返回500错误:
[root@server ~]# curl -v
* About to connect() to 127.0.0.1 port 8000 (#0)
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1:8000
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Server: gunicorn
< Date: Tue, 03 Feb 2026 08:12:52 GMT
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
<
<!doctype html>
<html lang="en">
<head>
<title>Server Error (500)</title>
</head>
<body>
<h1>Server Error (500)</h1><p></p>
</body>
</html>
* Closing connection 0
此时的关键变化:请求已经到达Gunicorn,并传递给了Django,但Django处理请求时抛出了内部异常——错误从“网络层”转向了“应用层”。
我再次查看Gunicorn的error.log,发现只有之前“模块找不到”的旧报错,没有任何关于500错误的新异常;再查看access.log,只看到请求返回500状态码,却没有具体错误原因:
[root@server HealthForum]# tail -n 100 /var/log/gunicorn/access.log
127.0.0.1 - - [03/Feb/2026:16:12:52 +0800] "GET / HTTP/1.1" 500 145 "-" "curl/7.29.0"
这里踩了一个坑:Gunicorn的error.log默认只记录“启动阶段错误”,Django运行时抛出的异常(如依赖缺失、数据库连接错误),不会自动写入该日志。
调试Django 500错误的终极办法——开启调试模式,让错误直接显示在响应中(仅测试环境使用,生产环境务必关闭!)。
编辑Django项目的settings.py文件(路径/code/HealthForum/HealthForum/settings.py):
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True # 从False改为True,开启调试模式
ALLOWED_HOSTS = ['*'] # 改为*,允许所有主机访问,避免400错误
保存后,重启Gunicorn(调试模式修改需重启生效),这次我选择前台启动Gunicorn(去掉末尾的&),方便查看实时输出:
# 停止旧进程
kill -9 $(ps -ef | grep gunicorn | grep -v grep | awk '{print $2}')
# 前台启动Gunicorn,实时查看错误
cd /code/HealthForum/
gunicorn -w 4 -b 127.0.0.1:8000 HealthForum.wsgi
--error-logfile /var/log/gunicorn/error.log
--access-logfile /var/log/gunicorn/access.log
再次用curl触发请求,前台终端立刻输出了完整的异常堆栈——终于找到问题根源了!
前台启动Gunicorn后,curl触发请求,终端输出关键报错:
ModuleNotFoundError: No module named 'django_redis'
django.core.cache.backends.base.InvalidCacheBackendError: Could not find backend 'django_redis.cache.RedisCache': No module named 'django_redis'
真相大白:我的Django项目配置了Redis作为缓存/会话存储,但服务器的Python环境中,缺少django_redis这个依赖包——这是操作时的疏忽,本地开发时安装了,部署到服务器时忘了安装。
这里需要注意一个细节:我的服务器是Python 3.6,而django_redis 5.x及以上版本不再支持Python 3.6,直接安装会报错。
针对Python 3.6,推荐安装django_redis 4.12.1版本(稳定兼容,亲测可用)。
# 安装指定版本(兼容Python 3.6),用清华镜像源加速
pip3 install django-redis==4.12.1 -i
# 验证安装是否成功(无报错即正常)
python3 -c "import django_redis; print('django_redis 导入成功,版本:', django_redis.__version__)"
安装成功后,再次前台启动Gunicorn,用curl访问127.0.0.1:8000——这次终于不再返回500错误,而是返回了Django项目的正常页面!
问题解决后,务必关闭Django调试模式(避免泄露项目敏感信息),修改settings.py:
DEBUG = False
ALLOWED_HOSTS = ['你的服务器IP或域名'] # 改为具体的IP/域名
重启Gunicorn和Nginx,访问网页,一切正常——历时2小时的排错,终于圆满结束。
这次排错踩了很多新手常见的坑,总结3个关键经验,帮你避开重复踩坑:
整理了这次排错过程中高频使用的命令,新手可直接复制使用:
# 1. 查看Gunicorn进程
ps -ef | grep gunicorn
# 2. 查看8000端口状态
ss -lntp | grep 8000 # 或 netstat -lntp | grep 8000(需安装net-tools)
# 3. 批量停止Gunicorn进程
kill -9 $(ps -ef | grep gunicorn | grep -v grep | awk '{print $2}')
# 4. 查看Gunicorn日志
tail -f /var/log/gunicorn/error.log # 实时查看错误日志
tail -n 100 /var/log/gunicorn/access.log # 查看最新100行访问日志
# 5. 验证Python模块是否存在
python3 -c "import 模块名; print('导入成功')"
# 6. 重启Nginx
systemctl restart nginx