基于Docker部署DRF+Gunicorn+MariaDB+Nginx:静态文件无法加载
问题排查与解决方案
一、先修复自定义中间件的错误
你的LogIPMiddleware直接访问response.content,但请求静态文件时Django返回的是FileResponse(流式响应子类),这类响应没有content属性,需改用streaming_content处理。修改中间件代码:
# middlewares.py 修改后示例 class LogIPMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) # 区分响应类型,避免属性访问错误 if hasattr(response, 'content'): content = response.content else: # 流式响应(如静态文件)无需记录内容则直接跳过,或按需处理 content = b"" # 若需读取流式内容,需重新封装避免响应失效: # content = b"".join(response.streaming_content) # response.streaming_content = iter([content]) # 你的日志逻辑代码... return response
说明:中间件的异常会中断静态文件请求流程,这是导致静态文件无法加载的核心诱因之一。
二、排查静态文件部署配置
1. 检查Django settings.py 静态文件配置
确保生产环境配置正确:
# settings.py DEBUG = False # 生产环境必须关闭DEBUG模式 ALLOWED_HOSTS = ["你的域名/服务器IP", "localhost"] STATIC_URL = '/static/' STATIC_ROOT = '/var/www/static/' # 需与Docker容器内路径、Nginx配置一致 # 若项目有自定义静态目录,需加入STATICFILES_DIRS # STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
2. 检查Dockerfile的静态文件处理逻辑
确保构建时创建静态目录并执行collectstatic:
# Dockerfile示例 FROM python:3.10-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . # 创建静态文件存储目录 RUN mkdir -p /var/www/static/ # 非交互模式执行静态文件收集 RUN python manage.py collectstatic --noinput CMD ["gunicorn", "--bind", "0.0.0.0:8000", "你的项目名.wsgi:application"]
3. 检查docker-compose.yml的卷挂载配置
确保Nginx容器能通过共享卷访问Django收集的静态文件:
# docker-compose.yml示例 version: '3.8' services: web: build: . volumes: - static_volume:/var/www/static/ # 共享静态文件卷给Nginx depends_on: - db db: image: mariadb:latest # 数据库相关配置... nginx: image: nginx:latest ports: - "80:80" volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf - static_volume:/var/www/static/ # 挂载共享静态卷 depends_on: - web volumes: static_volume: # 定义共享卷
4. 检查Nginx default.conf 配置
确保Nginx正确处理静态文件请求,转发动态请求到Gunicorn:
# default.conf server { listen 80; server_name 你的域名/服务器IP; # 静态文件路由 location /static/ { alias /var/www/static/; # 路径需与STATIC_ROOT、卷挂载完全一致 expires 30d; # 静态文件缓存优化 } # 动态请求转发到Gunicorn location / { proxy_pass http://web:8000; 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; } }
5. 验证静态文件是否正确收集
进入Django容器,检查STATIC_ROOT目录是否有静态文件:
docker exec -it <你的web容器名> ls -l /var/www/static/
若目录为空,说明collectstatic执行失败,需检查构建日志或手动在容器内执行命令排查错误。
三、验证步骤
- 重启所有容器:
docker-compose down && docker-compose up --build - 打开浏览器F12开发者工具,访问管理面板,查看静态文件请求的HTTP状态码(应为200)
- 检查容器日志确认无报错:
docker logs <nginx容器名> docker logs <web容器名>
内容的提问来源于stack exchange,提问作者Mahian Mahin
相关产品推荐
相关产品推荐

