Перенос учебного портала на новый сервер выглядит довольно просто: развернуть веб-сервер, восстановить базу данных, распаковать файлы и поправить конфигурацию. На практике всё оказалось интереснее.
При восстановлении Moodle 4.1.11 на Ubuntu 24.04.5 LTS мы столкнулись с несколькими проблемами: в конфигурации оказалось неправильное имя базы данных, на сервере обнаружились два каталога с кодом Moodle, MySQL отказывался запускаться, а после восстановления возникли ошибки кэширования и invalidparameter.
В этой статье разберём последовательность работ, диагностические команды и выводы, которые можно использовать при переносе собственной LMS.
Важно: на момент подготовки статьи часть ошибок ещё находилась в стадии диагностики. Поэтому ниже я отдельно отмечаю, что удалось установить, а что требует дополнительной проверки.
1. Исходные условия
Восстанавливали тестовый учебный портал на сервере moodle-test.
Исходные параметры:
|
Компонент |
Значение |
|---|---|
|
ОС |
Ubuntu Server 24.04.5 LTS |
|
Код Moodle |
4.1.11 (Build: 20240610) |
|
PHP CLI |
8.3.6 |
|
PHP-FPM |
PHP 8.3-FPM |
|
Веб-сервер |
Nginx |
|
СУБД |
MySQL Community Server |
|
Каталог Moodle |
|
|
Каталог данных |
|
|
Имя базы |
|
|
Префикс таблиц |
|
Резервные копии включали три основных компонента:
-
архив кода Moodle;
-
архив
moodledata; -
SQL-дамп базы данных.
Для полноценного переноса этого недостаточно без проверки остальной инфраструктуры. Также нужно учитывать конфигурацию Nginx и PHP-FPM, параметры MySQL, задания cron, дополнительные плагины, тему оформления и особенности установленного окружения OTLAMP.
2. Перед восстановлением проверяем резервные копии
Первое правило миграции — не начинать восстановление, пока не проверены сами архивы.
Посмотрим, какие файлы доступны:
ls -lh /restore/moodle/
Для проверки gzip-архивов используем:
gzip -t /restore/moodle/moodle-htdocs_2026-09-21_21-00.tar.gzgzip -t /restore/moodle/moodle-data_2026-09-21_21-00.tar.gzgzip -t /restore/moodle/w1_c2595_2026-09-21_21-00.sql.gz
Если команды завершаются без ошибок, gzip-потоки проходят проверку целостности. Однако это ещё не доказывает, что внутри находятся нужные данные.
Поэтому дополнительно проверяем структуру архивов:
tar -tzf /restore/moodle/moodle-htdocs_2026-09-21_21-00.tar.gz | head -n 30tar -tzf /restore/moodle/moodle-data_2026-09-21_21-00.tar.gz | head -n 30
SQL-дамп можно просмотреть без распаковки на диск:
gzip -dc /restore/moodle/w1_c2595_2026-09-21_21-00.sql.gz | head -n 30
Зачем проверять структуру заранее?
При распаковке архива важны не только файлы, но и уровень вложенности каталогов. Например, параметр --strip-components=1 убирает первый компонент пути. Если применить его к архиву с другой структурой, файлы окажутся не там, где ожидается.
До начала работ также следует сохранить отдельную копию конфигурации Moodle, Nginx, PHP-FPM, MySQL и сведения об установленных плагинах.
3. Проверяем Ubuntu и состояние служб
Убедимся, что действительно работаем с Ubuntu 24.04:
cat /etc/os-release
Ожидаемые ключевые значения:
PRETTY_NAME="Ubuntu 24.04.5 LTS"VERSION_ID="24.04"VERSION_CODENAME=noble
Проверим дисковое пространство:
df -hdf -i
Для Moodle это особенно важно: каталог данных может занимать значительный объём, а исчерпание inode способно помешать созданию большого количества небольших файлов.
Проверяем версии и состояние компонентов:
nginx -vphp -vphp-fpm8.3 -vmysql --versionsudo systemctl status nginx --no-pagersudo systemctl status php8.3-fpm --no-pagersudo systemctl status mysql --no-pager
На этом этапе важно не устанавливать новые пакеты вслепую. Сначала нужно понять, что уже установлено и как взаимодействуют компоненты. Особенно это касается систем с дополнительными сборками вроде OTLAMP.
4. MySQL не запускается: что делать с FROZEN
Одна из проблем возникла при запуске MySQL. Служба сообщала:
MySQL has been frozen to prevent damage to your system.Please see /etc/mysql/FROZEN for help.
В такой ситуации опасно сразу переустанавливать сервер базы данных или удалять каталог с данными.
Сначала проверяем состояние службы и журнал:
sudo systemctl status mysql --no-pager -lsudo journalctl -u mysql -n 100 --no-pager
Если файл существует, читаем его:
sudo cat /etc/mysql/FROZEN
Проверяем, какая служба базы данных фактически используется:
systemctl --type=service --state=running | grep -Ei 'mysql|maria'
В нашем случае впоследствии выяснилось, что MySQL Community Server работал, а отдельной службы mariadb.service не было.
Проверить доступность MySQL можно командой:
sudo mysqladmin ping
Ожидаемый ответ:
mysqld is alive
Здесь важно разделять две задачи: запуск сервера БД и восстановление самой базы Moodle. Пока не подтверждена доступность MySQL, переходить к диагностике ошибок приложения преждевременно.
5. Два каталога Moodle вместо одного
Следующая неожиданность — на сервере обнаружились два каталога с кодом:
/var/www/moodle//var/www/moodle/moodle/
При этом рабочая конфигурация находилась в:
/var/www/moodle/config.php
А параметр в ней был задан следующим образом:
$CFG->dirroot = __DIR__;
То есть активным каталогом Moodle являлся /var/www/moodle, а не вложенный /var/www/moodle/moodle.
Проверяем структуру:
ls -l /var/www/moodle/config.phpls -l /var/www/moodle/version.phpls -l /var/www/moodle/admin/cli/
Версию приложения определяем по version.php:
grep -E '^\$version|^\$release' /var/www/moodle/version.php
В нашем случае исходная версия была Moodle 4.1.11 (Build: 20240610).
Этот пример хорошо показывает, почему нельзя без проверки выполнять команды из текущего каталога терминала. Рабочая директория может не совпадать с каталогом, который обслуживает Nginx.
Практический вывод: во время миграции лучше использовать абсолютные пути в командах и отдельно проверять настройки виртуального хоста Nginx.
6. Восстанавливаем moodledata
В конфигурации Moodle использовался следующий путь:
$CFG->dataroot = '/var/www/moodledata';
Создаём каталог, если его нет:
sudo mkdir -p /var/www/moodledata
Перед распаковкой обязательно проверяем структуру архива. Если архив содержит один общий верхний каталог, данные можно распаковать так:
sudo tar -xzf /restore/moodle/moodle-data_2026-09-21_21-00.tar.gz \ -C /var/www/moodledata \ --strip-components=1
Это пример для архива с соответствующей структурой, а не универсальная команда для любого бэкапа.
После восстановления проверяем наличие файлового хранилища:
sudo ls -la /var/www/moodledata/filedir
И доступность каталога для веб-пользователя:
sudo chown -R www-data:www-data /var/www/moodledatasudo -u www-data test -w /var/www/moodledata \ && echo "moodledata writable" \ || echo "ERROR: moodledata is not writable"
Изменять владельца нужно с учётом реальной конфигурации сервера. Не стоит автоматически менять права на весь /var/www.
7. Восстанавливаем базу данных
Восстановленная база называлась:
w1_c2595
Однако в config.php первоначально было указано другое имя:
w1_c25958a59ee
В результате Moodle обращался не к той базе данных.
Проверяем наличие нужной базы:
sudo mysql -NBe "SHOW DATABASES LIKE 'w1_c2595';"
Проверяем количество таблиц:
sudo mysql -NBe \ "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='w1_c2595';"
В нашей базе обнаружилось 694 таблицы, включая mdl_config.
Это подтверждало наличие структуры Moodle, но само по себе не гарантировало, что восстановление прошло полностью успешно.
Если база ещё не восстановлена, импорт можно выполнить из gzip-дампа:
gzip -dc /restore/moodle/w1_c2595_2026-09-21_21-00.sql.gz \ | sudo mysql w1_c2595
Если база уже содержит данные, повторный импорт выполнять без проверки нельзя. В таком случае безопаснее сначала оценить состояние базы или использовать отдельную временную базу для пробного восстановления.
Проверяем права пользователя:
sudo mysql -e "SHOW GRANTS FOR 'moodle_user'@'localhost';"
У пользователя должны быть необходимые права на базу Moodle. Глобальные привилегии на все базы для этого не требуются.
8. Исправляем config.php
Перед изменением конфигурации создаём резервную копию:
sudo cp -a /var/www/moodle/config.php \ /var/www/moodle/config.php.bak
Проверяем ключевые параметры:
sudo grep -nE \'dbtype|dbhost|dbname|dbuser|prefix|wwwroot|dirroot|dataroot|lib/setup.php' \/var/www/moodle/config.php
В нашей конфигурации существенными оказались следующие параметры:
$CFG->dbtype = 'mysqli';$CFG->dbhost = 'localhost';$CFG->dbname = 'w1_c2595';$CFG->dbuser = 'moodle_user';$CFG->prefix = 'mdl_';$CFG->dirroot = __DIR__;$CFG->dataroot = '/var/www/moodledata';
Это фрагмент с основными параметрами, а не готовый файл конфигурации. Остальные параметры, в том числе wwwroot и пароль, должны соответствовать исходной системе.
После редактирования обязательно проверяем синтаксис:
php -l /var/www/moodle/config.php
Ожидаемый результат:
No syntax errors detected in /var/www/moodle/config.php
Во время восстановления мы уже сталкивались с синтаксической ошибкой в config.php на строке 14. После исправлений сайт снова начал обрабатывать запросы.
Поэтому проверка php -l должна выполняться после каждого редактирования, а не только в конце работ.
9. PHP 8.3: проверяем совместимость
На тестовом сервере использовался PHP CLI 8.3.6 и PHP-FPM 8.3.
При этом исходный Moodle был версии 4.1.11. Совместимость старой версии Moodle и сторонних плагинов с PHP 8.3 необходимо проверять отдельно. Тот факт, что главная страница открывается, ещё не означает, что все компоненты работают корректно.
Проверяем PHP:
php -vphp -m
Среди модулей проверяем наличие необходимых Moodle расширений:
php -m | grep -Ei \'curl|gd|intl|ldap|mbstring|mysqli|soap|xml|zip|sodium|opcache'
Проверяем PHP-FPM:
sudo systemctl status php8.3-fpm --no-pager -l
И конфигурацию Nginx:
sudo nginx -tsudo grep -Rni 'fastcgi_pass' /etc/nginx/
В нашем случае Nginx передавал PHP-запросы через сокет:
/run/php/php8.3-fpm.sock
Важно проверить, что CLI и PHP-FPM используют ожидаемые версии и конфигурации. При диагностике ошибок сайта недостаточно смотреть только на результат команды php -v.
10. Ошибка кэша: The data source class does not exist
После исправления подключения к базе мы попробовали очистить кэш штатной командой Moodle:
sudo -u www-data php /var/www/moodle/admin/cli/purge_caches.php
Вместо успешного завершения появилась ошибка:
The data source class does not exist.
Она возникала внутри механизма определения и загрузки источников данных кэша Moodle.
На этом этапе нельзя уверенно утверждать, какой именно компонент вызвал проблему. Возможные направления диагностики — определения кэша, файлы плагинов и соответствие кода восстановленной версии Moodle.
Правильный порядок действий:
-
Сохранить полный стек ошибки.
-
Найти место, в котором Moodle загружает определение кэша.
-
Установить, какое определение приводит к исключению.
-
Проверить соответствующий класс и файл плагина.
-
Сверить код с резервной копией и версией Moodle.
Не стоит удалять таблицы базы данных, произвольные каталоги кэша или сторонние плагины, пока причина не установлена.
11. Окно invalidparameter на главной странице
После восстановления портал начал открываться, но в браузере появлялось сообщение:
invalidparameterInvalid parameter value detected
В журнале Nginx при этом повторялись предупреждения PHP:
Creation of dynamic property cache_config::$configlockmappings is deprecated
Также в запросах встречались компоненты темы opentechnology и плагин filter_otspoiler.
Однако эти записи сами по себе не доказывают, что причиной invalidparameter является тема, плагин или предупреждение PHP.
Чтобы определить источник ошибки, нужно смотреть на сам запрос, который её возвращает.
В браузере открываем инструменты разработчика:
-
Нажимаем F12.
-
Переходим во вкладку Network.
-
Включаем Preserve log.
-
Обновляем страницу и воспроизводим ошибку.
-
Ищем запрос с ошибочным ответом.
-
Открываем Response и Preview.
Особое внимание стоит обратить на AJAX-запросы Moodle, например к lib/ajax/service.php или lib/ajax/service-nologin.php.
В нашем случае подробная причина ошибки ещё требовала установления. Поэтому считать проблему решённой только на основании журналов Nginx было бы неправильно.
12. Что нужно проверить перед обновлением Moodle
После переноса не следует сразу обновлять Moodle до новой версии.
Сначала нужно добиться стабильной работы восстановленной версии и проверить:
-
вход под пользователем и администратором;
-
главную страницу;
-
открытие курсов;
-
доступность файлов и загрузок;
-
работу темы и сторонних плагинов;
-
выполнение cron;
-
корректность резервного копирования;
-
отсутствие ошибок подключения к базе;
-
работу механизма кэширования.
Перед обновлением необходимо отдельно проверить требования целевой версии Moodle, совместимость PHP, MySQL, темы и плагинов, а также поддерживаемый путь обновления между версиями.
Обновление базы запускается штатным CLI-скриптом:
sudo -u www-data php /var/www/moodle/admin/cli/upgrade.php --non-interactive
Но эта команда предназначена именно для выполнения обновления. Её нельзя использовать как диагностическую проверку на ещё не подготовленной системе.
Перед запуском нужны резервные копии базы, кода и moodledata, а также проверенная копия сервера для тестирования процедуры.
13. Итоговый чек-лист
Перед завершением переноса стоит пройтись по списку:
-
Проверена версия Ubuntu и свободное место.
-
Проверена целостность резервных копий.
-
Подтверждено, какая служба MySQL используется.
-
Найден активный каталог Moodle.
-
Восстановлен
moodledata. -
Проверено имя базы и права пользователя.
-
Проверен синтаксис
config.php. -
Проверены PHP-FPM и конфигурация Nginx.
-
Проверена совместимость версии Moodle с PHP.
-
Проверена работа темы и сторонних плагинов.
-
Установлена причина ошибки кэша.
-
Установлена причина
invalidparameter. -
Проверены пользователи, курсы, файлы и результаты обучения.
-
Создана новая резервная копия восстановленной системы.
-
Проверено восстановление резервной копии на тестовом стенде.
Выводы
Перенос Moodle на новый сервер — это не просто распаковка архива и импорт SQL-дампа. Значительная часть работы заключается в проверке взаимосвязей между кодом, базой данных, каталогом пользовательских файлов, PHP, веб-сервером и сторонними плагинами.
В нашем случае наиболее полезными оказались простые диагностические проверки: поиск реального config.php, сверка имени базы, проверка службы MySQL и явное указание путей в CLI-командах.
Ещё один важный вывод: предупреждение в журнале и ошибка приложения — не всегда одно и то же. Чтобы не исправлять систему наугад, нужно искать конкретный запрос или компонент, который приводит к сбою.
В итоге безопасная миграция должна идти поэтапно: сначала восстановление, затем проверка функциональности и только потом обновление Moodle и его зависимостей.
Это позволяет локализовать проблемы и не превращать перенос учебного портала в одновременную отладку нескольких уровней инфраструктуры.
ссылка на оригинал статьи https://habr.com/ru/articles/1101336/