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

Django静态文件可访问但未加载问题(Nginx+Docker部署环境)

问题:Django Admin页面静态文件返回200但样式不生效(Docker+Nginx部署环境)

我已将Django(DRF)与Gunicorn、Nginx整合并部署在Docker环境中。访问mysite.com/admin/时页面显示为纯文本,看似未加载静态文件,但浏览器控制台无任何错误。
进一步排查发现:

  • 所有/static/请求均返回HTTP 200状态码
  • 直接访问mysite.com/static/admin/css/base.css也能正常打开文件,但admin页面并未应用这些样式
  • 本地开启Debug=True时一切正常
  • 主站的/media/资源也能正常加载,仅/static/存在问题

相关配置文件

nginx.conf

events {}
http {
    server {
        listen 80;
        server_name mysite.com;
        server_tokens off;

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 80;
        server_name api.mysite.com;
        server_tokens off;

        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name mysite.com;
        server_tokens off;

        ssl_certificate  /etc/nginx/certs/mysite.com-chain.pem;
        ssl_certificate_key /etc/nginx/certs/mysite.com-key.pem;

        location / {
            proxy_pass http://10.0.2.237:3004; # React Frontend
        }

    }

    server {
        listen 443 ssl;
        server_name api.mysite.com;
        server_tokens off;

        ssl_certificate  /etc/nginx/certs/api.mysite.com-chain.pem;
        ssl_certificate_key /etc/nginx/certs/api.mysite.com-key.pem;

        location /media/ {
            autoindex on;
            alias /django-media/;
        }

        location /static/ {
            autoindex on;
            alias /django-static/;
        }

        location / {
            try_files $uri @proxy_api;
        }

        location @proxy_api {
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Url-Scheme $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass   http://10.0.2.237:7000; # Django Gunicorn Backend
        }


    }
}

docker-compose.backend.yml

version: '3.8'
services:
  postgres_db:
    container_name: postgres-prod
    image: postgres
    ports:
      - "5543:5543"
    volumes:
      - postgres_data_prod:/var/lib/postgresql/data/
    env_file:
      - .env.production
    command: -p 5543
  web:
    container_name: django-backend-prod
    build: .
    env_file:
      - .env.production
    ports:
      - "7000:8001"
    entrypoint: ./entrypoint.production.sh
    volumes:
      - .:/code
      - media:/code/media
      - static:/code/project/static
    depends_on:
      - postgres_db
    networks:
      - default
    restart: always

volumes:
  media:
    driver_opts:
      type: none
      device: ${PWD}/media
      o: bind
  postgres_data_prod:

networks:
  default:
    external:
      name: sentry-net

docker-compose.frontend.yml(位于不同目录,通过卷连接静态和媒体文件)

version: '3.8'

services:
  frontapp:
    container_name: React-Frontend-PROD
    build:
      context: .
      dockerfile: Dockerfile

    volumes:
      - '.:/app'
      - '/app/src'
      - '/app/node_modules'
    ports:
      - "3004:3000"
    env_file:
      - .env.production

  nginx:
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - .nginx/nginx.conf:/etc/nginx/nginx.conf
      - .certs/:/etc/nginx/certs
      - django-backend-prod_media:/django-media
      - django-backend-prod_static:/django-static
    links:
      - frontapp
    depends_on:
      - frontapp
    networks:
      - default

volumes:
  django-backend-prod_media:
    external: true
  django-backend-prod_static:
    external: true


networks:
  default:
    external:
      name: sentry-net

解决方案

核心问题分析

问题根源是域名路由与静态文件服务不匹配:

  • 你通过mysite.com/admin/访问后台,但Nginx配置中mysite.com的443端口服务直接转发到React前端,静态文件的Nginx规则只在api.mysite.com下生效。
  • 访问mysite.com/static/xxx时,请求实际被转发到了React前端,返回的200内容是React的页面(而非Django的静态资源),导致Admin页面加载的文件根本不是所需的CSS/JS。

具体修复步骤

1. 修改Nginx配置,为mysite.com添加Admin和静态文件路由

更新mysite.com的443 server块,新增Admin转发和静态文件服务规则:

server {
    listen 443 ssl;
    server_name mysite.com;
    server_tokens off;

    ssl_certificate  /etc/nginx/certs/mysite.com-chain.pem;
    ssl_certificate_key /etc/nginx/certs/mysite.com-key.pem;

    # 新增:将/admin/开头的请求转发到Django后端
    location /admin/ {
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Url-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass   http://10.0.2.237:7000;
    }

    # 新增:处理mysite.com域名下的静态文件请求
    location /static/ {
        autoindex on;
        alias /django-static/;
    }

    location / {
        proxy_pass http://10.0.2.237:3004; # React Frontend
    }
}

2. 确认Django生产环境配置正确

检查.env.production或settings.py中的关键配置:

  • DEBUG=False
  • ALLOWED_HOSTS = ['mysite.com', 'api.mysite.com']
  • STATIC_ROOT = os.path.join(BASE_DIR, 'static')(需与Docker卷挂载的/code/project/static路径一致)
  • STATIC_URL = '/static/'

3. 重新收集静态文件并重启服务

进入Django容器执行静态文件收集:

docker exec -it django-backend-prod python manage.py collectstatic --noinput

重启Nginx容器生效配置:

docker-compose -f docker-compose.frontend.yml restart nginx

验证

访问mysite.com/admin/,查看页面样式是否正常加载;同时检查浏览器控制台的静态文件请求,确认响应内容为正确的CSS/JS文件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 08:36:13