Ein Backup, das nie wiederhergestellt wurde, ist Hoffnung, keine Strategie – und im GLPI scheitert der Restore meist nicht am Datenbank-Dump, sondern an der glpicrypt.key. Im Betriebssupport von Kundenumgebungen haben wir schon einen „perfekten“ Restore der Datenbank erlebt, nach dem sich niemand mehr per LDAP anmelden oder E-Mails versenden konnte: Die Daten waren zurück, aber der Schlüssel, der die Passwörter für LDAP, SMTP und E-Mail-Collector entschlüsselt, war zurückgeblieben. Dieser Leitfaden fasst den Fahrplan für Backup, Rotation, Restore-Test und Disaster Recovery zusammen, den wir in der Produktion anwenden, mit den Stellen, an denen es wirklich bricht.
Was wirklich ins Backup gehört
Das GLPI hat drei Zustandsschichten, und alle drei müssen gemeinsam und konsistent zurückkommen:
- Datenbank – Tickets, Assets, Benutzer, Regeln und Konfigurationen. Sie ist das Herzstück, bringt die Umgebung allein aber nicht wieder zum Laufen.
- Dateiverzeichnis (
files/) – angehängte Dokumente (files/_documents), Bilder, XML-Inventare und Plugin-Daten. Wenn die Datenbank den Eintrag des Dokuments hat, die Datei aber nicht zurückgekommen ist, klickt der Benutzer und erhält einen Fehler. - Konfiguration (
config/) – dieconfig_db.php(Host, Datenbank und Zugangsdaten) und vor allem dieglpicrypt.key. Dieser Schlüssel entschlüsselt die in der Datenbank gespeicherten Passwörter: LDAP-Bind, E-Mail-Collector (mailcollector), SMTP der Benachrichtigungen und OAuth-Secrets. Wer die Datenbank ohne ihn wiederherstellt, macht all diese Passwörter zu nicht entschlüsselbarem Datenmüll.
Innerhalb von files/ braucht nicht alles ein Backup. Flüchtige Verzeichnisse wie _cache, _tmp, _sessions, _cron und _lock werden automatisch neu erzeugt und blähen das Backup nur auf – schließen Sie sie aus. Erhalten müssen Sie _documents, _pictures, _uploads, _inventories und _plugins.
Konsistenter Dump der Datenbank
GLPI 10 und 11 verwenden InnoDB für alle Tabellen, daher erstellt --single-transaction einen konsistenten Snapshot, ohne die Anwendung zu sperren – die Benutzer erstellen während des Backups weiter Tickets. --quick verhindert, dass riesige Tabellen in den Speicher geladen werden, und --default-character-set=utf8mb4 verhindert beschädigte Umlaute, Akzente und Emojis. Übergeben Sie das Passwort nie auf der Kommandozeile (es erscheint in ps und in den Logs); verwenden Sie eine Zugangsdatendatei mit eingeschränkten Rechten:
# ~/.my.cnf (chmod 600) - evita a senha no 'ps' e nos logs
[client]
host = 127.0.0.1
user = glpi
password = ...senha_do_glpi...
Das native Backup des GLPI (Verwaltung > Wartung) schreibt eine .sql nach files/_dumps, stößt bei großen Datenbanken aber gern an die Zeit- und Speichergrenzen von PHP. Für die Produktion ist ein geplanter mysqldump zuverlässiger.
Backup-Skript mit Rotation
Ein einziges Skript, das Datenbank, Dateien und Konfiguration in der richtigen Reihenfolge sichert und zusätzlich alles bereinigt, was älter als 30 Tage ist:
#!/usr/bin/env bash
set -euo pipefail
# Credenciais em ~/.my.cnf (chmod 600), nunca na linha de comando
DATA=$(date +%F)
DEST="/backup/glpi/${DATA}"
mkdir -p "${DEST}"
# Banco: snapshot consistente de InnoDB, sem travar a aplicacao
mysqldump --single-transaction --quick --routines --triggers \
--default-character-set=utf8mb4 glpi \
| gzip -6 > "${DEST}/glpi_db.sql.gz"
# Arquivos + config DEPOIS do dump (arquivo a mais e inofensivo;
# linha no banco apontando para arquivo ausente, nao)
tar -czf "${DEST}/glpi_files.tar.gz" \
--exclude='files/_cache' --exclude='files/_tmp' \
--exclude='files/_sessions' --exclude='files/_lock' \
-C /var/www/glpi files config
# Rotacao: manter 30 dias
find /backup/glpi -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +
echo "Backup OK: ${DEST}"
Achten Sie auf die Reihenfolge: Der Dump kommt vor dem tar. Eine Datei, die nach dem Dump auf die Platte geschrieben wurde, ist beim Restore harmlos; der umgekehrte Fall – ein Datenbankeintrag, der auf eine Datei verweist, die beim Lauf von tar noch nicht existierte – wird zum defekten Anhang. Planen Sie es im Cron ein:
# /etc/cron.d/glpi-backup - diario as 02h15
15 2 * * * root /opt/scripts/backup-glpi.sh >> /var/log/glpi-backup.log 2>&1
Entscheidungsmatrix: RPO x RTO
Bevor Sie Häufigkeit und Aufbewahrung festlegen, beantworten Sie zwei Fragen: Wie viele Daten darf das Unternehmen verlieren (RPO), und wie schnell muss es wieder laufen (RTO)? Die Antwort hängt von der Kritikalität ab:
| Profil der Umgebung | Ziel-RPO | Ziel-RTO | Häufigkeit (Datenbank) | Aufbewahrung | Offsite |
|---|---|---|---|---|---|
| Abnahme / Test | 24 h | Tage | täglich | 7 Tage | optional |
| Standardproduktion | 24 h | 4 h | täglich | 14–30 Tage | ja (Cloud) |
| Kritische Produktion (SLA) | 15 min | 1 h | täglich + Binlog oder Replikat | 30–90 Tage | ja, verschlüsselt |
Das sind ehrliche Spannen, keine Versprechen. Ein RPO von 15 Minuten erfordert das Binlog von MariaDB/MySQL oder ein Replikat – der tägliche Dump allein leistet das nicht.
Restore-Test: der Schritt, den fast niemand macht
Ein Backup, das nie wiederhergestellt wurde, ist eine Zahl in einem Bericht, keine Garantie. Proben Sie den Restore regelmäßig in einer Wegwerfumgebung – Docker ist ideal – und niemals über der Produktion:
# Ambiente DESCARTAVEL (Docker). Nunca ensaie por cima da producao.
mysql -u root -e "CREATE DATABASE glpi_restore CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
# 1) Banco
zcat glpi_db.sql.gz | mysql --default-character-set=utf8mb4 -u root glpi_restore
# 2) Arquivos + config (INCLUI o config/glpicrypt.key)
tar -xzf glpi_files.tar.gz -C /var/www/glpi
# 3) Codigo mais novo que o dump? aplica a migracao de schema
php bin/console db:update --no-interaction
# 4) Limpa o cache e sobe para validar login/LDAP/e-mail
php bin/console cache:clear
Bestätigen Sie nach dem Restore, dass der Zustand mit der Realität übereinstimmt, bevor Sie ihm vertrauen. Zwei schnelle Abfragen fangen bereits die häufigsten Probleme ab:
-- Versao gravada no banco (precisa casar com a do codigo antes do db:update)
SELECT value AS versao_db
FROM glpi_configs
WHERE context = 'core' AND name = 'version';
-- Quantos documentos apontam para um arquivo fisico em files/_documents
SELECT COUNT(*) AS docs_com_arquivo
FROM glpi_documents
WHERE filepath <> '';
Die erste zeigt die in der Datenbank gespeicherte Version: Ist sie niedriger als die des Codes, gleicht db:update das Schema an. Die zweite zählt die Dokumente, für die eine Datei auf der Platte erwartet wird – vergleichen Sie das mit dem, was tatsächlich in files/_documents angekommen ist. In Docker laufen dieselben Schritte mit docker exec -u www-data glpi php bin/console ....
Echtes Disaster Recovery
Backup ist ein Befehl; Disaster Recovery ist ein Plan. Das gesunde Minimum ist die 3-2-1-Regel: drei Kopien, auf zwei verschiedenen Medien, eine davon offsite. Und hier liegt der häufige Fehler: den Datenbank-Dump und config/ (mit der glpicrypt.key) unverschlüsselt in dieselbe .tar zu packen und in einen Bucket zu schicken. Wer diese Datei in die Hände bekommt, hat die gesamte Datenbank und den Schlüssel, der die Passwörter für LDAP, SMTP und Collector entschlüsselt – also Infrastruktur-Zugangsdaten des Kunden in wiederherstellbarer Form. Ein Offsite-Backup muss verschlüsselt (zum Beispiel mit age oder gpg) und mit eingeschränktem Zugriff übertragen werden.
Schließen Sie den Plan mit einem schriftlichen Runbook ab – wo die Backups liegen, in welcher Reihenfolge wiederhergestellt wird, wer auslöst – und mit dem in einer echten Probe gestoppten RTO. Im Betriebssupport war das, was einen Schreck von einer Katastrophe trennt, nie das Vorhandensein eines Backups; es war, dieses Backup vorher mit der Stoppuhr in der Hand wiederhergestellt zu haben und zu wissen, dass es in 40 Minuten zurück ist und nicht in „keine Ahnung“.
Wenn Ihr GLPI kritisch ist und Sie noch nie einen vollständigen Restore gestoppt haben – Datenbank, Dateien und Verschlüsselungsschlüssel zusammen –, entwirft und betreibt NexTool die Backup- und Disaster-Recovery-Routine Ihrer Umgebung, mit geprobtem Restore und verschlüsseltem Offsite-Backup. Sprechen Sie mit uns über Support und Betriebssupport für GLPI.
Geprüft vom Team der NexTool Solutions.