Разработка сайта на CMS Drupal
Drupal — не самый быстрый старт, зато один из самых гибких инструментов для сложных сайтов: порталов, корпоративных сайтов с многоуровневым доступом, multilingual-проектов с нетривиальной структурой контента. Архитектура модульная: базовый Drupal — это ядро плюс contrib-модули, кастомный код пишется только там, где нет готового решения.
Стек Drupal-проекта
- Drupal 10+ (PHP 8.2+, Symfony компоненты внутри)
- Composer — управление зависимостями, единственный правильный способ устанавливать Drupal
- Drush — CLI для управления сайтом
- DDEV или Docker Compose — локальная разработка
- PostgreSQL или MySQL — Drupal работает с обоими
- Redis — кэш. Без него Drupal медленный
- Varnish или Nginx FastCGI cache — page cache для анонимных пользователей
Инициализация проекта
composer create-project drupal/recommended-project my-project
cd my-project
# Инструменты разработки
composer require drush/drush drupal/devel drupal/admin_toolbar
# Обязательные contrib-модули
composer require \
drupal/pathauto \ # автоматические URL
drupal/token \ # токены для pathauto
drupal/metatag \ # SEO мета-теги
drupal/redirect \ # редиректы
drupal/simple_sitemap \ # sitemap.xml
drupal/paragraphs \ # гибкий контент
drupal/entity_reference_revisions \
drupal/field_group \ # группировка полей в форме
drupal/views_bulk_operations \
drupal/redis \ # Redis кэш
drupal/restui # REST API управление
# Установка
drush site:install --account-name=admin --account-pass=admin --db-url="pgsql://user:pass@localhost/drupal"
Структура кастомного модуля
Весь кастомный код — в web/modules/custom/:
web/modules/custom/my_project/
├── my_project.info.yml
├── my_project.module
├── my_project.install # хуки установки/обновления
├── my_project.routing.yml # маршруты
├── my_project.services.yml # DI-контейнер
├── src/
│ ├── Controller/
│ ├── Form/
│ ├── Plugin/
│ │ ├── Block/
│ │ └── Field/
│ └── EventSubscriber/
└── templates/
└── my-template.html.twig
Конфигурационный workflow
Drupal хранит конфигурацию (типы контента, поля, Views, роли) в YAML-файлах. Это ключевое для командной работы:
# Экспорт текущей конфигурации в файлы (после изменений в UI)
drush config:export
# Импорт конфигурации из файлов (деплой на другую среду)
drush config:import
# Просмотр diff между активной конфигурацией и файлами
drush config:status
В settings.php указываем директорию:
$settings['config_sync_directory'] = '../config/sync';
Все YAML-файлы конфигурации коммитятся в git. Деплой на production — это git pull + drush config:import + drush updb + drush cr.
Производительность
Drupal без кэша работает медленно. Минимальный набор для production:
// settings.php — Redis для кэша
$settings['cache']['default'] = 'cache.backend.redis';
$settings['redis.connection']['host'] = 'redis';
$settings['redis.connection']['port'] = 6379;
// Internal Page Cache + Dynamic Page Cache уже в ядре
// Включаются в /admin/config/development/performance
Для анонимного трафика — Varnish перед Drupal:
// default.vcl — упрощённо
sub vcl_recv {
// Не кэшируем авторизованных пользователей
if (req.http.Cookie ~ "SESS|NO_CACHE") {
return (pass);
}
// Убираем лишние куки для кэширования
unset req.http.Cookie;
return (hash);
}
С этой конфигурацией анонимные страницы отдаются за миллисекунды — Drupal вообще не участвует.
Multisite и мультиязычность
Drupal нативно поддерживает несколько языков. Включаем модули ядра:
drush en language locale content_translation config_translation
Конфигурация через UI или YAML:
# language.entity.ru.yml
langcode: ru
status: true
label: 'Russian'
direction: ltr
weight: 0
locked: false
После включения переводов у каждой сущности (ноды, термины, блоки) появляется вкладка "Переводы". Переводы хранятся в той же таблице через content_translation_* поля.
Headless Drupal
Drupal 10 включает JSON:API из коробки:
GET /jsonapi/node/article
GET /jsonapi/node/article/{uuid}
GET /jsonapi/node/article?filter[status]=1&sort=-created&page[limit]=10
Фильтрация, include связанных сущностей, sparse fieldsets:
GET /jsonapi/node/article?
include=field_author,field_tags,field_image&
fields[node--article]=title,body,field_author,field_tags&
filter[field_tags.name]=PHP&
sort=-created
Для GraphQL — модуль drupal/graphql:
composer require drupal/graphql
Деплой
# Composer install без dev-зависимостей
composer install --no-dev --optimize-autoloader
# Стандартная последовательность деплоя
drush updatedb --no-interaction
drush config:import --no-interaction
drush cache:rebuild
drush deploy:hook # если есть пост-деплой хуки
CI/CD: эти команды в stage после git pull или rsync. Нулевого даунтайма достичь сложно — config:import требует временного режима обслуживания при структурных изменениях.
Сроки
Типовой корпоративный сайт (главная, разделы, блог, форма обратной связи, 2 языка): 4–6 недель. Портал с личным кабинетом, ролями, каталогом и REST API: 8–12 недель.







