如何用Nginx+uWSGI在单个Django项目中实现多域名对应独立应用
嘿,我来帮你搞定这个子域名映射的问题!你之前用rewrite导致URL显示/app1/,是因为rewrite属于重定向操作,会主动让浏览器跳转带路径的地址;而你真正需要的是Nginx的反向代理根路径映射——这种方式能让Nginx在后台悄悄把请求转发到Django的App路径,浏览器完全看不到内部路径,URL会保持干净的appa.test.com/样式。下面是完整的实现步骤:
一、Nginx虚拟主机配置(核心部分)
你需要为每个子域名单独配置一个server块,通过proxy_pass实现无跳转的路径映射,同时处理好静态文件和请求头部:
1. 主域名(www.test.com)配置
server { listen 80; server_name www.test.com test.com; # 同时匹配带www和不带www的主域名 # 直接托管Django静态文件(生产环境推荐Nginx处理静态资源) location /static/ { root /path/to/your/django/project; # 替换成你的Django项目根目录 expires 30d; # 静态资源缓存30天,优化访问速度 } # 主站请求转发给Django后端 location / { proxy_pass http://127.0.0.1:8000/; # 假设Django服务运行在本地8000端口 # 传递必要的请求头部,让Django正确识别请求来源 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
2. AppA子域名(appa.test.com)配置
server { listen 80; server_name appa.test.com; # 如果AppA有独立的静态文件目录,可单独配置;否则和主站一致即可 location /static/ { root /path/to/your/django/project/appa; # 替换成AppA的静态文件目录 expires 30d; } location / { # 关键:proxy_pass末尾必须带斜杠! # 这样Nginx会把当前location的/,映射到后端的/appa/路径 proxy_pass http://127.0.0.1:8000/appa/; # 传递请求头部 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 可选但重要:修正Django的重定向响应 # 避免Django把重定向地址返回成带/appa/的格式,确保浏览器显示子域名根路径 proxy_redirect http://127.0.0.1:8000/appa/ /; } }
3. AppB子域名(appb.test.com)配置
和AppA的配置几乎一致,只需要把server_name改成appb.test.com,proxy_pass的路径改成/appb/即可。
二、Django项目的配套调整
ALLOWED_HOSTS配置
需要把所有子域名加入允许列表,确保Django能正常接收请求:# settings.py ALLOWED_HOSTS = ['www.test.com', 'test.com', 'appa.test.com', 'appb.test.com']生产环境如果需要兼容所有子域名,也可以用通配符(谨慎使用):
ALLOWED_HOSTS = ['.test.com']URL路由保持不变
你之前的路径式路由不需要修改,因为Nginx已经帮你完成了子域名到内部路径的映射:# 项目根urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('', include('main.urls')), # 主站对应/ path('appa/', include('appa.urls')), # AppA的内部路径 path('appb/', include('appb.urls')), # AppB的内部路径 ]
三、关键区别:rewrite vs proxy_pass
- 你之前用的
rewrite / /app1/是外部重定向,Nginx会返回302状态码告诉浏览器“去访问/app1/”,所以URL会明显变化; - 而
proxy_pass是内部代理,Nginx在后台把请求转发到Django的对应路径,浏览器全程只和子域名交互,看不到内部的/appa/路径,完全符合你的需求。
四、测试验证步骤
- 确保DNS解析正确:把
www.test.com、appa.test.com、appb.test.com都指向你的服务器IP; - 重启Nginx生效配置:
sudo nginx -s reload; - 启动Django生产服务(推荐用gunicorn/uwsgi,不要用runserver):比如
gunicorn yourproject.wsgi:application --bind 127.0.0.1:8000; - 访问各个子域名,确认URL不会跳转到带路径的地址,功能正常。
内容的提问来源于stack exchange,提问作者LJC
相关产品推荐
相关产品推荐

