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

Django+Docker+Nginx部署静态文件无法加载问题求助

api:
image: meduzzen-backend-api
container_name: django
entrypoint: ./start_prod.sh
tty: true
stdin_open: true
volumes:
- .:/code
- ./code:/apps
- static:/code/static
expose:
- "8000"
ports:
- "8000:8000"
depends_on:
- postgres-db
- redis
env_file:
- .env
networks:
- api-db-redis
...
nginx:
image: meduzzen-backend-nginx
container_name: nginx
volumes:
- static:/static
- ./nginx-conf.d:/etc/nginx/conf.d
ports:
- "80:80"
depends_on:
- api

volumes:
static:
...

#### meduzzen-backend-api 镜像的Dockerfile
```dockerfile
FROM python:3.11.3-alpine

ENV PYTHONBUFFERED=1
# Enable pytest-django 
ENV DJANGO_SETTINGS_MODULE=meduzzen_backend.settings

WORKDIR /code

COPY requirements.txt .

RUN pip install -r requirements.txt --upgrade pip

COPY . .

# Copy start.sh script into project folder
COPY start.sh .

# Give access rights to start.sh
RUN chmod +x start.sh
RUN chmod +x start_prod.sh

EXPOSE 8000

meduzzen-backend-nginx 镜像的Dockerfile

FROM nginx:1.25.3-alpine

COPY ./default.conf /etc/nginx/conf.d/default.conf

default.conf 配置

upstream django {
    server api:8000;
}

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://django;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /static/ {
        alias /static/;
        add_header Access-Control-Allow-Origin *;
    }
}

start_prod.sh 脚本内容

#!/bin/sh
python manage.py migrate
python manage.py collectstatic --noinput
gunicorn meduzzen_backend.wsgi:application --bind 0.0.0.0:8000

问题原因及解决办法

核心原因

  1. STATIC_ROOT与Docker卷挂载路径不匹配
    Django的collectstatic会把静态文件收集到STATIC_ROOT指定的目录,如果这个目录和Docker共享卷static挂载到django容器的路径不一致,收集的文件就不会进入共享卷,Nginx自然无法读取。

  2. 错误直接访问Django端口的静态资源
    当DEBUG=False时,Django本身不会处理静态文件请求,所有静态资源请求必须通过Nginx转发,直接访问8000端口的静态路径必然返回404,这是正常行为,但说明你可能没走Nginx访问静态资源。

  3. 静态文件权限问题
    Alpine镜像的Nginx默认以nginx用户运行,如果共享卷里的静态文件权限不允许该用户读取,Nginx会返回403或404。

解决步骤

1. 对齐STATIC_ROOT与Docker卷路径

在settings.py中确保配置:

STATIC_URL = '/static/'
STATIC_ROOT = '/code/static/'  # 必须和django容器中static卷的挂载路径完全一致

2. 通过Nginx端口访问静态资源

不要直接访问http://localhost:8000/static/...,而是访问Nginx的80端口:http://localhost/static/admin/img/calendar-icons.svg

3. 修复静态文件权限

修改start_prod.sh,在collectstatic后添加权限设置,确保Nginx用户能读取静态文件:

#!/bin/sh
python manage.py migrate
python manage.py collectstatic --noinput
chown -R nginx:nginx /code/static  # 给静态文件目录设置可读权限
gunicorn meduzzen_backend.wsgi:application --bind 0.0.0.0:8000

4. 重启容器验证

执行以下命令重建镜像并重启服务:

docker-compose -f docker-compose-prod.yml down
docker-compose -f docker-compose-prod.yml build
docker-compose -f docker-compose-prod.yml up -d

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:58:12