Como Atualizar o GLPI no Docker Entre Versões

Roteiro de produção para atualizar o GLPI no Docker entre versões minor e major: matriz de decisão, backup consistente, migração de schema, rollback ensaiado e as armadilhas reais (config_db perdido, OPcache, plugin incompatível) que causam downtime.

Atualizar o GLPI no Docker parece trivial - trocar a tag da imagem e subir o container - mas é justamente essa aparente simplicidade que gera downtime não planejado. Na sustentação de ambientes de clientes, a maioria dos incidentes de atualização não vem da migração do banco em si, e sim de plugins incompatíveis, do PHP embarcado na imagem nova ou de um volume mapeado errado que faz o GLPI perder a configuração de banco. Este guia consolida o roteiro que aplicamos em produção, com os pontos onde as coisas realmente quebram.

Antes de tocar em qualquer container: o inventário de compatibilidade

Uma atualização de GLPI não é só a imagem. São três camadas que precisam subir juntas: o core, os plugins e o schema do banco. O erro clássico é atualizar a imagem e descobrir, com o site fora, que um plugin crítico (por exemplo o de inventário nativo, um SSO ou uma customização de campo) não tem versão para o novo core. Levante isto antes:

  • Versão de origem e destino exatas - salto minor (10.0.15 para 10.0.18) é seguro; salto major (10.x para 11.x) muda requisito de PHP e pode aposentar plugins.
  • Matriz de plugins - para cada plugin instalado, confirmar que existe release compatível com o destino. Plugin sem versão compatível = decisão de negócio (desativar, substituir ou adiar o upgrade), nunca uma surpresa às 2h da manhã.
  • PHP embarcado na imagem - a imagem oficial já traz o PHP certo, mas se você usa imagem própria (Alpine + php-fpm), o GLPI 11 exige PHP 8.2+. Um core novo sobre PHP velho dá tela branca sem log claro.
  • Espaço em disco - o dump e o tar de volumes podem dobrar temporariamente o uso. Verifique antes, não durante.

Matriz de decisão: minor, major ou pular versões

O tipo de salto define o roteiro. Esta é a matriz que usamos para dimensionar janela e risco:

CenárioExemploRiscoJanela típicaCuidado principal
Patch/minor10.0.15 → 10.0.18Baixo5 a 15 minMigração de schema leve; plugins geralmente seguem
Major10.0.x → 11.0.xAlto30 a 90 minPHP, plugins e mudanças de comportamento; homologar antes
Pular majors9.5.x → 11.0.xMuito altoPlanejar por etapasNÃO pular; migrar 9.5 → 10.0 → 11.0 em saltos

O erro comum aqui é achar que pular versões economiza tempo. O GLPI não garante migração de schema saltando um major inteiro; a rotina de db:update espera a estrutura da versão imediatamente anterior. Pular 9.5 direto para 11 costuma travar a migração no meio, com o banco em estado inconsistente - e aí o rollback deixa de ser opcional.

Passo a passo da atualização

1. Backup consistente (banco + volumes)

Backup não é o dump sozinho. É o dump do banco mais o tar dos volumes de arquivos (uploads, documentos, cache de plugins). Os dois têm que ser do mesmo instante - por isso paramos a aplicação antes, mantendo só o banco de pé para o dump:

# Para a app, mantém o banco de pé
docker compose stop glpi-app

# Dump do banco (usuário dedicado, senha via variável de ambiente)
docker exec glpi-db sh -c 'mysqldump --single-transaction \
  -u glpi -p"${MYSQL_PASSWORD}" glpi' | gzip > /backup/pre-update-$(date +%F).sql.gz

# Tar dos volumes de arquivos do GLPI
tar -czf /backup/pre-update-files-$(date +%F).tar.gz \
  /var/lib/docker/volumes/glpi_files/_data

O --single-transaction garante um dump coerente sem travar as tabelas InnoDB. E jamais coloque a senha literal na linha de comando: ela vaza no histórico do shell e no docker inspect.

2. Congelar a versão de destino no compose

Nunca use a tag latest em produção. Ela move o alvo sem aviso e impede um rollback determinístico. Fixe a versão exata:

# docker-compose.yml
services:
  glpi-app:
    # De:
    image: glpi/glpi:10.0.18
    # Para (versão exata de destino, nunca :latest):
    image: glpi/glpi:11.0.1
    volumes:
      - glpi_files:/var/glpi/files
      - glpi_config:/var/glpi/config   # config_db.php mora aqui - NÃO perder

3. Subir a nova imagem

docker compose pull glpi-app
docker compose up -d glpi-app

4. Rodar a migração de schema

O comando de migração mudou de nome entre gerações do GLPI. Confirme qual o binário disponível antes de rodar às cegas:

# GLPI 10/11 (console Symfony):
docker exec -u www-data glpi-app php bin/console db:update --no-interaction

# GLPI mais antigo (10.0 inicial) usava:
# docker exec -u www-data glpi-app php bin/console glpi:database:update --no-interaction

Rode sempre como o usuário do web server (www-data ou apache), nunca como root. Rodar a migração como root cria arquivos de cache com dono errado, e o GLPI passa a dar erro de permissão depois - um falso "quebrou na atualização" que é só ownership.

5. Limpar cache e validar

docker exec -u www-data glpi-app php bin/console cache:clear
  • Acesse a interface e confira a versão em Configuração > Geral.
  • Rode o diagnóstico interno em Configuração > Verificações (checa PHP, extensões e permissões).
  • Confirme que os plugins críticos aparecem como ativos, não como "precisa atualizar".
  • Teste um fluxo real: abrir um chamado, anexar um documento, disparar uma notificação.

O que aprendemos operando isto para clientes

Na sustentação, o incidente que mais se repete não é a migração falhar - é a migração parecer ter dado certo e o GLPI subir com o banco padrão vazio. A causa quase sempre é a mesma: o volume que guarda o config/config_db.php não foi mapeado, ou foi mapeado para um caminho diferente na versão nova. O GLPI não acha a configuração de banco, assume que é uma instalação limpa e mostra o wizard de instalação. Quem está com pressa clica em "instalar" e cria um banco novo por cima - agora além do downtime há risco de perda de dados. Por isso, na nossa checklist, a primeira validação pós-boot não é a versão: é docker exec glpi-app cat /var/glpi/config/config_db.php retornar a configuração real do cliente. Se aparecer o wizard, paramos tudo antes de qualquer clique e revisamos o mapeamento de volume - nunca seguimos pela interface.

O segundo padrão é o cache do OPcache servindo código antigo depois do upgrade. A imagem trocou, o código no disco é novo, mas o php-fpm ainda tem a versão antiga compilada em memória. Sintoma: erros de método inexistente ou versão do core que não bate com a imagem. Recriar o container (e não apenas reiniciar) resolve, porque o processo do php-fpm é reinicializado do zero.

Plano de rollback (ensaiado, não improvisado)

Rollback só é confiável se foi pensado antes. Com o dump e o tar do passo 1, o retorno é determinístico:

# Derruba a versão nova
docker compose down

# Restaura o banco a partir do dump
gunzip < /backup/pre-update-2026-07-02.sql.gz \
  | docker exec -i glpi-db sh -c 'mysql -u glpi -p"${MYSQL_PASSWORD}" glpi'

# Reverte a tag da imagem no docker-compose.yml para a versão anterior
# (ex.: glpi/glpi:11.0.1 de volta para glpi/glpi:10.0.18)

docker compose up -d

Ponto crítico do rollback: o schema. Depois que o db:update alterou a estrutura, o banco não é mais compatível com a imagem antiga. Por isso o rollback tem que restaurar o dump - não basta voltar a tag. Restaurar só a imagem, com o schema já migrado, deixa o GLPI antigo lendo tabelas de estrutura futura, o que gera erros silenciosos e difíceis de rastrear.

Fazendo isto sem downtime não planejado

Se o ambiente é crítico, a janela precisa ser ensaiada em homologação com um clone do banco de produção. É lá que se descobre, sem pressão, se um plugin quebra ou se a migração demora mais que a janela combinada. Atualizar direto em produção sem esse ensaio é apostar a disponibilidade do cliente na sorte.

Se a sua equipe não tem janela para ensaiar cada upgrade, ou já apanhou de uma atualização que virou madrugada, a NexTool cuida da sustentação e das atualizações do seu GLPI com rollback ensaiado e janela combinada. 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.

Perguntas Frequentes

Pare a aplicação (mantendo o banco de pé), faça o dump com --single-transaction e o tar dos volumes de arquivos no mesmo instante, fixe a versão exata da imagem no docker-compose.yml (nunca :latest), suba o container e rode php bin/console db:update --no-interaction como www-data. A perda de dados quase sempre vem de volume mal mapeado, não da migração em si.

Não. A rotina de db:update espera a estrutura da versão imediatamente anterior. Pular um major inteiro trava a migração no meio e deixa o banco inconsistente. O caminho seguro é migrar em saltos: 9.5 para 10.0, validar, depois 10.0 para 11.0.

Depende do salto. Patch ou minor (ex.: 10.0.15 para 10.0.18) costuma levar de 5 a 15 minutos. Um upgrade major (10.x para 11.x) leva de 30 a 90 minutos, incluindo backup, migração e validação, e deve ser ensaiado antes em homologação.

O container não encontrou o config/config_db.php - normalmente porque o volume que guarda a configuração de banco não foi mapeado ou mudou de caminho na imagem nova. Não clique em instalar (isso cria um banco vazio por cima). Pare tudo, corrija o mapeamento do volume de config e suba de novo.

Derrube os containers, restaure o dump do banco pré-atualização e reverta a tag da imagem no docker-compose.yml para a versão anterior. É obrigatório restaurar o dump: depois que o db:update alterou o schema, a imagem antiga não é mais compatível com a estrutura migrada, então só voltar a tag causa erros silenciosos.

Não, o contrário. Rode sempre como o usuário do web server (www-data ou apache). Rodar db:update como root cria arquivos de cache com dono errado e o GLPI passa a dar erro de permissão depois - um falso alarme de 'quebrou na atualização' que é só ownership.

Precisa de ajuda?