You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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项目的配套调整
  1. ALLOWED_HOSTS配置
    需要把所有子域名加入允许列表,确保Django能正常接收请求:

    # settings.py
    ALLOWED_HOSTS = ['www.test.com', 'test.com', 'appa.test.com', 'appb.test.com']
    

    生产环境如果需要兼容所有子域名,也可以用通配符(谨慎使用):ALLOWED_HOSTS = ['.test.com']

  2. 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/路径,完全符合你的需求。
四、测试验证步骤
  1. 确保DNS解析正确:把www.test.com、appa.test.com、appb.test.com都指向你的服务器IP;
  2. 重启Nginx生效配置:sudo nginx -s reload;
  3. 启动Django生产服务(推荐用gunicorn/uwsgi,不要用runserver):比如gunicorn yourproject.wsgi:application --bind 127.0.0.1:8000;
  4. 访问各个子域名,确认URL不会跳转到带路径的地址,功能正常。

内容的提问来源于stack exchange,提问作者LJC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:24:38