Статические файлы Django не найдены в контейнере docker

Я создаю приложение Django с помощью Docker. Я выполняю команду collectstatic в своей точке входа, когда база данных готова. Когда я проверяю свой контейнер, папка /static/ пуста. Таким образом, Nginx не может загрузить статические файлы.

# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = '/static/'

Вот мой файл docker-compose

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"]

И точка входа:

#!/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/', которая должна быть создана. Как это так? Я проверил наличие папок static в backend и nginx по ssh в контейнере, и папки static были пусты. В журналах collectstatic был выполнен без ошибки с таким сообщением:

backend | 173 статических файла скопированы в '/static'.

Попробуйте добавить следующую команду в Dockerfile и пересобрать образ.

RUN python manage.py collectstatic --noinput

Вы можете разместить его после RUN pip install --no-cache-dir -r requirements.txt

Вы используете Docker именованный том для хранения статических файлов

    volumes:
      - static:/usr/src/app/static
      # ^^^^^^
      #   a volume name, not a host path

Этот именованный том существует только внутри хранилища Docker; вы не увидите его содержимого на хост-системе или в локальном дереве исходников.

Это не является проблемой для установки, которую вы здесь описываете: поскольку вы повторно запускаете collectstatic при каждом запуске контейнера, и содержимое тома скрывает содержимое образа в этом каталоге, нет особой необходимости в существовании файлов в контроле исходных кодов или в файловой системе вашего хоста. Если бы они вам были нужны, вы могли бы запустить manage.py collectstatic в виртуальной среде, не связанной с Docker.

Вернуться на верх