如何通过Supervisor部署多个Django应用并解决Nginx端口占用错误
问题根因
你遇到的端口冲突报错核心原因是多Nginx实例重复启动导致的资源抢占:
- 系统已经通过systemd启动了全局Nginx服务(从
service nginx status输出可确认Nginx处于运行状态) - 你为每个Django应用都单独配置了Supervisor管理的Nginx进程,多个Nginx进程同时尝试绑定端口时就会触发
Address already in use报错,哪怕是未被其他服务占用的端口,也会因为多个Nginx之间互相抢占而报错。
解决步骤
1. 清理冗余Nginx Supervisor配置
Nginx全局只需运行1个实例即可代理所有站点,无需为每个应用单独启动Nginx进程:
- 删除
/etc/supervisor/conf.d/目录下所有nginx-前缀的配置文件 - 执行以下命令更新Supervisor配置,停掉所有Supervisor管理的Nginx进程:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl stop nginx-*
- 重启全局Nginx清理残留端口占用:
sudo systemctl restart nginx
2. 为新增Django应用添加Nginx站点配置
每新增一个Django应用,只需在/etc/nginx/sites-available/目录下新增独立的站点配置文件,通过不同端口或不同域名区分即可,示例如下:
# /etc/nginx/sites-available/your-second-app server { server_name xx.xxx.xxx.xxx; listen 81; # 每个站点用不同的端口 listen [::]:81 ipv6only=on; error_log /path/to/second/app/gunicorn-error.log; access_log /path/to/second/app/gunicorn-access.log; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /path/to/second/app/static_root; } location /media/ { root /path/to/second/app/media_root; } location / { include proxy_params; proxy_pass http://unix:/path/to/second/app/gunicorn.sock; } }
第三个应用同理,配置对应路径、sock地址和未被占用的端口即可。
3. 启用站点并生效配置
- 将新增的站点配置软链接到
sites-enabled目录:
sudo ln -s /etc/nginx/sites-available/your-second-app /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/your-third-app /etc/nginx/sites-enabled/
- 验证Nginx配置语法是否正确:
sudo nginx -t
如果输出syntax is ok和test is successful,执行重载命令生效配置:
sudo systemctl reload nginx
4. 确认Gunicorn配置
你现有的Gunicorn Supervisor配置逻辑是正确的,每个应用单独一个Supervisor管理的Gunicorn进程,只要保证每个应用的Gunicorn配置中sock路径不重复、Django静态文件路径配置正确即可正常运行。启动成功时生成3个进程符合预期,对应你Gunicorn配置中的workers = 3参数。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

