Хорошо, я думаю, что понял проблему.
Wordpress использует две переменные для определения:
- Какой URL-адрес ведет к местоположению вашего сайта WordPress (
WP_HOME
)
- Какой URL-адрес используется для загрузки ресурсов для вашего сайта WordPress (
WP_SITEURL
)
Первое, что мне нужно было сделать для контейнера WordPress, это убедиться, что эти URL-адреса соответствуют внутреннему URL-адресу контейнера, т.е. $БЛОГ_СЕРВЕР
. Поскольку я использую docker-compose, было легко ввести этот URL-адрес, используя переменные среды через WORDPRESS_CONFIG_EXTRA
аргумент.
wordpress-блог:
изображение: вордпресс: 5
зависит от:
- блог-БД
среда:
WORDPRESS_DB_HOST: БД блога
WORDPRESS_DB_NAME: блог
WORDPRESS_DB_USER: вордпресс
WORDPRESS_DB_PASSWORD: вордпресс
WORDPRESS_CONFIG_EXTRA: |
определить('WP_HOME', 'http://wordpress-blog');
определить('WP_SITEURL', 'http://wordpress-blog');
тома:
- вордпресс:/var/www/html
Теперь, когда это сделано, мы можем сосредоточиться на прокси.
Прежде чем я пошел по пути полного обратного прокси-сервера, я предполагал, что прокси-сервер каким-то образом возьмет на себя каждый запрос на /блог/
и возвращать страницы с прокси-сайта, которые будут выглядеть так, как будто они обслуживаются непосредственно из WordPress. Одна вещь, которую я не учел, заключалась в том, что это предположение также предполагало страницы, отображаемые на стороне сервера.
Начиная с нового Виртуальный хост
конфигурации, теперь это выглядит так:
<VirtualHost *:80>
ProxyPass "/blog/" "${BLOG_SERVER}/"
ProxyPass "/" "${REACT_SERVER}/"
<Location "/">
ProxyPreserveHost On
ProxyErrorOverride On
ProxyPassReverse "${DEV_SERVER}/"
</Location>
<Location "/blog/">
ProxyPreserveHost Off
ProxyPassReverse "${BLOG_SERVER}/"
ProxyPassReverseCookiePath "/" "/blog/"
ProxyErrorOverride On
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLURLMap "${BLOG_SERVER}/"
SetOutputFilter INFLATE;proxy-html;DEFLATE
# ProxyPassReverseCookieDomain "%{HTTP_HOST:${BLOG_SERVER}}" %{HTTP_HOST}
</Location>
</VirtualHost>
Следующее, что мне нужно было сделать, чтобы этот прокси начал вести себя как прокси, это добавить эту строку:
ProxyPreserveHost выключен
Это гарантирует, что все ответы/запросы, которые мы получаем от wordpress, не будут выглядеть так, как будто они пришли от нас (прокси). Причина этого скоро станет очевидной, когда мы начнем разбираться с проксированием html.
Далее ПроксиПасс
директивы были выведены из Место расположения
емкость и непосредственно в Виртуальный хост
.
ProxyPass "/блог/" "${BLOG_SERVER}/"
ProxyPass "/" "${REACT_SERVER}/"
Причина этого в том, что Место расположения
блоки очень поздно соответствовали запросам, а иногда /
путь побеждает /блог/
дорожка. Мне нужно было, чтобы было надежнее, поэтому я решил пойти с указанием прокси самостоятельно (я видел пример здесь), затем изменив пути внутри Место расположения
контейнер.
На данный момент обратный прокси теперь за работой! Однако в html на страницах были ссылки, которые указывали на внутренний URL-адрес сайта WordPress. Вот где mod_proxy_html входит. Его можно использовать для перезаписи всех ссылок в html, чтобы они указывали на обратный прокси. Везде, где он находит ссылку, указывающую на внутренний сайт блога, эта ссылка заменяется ссылкой, использующей обратный прокси-сервер.
ProxyHTMLEnable Вкл.
ProxyHTMLExtended On
ПроксиHTMLURLMap "${BLOG_SERVER}/"
SetOutputFilter INFLATE; прокси-html; DEFLATE
Последняя строка может стать узким местом, потому что она, по сути, распаковывает полезную нагрузку с сайта блога, переписывает все URL-адреса, чтобы они указывали на обратный прокси-сервер, а затем снова их сжимает. Если вы этого не хотите, другой способ сделать это - использовать:
RequestHeader не установлен Accept-Encoding
Даже со всем этим решение все еще не было совершенным, потому что любой файл javascript, загруженный на страницу, который делает запрос на внутренний сайт, не будет перенаправлять свои запросы на прокси.
Одним из решений этого было бы пойти с первым решением, предложенным текущий ответ по этому вопросу и изменить WP_SITEURL
чтобы указать на обратный прокси напрямую.
Еще одно решение заключается в использовании Сервисный работник к перехватывать сетевые запросы. Мне нравится это решение, потому что оно не связывает сайт блога с обратным прокси-сервером. Я мог представить, что это не будет слишком надуманной (хе-хе) идея внедрить работника службы в любые html-страницы, запрошенные с прокси-сервера, и заставить этого работника службы перехватывать все запросы, которые соответствуют внутреннему URL-адресу сайта блога, и заменить их с обратным URL-адресом прокси-сервера.
Я не пошел ни с одним из них. После долгих размышлений я думаю, что хостинг wordpress в поддомене будет лучше для моих нужд. Что-то вроде blog.example.com — это то, на что я мог бы пойти, но это будет работа для другого дня.
В заключение отметим, что обратные прокси трудно правильно реализовать с помощью Apache. Я не знаю, зеленее ли трава на стороне nginx, но, может быть, когда-нибудь мы это проверим. Решение, которое я выбрал, предполагало контент только на стороне сервера, который оказался бы идеальным кандидатом для проксирования, но, увы, динамически загружаемый контент потребует больше работы.
Источники
Модули Apache включены для проксирования html
Модули загрузки deflate_module modules/mod_deflate.so
LoadModule xml2enc_module modules/mod_xml2enc.so
LoadModule proxy_html_module modules/mod_proxy_html.so