Backup que nunca foi restaurado é esperança, não estratégia - e no GLPI a parte que mais derruba o restore não é o dump do banco, é o glpicrypt.key. Na sustentação de ambientes de clientes já vimos restore "perfeito" do banco em que ninguém mais conseguia logar por LDAP nem enviar e-mail: os dados voltaram, mas a chave que decifra as senhas de LDAP, SMTP e coletor de e-mail ficou para trás. Este guia consolida o roteiro de backup, rotação, teste de restore e disaster recovery que aplicamos em produção, com os pontos onde as coisas realmente quebram.
O que realmente precisa entrar no backup
O GLPI tem três camadas de estado, e as três precisam voltar juntas e coerentes:
- Banco de dados - chamados, ativos, usuários, regras e configurações. É o coração, mas sozinho não reergue o ambiente.
- Diretório de arquivos (
files/) - documentos anexados (files/_documents), imagens, inventários XML e dados de plugins. Se o banco tem a linha do documento mas o arquivo não voltou, o usuário clica e recebe erro. - Configuração (
config/) - oconfig_db.php(host, base e credenciais) e, principalmente, oglpicrypt.key. Essa chave é o que decifra as senhas gravadas no banco: bind do LDAP, coletor de e-mail (mailcollector), SMTP das notificações e segredos de OAuth. Restaurar o banco sem ela deixa todas essas senhas como lixo indecifrável.
Dentro de files/ nem tudo precisa de backup. Diretórios voláteis como _cache, _tmp, _sessions, _cron e _lock são regenerados sozinhos e só incham o backup - exclua-os. O que importa preservar é _documents, _pictures, _uploads, _inventories e _plugins.
Dump consistente do banco
O GLPI 10 e 11 usam InnoDB em todas as tabelas, então o --single-transaction tira um snapshot coerente sem travar a aplicação - os usuários continuam abrindo chamados durante o backup. O --quick evita carregar tabelas gigantes na memória e o --default-character-set=utf8mb4 impede corrupção de acentos e emojis. Nunca passe a senha na linha de comando (ela aparece no ps e nos logs); use um arquivo de credenciais restrito:
# ~/.my.cnf (chmod 600) - evita a senha no 'ps' e nos logs
[client]
host = 127.0.0.1
user = glpi
password = ...senha_do_glpi...
O backup nativo do GLPI (Administração > Manutenção) grava um .sql em files/_dumps, mas em bases grandes ele tende a estourar tempo e memória do PHP. Para produção, o mysqldump agendado é mais confiável.
Script de backup com rotação
Um script único que resolve banco, arquivos e config na ordem certa e ainda limpa o que passou de 30 dias:
#!/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}"
Repare na ordem: o dump vem antes do tar. Um arquivo que caiu no disco depois do dump é inofensivo no restore; o contrário - uma linha no banco apontando para um arquivo que ainda não existia quando o tar rodou - vira um anexo quebrado. Agende no cron:
# /etc/cron.d/glpi-backup - diario as 02h15
15 2 * * * root /opt/scripts/backup-glpi.sh >> /var/log/glpi-backup.log 2>&1
Matriz de decisão: RPO x RTO
Antes de fechar frequência e retenção, responda duas perguntas: quanto de dado o negócio aceita perder (RPO) e em quanto tempo precisa estar de pé de novo (RTO). A resposta muda por criticidade:
| Perfil do ambiente | RPO alvo | RTO alvo | Frequência do banco | Retenção | Offsite |
|---|---|---|---|---|---|
| Homologação / teste | 24 h | dias | diário | 7 dias | opcional |
| Produção padrão | 24 h | 4 h | diário | 14-30 dias | sim (nuvem) |
| Produção crítica (SLA) | 15 min | 1 h | diário + binlog ou réplica | 30-90 dias | sim, cifrado |
São faixas honestas, não promessas. RPO de 15 minutos exige binlog do MariaDB/MySQL ou réplica - o dump diário sozinho não entrega isso.
Teste de restore: o passo que quase ninguém faz
Backup que nunca foi restaurado é um número num relatório, não uma garantia. Ensaie o restore periodicamente num ambiente descartável - Docker é ideal - e nunca por cima da produção:
# 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
Depois do restore, confirme que o estado bate com a realidade antes de confiar. Duas consultas rápidas já pegam os problemas mais comuns:
-- 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 <> '';
A primeira mostra a versão gravada no banco: se ela for menor que a do código, é o db:update que reconcilia o schema. A segunda conta os documentos com arquivo esperado em disco - compare com o que realmente veio no files/_documents. Em Docker, os mesmos passos rodam com docker exec -u www-data glpi php bin/console ....
Disaster recovery de verdade
Backup é comando; disaster recovery é plano. O mínimo saudável é a regra 3-2-1: três cópias, em dois meios diferentes, uma delas offsite. E aqui mora o erro comum: jogar o dump do banco e o config/ (com o glpicrypt.key) no mesmo .tar sem cifrar e mandar para um bucket. Quem puser a mão nesse arquivo tem o banco inteiro e a chave que decifra as senhas de LDAP, SMTP e coletor - ou seja, credenciais de infraestrutura do cliente em texto recuperável. Backup offsite tem que ir cifrado (por exemplo com age ou gpg) e com acesso restrito.
Feche o plano com um runbook escrito - onde estão os backups, qual a ordem de restore, quem aciona - e com o RTO cronometrado num ensaio real. Na sustentação, o que separa um susto de uma catástrofe nunca foi ter backup; foi ter restaurado aquele backup antes, com relógio na mão, e saber que ele volta em 40 minutos e não em "não sei".
Se o seu GLPI é crítico e você nunca cronometrou um restore completo - banco, arquivos e a chave de cifra juntos - a NexTool desenha e opera a rotina de backup e disaster recovery do seu ambiente, com restore ensaiado e offsite cifrado. Fale com a gente sobre suporte e sustentação de GLPI.
Este conteúdo foi produzido com auxílio de inteligência artificial e revisado pela equipe Nextool Solutions.