Мультисайтинг на Друпале - это круто!

Изображение пользователя andyceo.

Импульсом к написанию этой статьи стала потребность в мультисайтинге, идеей чего я озаботился сразу после прочтения статей

Мультисайтинг – как и зачем , автор jerboa7,
Мультисайтинг - это просто, автор Макс Кириленко,
а чуть позже к ним присоединился и Mультисайтинг. В который раз. :) автора andron13

и усвоил мысль, что если хочешь потом сделать мультисайтинг, то лучше его делать сразу.

Базовые вещи, которые необходимо знать для того чтобы организовать мультисайтинг на Друпале, я почерпнул из вышеуказанных статей. Поэтому подробно останавливаться на самом процессе, я не буду. Просто позволю себе написать еще одну статью о мультисайтинге.

1. Установка Друпал
Паркуем на хостинг наш домен сайт1. Этот домен будет указывать на какую-то директорию на Вашем сайте, которая для него будет являться базовой. В эту директорию на хостинге копируем Друпал - распаковываем его из архива.
Заводим новую БД на хостинге. Её будет использовать Друпал. Завели? Теперь у нас есть База Данных:

Имя БД: БД_сайт1
Пользователь БД: юзер_БД_сайт1
Пароль пользователя: пароль_БД_сайт1

У пользователя юзер_БД_сайт1, само собой, должны быть выставлены привелегии, позволяющие ему полный доступ к базе данных БД_сайт1.

Также у Вас есть файл settings.php, находящийся в подпапке sites/default/settings.php. В нем прописываются все необходимые параметры базы данных, нужные для работы Друпал. Заполните его, в соответствии с инструкциями, расположенными в нем в комментариях, и описанными ниже.

Строка доступа к базе данных, выглядит так:

$db_url = 'mysql://юзер_БД_сайт1:пароль_БД_сайт1@localhost/БД_сайт1';

Еще мы должны задать префикс таблиц. Это означает, в самом простом случае, что к имени таблицы в БД будет приписываться в начале некий префикс:

$db_prefix = 'префикссайт1_';

т.е. таблица с именем, скажем, sequences будет префикссайт1_sequences. Я рекомендую в конце префикса ставить знак подчёркивания "_", чтобы отделять префикс от собственно имени таблицы.

Префикс можно не задавать:

$db_prefix = '';

однако я не рекомендую этого делать. Подумайте о возможной SQL атаке? Или просто о попытках взломать ваш сервер. Хакеру не трудно будет догадаться, что Вы используете Друпал. Ну а с какими именами Друпал создаёт таблицы, тоже хорошо всем известно. Поэтому Вы затрудните доступ к Вашим таблицам, если вначале каждой пропишите префикс из случайной последовательности символов.

А теперь информация для самых ретивых: задавая префикс таблиц не в виде

$db_prefix = 'префикссайт1_';

а в виде

$db_prefix = 'префикссайт1.';

Вы на самом деле указываете Друпал, что он должен обращаться к базе данных "префикссайт1", вместо БД_сайт1! Поэтому будьте предусмотрительны при выборе разделителя префикса и имени таблицы. Самое удобное, на мой взгляд, использовать "_" - знак подчёркивания.

Однако и это ещё не все о префиксах. Друпал позволяет для каждой из таблиц задать отдельный префикс. Выглядит это так:

$db_prefix = array (
'default'   => 'main_',
'users'     => 'shared_',
'sessions'  => 'shared_',
'role'      => 'shared_',
'authmap'   => 'shared_',
'sequences' => 'shared_',
);

Зачем это надо? Если Вы ставите 1 сайт и уверены, что больше Вам никогда не понадобиться, то не забивайте себе голову. Ну позволяет это Друпал, ну и позволяет, Вам-то что?

Однако если когда-нибудь Вы запланируете поставить ещё один сайт, (о чем и пойдёт дальше речь), да так, чтобы не копировать ещё раз все скрипты (ядро и модули), да чтобы использовать какую-нибудь информацию, которая у Вас уже есть в БД (например, переводы Друпала и модулей, или данные самописных модулей, или данные из общих таблиц, созданных вообще другими скриптами) - то эта возможность очень даже пригодится... Но обо всем по порядку.

Итак, сайт1 мы поставили, запустили, работает - все замечательно! И вот в один прекрасный день...

2. Возникает потребность в новом сайте на Друпале, хотим организовать его на том же хостинге. Имя сайта - сайт2.
Паркуем на хостинг наш новый домен сайт2. Домен должен указывать на ту директорию, в которую вы ранее скопировали/поставили Друпал (в нашем примере - на директорию с сайт1).

Если после парковки домена при переходе на него мы попадаем на сайт1. (Так должно быть, если этого не происходит, значит что-то сделано не так.)

Создаём директорию sites/сайт2, копируем в него файл settings.php и правим его в соответствии с нуждами нашего сайт2:

задаем параметры доступа к БД,
прописываем другой (не такой как у сайт1) префикс таблиц для сайт2.

Переходим опять по нашему новому адресу сайт2 - и видим, что Друпал сыпется ошибками. И правильно, ведь никаких таблиц в БД сейчас нет. В БД сейчас есть только таблицы для сайт1. Друпал думает, что у нас уже установлен сайт2, и пытается сгенерировать главную страницу, но обламывается. Вот так вот, сгенерив страницу с ошибками, Друпал кэширует её. Если вы попробуете перейти опять по новому адресу, то увидите страницу с ошибками опять. Однако нам пока главная страница не нужна.

Перейдём на страницу установки Друпала для сайта2, т.е. перейдем на сайт2/install.php - скрипт установки отработает, создав нужные таблицы и прописав все необходимые связи между ними. Если какие-то таблицы уже существуют, они перезаписаны не будут, и никаких повреждений в них не будет, однако Друпал сообщит об ошибке при создании этих таблиц.

Перейдём на главную страницу свежесозданного сайта - сайт2. Видим опять всяческие сообщения об ошибке. Это отображается закэшированная ранее страница. Обновите ее - и о чудо! - видим первую страницу Друпала для сайта2 с инструкциями.

Т.е. у нас получилось два сайта, использующие одни и те же скрипты и одну и ту же БД, но разные таблицы в БД. Очень удобно.

А теперь помните, что если бы в качестве разделителя префикса таблиц указали не знак подчёркивания, "_", а точку - ".", то Друпал обращался бы не к базе данных "БД_сайт1", а к базе "префикссайт2"? Это можно использовать, если вы хотите чтобы для разных сайтов использовалась разная БД, но был один и тот же пользователь БД и пароль (такая задача часто возникает при объединении таблиц, о чем речь пойдёт дальше). Конечно можно просто задать разные параметры для БД для сайт2.

Но давайте представим, что у Вас...

3. Возникает понимание, что некоторую информацию сайта1 и сайта2 неплохо бы объединить. Например сделать общих пользователей.

Вот здесь-то и проявляется вся гибкость и мощь Друпала, здесь-то мы и осознаем в полной мере, насколько удобно задавать разным таблицам разные префиксы, и как Друпал умеет работать с разными БД.

Сделать общим можно все! Начиная от пользователей и заканчивая документами (нодами). Но если общих пользователей я ещё могу понять и принять, то делать общие документы между сайтами я не вижу смысла - тогда чем будет отличаться один сайт от другого? Только дизайном? Поэтому, после некоторого тестинга, я пришёл к выводу, что объединить без ущерба нарушения целостности БД и психики можно:

  1. Пользователей,
  2. Роли пользователей и права ролей
  3. Профили пользователей
  4. Переводы ядра и модулей
  5. Словари
  6. Термины в словарях
  7. Фильтры сообщений - насчет этого уже не уверен, т.к. таблица filter_formats привязывается к кэшу (поле cash), а таблица filters использует id фильтра из таблицы filter_formats, таким образом, обе таблицы фильтров привязаны к конкретному сайту.

Т.е. вообще все таблицы и модули, в которых нет жёсткой привязки к документам (нодам).

Также сразу скажу, что задача объединения словарей и терминов в них (модуль таксономии) может возникнуть только на очень тесных и близких по тематике сайтах. Я объединил словари и попробовал использовать в таком режиме документы, это оказалось очень неудобным и нецелесообразным. Поэтому мы не будем это рассматривать в этой статье. Остальные же вещи, удалось объединить очень даже удобно.

Итак, чтобы сделать общих пользователей, нам нужно сделать для сайтов общие таблицы пользователей. Допустим, что у нас уже есть сайт1, и новый сайт сайт2, и мы осознали что неплохо было бы, если пользователь зарегистрировался на каком-либо из этих сайтов, имел бы доступ и к другому.

За пользователей у нас в Друпале отвечают следующие таблицы:

'authmap'
'sessions'
'sequences'
'users'

Таблица users - непосредственно хранит данные пользователя.
Таблица sequences - хранит служебную информацию Друпал. Для каждой таблицы, в sequences сохраняется её имя, и следующее значение первичного ключа. (Если вообще планируете сделать что-то общее для каких-то двух сайтов, таблицу sequences рекомендую делать общей при любом раскладе).
Таблица sessions хранит информацию текущих сессий пользователя.
Таблица authmap я не знаю пока чего хранит.

Помимо вышеперечисленных таблиц, для пользователей существуют роли:

'role'
'users_roles'

При этом в таблице role хранится для каждого сайта информация о ролях пользователей, а в таблице users_roles - информация, какой пользователь к какой группе (роли) принадлежит. Скажу сразу, что если Вы хотите сделать так, чтобы роли для каждого сайта были абсолютно независимы, то Вам не нужно делать общей таблицу role. Таблицу users_roles можно сделать общей, если Вы делаете общих пользователей. Я же, потестив немного, нашёл, что очень удобно когда роли пользователей общие для всех сайтов, т.к. не нужно по 10, или сколько у вас там сайтов, раз заводить одни и те же роли: вот этим пользователям можно то, а этим это.

Profile module. Если у Вас включён модуль профилей для пользователей, тогда его таблицы тоже имеет смысл сделать общими:

'profile_fields' - хранит информацию о полях профиля
'profile_values' - хранит информацию поля.

Locale module. Модуль локализации. Одна из удобнейших возможностей - использовать общую таблицу локализации, т.к. переводы всего и вся можно залить один раз и потом просто выбирать из админки нужного сайта.
'locales_meta'
'locales_source'
'locales_target'

BUEditor Module. Это я привел чисто для примера. Любой модуль, не использующий привязку к документам, может быть объединён. Строго говоря, то же верно и для любого модуля, жёстко привязанного к документам, просто в нем надо найти таблицу связей для модуля и документов, и не делать её общей. Для модуля BUEditor таких таблиц нет, поэтому смело объединяем:
'bueditor_buttons'
'bueditor_editors'

Что нужно, чтобы использовать на сайт2 эти таблицы, которые уже поставлены и работают для сайт1? Ответ очень прост: надо просто прописать префикс сайт1 для этих таблиц: "префикссайт1_", в файле настроек settings.php для сайт2:
$db_prefix = array (
'default'   => 'main_',
'authmap' => 'префикссайт1_',
'sessions' => 'префикссайт1_',
'sequences' => 'префикссайт1_',
'users' => 'префикссайт1_' и т.д. если объединять будете что либо кроме пользователей.

Также, сайт1 и сайт2 должны использовать одну и ту же БД.

Теперь из админки сайт2 доступны пользователи (и еще что-нибудь, если еще что-нибудь объединяли) сайт1. И пользователи на сайтах общие.

Всё!

Ах да... еще одна деталь. Если Вы будете мультисайтить большое количество сайтов, то для этого может быть целесообразно разделить сайты по разным базам данных. В этом случае схема будет такой: создаем столько баз данных, сколько у нас сайтов, и еще одну общую (shared) и при этом пользователь для всех этих БД должен быть один и тот же. В качестве префиксов указываем префиксы с точкой, например так: "сайт1.". Т.е. в нашем случае можно сделать так:

БД с именем shared (общая для всех сайтов) -

'authmap'
'sessions'
'sequences'
'users'
'role'
'users_roles'
'profile_fields'
'profile_values'
'locales_meta'
'locales_source'
'locales_target'
'bueditor_buttons'
'bueditor_editors'

БД с именем сайт1 (БД для сайт1) -
содержит все таблицы, кроме тех, что в таблице shared
БД с именем сайт2 (БД для сайт2) -
содержит все таблицы, кроме тех, что в таблице shared

В файле settings.php Вы прописываете значения (для сайт1):

$db_url = 'mysql://юзер_БД:пароль_БД@localhost/сайт1';
$db_prefix = array (
'default'   => 'сайт1.',
'authmap' => 'shared.',
'sessions' => 'shared.',
'sequences' => 'shared.',
'users' => 'shared.',
//Роли общие
'role'  => 'shared.',
'users_roles' => 'shared.',
//Profile module
'profile_fields' => 'shared.',
'profile_values' => 'shared.',

//Locale module :
'locales_meta' => 'shared.',
'locales_source' => 'shared.',
'locales_target' => 'shared.',
//BUEditor Module :
'bueditor_buttons' => 'shared.',
'bueditor_editors' => 'shared.'
);

Комментарии

Изображение пользователя VolCh.

По-моему не очень верно иделогически

прописывать для первого сайта установки в sites/default, там по хорошему надо прописать префикс "shared_", установить дефолтный конфиг, а вот в sites/сайт1 уже расписывать для сайт1 конкретно.

А так спасибо, как раз об этом задумался :) Правда пользователей трогать не буду, они по идее и не должны знать, что на разных моих сайтах :)

Изображение пользователя andyceo.

По-моему не

По-моему не очень верно иделогически прописывать для первого сайта установки в sites/default, там по хорошему надо прописать префикс "shared_", установить дефолтный конфиг, а вот в sites/сайт1 уже расписывать для сайт1 конкретно.

Согласен с Вами, верно. Просто когда я писал эту статью, был зелёным новичком в Drupal :) Сейчас, спустя год после его активного изучения и сайтостроительства на Drupal, чувствую, что статью надо бы основательно переписать и дополнить, что, наверное, я когда-нибудь сделаю.

Сейчас же я использую мультисайтинг в следующем режиме - один набор скриптов (одна копия движка и набор тем и модулей) и разные базы данных. Общих таблиц нет вообще - я пришёл к выводу, что такая схема крайне неэффективна на множестве несвязанных между собой сайтов, т.к. взаимные влияния очень трудно отслеживать (изменил настройки на одном сайте - будь готов к глюкам на другом). Даже таблицы переводов у меня не общие, т.к. для каждого проекта может быть свой специфический перевод. Общие таблицы, имхо, имеет смысл делать на сильно связанных между собой проектах, или под специфические нужды.

Изображение пользователя VolCh.

Я тоже пришел к

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

Изображение пользователя Гость.

Ну вот,

Ну вот, говорили говорили, чудесно все расписали и на тебе - все держат данные на разных бд/таблицах.
А как же общие юзеры? Юзеры общие как?

Кстати, спасибо за статью, только после нее я понял что такое мультисайтингна Drupal! респект

Изображение пользователя andyceo.

Всему своё время и место :)

Говорю же, общие таблицы оправданы только на связанных между собой проектах. Даже таблицы с переводами. Потому что один сайт, например, будет молодёжным и стёбным вроде КВН'а и сообщение об отправке материала может звучать так: "Заливай!", а другой сайт будет политическим и нейтральным, в нём сообщение об отправке должно звучать нейтрально и серьёзно: "Сохранить". И так далее, тому подобное. Каждый сайт может звучать по-разному, и потому использование общих таблиц на несвязанных между собой сайтах может дать нежелательные последствия.

С другой стороны, использование мультисайтинга в режиме "один набор скриптов, каждому сайту - своя БД", имеет множество плюсов, которые осознавать начинаешь уже при количестве сайтов > 1. Начиная от того, что обновление скриптов производится сразу на всех сайтах за один раз, и заканчивая тем, что так удобнее следить за сайтами, чем имея для каждого свою копию движка.

Вам спасибо за похвалу, буду стараться!

Добавьте страницу в закладки. Перейти к верху страницы
Синдикация материалов