Multisite WordPress: Настройка сети сайтов с общими пользователями

Когда нужно управлять несколькими WordPress-сайтами с общим кодом и пользователями, установка отдельных копий WordPress для каждого проекта становится неэффективной. WordPress Multisite (ранее известный как WordPress MU) решает эту проблему, позволяя создавать неограниченное количество сайтов в рамках одной установки с общей базой данных, темами и плагинами.

В этом руководстве настраивается полноценная Multisite-сеть: от выбора схемы (поддомены vs подпапки) до конфигурации Nginx, domain mapping и оптимизации производительности. Такой подход используется в корпоративных порталах, образовательных платформах и веб-студиях для управления клиентскими сайтами.

Когда использовать Multisite, а когда нет

Multisite — не универсальное решение. Перед включением стоит оценить, подходит ли он для конкретной задачи.

Multisite подходит, если:

  • Нужно управлять 10+ сайтами с одинаковой структурой (франшизы, филиалы)
  • Пользователи должны иметь единый аккаунт для всех сайтов (SSO-эффект)
  • Требуется централизованное управление темами и плагинами
  • Сайты используют общую базу пользователей (корпоративный портал)
  • Бюджет ограничен — один VPS вместо нескольких хостингов

Multisite НЕ подходит, если:

  • Сайты сильно различаются по функциональности (разные плагины, темы)
  • Нужна полная изоляция (один скомпрометированный сайт = вся сеть под угрозой)
  • Требуется независимое масштабирование (один сайт нагружен, другие нет)
  • Клиенты хотят полный доступ к файлам и базе данных своего сайта

Для агентств с разнородными проектами лучше использовать отдельные Docker-контейнеры для каждого сайта. Multisite идеален для однотипных проектов с общим управлением.

Шаг 1: Выбор схемы сети

WordPress Multisite поддерживает два варианта организации сайтов:

Вариант А: Поддомены (subdomains)

Каждый сайт получает свой поддомен: site1.custom-code.ru, site2.custom-code.ru.

  • Плюсы: каждый сайт выглядит как отдельный домен, проще с SEO, нет конфликтов URL
  • Минусы: нужен wildcard SSL-сертификат, сложнее настройка DNS
  • Идеально для: публичных сайтов, клиентских проектов

Вариант Б: Подпапки (subdirectories)

Сайты размещаются в подпапках основного домена: custom-code.ru/site1, custom-code.ru/site2.

  • Плюсы: простая настройка, один SSL-сертификат, общий domain authority
  • Минусы: могут быть конфликты URL, сложнее с брендингом
  • Идеально для: внутренних порталов, блогов с разделами

Выбор схемы делается до включения Multisite и не может быть изменён без полной переустановки сети. Для продакшна рекомендуется вариант с поддоменами — он более гибкий и масштабируемый.

Шаг 2: Подготовка сервера

Multisite создаёт дополнительную нагрузку на сервер, особенно при большом количестве сайтов. Перед настройкой убеждаемся, что инфраструктура готова.

Требования к серверу:

  • RAM: минимум 2 ГБ для сети до 10 сайтов, 4+ ГБ для 50+ сайтов
  • CPU: 2+ ядра (каждый сайт генерирует отдельные запросы)
  • Диск: SSD/NVMe (много мелких файлов в wp-content/uploads/sites/)
  • База данных: оптимизированная MariaDB/MySQL с увеличенным innodb_buffer_pool_size

Настройка PHP-FPM:

Multisite потребляет больше памяти, чем одиночный WordPress. Увеличиваем лимиты в www.conf:

; Увеличиваем память для каждого процесса
php_admin_value[memory_limit] = 512M

; Увеличиваем количество процессов (каждый сайт может создавать свои процессы)
pm.max_children = 50
pm.start_servers = 15
pm.min_spare_servers = 10
pm.max_spare_servers = 20

Детальный расчёт параметров пула процессов приведён в руководстве по оптимизации PHP-FPM.

Настройка MySQL/MariaDB:

Multisite создаёт отдельные таблицы для каждого сайта (wp_2_posts, wp_3_posts и т.д.), что увеличивает размер базы данных в разы. Критичные параметры в my.cnf:

[mysqld]
; Увеличиваем буферный пул (60-70% от RAM)
innodb_buffer_pool_size = 3G

; Увеличиваем максимальное количество соединений
max_connections = 100

; Увеличиваем размер пакета для больших импортов
max_allowed_packet = 128M

Шаг 3: Включение Multisite в wp-config.php

Перед включением создаём полный бэкап сайта и базы данных. Процесс настройки описан в руководстве по автоматическому резервному копированию.

Открываем wp-config.php и добавляем константы перед строкой /* That's all, stop editing! */:

// Включаем Multisite
define( 'WP_ALLOW_MULTISITE', true );

// После настройки сети добавляем эти строки (WordPress сгенерирует их автоматически)
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', true ); // true для поддоменов, false для подпапок
define( 'DOMAIN_CURRENT_SITE', 'custom-code.ru' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );

// Опционально: разрешить регистрацию новых сайтов
define( 'WP_ALLOW_SIGNUP', true );

После добавления WP_ALLOW_MULTISITE переходим в админку: Инструменты → Настройка сети. WordPress предложит выбрать схему и сгенерирует код для wp-config.php и .htaccess.

Шаг 4: Настройка Nginx для Multisite

Для схемы с поддоменами нужен wildcard-домен и правильный конфиг Nginx. Создаём файл /etc/nginx/sites-available/multisite:

server {
    listen 80;
    server_name custom-code.ru *.custom-code.ru;
    root /var/www/wordpress;
    index index.php;

    client_max_body_size 128M;

    # Multisite rewrite rules для поддоменов
    if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^(/[^/]+)?(/wp-.*) $2 last;
        rewrite ^(/[^/]+)?(/.*\.php) $2 last;
    }

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
    }

    # Защита wp-config.php
    location ~* wp-config\.php {
        deny all;
    }

    # Кэширование статики
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Запрет доступа к скрытым файлам
    location ~ /\. {
        deny all;
    }
}

Для схемы с подпапками конфиг проще — не нужен wildcard, достаточно стандартных rewrite rules из генератора WordPress.

Шаг 5: Настройка Wildcard SSL через Let’s Encrypt

Для поддоменов нужен wildcard SSL-сертификат, который покрывает *.custom-code.ru. Certbot поддерживает это через DNS-проверку:

# Установка плагина для DNS-проверки (пример для Cloudflare)
sudo apt install python3-certbot-dns-cloudflare

# Создание файла с credentials
sudo nano /etc/letsencrypt/cloudflare.ini
# Содержание:
# dns_cloudflare_api_token = your_api_token_here

sudo chmod 600 /etc/letsencrypt/cloudflare.ini

# Получение wildcard сертификата
sudo certbot certonly \
    --dns-cloudflare \
    --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
    -d custom-code.ru \
    -d *.custom-code.ru

После получения сертификата обновляем конфиг Nginx, добавляя SSL-директивы. Детальная настройка HTTPS описана в руководстве по Nginx reverse proxy.

Шаг 6: Domain Mapping (привязка своих доменов)

По умолчанию все сайты в сети используют поддомены основного домена. Но клиентам часто нужны свои домены (client-site.ru вместо client.custom-code.ru). Для этого используется domain mapping.

Настройка DNS:

Клиент добавляет CNAME-запись у своего регистратора:

# На стороне клиента
client-site.ru.    CNAME    custom-code.ru.

Настройка Nginx:

Добавляем домен клиента в server_name:

server {
    listen 80;
    server_name custom-code.ru *.custom-code.ru client-site.ru www.client-site.ru;
    # ... остальные настройки
}

Привязка в админке WordPress:

Переходим в Мои сайты → Управление сетью → Сайты, выбираем нужный сайт и во вкладке «Настройки» указываем домен клиента в поле «Домен сайта».

Начиная с WordPress 4.5, domain mapping встроен в ядро и не требует дополнительных плагинов. Для автоматического выпуска SSL-сертификатов для доменов клиентов используется Certbot с флагом --expand или скрипт, который добавляет новые домены в конфиг Nginx и запрашивает сертификаты.

Шаг 7: Управление пользователями и правами

В Multisite есть три уровня пользователей:

  • Super Admin — полный доступ ко всей сети, управление плагинами и темами
  • Администратор сайта — управление только своим сайтом
  • Обычные пользователи — редакторы, авторы, подписчики

Регистрация пользователей:

По умолчанию новые пользователи могут регистрироваться только на основном сайте. Чтобы разрешить регистрацию на всех сайтах, добавляем в wp-config.php:

// Разрешить регистрацию новых сайтов (создаётся новый сайт + пользователь)
define( 'WP_ALLOW_SIGNUP', true );

// Или только регистрацию пользователей (без создания сайтов)
// В админке: Настройки сети → Разрешить регистрацию новых пользователей

Добавление существующего пользователя на другой сайт:

Администратор сайта может добавить пользователя, который уже зарегистрирован в сети. Переходим в Пользователи → Добавить существующего и вводим email пользователя.

Ограничение возможностей администраторов сайтов:

По умолчанию администраторы отдельных сайтов не могут устанавливать плагины и темы — это прерогатива Super Admin. Это сделано для безопасности сети. Если нужно дать больше прав, используется плагин User Role Editor или кастомный код:

// Разрешить администраторам сайтов устанавливать плагины
add_filter( 'map_meta_cap', function( $caps, $cap, $user_id ) {
    if ( in_array( $cap, array( 'install_plugins', 'install_themes', 'edit_themes', 'edit_plugins' ) ) ) {
        $user = get_userdata( $user_id );
        if ( $user && in_array( 'administrator', $user->roles ) ) {
            return array( 'manage_options' );
        }
    }
    return $caps;
}, 10, 3 );

Шаг 8: Управление темами и плагинами в сети

В Multisite темы и плагины устанавливаются один раз и могут быть активированы на любом сайте сети.

Сетевая активация плагинов:

Некоторые плагины (например, кэширование, безопасность) должны работать на всех сайтах. Переходим в Мои сайты → Управление сетью → Плагины и нажимаем «Активировать для сети».

Плагин, активированный для сети, нельзя отключить на отдельных сайтах — он работает везде.

Разрешение установки для администраторов сайтов:

По умолчанию только Super Admin может устанавливать новые плагины. Чтобы дать эту возможность администраторам отдельных сайтов, включаем опцию в Настройки сети → Разрешить администраторам сайтов устанавливать плагины.

Управление темами:

Темы работают аналогично плагинам. Можно:

  • Активировать тему для всей сети (все сайты будут использовать её)
  • Разрешить тему для сети (администраторы сайтов смогут её выбрать)
  • Запретить тему (она не будет доступна для активации)

Шаг 9: Оптимизация производительности Multisite

Multisite создаёт дополнительную нагрузку на сервер. Без оптимизации сеть из 50+ сайтов будет работать медленно.

1. Включение Redis Object Cache:

Object Cache критичен для Multisite, так как каждый сайт делает много одинаковых запросов к общим таблицам (wp_options, wp_users). Настройка Redis Object Cache описана в отдельном руководстве.

// В wp-config.php для каждого сайта
define( 'WP_REDIS_DATABASE', 0 ); // Можно использовать разные БД для разных сайтов

2. Кэширование страниц через Nginx FastCGI Cache:

FastCGI Cache кэширует HTML-страницы на уровне веб-сервера, снижая нагрузку на PHP-FPM. Для Multisite нужно настроить кэш так, чтобы каждый сайт имел свой namespace:

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=MULTISITE:100m inactive=60m;

# В location ~ \.php$
fastcgi_cache MULTISITE;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

3. Разделение базы данных (для крупных сетей):

Если в сети больше 100 сайтов, одна база данных становится узким местом. Используется плагин HyperDB от Automattic, который распределяет таблицы сайтов по нескольким базам данных.

// В wp-config.php
$wpdb->add_database( array(
    'host'     => 'db2.custom-code.ru',
    'user'     => 'wp_user',
    'password' => 'password',
    'name'     => 'wordpress_sites_1_50',
    'dataset'  => 'global',
) );

4. Оптимизация таблицы wp_options:

В Multisite таблица wp_options общая для всех сайтов и быстро растёт. Регулярно очищаем транзенты и автозагружаемые опции:

# Удаление просроченных транзентов
wp transient delete --all

# Поиск больших автозагружаемых опций
wp db query "SELECT option_name, LENGTH(option_value) as size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 20;"

Шаг 10: Мониторинг и обслуживание

Multisite требует регулярного обслуживания. Настраиваем автоматические проверки через WP-CLI и системный cron.

Список всех сайтов в сети:

# Получить все сайты
wp site list --fields=blog_id,url,registered,last_updated

# Поиск неактивных сайтов (не обновлялись больше года)
wp site list --fields=url --format=csv | tail -n +2 | while read url; do
    last_update=$(wp site meta get $url last_updated 2>/dev/null)
    if [ -z "$last_update" ] || [ "$last_update" -lt $(date -d "1 year ago" +%s) ]; then
        echo "Inactive: $url"
    fi
done

Массовое обновление плагинов во всей сети:

# Обновить все плагины для всех сайтов
wp site list --field=url | xargs -I {} wp plugin update --all --url={}

Бэкап всей сети:

Стандартный скрипт бэкапа, описанный в руководстве по резервному копированию, работает и для Multisite. Но нужно учитывать, что папка wp-content/uploads/sites/ может занимать десятки гигабайт. Используем инкрементальные бэкапы для файлов и полные бэкапы только для базы данных.

Чек-лист настройки Multisite

  • ✅ Выбрана схема сети (поддомены или подпапки)
  • ✅ Сервер подготовлен (увеличены лимиты PHP-FPM и MySQL)
  • ✅ Multisite включён в wp-config.php
  • ✅ Nginx настроен для wildcard-доменов
  • ✅ Получен wildcard SSL-сертификат
  • ✅ Настроен domain mapping для клиентских доменов
  • ✅ Включён Redis Object Cache
  • ✅ Настроено кэширование страниц через FastCGI Cache
  • ✅ Созданы роли и права для администраторов сайтов
  • ✅ Настроен мониторинг через WP-CLI

Решение частых проблем

Ошибка «Error establishing a database connection» при создании нового сайта

Multisite создаёт новые таблицы для каждого сайта. Если max_connections в MySQL слишком низкий, новые соединения отклоняются. Увеличиваем до 100-150 и перезапускаем MySQL.

Сайты в сети не загружаются (404 или белый экран)

Проверяем rewrite rules в Nginx. Для поддоменов критичны правила:
rewrite ^(/[^/]+)?(/wp-.*) $2 last;
Если они отсутствуют или неправильные, WordPress не может найти файлы. Также убеждаемся, что SUBDOMAIN_INSTALL в wp-config.php соответствует реальной схеме сети.

Медленная работа админки при большом количестве сайтов

Страница «Все сайты» в сетевой админке загружает данные всех сайтов. При 500+ сайтах это может занимать 10+ секунд. Решения:

  • Использовать поиск и фильтры вместо прокрутки всего списка
  • Увеличить memory_limit до 512M
  • Включить Object Cache для кэширования запросов к таблице wp_blogs

Проблемы с загрузкой медиафайлов на подсайтах

В Multisite медиафайлы хранятся в wp-content/uploads/sites/{blog_id}/. Если права на эту папку неправильные, загрузка не работает:

sudo chown -R www-data:www-data /var/www/wordpress/wp-content/uploads/sites
sudo find /var/www/wordpress/wp-content/uploads/sites -type d -exec chmod 755 {} \;
sudo find /var/www/wordpress/wp-content/uploads/sites -type f -exec chmod 644 {} \;

Плагин не работает в Multisite

Не все плагины поддерживают Multisite. Если плагин не работает на подсайтах, проверяем:

  • Активирован ли он для сети или для конкретного сайта
  • Использует ли он $wpdb->prefix вместо жёстко прописанного wp_
  • Есть ли у него настройка «Network Activate» в документации

Для критичных плагинов, которые не поддерживают Multisite, рассматриваем альтернативы или используем отдельные установки WordPress для проектов, требующих специфичный функционал.

Итог

WordPress Multisite — мощный инструмент для управления сетью сайтов из одной установки. Правильная настройка серверной инфраструктуры (Nginx, PHP-FPM, MySQL), включение Object Cache и FastCGI Cache позволяют сети из сотен сайтов работать быстро и стабильно. Multisite идеален для агентств, корпоративных порталов и образовательных платформ, где важна централизация управления при сохранении независимости отдельных проектов.