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

Docker容器内Django静态文件缺失问题求助

问题描述

使用Docker构建Django应用,entrypoint脚本在数据库就绪后执行collectstatic命令,日志显示已将173个静态文件复制到/static/,但进入backend和nginx容器查看时,/static/目录为空,导致Nginx无法加载静态文件,本地也未生成/static/文件夹。

配置文件详情

settings.py

STATIC_URL = '/static/'
STATIC_ROOT = '/static/'

docker-compose.yml

version: "3.9"

services:
  db:
    image: postgis/postgis:14-3.3
    container_name: db
    volumes:
      - ./data/db:/var/lib/postgresql/data
    env_file:
    - prod.env

  backend:
    container_name: backend
    build:
      dockerfile: ./django/Dockerfile
    command: gunicorn api.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static:/usr/src/app/static
    ports:
      - "8000:8000"
    env_file:
    - prod.env
    depends_on:
      - db
  
  nginx:
    container_name: nginx
    build:
      dockerfile: ./nginx/Dockerfile
    volumes:
      - static:/usr/src/app/static
    ports:
      - "80:80"
    depends_on:
      - backend
    restart: always

  redis:
    container_name: redis
    restart: unless-stopped
    image: redis:alpine 
    expose:
      - 6379

  worker:
    container_name: worker
    build:
      dockerfile: ./django/Dockerfile
    command: celery -A api worker -l INFO
    volumes:
      - static:/usr/src/app/static
    env_file:
    - prod.env
    depends_on:
      - db
      - backend
      - redis
  
volumes:
  static:

Nginx配置

upstream api {
    server backend:8000;
}

server {
    listen 80;

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

    location /static/ {
        alias /usr/src/app/static/;
    }
}

backend Dockerfile

# syntax=docker/dockerfile:1
FROM python:3
WORKDIR /usr/src/app
RUN apt-get update
RUN apt-get install -y libgdal-dev gdal-bin netcat

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY /django/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY /django/django-entrypoint.sh /django-entrypoint.sh
RUN chmod +x /django-entrypoint.sh

COPY django /usr/src/app

ENTRYPOINT ["/django-entrypoint.sh"]

entrypoint脚本

#!/bin/sh

if [ "$POSTGRES_NAME" = "postgres" ]
then
    echo "Waiting for Postgres..."

    while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

ls
# python manage.py flush --no-input
python manage.py migrate --no-input
python manage.py collectstatic --no-input

exec "$@"
问题分析与解决方案

核心问题

STATIC_ROOT设置为/static/,但Docker卷挂载的是/usr/src/app/static,两者路径不匹配。collectstatic把文件写到了容器内部的/static/目录(未挂载卷),而共享卷/usr/src/app/static始终为空,导致nginx和backend容器无法读取到静态文件。

具体解决步骤

  1. 修改Django的STATIC_ROOT路径
    在settings.py中更新STATIC_ROOT,使其与卷挂载路径一致:

    STATIC_URL = '/static/'
    STATIC_ROOT = '/usr/src/app/static/'
    
  2. 清理旧容器与卷(推荐)
    避免旧容器的缓存路径影响,执行以下命令重置环境:

    # 停止并删除所有容器
    docker-compose down
    # 删除命名卷(如有重要数据请先备份)
    docker volume rm $(docker volume ls -q | grep static)
    # 重新构建并启动服务
    docker-compose up --build
    
  3. 验证静态文件
    启动后进入backend容器查看卷目录:

    docker exec -it backend ls /usr/src/app/static
    

    此时应能看到173个静态文件,nginx容器中相同路径也能看到。

补充说明

  • 命名卷static由Docker管理,不会在本地生成对应文件夹,这是生产环境的正常配置。
  • 如果需要本地查看静态文件,可将卷改为绑定挂载(不推荐生产环境):
    # 在backend、nginx、worker服务的volumes中替换为
    volumes:
      - ./static:/usr/src/app/static
    
    同时删除docker-compose.yml末尾的volumes: static:配置,本地会生成./static目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:55:23