Настройка Django static с помощью Docker/Nginx

Я докеризирую свое приложение Django/React, но у меня возникают проблемы с отображением статических файлов на сервере prod.

Каталог проекта:

.
├── README.md
├── backend
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── backend
│   ├── entrypoint.prod.sh
│   ├── entrypoint.sh
│   ├── manage.py
│   ├── requirements.txt
│   └── static
├── docker-compose.ci.yml
├── docker-compose.prod.yml
├── docker-compose.yml
├── frontend
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── README.md
│   ├── build
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   ├── src
│   └── webpack.config.js
└── nginx
    ├── Dockerfile
    └── nginx.conf

nginx.conf

upstream backend {
    server backend:8000;
}

server {
    listen 80;

    location / {
        root "/var/www/frontend";
    }    

    location /api/ {
        proxy_pass http://backend;
        proxy_set_header Host $http_host;
    }

    location /admin/ {
        proxy_pass http://backend;
        proxy_set_header Host $http_host;
    }
    
    location /static/ {
        alias /backend/static;
    }
}

Статическая настройка Django:

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

docker-compose.ci.yml (собирает образы):

version: "3.8"

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
    image: "${BACKEND_IMAGE}"
    command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/backend/static
      - media_volume:/backend/media
    expose:
      - 8000
    env_file: .env
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    image: "${FRONTEND_IMAGE}"
    volumes:
      - frontend_build:/frontend/build
  nginx:
    build:
      context: ./nginx
    image: "${NGINX_IMAGE}"
    ports:
      - 80:80
    volumes:
      - static_volume:/backend/static
      - frontend_build:/var/www/frontend
    depends_on:
      - backend
      - frontend

volumes:
  frontend_build:
  static_volume:
  media_volume:

На вкладке сети в Chrome Dev Tools он показывает этот URL при попытке загрузить статические данные:

URL запроса: http://ipaddress/static/admin/css/nav_sidebar.cs

Статические файлы, собранные внутри контейнера backend во время сборки, скрываются контейнером static_volume, который монтируется при запуске docker-compose.

Когда вы монтируете том поверх каталога, вы видите только содержимое тома, а не файлы, которые были в каталоге до этого.

Чтобы исправить это, вы можете

  • Запустите collectstatic после того, как том будет смонтирован. Т.е. после того, как сервер будет запущен
  • .
  • Копировать статические файлы, созданные Django, в контейнер nginx во время сборки (больше не нужно использовать том)
Вернуться на верх