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=FalseALLOWED_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
相关产品推荐
相关产品推荐

