RE:NODE

Веб-хостинг12 мин чтения

Хостинг Drupal: требования, Composer и настройки

Правильный хостинг Drupal 11: требования к PHP и базе данных, сборка через Composer без доступа к shell, settings.php, правила nginx, cron, кэширование и обновления.

0 прочтений

Drupal 11 нужны PHP 8.3 или новее, база данных уровня MySQL 8.0, MariaDB 10.6 или PostgreSQL 16, на практике не меньше 128 МБ памяти для PHP и веб-сервер, который отправляет в index.php каждый запрос, не найденный как файл. Устанавливается он через Composer, а не распаковкой архива, и этот факт определяет всё в его хостинге: сборка происходит там, где запущен Composer, а результат - включая каталог vendor из нескольких тысяч файлов - отправляется на сервер.

На хостинге с shell это две команды. На панельном хостинге без shell вы собираете сайт на своей машине и загружаете его, и это прекрасно работает, когда знаешь, куда должен смотреть корень сайта. Это руководство описывает оба варианта, затем settings.php построчно, правила nginx, cron, кэширование (включая Valkey), обновления и ошибки, на которые люди натыкаются на самом деле.

Какой Drupal и что ему нужно#

В конце 2026 года в ходу три мажорные версии, и для нового сайта правильный выбор только один.

ВерсияСтатусPHP
Drupal 10Поддержка безопасности заканчивается 9 декабря 2026 года8.1 до 8.4
Drupal 11Актуальная, её и устанавливать8.3 до 8.5 (8.5 начиная с 11.3)
Drupal 12Запланирована; сверьтесь с графиком выпусков8.5

Новые сайты начинайте на Drupal 11. Сайт на Drupal 10 стоит обновить сейчас, а не в декабре; путь - с 10.3 или новее на 11, модуль за модулем, а модуль Upgrade Status подскажет, что несовместимо. Требования меняются с минорными выпусками, так что прежде чем что-то покупать, загляните на официальные страницы: требования к PHP и требования к базе данных.

Требования Drupal 11 на практике:

ТребованиеDrupal 11Примечания
PHP8.3 или новее8.4 - хороший выбор в 2026 году
Расширения PHPpdo, драйвер PDO для вашей базы, gd, json, xml/dom, mbstring, openssl, curlgd (или ImageMagick) для стилей изображений
memory_limitМинимум 64 МБ, на практике 128-256 МБСайтам с большим количеством медиа и крупным миграциям нужно больше
База данныхMySQL 8.0+, MariaDB 10.6+, PostgreSQL 16+, SQLite 3.45+InnoDB для семейства MySQL; pg_trgm для PostgreSQL
Диск300-500 МБ под кодПлюс sites/default/files, который и растёт
Веб-серверnginx или Apache с rewritenginx игнорирует .htaccess

О памяти стоит сказать отдельно. Сайт на Drupal с парой десятков сторонних модулей расходует больше памяти PHP на запрос, чем аналогичный сайт на WordPress, а самый тяжёлый момент - пересборка кэшей после deploy. Небольшой сайт на Drupal работает на тарифе с 1 ГБ; 2 ГБ - комфортная отправная точка для всего, где есть страницы с тяжёлыми Views, Media и Search API, и memory_limit PHP на таких сайтах должен быть 256 МБ. memory_limit, max_execution_time и OPcache описаны в статье важные настройки php.ini.

Есть ещё Drupal CMS - готовый дистрибутив поверх ядра Drupal для сборщиков сайтов, с заранее настроенными рецептами типовых функций. Он устанавливается и размещается так же; всё сказанное здесь относится и к нему.

Сборка кодовой базы через Composer#

Поддерживаемая отправная точка - шаблон drupal/recommended-project:

bash
$ composer create-project drupal/recommended-project example.com$ cd example.com$ composer require drush/drush$ composer require drupal/admin_toolbar drupal/pathauto drupal/redis

У результата особая структура, и её понимание предотвращает большинство проблем с хостингом:

code
example.com/  composer.json        what you asked for  composer.lock        exact versions installed - commit this  vendor/              PHP libraries, Drush, Symfony - not web-accessible  web/                 the web root    index.php    core/    modules/contrib/    themes/contrib/    sites/default/

Отдаваться должен только web/. vendor/ и composer.json лежат рядом, вне корня сайта, так что никто не может запросить их по HTTP. В этом главное структурное отличие от WordPress или Joomla, где всё живёт в корне сайта.

Держите composer.json и composer.lock в системе контроля версий вместе со своими модулями и темами, а vendor/, web/core и web/modules/contrib считайте результатом сборки. Всегда коммитьте composer.lock - именно он гарантирует, что сборка на вашем ноутбуке и сборка через полгода дадут один и тот же сайт.

Установка на хостинг без shell#

Панельный хостинг часто даёт файловый менеджер и SFTP, но не даёт shell для входа, так что Composer на сервере запустить нельзя. Это не препятствие. Соберите локально, затем загрузите сборку.

  1. Совместите версии PHP. Используйте локально ту же мажорную и минорную версию PHP, что и на сервере. Composer разрешает зависимости для того PHP, под которым запущен, и lock-файл, собранный на PHP 8.4, может подтянуть пакеты, которые откажутся работать на 8.3. Если на вашей машине версия новее, закрепите её в composer.json через "config": { "platform": { "php": "8.3.0" } }.
  2. Соберите без пакетов для разработки: composer install --no-dev --optimize-autoloader.
  3. Решите, где будет корень сайта. Если можно загрузить весь проект и направить сайт на web/, так и сделайте. Если хостинг отдаёт фиксированный каталог - public_html, www, public, - переименуйте корень сайта Drupal под него, а не перекладывайте файлы: в composer.json замените каждый путь web/ в extra.installer-paths и задайте extra.drupal-scaffold.locations.web-root равным имени каталога, затем снова выполните composer install. Загрузите проект на уровень выше этого каталога, чтобы vendor остался вне его.
  4. Загружайте одним архивом. Тысячи мелких файлов по SFTP загружаются гораздо дольше, чем один zip. Файловый менеджер, распаковывающий архивы на месте, превращает это в одну загрузку; оба пути описаны в статье SFTP и файловый менеджер.
  5. Создайте базу данных и пользователя, затем откройте сайт и запустите установщик.

Если хостинг позволяет писать только внутри корня сайта, Drupal всё равно можно запустить с vendor внутри него, но тогда нужно убедиться, что веб-сервер отклоняет запросы к vendor/, composer.json и composer.lock - эти файлы раскрывают точные версии всего, что у вас работает. Если есть возможность, структура с корнем сайта уровнем ниже лучше.

В RE:NODE линейка, рассчитанная на такие CMS, - это тарифы Engines. Drupal вы устанавливаете сами через SFTP или файловый менеджер - установщика в один клик нет, а значит, никто другой не закрепляет вашу версию, - и на каждом тарифе есть два слота баз данных, которые создаются из панели со сгенерированными хостом, пользователем и паролем. Сайту на Drupal нужен один из них; второй предназначен для тестовой копии.

settings.php построчно#

Установщик копирует sites/default/default.settings.php в settings.php и записывает туда учётные данные базы. Несколько настроек нужно добавить или проверить вручную.

web/sites/default/settings.php
$databases['default']['default'] = [  'driver'    => 'mysql',  'database'  => 'drupal',  'username'  => 'drupal_site',  'password'  => getenv('DRUPAL_DB_PASSWORD') ?: 'from-the-panel',  'host'      => 'db.example.internal',  'port'      => '3306',  'prefix'    => '',  'collation' => 'utf8mb4_general_ci',  'init_commands' => [    'isolation_level' => 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',  ],];$settings['hash_salt'] = 'a-long-random-string';$settings['config_sync_directory'] = '../config/sync';$settings['file_private_path'] = '../private';$settings['trusted_host_patterns'] = ['^example\.com$', '^www\.example\.com$'];$settings['update_free_access'] = FALSE;

Зачем нужна каждая строка:

  • `host` и `port` - здесь ошибаются чаще всего, точно как с WordPress. localhost работает, только если база запущена на той же машине; со слотом базы данных или отдельным сервером базы используйте выданные вам имя хоста и порт.
  • `init_commands` с `READ COMMITTED` относится к базам семейства MySQL. Его рекомендует отчёт о состоянии Drupal, потому что уровень по умолчанию REPEATABLE READ при характерных для Drupal записях вызывает больше взаимоблокировок. Новые установщики могут сами записать эквивалентный ключ isolation_level; достаточно одного из двух.
  • `hash_salt` используется для одноразовых ссылок входа, токенов форм и других подписей. Установщик генерирует его сам; держите его в секрете и одинаковым на всех серверах, где работает один и тот же сайт.
  • `config_sync_directory` - каталог, куда экспортируется и откуда импортируется конфигурация. Разместите его вне корня сайта, как показано, чтобы экспортированную конфигурацию нельзя было скачать.
  • `file_private_path` включает приватные файлы, которые отдаются только через проверки доступа Drupal. Тоже вне корня сайта.
  • `trusted_host_patterns` - настройка безопасности, а не необязательная. Без неё Drupal принимает любой заголовок Host, и его можно обманом заставить генерировать в письмах для сброса пароля ссылки на домен злоумышленника. Отчёт о состоянии предупреждает, пока она не задана.

После установки сделайте settings.php и каталог sites/default доступными только для чтения. Drupal это проверяет и жалуется в отчёте о состоянии, если может в них писать.

За обратным прокси Drupal нужно явно об этом сообщить, иначе он не будет доверять X-Forwarded-For и X-Forwarded-Proto:

web/sites/default/settings.php
$settings['reverse_proxy'] = TRUE;$settings['reverse_proxy_addresses'] = ['192.0.2.10'];

Адреса - это те, с которых подключается ваш прокси. Без этого каждый посетитель выглядит пришедшим с прокси, защита от флуда блокирует всех разом, а генерируемые URL могут использовать http:// на сайте с HTTPS. Заголовки объясняются в статье что делает обратный прокси.

Правила nginx#

Drupal поставляется с файлом .htaccess, где лежат правила rewrite и набор защит - запрет доступа к .yml, .twig, composer.json и подобным файлам. nginx полностью игнорирует .htaccess, так что эти защиты нужно воссоздать в конфигурации сервера. Основа:

nginx
location / {    try_files $uri /index.php?$query_string;}location @rewrite {    rewrite ^ /index.php;}location ~ ^/sites/.*/files/styles/ {    try_files $uri @rewrite;}location ~ (^|/)\. { return 403; }location ~ ^/sites/.*/private/ { return 403; }location ~* \.(engine|inc|install|make|module|profile|po|sh|sql|theme|twig|tpl|yml|yaml)$ {    return 403;}location ~ /vendor/ { deny all; }

Блок styles важнее, чем кажется: производные стилей изображений генерируются при первом запросе, так что отсутствующий там файл должен уходить в Drupal, а не возвращать 404. Без него все уменьшенные изображения на сайте будут сломаны. Сравните полный список защит с файлом .htaccess в вашем собственном каталоге web/ - для вашей версии Drupal авторитетен именно он.

На управляемом хостинге вы можете не иметь права сами править конфигурацию nginx. Проверьте, есть ли уже стандартное правило фронт-контроллера (try_files ... /index.php): если /user/login открывается, значит есть. Если неправильно ведут себя стили изображений или приватные файлы, именно об этом стоит спросить хостинг.

Cron и фоновая работа#

Drupal нужен cron для индексации поиска, очистки просроченных кэшей и сессий, проверки обновлений, обработки очередей и всего, что планируют модули. Запустить его можно тремя способами.

  • Automated Cron, модуль ядра, запускает cron в конце запроса страницы, когда прошло достаточно времени, - по умолчанию раз в три часа, настраивается в /admin/config/system/cron. Годится для небольших сайтов; посетитель, который его запустил, получает ответ медленнее.
  • URL cron, показанный на той же странице в виде https://example.com/cron/<key>. Его может запрашивать любой внешний планировщик - сервис мониторинга, задача по расписанию на другой машине. Держите ключ в секрете: любой, у кого есть URL, может запустить cron.
  • Drush, drush cron, из системного crontab там, где у вас есть shell. Самый надёжный вариант и единственный, который не привязывает cron к веб-трафику.

Если вы используете внешний запуск, отключите Automated Cron, чтобы cron не запускался ещё и внутри запросов посетителей. Синтаксис расписания описан в статье выражения cron простыми словами.

Кэширование и подключение Valkey#

Встроенное кэширование Drupal хорошее и включено по умолчанию:

  • Internal Page Cache хранит страницы целиком для анонимных посетителей.
  • Dynamic Page Cache кэширует части страниц, одинаковые для многих пользователей, включая вошедших, с помощью контекстов кэша.
  • BigPipe сначала отправляет закэшированный каркас страницы, а персонализированные части передаёт потоком следом.
  • Агрегация CSS и JavaScript в разделе Configuration, затем Performance, в продакшене должна быть включена.

По умолчанию все корзины кэша (cache bins) живут в таблицах базы данных. На загруженном сайте это много трафика к базе ради данных, которым не нужна надёжность, и перенос корзин кэша в Valkey - стандартное улучшение. Модуль drupal/redis говорит на протоколе Redis и подключается к Valkey без изменений. Сначала включите модуль, затем добавьте в settings.php:

web/sites/default/settings.php
$settings['redis.connection']['interface'] = 'PhpRedis';$settings['redis.connection']['host'] = '203.0.113.20';$settings['redis.connection']['port'] = 6380;$settings['redis.connection']['password'] = getenv('VALKEY_PASSWORD');$settings['cache']['default'] = 'cache.backend.redis';$settings['cache_prefix'] = 'example_com_';$settings['container_yamls'][] = 'modules/contrib/redis/example.services.yml';

PhpRedis требует расширения phpredis; Predis - альтернатива на чистом PHP, устанавливается через composer require predis/predis. Если несколько сайтов делят один Valkey, задайте каждому уникальный cache_prefix. Источником истины остаётся база данных: кэш можно очистить в любой момент через drush cr или кнопку Clear all caches. Тариф Valkey начинается с 256 МБ, а этого с избытком хватает для корзин кэша большинства сайтов на Drupal; почему для экземпляра, который служит только кэшем, подходит политика с вытеснением, объясняет статья память и политики вытеснения Valkey.

Обновления и deploy конфигурации#

Drupal выпускает обновления безопасности по опубликованному графику, обычно по средам. Выпуски безопасности для ядра и популярных модулей объявляются на drupal.org, а модуль Update Status присылает письмо, когда ваш сайт отстаёт. Читайте бюллетени: выпуск ядра с пометкой «highly critical», как проблемы Drupalgeddon в 2018 году, начинают эксплуатировать в течение нескольких часов.

Само обновление через Composer:

bash
$ composer update "drupal/core-*" --with-all-dependencies$ drush updatedb$ drush cache:rebuild

Без shell выполните composer update локально, загрузите изменившиеся vendor/ и web/core/ (и обновлённые модули), затем откройте /update.php от имени администратора, чтобы выполнить обновления базы данных. Каждый раз сначала делайте backup и переводите сайт в режим обслуживания на время обновления, чтобы никто не писал в базу на полпути. Почему этот backup стоит проверять, объясняет статья backup, из которого действительно можно восстановиться.

Изменения конфигурации - типы материалов, поля, представления - должны переезжать из разработки в продакшен через управление конфигурацией, а не прокликиваться дважды: drush config:export на копии для разработки, коммит YAML-файлов, deploy, drush config:import на продакшене. Аналог в интерфейсе находится в Configuration, затем Development, затем Configuration synchronisation.

Устранение неполадок#

Установщик останавливается на «Requirements problem». Прочитайте список: обычно не хватает расширения PHP, версия PHP ниже 8.3 для Drupal 11 или sites/default/files недоступен для записи.

«The provided host name is not valid for this server». trusted_host_patterns не совпадает с именем хоста, которое вы открываете. Добавьте его, включая www, если он используется.

Белый экран или «The website encountered an unexpected error». Посмотрите последние сообщения журнала в /admin/reports/dblog или журнал ошибок PHP, если админка недоступна. Нехватка памяти при пересборке кэшей - частое дело; увеличьте memory_limit.

Все страницы, кроме главной, возвращают 404. Нет rewrite на фронт-контроллер - типичная ситуация на nginx, когда полагались только на .htaccess от Apache.

Изображения в стилях изображений сломаны. Нет правила styles из примера выше, или sites/default/files недоступен для записи.

Циклы перенаправлений после включения HTTPS. Заголовкам прокси не доверяют; задайте reverse_proxy и его адреса.

FAQ#

Можно ли установить Drupal без Composer?

Для Drupal 11 - не поддерживаемым способом. Архивы ядра для скачивания существуют, но сторонние модули объявляют свои зависимости через Composer, а ручное управление ими ломается на первом же модуле с зависимостью от библиотеки. Соберите через Composer на любой машине, затем загрузите результат.

Сколько ресурсов нужно сайту на Drupal?

Небольшой сайт-визитка работает на 1 ГБ с одним-двумя ядрами CPU. Сайту со страницами на тяжёлых Views, Media, Search API и некоторым трафиком вошедших пользователей нужно 2 ГБ или больше и memory_limit PHP 256 МБ. Обычно раньше CPU упираешься в память и число PHP workers.

Сложнее ли хостить Drupal, чем WordPress?

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

Когда нужно уйти с Drupal 10?

Поддержка безопасности Drupal 10 заканчивается 9 декабря 2026 года. Обновитесь до Drupal 11 раньше; сайты, оставшиеся на Drupal 10 после этой даты, не получают исправлений безопасности.

Нужен ли Drupal Valkey?

Нет. Кэши Drupal на базе данных работают в малых и средних масштабах. Перенос корзин кэша в Valkey снимает нагрузку с базы и помогает загруженным сайтам, особенно с большим числом вошедших пользователей.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000