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

Docker+Nginx部署Django时无法加载静态文件的问题排查

Django+Docker+Nginx部署静态文件加载失败问题

Docker部署Django应用搭配Nginx反向代理,应用本身可正常访问,但静态文件返回404错误,推测问题出在卷路径或Nginx配置上。

目录结构

- nginx
  -- default.conf
  -- Dockerfile
- portfolio_app (Django项目)
  -- main_app
     --- settings.py
     --- wsgi.py
  -- sub_app
     --- views.py
     --- static
     --- media
- docker-compose.yml
- Dockerfile (Django相关)
- entrypoint.sh (启动Django服务脚本)

Django相关配置

Dockerfile

FROM python:3.8.13-slim-buster

WORKDIR /app
RUN pip install --upgrade pip
COPY ./requirements.txt ./
RUN pip install -r requirements.txt

COPY ./portfolio_app ./

COPY ./entrypoint.sh ./
ENTRYPOINT ["sh","/app/entrypoint.sh"]

settings.py 静态文件配置

MEDIA_ROOT = os.path.join(BASE_DIR, 'sub_app','media') 
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'sub_app','static')

Nginx相关配置

default.conf

upstream django {
    server portfolio_application:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
    }

    location /static/ {
        alias /static_volume/;
    }
}

Nginx Dockerfile

FROM nginx:1.19.0-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf

docker-compose.yml

version: '3.3'
services:
  portfolio_application:
    build: 
      context: .
    container_name: portfolio_app
    volumes:
      - static_volume:/app/sub_app/static
      - media_volume:/app/sub_app/media
    ports:
      - "8000:8000"
    env_file:
      - .env

  nginx:
    build: ./nginx
    volumes:
      - static_volume:/app/sub_app/static
      - media_volume:/app/sub_app/media
    ports:
      - "80:80"
    depends_on:
      - portfolio_application


volumes:
  media_volume:
  static_volume:

日志信息

Attaching to portfolio_app, docker_nginx_1
portfolio_app            | [2022-07-21 09:22:10 +0000] [7] [INFO] Starting gunicorn 20.1.0
nginx_1                  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx_1                  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
portfolio_app            | [2022-07-21 09:22:10 +0000] [7] [INFO] Listening at: http://0.0.0.0:8000 (7)
portfolio_app            | [2022-07-21 09:22:10 +0000] [7] [INFO] Using worker: sync
nginx_1                  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
portfolio_app            | [2022-07-21 09:22:10 +0000] [9] [INFO] Booting worker with pid: 9
nginx_1                  | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx_1                  | 10-listen-on-ipv6-by-default.sh: /etc/nginx/conf.d/default.conf differs from the packages version, exiting
nginx_1                  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx_1                  | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx_1                  | 172.19.0.1 - - [21/Jul/2022:09:22:13 +0000] "GET / HTTP/1.1" 200 48080 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"
nginx_1                  | 2022/07/21 09:22:13 [error] 29#29: *1 open() "/static_volume/lib/animate/animate.min.css" failed (2: No such file or directory), client: 172.19.0.1, server: , request: "GET /static/lib/animate/animate.min.css HTTP/1.1", host: "0.0.0.0", referrer: "http://0.0.0.0/"
nginx_1                  | 172.19.0.1 - - [21/Jul/2022:09:22:13 +0000] "GET /static/lib/animate/animate.min.css HTTP/1.1" 404 153 "http://0.0.0.0/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0" "-"

问题分析与修复步骤

从日志可明确看到,Nginx尝试访问/static_volume/lib/animate/animate.min.css但找不到文件,核心问题是Nginx配置的静态文件路径与实际卷挂载路径不匹配,同时需确保Django已将静态文件收集到指定目录。

修复方案二选一:

方案1:调整Nginx配置匹配卷挂载路径

修改nginx/default.conf中的静态文件location配置,将alias指向Nginx容器内的静态卷路径,同时补充媒体文件的location配置:

location /static/ {
    alias /app/sub_app/static/;
}

location /media/ {
    alias /app/sub_app/media/;
}

方案2:调整卷挂载路径匹配Nginx配置

修改docker-compose.yml中Nginx服务的volumes配置,将静态卷挂载到/static_volume,媒体卷挂载到/media_volume:

nginx:
    build: ./nginx
    volumes:
      - static_volume:/static_volume
      - media_volume:/media_volume
    ports:
      - "80:80"
    depends_on:
      - portfolio_application

关键补充:确保Django收集静态文件

修改entrypoint.sh,在启动Gunicorn之前执行collectstatic命令,确保静态文件被收集到STATIC_ROOT(即卷挂载的目录):

#!/bin/sh
# 收集静态文件,--noinput避免交互确认
python manage.py collectstatic --noinput
# 启动Gunicorn服务
gunicorn main_app.wsgi:application --bind 0.0.0.0:8000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 12:18:27