Вопрос или проблема
Я использую apache2 и mod-proxy для интеграции блогов WordPress в поддиректории моего TLD.
- Главный сайт: example.com
- Блог1: [http://example.com/blog]
- Блог2: [http://example.com/other-blog]
Виртуальный хост Apache2 для основного сайта с прокси:
<VirtualHost *:80>
ServerName example.com
...
# Правило перенаправления для добавления отсутствующих слэшей
RewriteRule ^/blog$ /blog/ [R=301]
RewriteRule ^/other-blog$ /other-blog/ [R=301]
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyRequests off
ProxyPass /blog/ http://blog1.localhost/
ProxyPassReverse /blog/ http://blog1.localhost/
ProxyPass /other-blog/ http://blog2.localhost/
ProxyPassReverse /other-blog/ http://blog2.localhost/
...
</VirtualHost>
Виртуальные хосты Apache2 для блогов:
<VirtualHost *:80>
ServerName blog1.localhost
DocumentRoot /var/www/blog1/
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>
Добавление строк в файл hosts Linux:
127.0.0.1 blog1.localhost localhost.localdomain
127.0.0.1 blog2.localhost localhost.localdomain
WordPress: Настройки > Общие настройки:
- Адрес WordPress (URL): [http://example.com/blog]
- Адрес сайта (URL): [http://example.com/blog]
Файл .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Эта настройка в целом работает нормально. К сожалению, у бэк-энда WordPress возникают проблемы в некоторых частях, так как подкаталоги удаляются из URL, что приводит к проблемам с сохранением настроек или загрузкой изображений. Например:
- Использует: [http://example.com/wp-admin/…]
- Должен использовать: [http://example.com/blog/wp-admin/…]
или
- Использует: [http://example.com/wp-content/…]
- Должен использовать: [http://example.com/blog/wp-content/…]
Что я пробовал сделать:
- использовал различные предложенные правила перенаправления
- использовал различные модификации в wp-config.php из: http://codex.wordpress.org/Editing_wp-config.php#WordPress_address_.28URL.29 *
- искал неправильные URL в базе данных mySQL
Ничего из этого не помогло или даже ухудшило ситуацию.
Если у кого-то есть идея, как решить эту проблему, буду очень признателен.
*) Редактирование: Что я уже пробовал здесь:
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/blog');
define('WP_HOME', 'http://example.com/blog');
define('WP_SITEURL', 'http://example.com' . $_SERVER['SERVER_NAME'] . '/blog');
define('WP_SITEURL', 'http://' . $_SERVER['SERVER_NAME'] . '/blog');
define('WP_SITEURL', 'http://example.com/blog/');
Абсолютные (и неправильные) пути содержатся в контенте, сгенерированном WordPress — невозможно их переписать с помощью Apache (как Apache узнает, о каком блоге идет речь, когда клиент запрашивает /wp-content
?).
Изменение URL сайта в конфигурации WordPress – правильный путь.
Для экземпляра блог1:
define('WP_SITEURL', 'http://example.com/blog');
Для экземпляра блог2:
define('WP_SITEURL', 'http://example.com/other-blog');
Что вы пробовали, и какое поведение наблюдали?
На февраль 2025 года WordPress не полностью готов к запуску в подкаталоге “из коробки”.
Первым шагом обязательно должна быть настройка URL сайта и URL домашней страницы в wp-config.php
, включая подкаталог, в котором расположены файлы WordPress:
const WP_SITEURL = 'https://example.com/subfolder';
const WP_HOME = WP_SITEURL;
Но ядро WordPress, а также различные плагины нужно патчить, чтобы они не предполагали, что сайт работает в корне домена.
Вам придется найти и исправить неверные предположения в разных частях кодовой базы по мере их обнаружения.
К счастью, исправить это обычно довольно просто. В следующем примере показаны необходимые исправления для wp-login.php
:
diff --git a/wp-login.php b/wp-login.php
index 16faccb70..b193f6a26 100644
--- a/wp-login.php
+++ b/wp-login.php
@@ -831,7 +831,7 @@ switch ( $action ) {
$errors = retrieve_password();
if ( ! is_wp_error( $errors ) ) {
- $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
+ $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : site_url( 'wp-login.php?checkemail=confirm', 'login' );
wp_safe_redirect( $redirect_to );
exit;
}
@@ -930,13 +930,14 @@ switch ( $action ) {
case 'resetpass':
case 'rp':
list( $rp_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
+ $rp_path = site_url( $rp_path );
$rp_cookie="wp-resetpass-" . COOKIEHASH;
if ( isset( $_GET['key'] ) && isset( $_GET['login'] ) ) {
$value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['key'] ) );
setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
- wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
+ wp_safe_redirect( site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' ) );
exit;
}
По сути, вам нужно найти места, где генерируется ссылка или URL для перенаправления без учета URL сайта, и обернуть их в site_url( ..., 'login')
, например:
-'wp-login.php?checkemail=confirm'
+site_url( 'wp-login.php?checkemail=confirm', 'login' )
-remove_query_arg( array( 'key', 'login' ) )
+site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' )
(Второй аргумент 'login'
применяется только в случае изменений в wp-login.php
и обычно его нужно опустить в других местах.)
Я отправлю патчи для ядра WordPress, WooCommerce и Elementor в ближайшие дни.
Возможно, вам нужно переместить ваши установки WordPress в поддиректорию, чтобы решить эту проблему. После этого измените ваши правила перенаправления, чтобы они выглядели примерно так:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog1/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog1/index.php [L]
</IfModule>
.
Ответ или решение
Конфигурация WordPress с использованием подкаталогов и прокси на базе Apache может быть сложной задачей, особенно когда возникают проблемы с неправильными URL-адресами в админке (wp-admin) и контенте (wp-content). Давайте подробно разберем возможные решения этой проблемы в контексте WordPress, размещенного в подкаталогах через Apache2 и mod_proxy.
Теория
Когда вы используете подкаталоги для размещения различных экземпляров WordPress через прокси-сервер Apache, вы по существу обеспечиваете маршрутизацию запросов через ваш основной домен (например, example.com) к локальным адресам (например, blog1.localhost, blog2.localhost). Каждый из этих подкаталогов должен правильно обрабатывать и модифицировать структуру URL, чтобы WordPress мог правильно интерпретировать и обрабатывать запросы.
Основная проблема, с которой вы столкнулись, связана с тем, что без дополнительных настроек WordPress пытается генерировать URL с корнем вашего основного домена (например, /wp-admin/ вместо /blog/wp-admin/), что приводит к неправильным маршрутам и ошибкам загрузки контента.
Пример
Рассмотрим вашу текущую установку. Вы настроили виртуальные хосты Apache таким образом, чтобы main site и два блоговых сайта были доступны через подкаталоги:
<VirtualHost *:80>
ServerName example.com
RewriteRule ^/blog$ /blog/ [R=301]
RewriteRule ^/other-blog$ /other-blog/ [R=301]
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyRequests off
ProxyPass /blog/ http://blog1.localhost/
ProxyPassReverse /blog/ http://blog1.localhost/
ProxyPass /other-blog/ http://blog2.localhost/
ProxyPassReverse /other-blog/ http://blog2.localhost/
</VirtualHost>
Базовая конфигурация предполагает перенаправление запросов из корневого домена в нужные подкаталоги. Однако, важной частью является правильная настройка WordPress URL.
Применение
-
Настройка wp-config.php: Убедитесь, что вы правильно указали переменные WP_SITEURL и WP_HOME в файле wp-config.php для каждого экземпляра WordPress. Это ключевой шаг, поскольку эти параметры определяют, как WordPress будет воспринимать базовый адрес сайта.
Для первого блога:
define('WP_SITEURL', 'http://example.com/blog'); define('WP_HOME', 'http://example.com/blog');
Для второго блога:
define('WP_SITEURL', 'http://example.com/other-blog'); define('WP_HOME', 'http://example.com/other-blog');
-
Исправление кода WordPress: WordPress и сторонние плагины не всегда готовы работать в подкаталогах без дополнительных исправлений в коде. Рассмотрите возможность корректировки кода, особенно если вы видите, что URL-адреса генерируются неправильно. Например, проверьте файлы вроде wp-login.php и подобные, чтобы убедиться, что URL-адреса всегда включают в себя ваш подкаталог:
Пример исправления в
wp-login.php
:- wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) ); + wp_safe_redirect( site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' ) );
-
Переписывание правил .htaccess: Убедитесь, что ваш файл .htaccess настроен правильно для каждого блога. Например, для первого блога:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /blog/ RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /blog/index.php [L] </IfModule>
-
Проверка базы данных: Иногда проблема может заключаться в сохраненных настройках URL в базе данных. Проверьте таблицы, такие как wp_options, на наличие неправильных URL и исправьте их вручную, если это необходимо.
-
Тестирование и отладка: После внесения изменений убедитесь, что протестированы все разделы сайта на наличие остаточных ошибок в ссылках или проблем с загрузкой. Используйте инструменты разработчика в вашем браузере для отладки сетевых запросов и посмотрите, какие URL вызываются неправильно.
-
Обновление и исправление кода: Если изменения в конфигурации и коде не помогают, возможно, стоит составить перечень участков кода, вызывающих проблемы, и предложить исправления или патчи команде WordPress, если такие репортировать невозможно.
Заключение
Развертывание WordPress в подкаталогах при помощи прокси-сервера может требовать значительных усилий, особенно из-за необходимости вносить изменения и исправления не только в конфигурационные файлы, но и в сам исходный код WordPress и его плагинов. Тем не менее, соблюдение надлежащей конфигурации, отладка и внимательное отношение к разветвленной настройке системы помогут вам достичь желаемого результата. Если вы сталкиваетесь с проблемами, которые не можете решить самостоятельно, рассмотрите возможность обращения за помощью к сообществу WordPress или к профессиональным консультантам.