Вопрос или проблема
Ок, эта задача должна быть простой, но я просто не могу добиться ее выполнения. Я хотел бы иметь подпапку после моего доменного имени (на самом деле, после IP этого доменного имени), которая перенаправляет на определенный порт на том же сервере. В сущности, я хочу избавиться от необходимости использовать множество портов.
Вот моя конфигурация nginx для этого
server {
listen 80;
index index.html index.htm index.nginx-debian.html index.php;
server_name aaa.bbb.ccc.ddd;
location ^~ /app2 {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://aaa.bbb.ccc.ddd:8001;
}
}
Таким образом, при доступе к aaa.bbb.ccc.ddd/app2, я хотел бы, чтобы это разрешалось на http://aaa.bbb.ccc.ddd:8001.
Не должно быть так сложно. Что я упускаю здесь?
Спасибо
Пат
Поскольку вы пометили это как вопрос о обратном прокси, я предполагаю, что вы хотите проксировать запрос так, чтобы пользователь видел только http://aaa.bbb.ccc.ddd/app2
в своем браузере.
Вы можете изменить свой location
блок на этот:
location ~/app2(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://aaa.bbb.ccc.ddd:8001$1;
}
Здесь мы захватываем часть URI после /app2
в переменную $1
и используем ее в директиве proxy_pass
.
Ответ Теро Килканена отличный. Однако в некоторых ситуациях неименованная группа регулярных выражений (например, $1
) может быть не найдена. Мы можем использовать именованную группу (например, $sub_dir
), чтобы избежать этой ошибки.
location ~/app2(?<sub_dir>.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://aaa.bbb.ccc.ddd:8001$sub_dir;
}
В приведенном выше примере используется (?<sub_dir>.*)
для установки именованной группы, мы можем использовать $sub_dir
, чтобы получить значение этой группы Regex.
Текущий ответ по какой-то причине не сработал для меня правильно (параметры запроса, похоже, пропали), но оказывается, есть и способ сделать это, который не использует регулярные выражения:
server {
listen 80;
index index.html index.htm index.nginx-debian.html index.php;
server_name aaa.bbb.ccc.ddd;
location ^~ /app2/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://aaa.bbb.ccc.ddd:8001/;
}
}
Что делает это работающим и отличает от конфигурации в вопросе, так это два завершающих слэша. Как объясняется в документации nginx, если вы укажете фактический путь в директиве proxy_pass, то он переписывает запрос, заменяя ту часть пути, которая соответствует секции location, на то, что указано в proxy_pass. Завершающий слэш в proxy_pass активирует это поведение, а завершающий слэш в совпадении location необходим для получения правильных результатов.
Ответ или решение
Конечно! Давайте разберем, как настроить nginx
для работы с подкаталогом при проксировании на другой порт, чтобы всё работало безупречно.
Ваша цель — настроить nginx
так, чтобы при доступе к http://aaa.bbb.ccc.ddd/app2
запрос перенаправлялся на http://aaa.bbb.ccc.ddd:8001
, но при этом в адресной строке оставалось http://aaa.bbb.ccc.ddd/app2
.
Ваша первоначальная конфигурация имеет правильный подход, однако вам нужно немного изменить настройки location
и proxy_pass
. Правильная настройка может выглядеть следующим образом:
server {
listen 80;
index index.html index.htm index.nginx-debian.html index.php;
server_name aaa.bbb.ccc.ddd;
location ^~ /app2/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://aaa.bbb.ccc.ddd:8001/;
}
}
Объяснение изменений:
-
location ^~ /app2/: Этот блок определяет, что если URL начинается с
/app2/
, то nginx будет обрабатывать его в этом блоке. Обратите внимание на слэш, который следует заapp2
. Он важен для того, чтобы правильно проксировать запросы. -
proxy_pass http://aaa.bbb.ccc.ddd:8001/: Включение слэша в конце URL в
proxy_pass
указывает nginx, что нужно заменить часть пути, соответствующуюlocation
, на этот URL, сохраняя остальную часть URI. Это значит, что если у вас есть запрос кhttp://aaa.bbb.ccc.ddd/app2/some/path
, он будет отправлен наhttp://aaa.bbb.ccc.ddd:8001/some/path
.
Почему это работает:
-
При наличии слэша в
proxy_pass
, nginx будет добавлять оставшуюся часть пути после совпадения сlocation
. Это позволяет избегать проблем с потерей параметров запроса и корректным формированием URL. -
Если в запросе присутствуют параметры, они также будут корректно переданы на сервер, работающий на порту 8001.
Возможные проблемы:
Если у вас возникают проблемы при использовании данного подхода (например, параметры запроса не передаются), вы можете проверить логи nginx
для диагностики. Логи могут помочь определить, что именно происходит с вашими запросами.
Заключение:
Убедитесь, что ваши порты открыты и ваш сервер настроен на прослушивание внешних запросов. Этот метод позволит вам эффективно и удобно использовать подкаталоги для проксирования, избегая множества портов. Если у вас возникнут другие вопросы, не стесняйтесь спрашивать!