Статические и мультимедийные файлы 404 за проходом прокси NGINX - PullRequest
1 голос
/ 04 июня 2019

У меня есть то, что я считаю слегка запутанным стеком Django / Gunicorn / NGINX, который доставляет мне проблемы, когда я пытаюсь перенести его с сервера разработки django на производственную установку с Gunicorn и NGINX. В частности, у меня проблемы с обслуживанием статических файлов.

СИСТЕМНАЯ АРХИТЕКТУРА: у меня есть один физический сервер с публичным IP-адресом. Этот физический сервер размещает 3 виртуальные машины в частной виртуальной сети (NAT). Каждая виртуальная машина запускает свой собственный проект django на порту 8001. Я пересылаю порт 8001 каждой виртуальной машины на уникальные доступные порты на физической машине. Итак, в итоге, архитектура выглядит следующим образом:

ЧАСТНАЯ ВИРТУАЛЬНАЯ СЕТЬ ВМ:

  • VM1 запускает «сайт 1» на порту VM1 8001
  • VM2 запускает «сайт 2» на порту VM2 8001
  • VM3 запускает «сайт 3» на порту VM3 8001

ПРИНИМАЮЩИЙ СЕРВЕР:

  • Публикует "сайт 1" на порте хоста 8001 (порт виртуальной машины 8001 fwd.to порт хоста 8001)
  • Публикует "сайт 2" на порте хоста 8002 (порт виртуальной машины 8001 fwd.to порт хоста 8002)
  • Публикует "сайт 3" на порте хоста 8003 (порт виртуальной машины 8001 fwd.to порт хоста 8003)

Это очень хорошо работает для разработки на сервере разработки django. Мне просто нужно включить номер порта в URL. Как в:

  • myserver.edu: 8001 для сайта 1
  • myserver.edu: 8002 для сайта 2
  • myserver.edu: 8003 для сайта 3

Для производства я бы хотел настроить NGINX для обслуживания сайтов:

  • myserver.edu / site1 для сайта 1
  • myserver.edu / site2 для сайта 2
  • myserver.edu / site3 для сайта 3

Я установил NGINX на хост-компьютере и настроил его для использования TLS. Конфигурация NGINX на хост-машине определяет 3 местоположения ниже со следующей конфигурацией. Вы можете видеть, что я использую proxy_pass для маршрутизации трафика для каждого сайта в виртуальную сеть на хост-компьютере.

location /site1/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X_Forwarded-Proto $scheme;
        proxy_pass http://192.168.122.243:8001/;
}

location /site2/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X_Forwarded-Proto $scheme;
        proxy_pass http://192.168.122.244:8001/;
}

location /site3/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X_Forwarded-Proto $scheme;
        proxy_pass http://192.168.122.245:8001/;
}

Так что любой запрос:

  • Элемент списка

myserver.edu / site1 переходит на порт 8001 на VM1

  • Элемент списка

myserver.edu / site2 переходит на порт 8001 на VM2

  • Элемент списка

myserver.edu / site3 переходит на порт 8001 на VM3

На VM1 у меня есть сайт django + gunicorn + NGINX со следующим конфигом (одинаковые настройки на всех виртуальных машинах):

server {
   listen 8001;
   server_name 0.0.0.0;

   location = /favicon.ico { access_log off; log_not_found off; }

   location /static/ {
        root /home/rcrv/bubbles/s2uds_user/gui;
   }

   location / {
        include proxy_params;
        proxy_pass http://unix:/home/rcrv/bubbles/s2uds_user/bubs.sock;
   }

}

Корневой URL моего сайта 1 из urls.py таков: url (r '^ $', gv.home),

ПОВЕДЕНИЕ ПОД КОНФИГОМ ПРОИЗВОДСТВА NGINX:

Если я просматриваю сайт 1 на VM1 из NAT с таким URL, как: 192.168.122.243:8001/

  • Это будет отлично работать - Статический файл и файл мультимедиа подаются

Если я просматриваю из общедоступного IP-пространства URL-адрес, например: myerver.edu/site1/

  • Это будет рендерить весь динамический контент из django, но не сможет обслуживать статический контент (с 404). Моя консоль разработчика браузера показывает, что браузер ищет статический контент на https://myserver.com/static

  • Обратите внимание, что я ожидал, что он будет искать статический контент в myserver / site1 / static

Если я изменю этот URL-адрес прямо в браузере, чтобы он стал myserver.com/site1/static, я получу доступ к статическому содержимому, которое отсутствовало

Попытки смягчить / исправить включают:

Я изменил блок местоположения в конфигурации NGINX виртуальной машины: location = / site1 / static / Не повезло.

Отладка показывает, что браузер все еще пытается найти статический контент по адресу: myserver.edu/static

ВОПРОС: Как, черт возьми, я могу изменить или исправить конфигурацию так, чтобы django включил эту часть "/ site1 /" в статический URL? Я склонен думать, что эта проблема не проблема конфигурации NGINX, а проблема django. Скорее, я считаю, что нужно указать django префикс / site1 / к его статическому URL.

Идеи? Я прочитал множество ответов на подобные проблемы со статическими файлами django, но пока это исправляет.

Спасибо.

ОБНОВЛЕНИЕ: я начал это понимать. Вот что сработало для меня.

  1. Я создал каталог / static / в / var / www / static на каждой виртуальной машине и установил STATIC_ROOT в файле settings.py в качестве этого расположения, затем запустил сбор статических данных, чтобы скопировать весь статический контент в этот каталог .

  2. Затем я изменил статический блок расположения файла в NGINX conf на ВМ:

location /static/ {
        root /var/www/;
   }
  1. Наконец, я изменил STATIC_URL в settings.py из: STATIC_URL = / static / в STATIC_URL = / site1 / static /

В результате статический контент теперь подается в производство под NGINX. Причиной было мое неполное понимание методов статического контента в целом. Печатание вопроса здесь как бы прояснило проблему и привело меня к решению. Надеется, что это помогает кому-то с похожей архитектурой. Теперь исправить медиа-файлы - скорее всего, тот же подход.

...