Я настраиваю nginx как обратный прокси в контейнере докеров для ссылки на сайты за пределами контейнера. У меня есть настройка конфигурации vhost следующим образом (я пробовал добавить ^ ~ перед местом для домашнего помощника):
server { # simple reverse-proxy
listen 80;
location / {
proxy_pass http://192.168.1.99:6789;
}
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123/;
}
location /calibre-web/ {
proxy_pass http://192.168.1.99:8181/;
}
}
Как для сайтов home-assistant, так и для сайтов caliber-web страница загружается, но я получаю 404 ошибки для всех остальных элементов (изображений, CSS и т. Д.). Если я попытаюсь щелкнуть ссылку в приложениях, она свяжет меня с 192.168.1.99/file, а не с 192.168.1.99/site-folder/file, как следовало бы.. Ниже приведены несколько записей из журналов (обратите внимание на один ответ 200 и другие ответы 404). Что я здесь делаю не так? Заранее спасибо за помощь.
192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/dev-template-0a099d4589636ed3038a3e9f020468a7.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/logbook-66108d82763359a218c9695f0553de40.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:54 +0000] "GET /home-assistant/ HTTP/1.1" 200 1654 "-" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/icons/favicon-192x192.png HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/core-457d5acd123e7dc38947c07984b3a5e8.js HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
Вот копия моего корневого nginx.conf. Я предполагаю, что ошибка где-то здесь, я просто не могу понять где.
Вы пытаетесь отправлять запросы proxy_pass из местоположения, неизвестного исходному приложению. В приложении docker-контейнера все еще считается, что к нему обращаются из корня веб-сайта (http://192.168.1.99:8123/
), поэтому он генерирует все URL-адреса относительно /
не твоему /home-assistant/
или /calibre-web/
.
Есть множество способов решить эту проблему, вы должны выбрать то, что вам больше всего подходит:
Прежде всего, это замена каждой ссылки, полученной от прокси-приложения, перед отправкой результата клиенту возможна с ngx_http_sub_module. По умолчанию он не включен, поэтому вам, возможно, придется скомпилировать nginx из исходников если в вашем дистрибутиве его нет (чтобы проверить доступность этого модуля, запустите nginx -V
, который должен отображать --with-http_sub_module
где-то по параметрам конфигурации).
Если вы выберете этот метод, добавьте в конфигурацию следующие директивы:
location ^~ /home-assistant {
rewrite ^/home-assistant(/.*)$ $1 break;
proxy_pass http://192.168.1.99:8123/;
sub_filter "<head>" "<head><base href=\"${scheme}://${host}/home-assistant\">";
}
Перенос приложения из контейнера докеров в /home-assistant
вместо root, поэтому он будет генерировать все URL-адреса в обслуживаемом контенте, связанные с этим путем, вместо root /
. Это очевидное (и, вероятно, самое простое) решение, которое вообще не требует касания конфигураций nginx (вместо этого вы редактируете конфигурацию внутри докера)
Определение того, какой восходящий поток следует использовать на основе Referer
заголовок. Взято отсюда. Выглядит довольно умно, хотя я бы сам не стал использовать его в продакшене (обратите внимание, что он работает только для файлов css / js).
location ~* ^/(css|js)/.+\.(css|js)$ {
#checking if referer is from home-assistant
if ($http_referer ~ "^.*/home-assistant"){
return 417;
}
#checking if referer is from calibre-web
if ($http_referer ~ "^.*/calibre-web"){
return 418;
}
}
error_page 417 /home-assistant$request_uri;
error_page 418 /calibre-web$request_uri;
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123/;
}
location /calibre-web {
proxy_pass http://192.168.1.99:8181/;
}
На вашем месте я бы выбрал второй вариант - перемещение приложений внутри контейнера как самый простой и наименее подверженный ошибкам способ получить то, что вам нужно.
P.S. Я совершенно забыл, что вы можете обслуживать статические файлы прямо со своего жесткого диска, поскольку ваш бэкэнд находится на том же сервере, что и nginx. Это потребует некоторой настройки, зависящей от приложения, но в результате вы получите наиболее эффективное решение.
Одним из решений может быть не передавать URI в proxy_pass
директива:
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123;
}
location ^~ /calibre-web/ {
proxy_pass http://192.168.1.99:8181;
}
Обратите внимание на отсутствие /
символ после номера порта в proxy_pass
заявление. Это означает, что nginx будет передавать URI, отправленный на сервер, на сервер приложения.
С /
символ (URI), он заменит URI запроса этим.
Это поведение задокументировано в http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass