Обновить GLPI в Docker кажется тривиальным — сменить тег образа и поднять контейнер, — но именно эта кажущаяся простота и приводит к незапланированному простою. В сопровождении клиентских сред большинство инцидентов при обновлении связано не с самой миграцией базы данных, а с несовместимыми плагинами, PHP, встроенным в новый образ, или неправильно смонтированным томом, из-за которого GLPI теряет настройки подключения к базе. В этом руководстве собран сценарий, который мы применяем в продакшене, с указанием мест, где всё действительно ломается.
Прежде чем трогать контейнеры: инвентаризация совместимости
Обновление GLPI — это не только образ. Есть три слоя, которые должны обновляться вместе: ядро, плагины и схема базы данных. Классическая ошибка — обновить образ и уже при лежащем сайте обнаружить, что у критичного плагина (например, нативной инвентаризации, SSO или кастомизации полей) нет версии для нового ядра. Выясните заранее:
- Точные исходная и целевая версии — minor-переход (10.0.15 на 10.0.18) безопасен; major-переход (10.x на 11.x) меняет требования к PHP и может отправить плагины на покой.
- Матрица плагинов — для каждого установленного плагина убедиться, что есть релиз, совместимый с целевой версией. Плагин без совместимой версии = бизнес-решение (отключить, заменить или отложить обновление), а не сюрприз в 2 часа ночи.
- PHP, встроенный в образ — официальный образ уже содержит нужный PHP, но если вы используете собственный образ (Alpine + php-fpm), GLPI 11 требует PHP 8.2+. Новое ядро на старом PHP даёт белый экран без внятного лога.
- Место на диске — дамп и tar томов могут временно удвоить занятое место. Проверьте до, а не во время.
Матрица решений: minor, major или пропуск версий
Тип перехода определяет сценарий. Вот матрица, по которой мы оцениваем окно и риск:
| Сценарий | Пример | Риск | Типичное окно | Главное, на что смотреть |
|---|---|---|---|---|
| Patch/minor | 10.0.15 → 10.0.18 | Низкий | 5–15 мин | Лёгкая миграция схемы; плагины обычно продолжают работать |
| Major | 10.0.x → 11.0.x | Высокий | 30–90 мин | PHP, плагины и изменения поведения; сначала протестировать |
| Пропуск major-версий | 9.5.x → 11.0.x | Очень высокий | Планировать поэтапно | НЕ пропускать; мигрировать 9.5 → 10.0 → 11.0 по шагам |
Частая ошибка — думать, что пропуск версий экономит время. GLPI не гарантирует миграцию схемы через целую major-версию; процедура db:update ожидает структуру непосредственно предыдущей версии. Прыжок с 9.5 сразу на 11 обычно обрывает миграцию на середине, оставляя базу в несогласованном состоянии, — и тогда откат перестаёт быть опцией.
Пошаговое обновление
1. Согласованный бэкап (база + тома)
Бэкап — это не только дамп. Это дамп базы плюс tar томов с файлами (загрузки, документы, кэш плагинов). Оба должны относиться к одному моменту — поэтому мы сначала останавливаем приложение, оставляя работать только базу для дампа:
# Stop the app, keep the database running
docker compose stop glpi-app
# Database dump (dedicated user, password via environment variable)
docker exec glpi-db sh -c 'mysqldump --single-transaction \
-u glpi -p"${MYSQL_PASSWORD}" glpi' | gzip > /backup/pre-update-$(date +%F).sql.gz
# Tar of the GLPI file volumes
tar -czf /backup/pre-update-files-$(date +%F).tar.gz \
/var/lib/docker/volumes/glpi_files/_data
--single-transaction гарантирует согласованный дамп без блокировки таблиц InnoDB. И никогда не указывайте пароль в командной строке открытым текстом: он утечёт в историю shell и в docker inspect.
2. Зафиксировать целевую версию в compose
Никогда не используйте тег latest в продакшене. Он без предупреждения смещает цель и делает детерминированный откат невозможным. Зафиксируйте точную версию:
# docker-compose.yml
services:
glpi-app:
# From:
image: glpi/glpi:10.0.18
# To (exact target version, never :latest):
image: glpi/glpi:11.0.1
volumes:
- glpi_files:/var/glpi/files
- glpi_config:/var/glpi/config # config_db.php lives here - do NOT lose it
3. Поднять новый образ
docker compose pull glpi-app
docker compose up -d glpi-app
4. Запустить миграцию схемы
Команда миграции меняла название между поколениями GLPI. Прежде чем запускать вслепую, проверьте, какая команда доступна:
# GLPI 10/11 (Symfony console):
docker exec -u www-data glpi-app php bin/console db:update --no-interaction
# Older GLPI (early 10.0) used:
# docker exec -u www-data glpi-app php bin/console glpi:database:update --no-interaction
Всегда запускайте от пользователя веб-сервера (www-data или apache), никогда от root. Миграция от root создаёт файлы кэша с неправильным владельцем, и затем GLPI начинает выдавать ошибки прав доступа — ложное «сломалось при обновлении», которое на деле просто ownership.
5. Очистить кэш и проверить
docker exec -u www-data glpi-app php bin/console cache:clear
- Откройте интерфейс и проверьте версию в Настройки > Общие.
- Запустите внутреннюю диагностику в Настройки > Проверки (проверяет PHP, расширения и права).
- Убедитесь, что критичные плагины отображаются как активные, а не как «требует обновления».
- Проверьте реальный сценарий: создать заявку, приложить документ, отправить уведомление.
Чему мы научились, делая это для клиентов
В сопровождении чаще всего повторяется не сбой миграции, а ситуация, когда миграция кажется успешной, а GLPI поднимается с пустой базой по умолчанию. Причина почти всегда одна: том, где хранится config/config_db.php, не смонтирован или смонтирован по другому пути в новой версии. GLPI не находит настройки базы, считает установку чистой и показывает мастер установки. Кто торопится, нажимает «установить» и создаёт новую базу поверх — теперь к простою добавляется риск потери данных. Поэтому в нашем чек-листе первая проверка после запуска — не версия, а то, что docker exec glpi-app cat /var/glpi/config/config_db.php возвращает реальную конфигурацию клиента. Если появился мастер, мы всё останавливаем до любого клика и пересматриваем монтирование томов — никогда не продолжаем через интерфейс.
Второй типичный сценарий — OPcache отдаёт старый код после обновления. Образ сменился, код на диске новый, но php-fpm всё ещё держит в памяти скомпилированную старую версию. Симптом: ошибки несуществующего метода или версия ядра, не совпадающая с образом. Помогает пересоздание контейнера (а не просто перезапуск), потому что процесс php-fpm инициализируется с нуля.
План отката (отрепетированный, а не импровизированный)
Откат надёжен, только если он продуман заранее. С дампом и tar из шага 1 возврат детерминирован:
# Tear down the new version
docker compose down
# Restore the database from the dump
gunzip < /backup/pre-update-2026-07-02.sql.gz \
| docker exec -i glpi-db sh -c 'mysql -u glpi -p"${MYSQL_PASSWORD}" glpi'
# Revert the image tag in docker-compose.yml to the previous version
# (e.g. glpi/glpi:11.0.1 back to glpi/glpi:10.0.18)
docker compose up -d
Критический момент отката — схема. После того как db:update изменил структуру, база больше не совместима со старым образом. Поэтому откат обязан восстанавливать дамп — вернуть тег недостаточно. Если восстановить только образ при уже мигрированной схеме, старый GLPI будет читать таблицы с «будущей» структурой, что порождает тихие и трудно отслеживаемые ошибки.
Как обойтись без незапланированного простоя
Если среда критичная, окно обновления нужно отрепетировать в тестовой среде на клоне продакшен-базы. Именно там без давления выясняется, ломается ли какой-то плагин и не дольше ли миграция согласованного окна. Обновлять сразу в продакшене без такой репетиции — значит ставить доступность сервиса клиента на удачу.
Если у вашей команды нет окна, чтобы репетировать каждое обновление, или обновление уже однажды растянулось на всю ночь, NexTool берёт на себя сопровождение и обновления вашего GLPI с отрепетированным откатом и согласованным окном. Обратитесь к нам по поводу поддержки и сопровождения GLPI.
Проверено командой NexTool Solutions.