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

如何在非根URL下用Nginx部署Django应用并修复静态文件问题?

解决Django在非根URL下静态文件加载失败问题

一、调整Django核心配置

这是解决静态文件路径问题的关键,让Django自动生成带非根前缀的URL:

  • 设置FORCE_SCRIPT_NAME:在settings.py中添加,指定你的部署前缀,比如部署在/myapp路径下:

    FORCE_SCRIPT_NAME = '/myapp'
    

    这个参数会让Django在生成所有URL(包括静态文件、视图路由)时自动带上该前缀。

  • 修改STATIC_URL:将静态文件URL前缀与FORCE_SCRIPT_NAME对齐,避免硬编码:

    STATIC_URL = f"{FORCE_SCRIPT_NAME}/static/"
    # 或者直接写死:STATIC_URL = '/myapp/static/'
    
  • 确保STATIC_ROOT与容器挂载一致:配置静态文件收集目录,比如:

    STATIC_ROOT = '/var/www/static/'
    

    部署前必须执行python manage.py collectstatic --noinput,将所有APP的静态文件收集到STATIC_ROOT目录。在docker中可以把这个命令加到启动脚本或command里。

  • 避免硬写URL:模板中引用静态文件必须用{% static %}标签,比如:

    <link rel="stylesheet" href="{% static 'css/main.css' %}">
    

    视图中生成URL要用reverse()函数,不要直接拼接字符串,确保自动带上前缀。

二、Docker-Compose与Nginx配置配合

通过Nginx反向代理正确传递请求前缀,并映射静态文件目录:

Docker-Compose示例配置

确保Django和Nginx共享静态文件卷,且处于同一网络:

services:
  django:
    build: .
    command: sh -c "python manage.py collectstatic --noinput && gunicorn myproject.wsgi:application --bind 0.0.0.0:8000"
    volumes:
      - static_volume:/var/www/static/
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - static_volume:/var/www/static/
    ports:
      - "80:80"
    depends_on:
      - django
    networks:
      - app-network

volumes:
  static_volume:

networks:
  app-network:
    driver: bridge

Nginx配置文件(nginx/conf.d/myapp.conf)

关键是正确处理前缀转发和静态文件映射:

server {
    listen 80;

    # 直接映射静态文件,不走Django
    location /myapp/static/ {
        alias /var/www/static/;
        expires 30d;
    }

    # 转发动态请求到Django服务
    location /myapp/ {
        proxy_pass http://django:8000/;  # 末尾的斜杠必须加,会去掉/myapp/前缀转发给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;
    }
}

注意:proxy_pass末尾的斜杠是核心,它会把/myapp/xxx转换成/xxx转发给Django,而Django通过FORCE_SCRIPT_NAME识别前缀,生成带/myapp的响应URL。

三、常见问题排查

  • 静态文件未收集:检查docker启动日志,确认collectstatic命令执行成功,且STATIC_ROOT目录下有静态文件。
  • HTTPS环境配置:如果用HTTPS,需在settings.py添加:
    USE_X_FORWARDED_HOST = True
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    
    确保Django识别正确的请求协议,生成HTTPS前缀的URL。
  • Gunicorn无需加前缀:不要给Gunicorn传递--prefix参数,前缀处理由Nginx和Django的FORCE_SCRIPT_NAME共同完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:46:23