Docker Compose+Gunicorn部署时Nginx无法加载静态文件问题
核心问题梳理
从配置来看,静态文件无法收集和加载的问题主要来自路径不匹配、Dockerfile执行顺序错误以及Nginx挂载配置错误这几个关键点。
1. 修复Dockerfile中的无效命令
你的Dockerfile在复制项目代码前就执行了python manage.py collectstatic,此时manage.py还未被复制到容器中,这行命令完全无效,甚至会导致构建失败。删除这行错误命令:
修改后的Dockerfile:
FROM python:3.11 RUN pip install --upgrade pip COPY ./requirements.txt . RUN pip install -r requirements.txt \ && pip install python-dotenv COPY ./backend /app WORKDIR /app COPY ./entrypoint.sh / ENTRYPOINT ["sh", "/entrypoint.sh"]
2. 对齐STATIC_ROOT与容器挂载卷路径
你的Django配置中STATIC_ROOT = os.path.join(BASE_DIR, 'static'),而BASE_DIR为/app(因为backend被复制到/app目录,manage.py位于此目录下),因此实际STATIC_ROOT是/app/static。但docker-compose中给django_gunicorn服务挂载的是static:/static/,路径不匹配导致收集的静态文件无法进入共享卷。
修改docker-compose中django_gunicorn的volumes配置:
services: django_gunicorn: volumes: - static:/app/static/ # 改为STATIC_ROOT的实际路径 # 其他配置保持不变
3. 修复Nginx的静态文件挂载配置
当前Nginx挂载的是本地./backend/service/static目录,但实际静态文件存储在共享卷static中。结合Nginx配置里的alias /static/,需要将共享卷static挂载到Nginx容器的/static目录:
修改docker-compose中nginx的volumes配置:
services: nginx: build: ./nginx volumes: - static:/static/ # 挂载共享卷到Nginx的/static目录 # 其他配置保持不变
4. 优化collectstatic执行逻辑
entrypoint.sh中的命令逻辑正确,可添加日志输出方便排查执行情况:
#!/bin/sh python manage.py migrate --no-input echo "开始收集静态文件..." python manage.py collectstatic --no-input -v 2 gunicorn config.wsgi:application --bind 0.0.0.0:8000
5. 清理缓存后重新构建
执行以下命令清理旧容器与卷,避免缓存影响:
docker-compose down -v docker-compose build --no-cache docker-compose up
此时查看日志,应该会显示正确的静态文件复制数量,Nginx也能正常加载/admin和rest_framework的静态文件。
内容的提问来源于stack exchange,提问作者Saba Guzitashvili

