Relato Real ⑤: resgate em 2 dias de um servidor sem suporte

Casos de adoção de IA

"Está funcionando, então não mexa." Um sistema que ouviu isso repetidamente e, quando se percebeu, seguia no centro da empresa igual a 10 anos atrás — muitas empresas devem se reconhecer nisso. Desta vez, o relato é de um sistema de gestão de projetos lançado em 2016 quecontinuava exposto na internet sobre um SO que perdeu o suporte em 2020, e que migramos desse estado para um ambiente moderno. 2 dias de trabalho efetivo.Transferimos 3.623 tickets e 4,0 GB de anexos sem uma única perda.

O "como está funcionando, não dá para mexer" durou 10 anos.

O alvo era o sistema interno de gestão de projetos (Redmine). O andamento dos projetos, os registros de tratamento de falhas, o histórico das trocas com clientes — 10 anos acumulados ali. Exatamente o estado denão dá para mexer porque não dá para parar.

Mas, ao examinar o conteúdo, definitivamente não era um estado que se pudesse deixar de lado.

ItemAntes da migraçãoDepois da migração
OSCentOS 6.10
(suporte encerrado em 2020)
AlmaLinux 10.1
AplicaçãoRedmine 3.2.1 (2016)Redmine 6.1.3
Ambiente de execuçãoRuby 2.2.4Ruby 3.3.10
Banco de dadosMySQL 5.7MariaDB 10.11
Servidor webApache 2.2 + Passengernginx 1.26 + puma

6 anos desde que o SO perdeu o suporte.Nenhuma das correções de vulnerabilidades divulgadas nesse período foi aplicada. E isso seguia rodando em um estado acessível de fora da empresa. Não é "seguro porque está funcionando", mas sim"apenas está funcionando, mas não está protegido"— esta é a descrição exata.

O verdadeiro risco do legado não é "quebrar um dia".
É que, sem quebrar, apenas a proteção ficou parada.

O sucesso ou o fracasso da migração já estava decidido pela medição feita antes de começar.

Antes de entrar na migração, fixamos a situação atual em números. No fim das contas, foi isso que mais influenciou o esforço.

  • Banco de dados 38 MB / arquivos anexos 4,0 GB
  • 20 a 30 requisições por dia =em uso ativo
  • Plugins de extensão: zero. Design próprio: nenhum

A última linha foi decisiva. O que mais gera atrito neste tipo de migração ése as extensões acrescentadas depois vão funcionar na nova versão. Se não funcionarem, restam três opções — "procurar um substituto", "abrir mão da funcionalidade" ou "consertar por conta própria" — e ali se perdem várias semanas. Desta vez, esse obstáculo simplesmente não existia desde o início.

Com base nessa medição, definimos 3 diretrizes antes de começar.

1. Abandonamos subir a versão degrau por degrau

Inicialmente estimamos com a premissa de subir por etapas: 3.2 → 4.2 → 5.1 → 6.x. Mas, ao verificar, descobrimos que era possívelatualizar de uma só vez, pulando 10 anos de golpe. O esforço que havíamos previsto ficou inteiramente dispensável.

2. Não mudamos o tipo de banco de dados

Havia também a ideia de migrar para outro produto de banco de dados para alinhar a operação com os demais sistemas. Mas, como o formato dos dados de origem é diferente, seria preciso intercalar um processo de conversão.Não trazer o risco da conversão para "dados cujo sumiço é difícil de perceber" — os 3.623 tickets e as 6.071 entradas de histórico.Priorizamos que nem um único registro se perdesse, acima da uniformização da operação.

3. Não atualizamos diretamente o servidor existente

Preparamos um servidor novo à parte e fizemos a troca consistir em reescrever apenas 1 linha da configuração da porta de entrada.se algo falhar, basta reverter 1 linha para voltar ao que eraFoi para manter esse estado até o fim.

O que tomou tempo não foi o Redmine.

Daqui em diante é a parte prática. Ao alinhar os problemas que enfrentamos durante a migração, uma tendência ficou nítida.

O servidor antigo e o novo, para começar, não conseguiam se comunicarOSO SO mais recente rejeita, por considerá-los inseguros, os métodos de criptografia de geração anterior.Não havia meio de transportar um arquivo de 4 GBFoi desse ponto que a migração começou. Criamos no lado do servidor antigo uma porta temporária de transferência e, ao terminar, a fechamos para resolver.
10 anos de atualizações de versão passaram de uma só vezAplicaçãoComo o Redmine guarda todos os procedimentos de atualização do passado, foi possível ir direto à versão mais recente sem passar pelas versões intermediárias. As 57 rotinas de atualização concluíram sem erros.só foi possível porque as extensões eram zeroÉ um atalho.
Uma peça necessária não vem na configuração padrãoAplicaçãoA peça usada para integrar com o servidor web não vem embarcada no Redmine em si. Resolvemos acrescentando-a ao espaço de extensão oficial, que não é sobrescrito em atualizações futuras.
Mesmo abrindo todas as permissões, era recusado com "você não tem permissão"OSO mecanismo de segurança do SO bloqueava a comunicação em uma camada distinta das permissões de arquivo.por mais que se afrouxem as configurações de permissão, não se resolveUm caso típico. Resolvemos alterando o próprio método de conexão.
No instante em que se fazia login, "página não encontrada"Rota de comunicaçãoDois servidores na rota sobrescreviam mutuamente a mesma informação, e a informação da comunicação criptografada se perdia. A aplicação estava normal, eapenas o destino do encaminhamento não existia— uma falha difícil de entender.
Não era possível enviar e-mails de notificação por erro de certificadoCriptografiaComo a conexão era por endereço IP, não coincidia com o nome do certificado.sem contornar desativando a verificação, resolvemos definindo um nome compatível com o certificado e mantendo a verificação ativada.
Não há, no padrão, uma função para deter a força bruta de senhasAplicaçãoO Redmine não tem a função padrão de "bloquear após um número determinado de falhas". Reforçamos limitando o número de tentativas no lado do servidor web.errar o local do bloqueio deixa todos os funcionários trancados para forapor isso, é premissa uma configuração que identifique corretamente a origem real do acesso.
A integração com o código-fonte dependia do servidor antigoIntegração externaUma configuração que referenciava diretamente arquivos dentro do servidor antigo; ao migrar, tudo se quebraria. Criamos um mecanismo de replicação automática a partir do servidor Git interno, passando a uma configuraçãoatualizada a cada 15 minutos. A integração, que estava congelada, na verdade ressuscitou.

Dos 8,apenas 3 vieram do próprio Redmine. E, ainda por cima, um deles foi um bom engano: "foi mais fácil do que se pensava". Na prática, os que realmente deram trabalho foram só 2.

O restante — diferença de geração do SO, mecanismo de segurança, rota de comunicação, criptografia, integração com sistemas externos —está tudo do lado de fora da aplicação.

O que devora o esforço de uma migração de legado não é a aplicação em si.
São as "diferenças do ambiente ao redor" acumuladas ao longo de 10 anos.

Não abrir mão do "reverte com 1 linha" até o fim.

A troca consiste apenas em apontar o destino de encaminhamento do servidor de entrada para o servidor novo. Reverter também é 1 linha. Enão paramos o ambiente antigo: deixamos ele em funcionamento.

No dia da troca, o "ambiente antigo funcionando" e o "ambiente novo funcionando" coexistiam, mantendo o estado em que se podia ir e voltar entre eles com 1 linha. Só depois de deixar passar alguns dias e confirmar que não havia problema é que paramos o lado antigo.

Separar em dias diferentes a "troca" e a "parada do ambiente antigo".Só isso já muda as decisões no dia. Sabendo que dá para reverter se algo acontecer, não é preciso, no afobamento, empilhar remendos sem conhecer a causa. O que sai mais caro num trabalho de migração éentrar em pânico num estado sem volta.

Não paramos na migração: preenchemos 10 anos de lacunas.

No novo ambiente, ao mesmo tempo, providenciamos o que não existia no antigo.

  • Backup diário (7 gerações) — o ambiente antigo não tinha sequer um mecanismo de backup
  • Registro da origem dos acessos — antes da migração, todos os acessos pareciam iguais, num estado em que não se conseguia rastrear quem vinha de onde
  • Limitação de tentativas de login — como não há função padrão, reforçamos no lado do servidor web
  • Atualização automática da integração com o código-fonte — a integração, na prática congelada, passou a se atualizar a cada 15 minutos

Os dados transferidos como resultado são os seguintes. Confirmamos que a contagem coincide perfeitamente entre o ambiente antigo e o novo.

21Projetos
3,623Tickets
6,071Histórico de tratamentos
4.0GBArquivos anexos (perda 0)

A integração vinda de sistemas externos também funciona como estava, sem alteração de configuração.Do ponto de vista do usuário, apenas a tela de login ficou nova— um desfecho ideal para uma migração.

Se "nós também temos um servidor igual".

As razões pelas quais esta migração terminou em pouco tempo se resumem a 3.

  • não havia extensões instaladas— por isso foi possível pular 10 anos de uma só vez
  • medimos de verdade antes de começar— o material de decisão estava reunido em números
  • mantivemos um estado reversível— não foi preciso apostar no dia da troca

Dito de outro modo,esses 3 pontos podem ser verificados antes de começar."Temos um sistema que não pode parar rodando em um servidor sem suporte" — se você se reconhece nisso, comece a conversa por captar a situação atual em números. Se dá ou não para migrar, na maioria das vezes se descobre ao investigar.

Apoiamos a migração e a modernização de sistemas corporativos que seguem rodando sobre SOs sem suporte e frameworks antigos.
A investigação da situação atual (versão, volume de dados, existência de extensões, abrangência da exposição) é gratuita. Junto com a modernização de sistemas legados (AI Re: Platform / abreviada como AIR Platform),Fale conosco agora mesmo.

Formulário de contato(indique "Desejo consulta sobre migração de legado") / info@flagship-ai.jp

Série "Do Legado à IA — Relatos Reais"

* Os números deste artigo são valores medidos em agosto de 2026. O prazo e o conteúdo do trabalho de migração variam conforme a configuração do sistema e a existência de extensões.

Tags:

🌐 Português