使用Nginx、Docker和Django时静态文件无法加载的问题
问题描述
通过Nginx访问 http://0.0.0.0/static/css/base.css 时静态文件可正常加载,但直接访问Django端口 http://0.0.0.0:8000/static/css/base.css 时提示静态文件未找到。
Nginx容器错误日志
nginx_1 | 172.22.0.1 - - [04/Oct/2023:04:59:33 +0000] "GET /static/css/base.css HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-" nginx_1 | 2023/10/04 04:59:34 [error] 8#8: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.22.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/static/css/base.css" nginx_1 | 172.22.0.1 - - [04/Oct/2023:04:59:34 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost/static/css/base.css" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-"
已尝试操作
- 在Nginx的conf.d配置中设置容器名称为
server_name - 添加
types配置识别CSS文件,但均未生效
相关配置文件
settings.py
STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'static'
Dockerfile
FROM python:3.10 ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONBUFFERED=1 \ POETRY_VERSION=1.4.2 \ POETRY_VIRTUALENVS_CREATE="false" RUN pip install "poetry==$POETRY_VERSION" WORKDIR /education_platform COPY pyproject.toml poetry.lock docker-entrypoint.sh ./ RUN poetry install --no-interaction --no-ansi --no-dev COPY . /education_platform EXPOSE 8000 RUN chmod +x wait-for-it.sh
docker-compose.yaml
version: '3' services: db: image: postgres:13.1-alpine restart: unless-stopped env_file: - ./.env volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres cache: image: redis:7.0.4 restart: unless-stopped volumes: - .data/cache:/data web: restart: unless-stopped build: context: . dockerfile: Dockerfile command: [ "/education_platform/wait-for-it.sh", "db:5432", "--", "gunicorn", "education_platform.wsgi:application", "-b", "0.0.0.0:8000"] env_file: - ./.env volumes: - .:/education_platform - ./static:/education_platform/static ports: - "8000:8000" environment: - DJANGO_SETTINGS_MODULE=education_platform.settings.prod - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres depends_on: - db - cache nginx: image: nginx:1.23.1 restart: unless-stopped volumes: - ./config/nginx/conf.d:/etc/config/nginx/conf.d/default.conf - ./static:/usr/share/nginx/html/static ports: - "80:80" command: ["/bin/sh", "-c", "nginx -g 'daemon off;'"] depends_on: - web
conf.d
server { listen 80; server_name education_platform_web_1; error_log stderr warn; access_log /dev/stdout main; location / { proxy_pass http://education_platform_web_1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; } location /static/ { alias /usr/share/nginx/html/static/; } location /media/ { alias /education_platform/media/; } types { text/javascript js; application/javascript js; text/css css; } }
解决方案
Gunicorn不处理静态文件是正常行为
Gunicorn作为WSGI服务器,本身不负责提供静态文件,生产环境下静态文件本就该由Nginx这类反向代理服务器处理。如果需要在开发阶段通过Django访问静态文件,应运行python manage.py runserver(Django开发服务器),而非Gunicorn。确保执行静态文件收集命令
你设置了STATIC_ROOT,必须运行collectstatic将所有应用的静态文件收集到指定目录。在Docker环境中可通过两种方式实现:
- 在Dockerfile中添加:
RUN python manage.py collectstatic --noinput - 或修改docker-compose的web服务命令:
command: [ "/education_platform/wait-for-it.sh", "db:5432", "--", "python", "manage.py", "collectstatic", "--noinput", ";", "gunicorn", "education_platform.wsgi:application", "-b", "0.0.0.0:8000"]
- 修正Nginx配置问题
- 挂载路径错误:将nginx服务的配置挂载改为
./config/nginx/conf.d:/etc/nginx/conf.d,原配置是把整个目录挂载成单个文件,导致Nginx无法读取配置:volumes: - ./config/nginx/conf.d:/etc/nginx/conf.d - ./static:/usr/share/nginx/html/static server_name优化:将容器名改为实际访问域名或localhost,更符合实际使用场景:server_name localhost;- 媒体文件路径修正:Nginx容器内不存在
/education_platform/media/,需挂载本地media目录并修改配置:# nginx服务volumes添加 - ./media:/usr/share/nginx/html/medialocation /media/ { alias /usr/share/nginx/html/media/; }
- 解决favicon.ico 404错误
将favicon.ico放入static目录,在Nginx配置中添加路由处理:
location = /favicon.ico { alias /usr/share/nginx/html/static/favicon.ico; }
内容的提问来源于stack exchange,提问作者Reboot
相关产品推荐
相关产品推荐

