如何配置Nginx实现单域名下多Django站点部署?
解决单域名下多Django站点的Nginx配置方案
没问题,我来帮你搞定这个多站点路径转发的需求!既然你已经搞定了uWSGI emperor模式,那只需要调整Nginx配置,再配合一点点Django的小设置就能实现目标了。
第一步:确认uWSGI实例的Socket配置
首先确保你的两个Django站点的uWSGI配置文件(比如web1.ini和web2.ini)已经分别指定了独立的socket文件,比如:
- web1的ini里:
socket = /tmp/web1.sock - web2的ini里:
socket = /tmp/web2.sock
emperor模式会自动管理这两个实例,这一步没问题的话就继续。
第二步:修改Nginx配置
把你原来的Nginx配置替换成下面的版本,我会逐段解释关键部分:
# 定义两个upstream,分别对应两个Django站点的uWSGI socket upstream web1 { server unix:///tmp/web1.sock; } upstream web2 { server unix:///tmp/web2.sock; } server { listen 80; server_name www.mywebsite.com; proxy_http_version 1.1; ssl_protocols TLSv1.2; # 处理web1的静态文件 location /web1/static { alias /path/to/web1/static; # 替换成web1实际的static目录路径 } # 处理web1的媒体文件 location /web1/media { alias /path/to/web1/media; # 替换成web1实际的media目录路径 } # 转发web1的动态请求到对应的uWSGI实例 location /web1/ { include /etc/nginx/uwsgi_params; include /etc/nginx/mime.types; # 关键:告诉Django当前请求的前缀是/web1,这样路由能正确匹配 uwsgi_param SCRIPT_NAME /web1; uwsgi_pass web1; # 把请求路径里的/web1去掉后传给Django uwsgi_modifier1 30; } # 处理web2的静态文件 location /web2/static { alias /path/to/web2/static; # 替换成web2实际的static目录路径 } # 处理web2的媒体文件 location /web2/media { alias /path/to/web2/media; # 替换成web2实际的media目录路径 } # 转发web2的动态请求到对应的uWSGI实例 location /web2/ { include /etc/nginx/uwsgi_params; include /etc/nginx/mime.types; uwsgi_param SCRIPT_NAME /web2; uwsgi_pass web2; uwsgi_modifier1 30; } }
关键配置说明
- 双Upstream块:分别指向两个站点的uWSGI socket,确保请求能正确转发到对应的实例。
- 静态/媒体文件分离:每个站点的static和media目录都单独配置
location,用alias指向实际路径,这样Nginx能直接返回静态资源,不用经过uWSGI。 - SCRIPT_NAME参数:这个是核心!它会告诉Django当前请求的URL前缀是
/web1或/web2,这样Django的路由系统就能正确匹配你在urls.py里定义的路径(不用修改原来的urls.py)。 - uwsgi_modifier1 30:这个参数会让uWSGI自动把请求路径中的
/web1前缀去掉后再传给Django,比如/web1/main.html会被转换成/main.html交给Django处理,完美匹配你原来的路由配置。
第三步:Django站点的小调整
- ALLOWED_HOSTS:确保两个站点的
settings.py里都添加了www.mywebsite.com,比如:ALLOWED_HOSTS = ['www.mywebsite.com'] - (可选)FORCE_SCRIPT_NAME:如果你的Django版本比较旧,或者遇到路由匹配问题,可以在
settings.py里加上:- web1的settings:
FORCE_SCRIPT_NAME = '/web1' - web2的settings:
FORCE_SCRIPT_NAME = '/web2'
不过通常用Nginx的uwsgi_param SCRIPT_NAME就足够了,这一步可以先跳过,有问题再加上。
- web1的settings:
最后一步:重启服务
修改完配置后,重启Nginx和uWSGI emperor服务:
sudo systemctl restart nginx sudo systemctl restart uwsgi-emperor # 或者你对应的emperor服务名
现在访问www.mywebsite.com/web1/main.html和www.mywebsite.com/web2/main.html应该就能正常访问各自的站点了!如果遇到问题,可以查看Nginx的错误日志(/var/log/nginx/error.log)和uWSGI的日志来排查。
内容的提问来源于stack exchange,提问作者YeP
相关产品推荐
相关产品推荐

