Uwsgi_pass не пересылает заголовок SCRIPT_NAME

Я пытаюсь сделать свое веб-приложение (на основе Django/wsgi) доступным из некоторой подпапки основного домена. Я использую докер для своего приложения и статические файлы, поэтому у меня есть основной nginx на моем сервере в качестве обратного прокси-сервера, еще один nginx в контейнере «nginx», который направляет данные для моего приложения, и uWSGI во втором контейнере, который обслуживает фактические данные Django. Uwsgi_pass не пересылает заголовок SCRIPT_NAME

И я хочу, чтобы мое приложение было доступно извне как myserver.com/mytool, в то же время я не хочу жестко кодировать mytool где-либо в своем приложении. Обычно для такого рода вещей используется заголовок SCRIPT_NAME, поэтому вот конфигурация nginx на хосте:

server {
  listen 80; # Just for sake of simplicity, of course in production it's 443 with SSL
  location /mytool/ {
    proxy_pass http://127.0.0.1:8000/;
    include proxy_params;
    proxy_set_header SCRIPT_NAME /mytool;  # <--- Here I define my header which backend should use
  }
}

Затем в моем docker-compose я выставляю 8000:80 для nginx и вот внутренняя конфигурация nginx:

server {
  listen 80;
  location / {
    include uwsgi_params;
    uwsgi_pass web:3031;
  }
}

С этой конфигурацией я ожидал бы, что мое приложение Django получит заголовок SCRIPT_NAME, но, по-видимому, это не так.

В то же время, если я определяю пользовательские заголовки, такие как proxy_set_header X-something something;, тогда они перенаправляются правильно, и я могу видеть это из Django.

Как мне передать SCRIPT_NAME, чтобы избежать жесткого кода пути в моем коде?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
1 019
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь есть две проблемы.

Во-первых, nginx считает заголовки, содержащие символы подчеркивания, недопустимыми, поэтому заголовок SCRIPT_NAME не принимается nginx в контейнере, потому что он недействителен с точки зрения nginx. К счастью, директива nginx underscores_in_headers здесь, чтобы помочь.

Просто добавьте underscores_in_headers on; в server раздел nginx внутри Докера (не в хост).

Когда это будет сделано, возникает еще одна проблема — nginx пересылает заголовок, добавляя HTTP перед своим именем. Итак, теперь со стороны Django вы увидите HTTP_SCRIPT_NAME вместо SCRIPT_NAME. Но опять же, к счастью для нас, это можно легко исправить, снова используя строку uwsgi_param SCRIPT_NAME $http_script_name; в nginx внутри Docker.

Таким образом, окончательный конфиг nginx внутри Docker должен выглядеть так:

server {
  underscores_in_headers on;  # <---- (1)
  listen 80;
  location / {
    include uwsgi_params;
    uwsgi_pass web:3031;
    uwsgi_param SCRIPT_NAME $http_script_name; # <--- (2)        
  }
}

В Джанго settings.py


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = '/static'

# Bug in Django of not using SCRIPT_NAME header...
# See https://code.djangoproject.com/ticket/25598
# Let's implement dirty workaround for now
if os.getenv('SCRIPT_NAME'):
    STATIC_URL = os.getenv('SCRIPT_NAME') + STATIC_ROOT

Привет @The Godfater, я сейчас сталкиваюсь с этой проблемой, как и ты. Тем не менее, я изменил настройки, которые вы предложили, но они все еще не работают для меня. Не могли бы вы поделиться своей конфигурацией uWSGI или настройками Django?

Andrew Li 28.10.2020 09:18

@AndrewLi Только что проверил - у меня действительно ничего особенного в конфиге... [uwsgi] socket = :3031 wsgi-file = my_project/wsgi.py processes = 4 threads = 2 # Default size is too low buffer-size = 32768

The Godfather 28.10.2020 14:56

@AndrewLi добавлен настройками Django, но упомянутая проблема была исправлена ​​​​в Django 3.1 мной, поэтому для 3.1+ она не нужна.

The Godfather 28.10.2020 14:58

Другие вопросы по теме