在docker上运行django+gunicorn+nginx时找不到静态文件

在docker上运行django+gunicorn+nginx时找不到静态文件

我知道这个问题已经得到很好的解答,但我找到的所有答案似乎都不适合我。我有一个简单的 django 项目,我正尝试使用 gunicorn 和 nginx 在 Docker 上运行它。以下是我的配置

Dockerfile

# Pull base image
FROM python:3.6-slim

# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV DATABASE_HOST db

# Set work directory
ARG PROJECT=my_project
ARG PROJECT_DIR=/var/www/${PROJECT}

RUN mkdir -p $PROJECT_DIR

# Copy project
COPY my_project $PROJECT_DIR/
COPY docker-entrypoint.sh /
RUN chmod u+x /docker-entrypoint.sh
# give permission for nginx to read static files
RUN chown -R "$USER":www-data /var/www/my_project/allstatic && chmod -R 0755 /var/www/my_project/allstatic

WORKDIR $PROJECT_DIR
EXPOSE 8000
ENTRYPOINT ["/docker-entrypoint.sh"]

docker-entrypoint.sh

#!/bin/bash

apt-get update
apt-get install -y git 
pip install --upgrade pip
pip install -r requirements.txt
python manage.py collectstatic --noinput
python manage.py migrate --no-input
touch ./logs/gunicorn.log
touch ./logs/gunicorn-access.log
tail -n 0 -f ./logs/gunicorn*.log &

gunicorn --bind 0.0.0.0:8000 my_project.wsgi:application --log-level=info --log-file=./logs/gunicorn.log --access-logfile=./logs/gunicorn-access.log 

exec "$@"

docker-compose.yml

version: '3.6'

services:
  db:
  image: postgres:10.5-alpine
volumes:
  - postgres_data:/var/lib/postgresql/data/
environment:
  - POSTGRES_USER=user
  - POSTGRES_PASSWORD=some_some
  - POSTGRES_DB=database
networks:
  - database_network

app:
  build: .
  volumes:
    - .:/var/www
    - static_volume:/var/www/my_project/allstatic
  depends_on:
    - db
  networks:
    - nginx_network
    - database_network

nginx:
  image: nginx:1.13
  ports:
    - 8000:8000
  volumes:
    - ./config/nginx/conf.d:/etc/nginx/conf.d
    - static_volume:/var/www/my_project/allstatic
  depends_on:
    - app
  networks:
    - nginx_network

networks:
  nginx_network:
    driver: bridge
  database_network:
    driver: bridge

volumes:
  postgres_data:
  static_volume:

nginx 配置

upstream develop_server {
    server app:8000;
}

server {
    listen 8000;
    server_name localhost;

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

    location /static/ {
        autoindex on;
        alias /var/www/my_project/allstatic;
    }
}

在项目设置中我将 STATIC_URL 和 STATIC_ROOT 定义为

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'allstatic/')
STATIC_URL = STATIC_ROOT

这是我得到的错误

app_1  | Not Found: /var/www/my_project/allstatic/really_important_file.js
nginx_1    | 172.22.0.1 - - [23/Sep/2018:11:55:26 +0000] "GET /var/www/my_project/allstatic/really_important_file.js HTTP/1.1" 404 3132 "http://localhost:8000/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0" "-"

除了这个错误之外,整个页面加载都没有问题。此外,当我运行带有manage.py runserver静态数据的服务器时,静态数据可以正常使用,因此我怀疑我的 nginx 配置存在某种错误。我找到的答案建议更改 nginx 在静态目录上的权限,这是在 Dockerfile 中完成的(或者可能是做错了?)。

如果您能指出我遗漏的内容,我将非常感激。

更新

这绝对不是权限问题 - 我可以在浏览器中通过 localhost:8000/static/really_important_file.js 访问此文件。现在我真的不知道是什么导致了这些错误。

答案1

问题出在 django 应用程序的设置上,而不是 nginx。我已将 STATIC_URL 指定为 STATIC_ROOT,它指向包含静态文件的文件夹的绝对路径。据我了解,当页面加载并尝试根据{{ static }}标签解析脚本的 URL 时,它最终会寻找这个绝对路径,而 nginx 显然无法处理这个绝对路径。我已将其更改STATIC_URL = '/static/',一切正常。

相关内容