Migração de US$ 1,4 mil para R$ 1.200 com tempo zero parado
A migração real de um servidor de produção da DigitalOcean para um dedicado da Hetzner, lidando com 248 GB de dados MySQL distribuídos em 30 bancos de dados, 34 sites Nginx, GitLab EE, Neo4j e tráfego ativo de aplicativos móveis – tudo sem nenhum tempo de inatividade. Essa não foi apenas uma mudança de hospedagem, mas uma revolução nos custos de infraestrutura que impactou diretamente a saúde financeira de uma empresa de software na Turquia.
Nos últimos anos, administrar uma empresa de tecnologia na Turquia tornou-se uma verdadeira dor de cabeça financeira. A inflação galopante e a desvalorização acentuada da lira turca frente ao dólar americano transformaram custos denominados em moeda estrangeira em um fardo insustentável. Aquela conta que parecia razoável dois anos atrás agora dói profundamente quando a cotação do dólar se multiplica diversas vezes.
Mensalmente, a empresa pagava US$ 1.432 à DigitalOcean por um droplet com 192 GB de RAM, 32 vCPUs, 600 GB de SSD, dois volumes de bloco (1 TB cada) e backups ativados. O servidor funcionava bem – mas a relação custo-benefício simplesmente deixou de fazer sentido. Foi quando descobrimos o Hetzner AX162-R.
A economia anual? Cerca de US$ 14.388 por ano – por um servidor que, em todas as métricas, é objetivamente mais potente. A decisão se tornou óbvia: era hora de trocar a nuvem pelo hardware dedicado, sem arrependimentos.
Sou cliente da DigitalOcean há quase oito anos. Tenho apenas elogios sobre a confiabilidade da plataforma e a experiência do desenvolvedor. No entanto, ao analisar esses números hoje, não posso deixar de me perguntar quanto dinheiro deixei de economizar ao longo dos anos. Se você está executando cargas de trabalho estáveis e não está aproveitando os recursos do ecossistema da DO, faça um favor a si mesmo: pesquise os preços de servidores dedicados antes do próximo ciclo de renovação.
Isso não foi um projeto secundário. A infraestrutura incluía:
Servidor antigo: CentOS 7 – há muito além do fim do suporte, mas ainda rodando em produção.
Servidor novo: AlmaLinux 9.7 – uma distribuição compatível com RHEL 9 e a sucessora natural do CentOS. Essa migração também representou a oportunidade de finalmente abandonar um sistema operacional que não recebia atualizações de segurança há anos.
A abordagem ingênua – mudar o DNS, reiniciar tudo e torcer pelo melhor – não era aceitável. Em vez disso, projetamos um plano de migração com seis fases cuidadosamente estruturadas para garantir zero tempo de inatividade.
Fase 1 – Instalação completa da pilha no novo servidor
Nginx (compilado a partir do código-fonte com as mesmas flags), PHP (via repositório Remi, com os mesmos arquivos .ini do servidor antigo), MySQL 8.0, Neo4j (banco de dados de grafos), GitLab EE, Node.js, Supervisor e Gearman. Cada serviço precisava ser configurado para replicar exatamente o comportamento do servidor antigo antes de sequer tocarmos em um registro DNS.
Os certificados SSL foram transferidos copiando todo o diretório /etc/letsencrypt/ do servidor antigo para o novo via rsync. Após a migração ser concluída e todo o tráfego fluindo pelo novo servidor, forçamos a renovação de todos os certificados de uma só vez.
Fase 2 – Clonagem dos arquivos web com rsync
Todo o diretório /var/www/html (cerca de 65 GB, 1,5 milhão de arquivos) foi replicado para o novo servidor usando rsync sobre SSH com a flag –checksum para verificação de integridade. Executamos uma sincronização incremental final pouco antes da troca de DNS para capturar quaisquer arquivos modificados após a clonagem inicial.
Fase 3 – Replicação MySQL mestre-escravo
Em vez de tirar o banco de dados do ar para um dump e restore tradicional, estabelecemos uma replicação ao vivo. O servidor antigo tornou-se o mestre, enquanto o novo virou um escravo somente leitura. Utilizamos o mydumper para o carregamento inicial em massa, seguido pelo início da replicação a partir da posição exata do binlog registrada nos metadados do dump. Isso manteve ambos os bancos de dados sincronizados em tempo real até o momento da troca definitiva.
Fase 4 – Redução do TTL do DNS
Criamos um script para acessar a API do DigitalOcean DNS e reduzir todos os registros A e AAAA de 3600 para 300 segundos – sem tocar em registros MX ou TXT (alterar o TTL de registros de email pode causar problemas de entregabilidade). Após aguardar uma hora para que os antigos TTLs expirassem globalmente, estávamos prontos para a troca em menos de cinco minutos.
Fase 5 – Conversão do Nginx do servidor antigo em proxy reverso
Desenvolvemos um script em Python que analisou cada bloco server {} em todos os 34 arquivos de configuração do Nginx, criou backups das configurações originais e as substituiu por configurações de proxy apontando para o novo servidor. Isso significava que, durante a propagação do DNS, qualquer requisição que ainda chegasse ao IP antigo seria silenciosamente encaminhada. Nenhum usuário perceberia qualquer interrupção.
Fase 6 – Troca do DNS e desativação do servidor antigo
Um único script em Python acionou a API do DigitalOcean e alterou todos os registros A para o novo IP do servidor em questão de segundos. O servidor antigo permaneceu como standby frio por uma semana antes de ser desligado permanentemente.
A lição-chave: em nenhum momento tivemos uma janela em que o serviço estivesse indisponível. O tráfego sempre foi atendido – seja diretamente ou através do proxy.
Essa parte foi, de longe, a mais complexa de toda a operação. Utilizamos o mydumper em vez do tradicional mysqldump – e a diferença foi monumental. Ao aproveitar os 48 núcleos de CPU do novo servidor para exportação e importação paralelas, o que teria levado dias com um mysqldump single-threaded foi concluído em poucas horas. Se você está migrando um banco de dados MySQL grande e não está usando o mydumper/myloader, está fazendo as coisas do jeito difícil.
O arquivo de metadados do dump principal registrava a posição do binlog no momento do snapshot – essa seria nossa referência inicial para a replicação. Assim que o dump foi concluído, transferimos o arquivo para o novo servidor via rsync sobre SSH. Com 248 GB de chunks compactados, a transferência foi significativamente mais rápida do que qualquer outro método.
A flag –compress do mydumper se mostrou crucial aqui – os chunks compactados trafegaram muito mais rápido pela rede. Ficar preso ao CentOS 7 também significava estar preso ao MySQL 5.7 – uma versão desatualizada que vinha rodando em produção há anos. Antes da migração, executamos mysqlcheck –check-upgrade para verificar se nossos dados eram compatíveis com o MySQL 8.0. O resultado foi positivo, então instalamos a versão mais recente do MySQL 8.0 Community no novo servidor. A melhoria de desempenho em todos os nossos projetos foi imediata – os tempos de execução de queries caíram significativamente graças ao otimizador aprimorado do MySQL 8.0 e às melhorias no InnoDB.
No entanto, a atualização de versão introduziu um problema complicado. Após a importação, a tabela mysql.user apresentou uma estrutura de colunas incorreta – 45 colunas em vez das 51 esperadas. Isso fez com que o mysql.infoschema estivesse ausente, quebrando a autenticação de usuários.
Primeiro, tentamos:
Mas isso falhou na primeira execução com:
O schema sys havia sido importado como tabelas regulares em vez de views. A solução foi:
Em seguida, executamos novamente a atualização. Funcionou.
Com ambos os dumps importados, configuramos o novo servidor como réplica do antigo – mas quase imediatamente a replicação parou com o erro 1062 (chave duplicada). Isso ocorreu porque nosso dump foi feito em duas etapas – durante a lacuna entre elas, linhas foram escritas em certas tabelas, e agora tanto o dump importado quanto a reprodução do binlog estavam tentando inserir as mesmas linhas.
A solução foi ativar o modo IDEMPOTENT, que silenciosamente ignora erros de chave duplicada e linhas ausentes. Todos os bancos de dados críticos sincronizaram sem nenhum erro. Em poucos minutos, o Seconds_Behind_Master caiu para zero.
Antes de sequer tocar em um registro DNS, precisávamos verificar se todos os serviços estavam funcionando corretamente no novo servidor. A estratégia: editamos temporariamente o arquivo /etc/hosts em nossa máquina local para apontar nossos domínios para o IP do novo servidor.
Com isso em vigor, nossos navegadores e o Postman acessavam o novo servidor enquanto o restante do mundo ainda ia para o antigo. Testamos nossas APIs, verificamos painéis de administração e confirmamos que cada serviço respondia corretamente. Somente após essa confirmação prosseguimos com a troca definitiva.
Assim que a replicação mestre-escravo estava totalmente sincronizada, notamos que instruções INSERT estavam sendo bem-sucedidas no novo servidor quando não deveriam – apesar da configuração read_only = 1 estar ativada.
O motivo? Todos os usuários de aplicativos PHP tinham privilégio SUPER concedido. No MySQL, o SUPER ignora a restrição read_only. Revogamos esse privilégio de todos os 24 usuários de aplicação:
Após isso, read_only = 1 passou a bloquear corretamente todas as escritas dos usuários do aplicativo enquanto permitia que a replicação continuasse normalmente.
Todos os domínios eram gerenciados pelo DigitalOcean DNS (com nameservers apontados do GoDaddy). Scriptamos a redução do TTL pela API do DigitalOcean, tocando apenas em registros A e AAAA – jamais MX ou TXT, já que alterar o TTL de registros de email pode causar problemas de entregabilidade com o Google Workspace.
Após aguardar uma hora para que os antigos TTLs expirassem, estávamos prontos. Em vez de editar manualmente 34 arquivos de configuração, desenvolvemos um script Python que analisou cada bloco server {} em todos os arquivos, identificou os blocos de conteúdo principais, substituiu-os por configurações de proxy e criou backups dos originais como arquivos .backup.
O detalhe crucial: proxy_ssl_verify off – o certificado SSL do novo servidor é válido para o domínio, não para o endereço IP. Desabilitar a verificação aqui é seguro porque controlamos ambas as extremidades.
Com a replicação em Seconds_Behind_Master: 0 e o proxy reverso pronto, executamos a troca definitiva na seguinte ordem:
O script de troca DNS acionou a API do DigitalOcean e alterou todos os registros A para o novo IP do servidor – em aproximadamente 10 segundos.
Após a migração, descobrimos que muitos webhooks de projetos no GitLab ainda apontavam para o IP antigo do servidor. Criamos um script para escanear todos os projetos via API do GitLab e atualizá-los em lote.
Passamos de US$ 1.432 por mês para R$ 1.200 (aproximadamente US$ 233) – economizando cerca de US$ 14.388 por ano. E ainda ganhamos um hardware mais potente:
CPU: de 32 vCPUs para 96 lógicas (AMD EPYC 9454P, 48 núcleos x 2 threads)
RAM: de 192 GB para 256 GB DDR5
Armazenamento: de ~2,6 TB mistos para 2 TB NVMe em RAID1
Tempo de inatividade: 0 minutos
A migração completa levou cerca de 24 horas. Nenhum usuário foi afetado.
A replicação MySQL é sua melhor amiga para migrações sem tempo de inatividade. Estabeleça-a cedo, deixe-a sincronizar e faça a troca com confiança.
Verifique os privilégios de usuário do MySQL antes da migração. O privilégio SUPER ignora a restrição read_only – se seus usuários de aplicação o tiverem, seu ambiente escravo não estará realmente em modo somente leitura.
Automatize tudo. Atualizações de DNS, reescritas de configuração do Nginx, atualizações de webhooks – fazer isso manualmente em 34+ sites teria consumido horas e introduzido erros.
O mydumper + myloader supera dramaticamente o mysqldump para grandes conjuntos de dados. O dump/restore paralelo com 32 threads transformou o que seria dias de trabalho em poucas horas.
Provedores de nuvem são caros para cargas de trabalho estáveis. Se você não está usando autoescalonamento ou infraestrutura efêmera, um servidor dedicado geralmente entrega melhor desempenho por uma fração do custo.
Todos os scripts Python utilizados nessa migração foram abertos e estão disponíveis no GitHub:
[GitHub Project](https://github.com/exemplo/projeto-migracao-hetzner)
Todos os scripts suportam um modo DRY_RUN = True, permitindo que você visualize as alterações com segurança antes de aplicá-las.
Essa migração não foi apenas uma mudança de provedor, mas uma redefinição completa da estratégia de infraestrutura. A combinação de planejamento meticuloso, automação agressiva e uso de ferramentas especializadas como o mydumper transformou o que poderia ter sido uma operação arriscada e complexa em um processo suave e transparente para os usuários finais.
A lição mais valiosa aprendida? Nunca subestime o poder da replicação de banco de dados em migrações críticas. Ela não apenas elimina a necessidade de janelas de manutenção, mas também fornece um mecanismo de fallback instantâneo caso algo dê errado durante a transição. O fato de termos mantido todas as aplicações funcionando durante todo o processo – mesmo durante a propagação do DNS – demonstra que, com as ferramentas certas e um planejamento cuidadoso, migrações complexas podem ser executadas com zero impacto para os usuários.
Outro ponto crucial foi a atenção aos detalhes nos privilégios do MySQL. O privilégio SUPER é um verdadeiro “quebra-galho”, mas em ambientes de replicação pode causar comportamentos inesperados. Revogar privilégios desnecessários antes da migração evita dores de cabeça durante a sincronização e garante que a réplica realmente se comporte como um servidor somente leitura.
A automação dos processos de DNS e configuração do Nginx foi outro divisor de águas. Tentar gerenciar 34 sites manualmente teria sido um pesadelo operacional, especialmente considerando que estávamos lidando com um ambiente de produção ativo. Os scripts Python não apenas economizaram tempo, mas também reduziram significativamente o risco de erros humanos durante a transição crítica.
Do ponto de vista financeiro, a migração representa uma economia anual equivalente a cerca de 84% do custo anterior. Em um cenário de alta inflação e moeda instável como o da Turquia, essa redução de custos não é apenas interessante – é fundamental para a sobrevivência do negócio. O novo servidor Hetzner não apenas custa menos, como também oferece melhor desempenho em praticamente todos os aspectos medíveis: mais núcleos de CPU, mais RAM, armazenamento NVMe rápido e uma arquitetura moderna que permite escalabilidade futura sem depender de provedores de nuvem caros.
Para empresas brasileiras que ainda dependem de infraestrutura na nuvem internacional, essa história serve como um alerta importante. Com a desvalorização do real frente ao dólar, custos denominados em moeda estrangeira podem rapidamente se tornar insustentáveis. A migração para servidores dedicados em data centers internacionais – como a Hetzner na Alemanha ou outras opções na Europa e EUA – pode representar economias significativas sem sacrificar performance.
No entanto, é fundamental ressaltar que esse tipo de migração requer expertise técnica considerável. A abordagem descrita aqui não é recomendada para iniciantes ou equipes sem experiência em administração de sistemas Linux e gerenciamento de bancos de dados. O uso de ferramentas como mydumper, configuração de replicação MySQL e automação de DNS exige conhecimento técnico sólido para evitar perdas de dados ou tempo de inatividade não planejado.
Outro aspecto importante a considerar são os custos ocultos da migração. Embora tenhamos economizado US$ 14.388 por ano, o processo consumiu aproximadamente 24 horas de trabalho técnico intensivo. Para uma equipe pequena, isso representa um investimento significativo de tempo e recursos. Além disso, há o risco inerente a qualquer mudança de infraestrutura – mesmo com todo o planejamento, sempre existe a possibilidade de algo dar errado no último segundo.
Felizmente, nossa estratégia de migração lenta e gradual, combinada com a replicação MySQL ao vivo, forneceu um colchão de segurança excelente. Mesmo se tivéssemos encontrado problemas graves durante a transição, poderíamos ter revertido para o servidor antigo em questão de minutos simplesmente alterando o DNS de volta. Essa abordagem “canário” é altamente recomendada para migrações críticas.
Do ponto de vista da segurança, a migração também representou uma atualização significativa. O novo servidor executando AlmaLinux 9.7 oferece suporte a longo prazo e atualizações de segurança contínuas, ao contrário do CentOS 7 que já estava em modo legacy há anos. Isso reduz significativamente a superfície de ataque da infraestrutura e elimina preocupações com vulnerabilidades não corrigidas.
O MySQL 8.0 trouxe melhorias significativas de desempenho, especialmente para queries complexas. Os benchmarks internos mostraram reduções de até 40% no tempo de resposta de queries pesadas após a migração. Além disso, os novos recursos do MySQL 8.0, como o suporte nativo a JSON e as melhorias no otimizador de queries, abrem portas para futuras otimizações da aplicação.
Para equipes brasileiras que estão considerando migrações semelhantes, algumas recomendações práticas emergem desse caso:
1. **Avalie seus padrões de uso**: Se você está executando cargas de trabalho estáveis sem necessidade de elasticidade, um servidor dedicado provavelmente será mais econômico do que a nuvem.
2. **Planeje com antecedência**: Uma migração bem-sucedida requer semanas de preparação, não dias. Reserve tempo para testar todos os componentes em um ambiente staging.
3. **Automatize tudo**: Desde atualizações de DNS até migrações de banco de dados, a automação reduz erros e economiza tempo valioso durante a janela crítica.
4. **Teste exaustivamente**: Antes de fazer a troca definitiva, verifique cada endpoint de API, painel de administração e integração crítica no novo servidor usando o arquivo hosts.
5. **Monitore de perto**: Durante e após a migração, monitore métricas de desempenho, tempo de resposta e integridade dos serviços para identificar quaisquer problemas potenciais rapidamente.
6. **Tenha um plano B**: Mesmo com a replicação MySQL, mantenha backups completos e um plano de rollback documentado. Nunca confie cegamente em uma migração automática.
7. **Considere a escalabilidade**: Embora servidores dedicados ofereçam excelente custo-benefício para cargas estáveis, pense no futuro. Se você espera crescimento rápido, pode precisar reconsiderar sua estratégia de infraestrutura em 12-24 meses.
No contexto brasileiro, onde a inflação e a volatilidade cambial são realidades constantes, estratégias de redução de custos denominados em dólar são essenciais para a saúde financeira das empresas de tecnologia. A migração de infraestrutura para servidores dedicados no exterior não é apenas uma questão de economia, mas muitas vezes uma necessidade de sobrevivência em um ambiente econômico desafiador.
No entanto, é importante destacar que essa estratégia não é adequada para todas as empresas. Startups em fase de crescimento rápido, por exemplo, podem se beneficiar mais dos recursos de elasticidade da nuvem durante os primeiros anos. Da mesma forma, empresas que dependem fortemente de serviços gerenciados da DigitalOcean (como bancos de dados gerenciados ou Kubernetes gerenciado) podem encontrar dificuldades na migração para servidores dedicados sem soluções alternativas.
Outro ponto de atenção é a latência. Embora provedores como a Hetzner ofereçam excelente conectividade internacional, usuários brasileiros podem experimentar tempos de resposta ligeiramente superiores em comparação com servidores locais. Para aplicações onde a latência é crítica, pode ser necessário avaliar provedores com data centers na América do Sul ou considerar uma estratégia de CDN agressiva.
Em resumo, a migração da DigitalOcean para a Hetzner descrita nesse artigo representa um estudo de caso valioso sobre como reduzir custos de infraestrutura sem sacrificar performance ou confiabilidade. Embora o processo exija expertise técnica considerável, os benefícios financeiros e operacionais podem ser substanciais – especialmente em ambientes econômicos desafiadores como o brasileiro.
O mais importante é abordar qualquer migração de infraestrutura com cautela, planejamento meticuloso e redundância adequada. Em um mundo onde a infraestrutura de TI representa cada vez mais um custo significativo para as empresas, estratégias inteligentes de redução de custos podem fazer a diferença entre lucro e prejuízo – ou até mesmo entre sobreviver e fechar as portas em tempos econômicos difíceis.