nginx在使用Docker Compose和Gunicorn启动时无法看到静态文件。

huangapple go评论67阅读模式
英文:

nginx does not seeing static files, when launching with docker compose +gunicorn

问题

事情是,我已经设置了Dockerfile,docker-compose正在按照预期运行所有内容。数据库已连接,所有东西都正常。但唯一的问题是,我无法加载静态文件。Gunicorn提示“Not Found”找不到管理和rest_framework静态文件。尽管它在根目录中创建了'static'文件夹,但在dockerfile运行时没有收集静态文件。

当我运行“docker-compose up”时,它说0个静态文件被复制到'/static',165个未修改的文件

到目前为止,我已经检查了在STATIC_ROOT和STATIC_URL中配置的路径。此外,我修改了我的docker-compose文件:

version: '3.11'

services:
  django_gunicorn:
    volumes:
      - static:/static/
    env_file:
      - .env
    build:
      context: .
    ports:
      - "8000:8000"
  nginx:
    build: ./nginx
    volumes:
      - ./backend/service/static:/backend/static
    ports:
      - "80:80"
    depends_on:
      - django_gunicorn
      - db
  db:
    image: postgres
    expose:
      - 5432
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
volumes:
  static:

我还再次检查了nginx配置文件:

upstream django {
    server django_gunicorn:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
    }
    location /static/ {
        autoindex on;
        alias /static/;
    }
}

我还尝试了不同的静态文件根目录和URL设置方法,但目前保持如下:

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

还有建议先运行“collectstatic”,我已经这样做了,但没有效果,所以我暂时删除了static文件夹,因为我在其他应用中也没有看到'static'文件夹。

entrypoint/sh

#!/bin/sh

python manage.py migrate --no-input
python manage.py collectstatic --no-input

gunicorn config.wsgi:application --bind 0.0.0.0:8000

这是我的Dockerfile:

FROM python:3.11

RUN pip install --upgrade pip

COPY ./requirements.txt .
RUN pip install -r requirements.txt \
    python manage.py collectstatic \
    pip install python-dotenv
COPY ./backend /app

WORKDIR /app

COPY ./entrypoint.sh /
ENTRYPOINT ["sh", "/entrypoint.sh"]
英文:

The thing is that i have set up dockerfiles, docker-compose is running everything as it should be. Databases is connected and all the staff. But the only problem is, that i cant load staticfiles. Gunicorn informs, that files "Not Found" both admin, and rest_framework static files. Even though it creates 'static' in the root directory, but doesn't collect static there, while dockerfile run.

When im doing "docker-compose up" it says that `0 static files were copied to '/static', 165 unmodified

So far i have checked paths which are configured in STATIC_ROOT and STATIC URL.
Also, modified my docker-compose file:

version: '3.11'

services:
  django_gunicorn:
    volumes:
      - static:/static/
    env_file:
      - .env
    build:
      context: .
    ports:
      - "8000:8000"
  nginx:
    build: ./nginx
    volumes:
      - ./backend/service/static:/backend/static
    ports:
      - "80:80"
    depends_on:
      - django_gunicorn
      - db
  db:
    image: postgres
    expose:
      - 5432
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=postgres
volumes:
  static:

Also i have inspected nginx config file one more time:

upstream django {
    server django_gunicorn:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
    }
    location /static/ {
        autoindex on;
        alias /static/;
    }
}

i have also tried different approaches to setting up root and url of staticfiles, but left it like this for now:

STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'

Also there were suggestions to run "collectstatic" first, which i have already done, but no effect, so ive deleted static folder for now, because i didnt see 'static' folder in other applications as well.

entrypoint/sh

#!/bin/sh

python manage.py migrate --no-input
python manage.py collectstatic --no-input

gunicorn config.wsgi:application --bind 0.0.0.0:8000

Here is my Dockerfile:

FROM python:3.11

RUN pip install --upgrade pip

COPY ./requirements.txt .
RUN pip install -r requirements.txt \
    python manage.py collectstatic \
    pip install python-dotenv
COPY ./backend /app

WORKDIR /app

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

答案1

得分: 1

Nginx必须将STATIC_URL映射到STATIC_ROOT,考虑到docker-compose中的卷映射。

Nginx的docker-compose卷映射:

- static:/static/

将虚拟卷“static”映射到根目录/static/

Nginx位置

location /static/ {
    autoindex on;
    alias /static/;
}

将STATIC_URL映射为容器内的目录/static/,与我们刚刚提到的docker-compose卷映射相匹配。位置应该匹配STATIC_URL,因为Django生成这些URL,并且它确实使用STATIC_URL,因此静态文件的URL将以STATIC_URL开头,为了捕获这些URL,Nginx必须使用相同的位置。但是别名值不应该匹配STATIC_ROOT,因为我们通过docker-compose中的虚拟卷映射将静态文件“传送”给Nginx,它们(静态文件)将出现在我们告诉它们的位置 - - static:/static/ - Nginx容器将在/static/路径下看到它们。Django设置不会影响此路径。

Django项目的docker镜像

COPY ./backend /app

这意味着容器内的BASE_DIR将是/app,这正是collectstatic向您报告的内容:'165 static files copied to '/app/static'

现在我们需要通过将虚拟卷映射到已收集的静态文件目录内的Django项目容器来与Nginx共享这些文件。静态文件已经被收集到/app/static。与Nginx共享的虚拟卷是“static”,所以

Django项目的docker-compose卷映射:

- static:/app/static/

英文:

Nginx must map STATIC_URL to STATIC_ROOT with respect to volume mapping in docker-compose.

docker-compose volume mapping for Nginx:

- static:/static/

virtual volume "static" to root directory /static/

Nginx location

location /static/ {
    autoindex on;
    alias /static/;
}

Maps STATIC_URL = /static/ to directory inside nginx container /static/ which matches docker-compose volume mapping we just mentioned. Location is supposed to match STATIC_URL because Django is generating those URLs and it does use STATIC_URL so static files URLs will begin with STATIC_URL and to catch those URLs nginx must use the same location. But alias value is not supposed to match STATIC_ROOT because we "deliver" static files to nginx via virtual volume mapping in docker-compose and they (static files) will appear for nginx just where we tell them to - - static:/static/ - nginx container will see them under /static/ path. Django settings do not affect this path.

Django project docker image

COPY ./backend /app

which means that BASE_DIR inside the container will be /app and this is exactly what collectstatic is reporting to you: '165 static files copied to '/app/static'

now we need to share those files with nginx via virtual volume by mapping virtual volume to the directory inside django project container with collected static files. Static files were collected to /app/static. Virtual volume shared with nginx is static, so

docker-compose volume mapping for Django project

- static:/app/static/

nginx在使用Docker Compose和Gunicorn启动时无法看到静态文件。

huangapple
  • 本文由 发表于 2023年2月7日 02:41:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365356.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定