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

跨服务器部署Django:如何分离Django项目与Nginx/Gunicorn应用服务器?

跨服务器分离Django应用与统一反向代理的解决方案

嘿,我来帮你理清楚这个跨服务器部署的问题!首先得明确一个关键前提:Gunicorn必须和Django项目代码部署在同一服务器,因为它需要直接加载Django的WSGI应用模块。所以你想要的「应用服务器与Django项目分离」的正确架构应该是:

  • 服务器1(172.30.10.92):托管所有Django项目,每个项目启动一个独立的Gunicorn进程,监听不同的内网端口
  • 服务器2(172.30.10.93):部署Nginx作为统一的反向代理入口,根据请求的域名或URL路径,把流量转发到服务器1对应Django应用的Gunicorn端口

下面是一步步的配置指南,帮你搞定多应用部署的问题:


第一步:配置服务器1的Django + Gunicorn

每个Django应用都需要单独配置Gunicorn,确保它们监听不同的端口(比如从8000开始递增),并且绑定到服务器1的内网IP(这样服务器2才能访问)。

1.1 启动Gunicorn并后台运行

进入你的Django项目根目录(就是有manage.py的那个文件夹),运行以下命令:

# 第一个应用:绑定到172.30.10.92的8000端口,后台运行
gunicorn --bind 172.30.10.92:8000 myproject.wsgi:application --daemon

# 第二个应用:绑定到172.30.10.92的8001端口
gunicorn --bind 172.30.10.92:8001 mysecondproject.wsgi:application --daemon
  • 别绑定127.0.0.1,否则服务器2根本连不上!
  • 为了避免服务器重启后要手动启动Gunicorn,建议用systemd管理进程。比如给第一个应用创建/etc/systemd/system/myproject.service:
    [Unit]
    Description=Gunicorn daemon for my Django app1
    After=network.target
    
    [Service]
    User=你的用户名
    Group=www-data
    WorkingDirectory=/home/你/myproject  # 替换成你的项目路径
    ExecStart=/usr/bin/gunicorn --bind 172.30.10.92:8000 myproject.wsgi:application
    
    [Install]
    WantedBy=multi-user.target
    
    然后启用并启动服务:
    sudo systemctl daemon-reload
    sudo systemctl enable myproject.service
    sudo systemctl start myproject.service
    
    每个Django应用都要做类似的配置,只需要改端口、项目路径和服务名就行。

1.2 验证Gunicorn的可访问性

在服务器2上跑个curl测试,确认能连到服务器1的Gunicorn:

curl http://172.30.10.92:8000

如果能返回Django的默认页面或者你的应用内容,说明这一步没问题。


第二步:配置服务器2的Nginx反向代理

Nginx的作用就是当用户请求过来时,把不同的请求转发到对应的Django应用。这里分两种场景:按域名区分多应用,或者按URL路径区分。

2.1 按域名区分(推荐)

假设你有两个域名:app1.yourdomain.com和app2.yourdomain.com,分别对应服务器1的8000和8001端口。

编辑Nginx配置文件(比如/etc/nginx/sites-available/django_proxy):

# 定义上游服务器(也就是服务器1的Gunicorn端口)
upstream app1 {
    server 172.30.10.92:8000;
}

upstream app2 {
    server 172.30.10.92:8001;
}

# 第一个应用的服务器块
server {
    listen 80;
    server_name app1.yourdomain.com;

    location / {
        proxy_pass http://app1;
        # 传递必要的请求头,让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;
    }

    # 静态文件优化:让Nginx直接托管静态文件(需要提前把服务器1的静态文件同步到服务器2)
    location /static/ {
        alias /var/www/static/app1/;  # 替换成你在服务器2存放app1静态文件的路径
        expires 30d;  # 缓存静态文件30天
    }
}

# 第二个应用的服务器块
server {
    listen 80;
    server_name app2.yourdomain.com;

    location / {
        proxy_pass http://app2;
        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;
    }

    location /static/ {
        alias /var/www/static/app2/;
        expires 30d;
    }
}

2.2 按URL路径区分(同一域名下)

如果想用同一个域名,比如yourdomain.com/app1和yourdomain.com/app2,可以这么配置:

upstream app1 {
    server 172.30.10.92:8000;
}

upstream app2 {
    server 172.30.10.92:8001;
}

server {
    listen 80;
    server_name yourdomain.com;

    location /app1/ {
        proxy_pass http://app1/;  # 注意末尾的斜杠,不然路径会出错!
        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;
    }

    location /app2/ {
        proxy_pass http://app2/;
        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;
    }

    # 静态文件对应路径
    location /app1/static/ {
        alias /var/www/static/app1/;
        expires 30d;
    }

    location /app2/static/ {
        alias /var/www/static/app2/;
        expires 30d;
    }
}

⚠️ 注意:这种情况下,每个Django应用的settings.py里要加FORCE_SCRIPT_NAME = '/app1'(对应各自的路径),不然URL反向解析会出问题。

2.3 启用配置并验证

把配置文件软链接到sites-enabled目录:

sudo ln -s /etc/nginx/sites-available/django_proxy /etc/nginx/sites-enabled/

测试Nginx配置是否合法:

sudo nginx -t

如果显示test is successful,就重启Nginx:

sudo systemctl restart nginx

现在访问对应的域名或路径,应该就能正常打开你的Django应用了。


常见问题排查

  • 服务器2连不上服务器1的Gunicorn:检查服务器1的防火墙有没有开放对应的端口(比如8000、8001),可以用sudo ufw allow 8000/tcp开放。
  • 静态文件加载失败:要么把服务器1的静态文件同步到服务器2(用scp或者rsync),要么在Django里用Whitenoise托管静态文件,让Gunicorn直接处理静态请求。
  • Django获取不到客户端真实IP:确保Nginx配置里的proxy_set_header都加了,并且在Django的settings.py里添加:
    USE_X_FORWARDED_HOST = True
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')  # 如果用HTTPS的话
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:14:10