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容器无法读取到静态文件。
具体解决步骤
修改Django的STATIC_ROOT路径
在settings.py中更新STATIC_ROOT,使其与卷挂载路径一致:STATIC_URL = '/static/' STATIC_ROOT = '/usr/src/app/static/'清理旧容器与卷(推荐)
避免旧容器的缓存路径影响,执行以下命令重置环境:# 停止并删除所有容器 docker-compose down # 删除命名卷(如有重要数据请先备份) docker volume rm $(docker volume ls -q | grep static) # 重新构建并启动服务 docker-compose up --build验证静态文件
启动后进入backend容器查看卷目录:docker exec -it backend ls /usr/src/app/static此时应能看到173个静态文件,nginx容器中相同路径也能看到。
补充说明
- 命名卷
static由Docker管理,不会在本地生成对应文件夹,这是生产环境的正常配置。 - 如果需要本地查看静态文件,可将卷改为绑定挂载(不推荐生产环境):
同时删除# 在backend、nginx、worker服务的volumes中替换为 volumes: - ./static:/usr/src/app/staticdocker-compose.yml末尾的volumes: static:配置,本地会生成./static目录。
内容的提问来源于stack exchange,提问作者Nikko
相关产品推荐
相关产品推荐

