Como sincronizar configurações entre ambientes no seu servidor de MU Online
Mantenha configurações consistentes entre staging e produção no seu servidor de MU Online, usando variáveis de ambiente, arquivos de template versionados e um processo claro de promoção de mudanças.
Um problema comum em servidores de MU Online administrados por mais de uma pessoa é a divergência silenciosa de configuração entre ambientes: o administrador testa uma mudança em staging, funciona, mas esquece de aplicar a mesma mudança em produção — ou pior, aplica uma versão levemente diferente, g
Um problema comum em servidores de MU Online administrados por mais de uma pessoa é a divergência silenciosa de configuração entre ambientes: o administrador testa uma mudança em staging, funciona, mas esquece de aplicar a mesma mudança em produção — ou pior, aplica uma versão levemente diferente, gerando um bug que só aparece na frente dos jogadores. Sincronizar configurações entre ambientes de forma sistemática, com um processo claro de "o que é igual em todo lugar" versus "o que é específico de cada ambiente", elimina essa classe inteira de erro. Este tutorial mostra como estruturar esse processo, dos arquivos de template ao fluxo de promoção de mudanças.
O problema da configuração divergente
Servidores de MU costumam ter dezenas de arquivos de configuração espalhados: GameServerInfo.dat, ConnectServerInfo.dat, arquivos .ini de balanceamento (taxa de experiência, drop, PvP), configurações de eventos, e as connection strings de banco. Quando cada ambiente (desenvolvimento, staging, produção) tem esses arquivos editados manualmente e sem controle, é praticamente garantido que eles divergem de formas não documentadas — e o dia em que isso é descoberto é geralmente o dia em que algo já quebrou em produção.
Separando o que é comum do que é específico por ambiente
O primeiro passo conceitual é classificar cada configuração em duas categorias:
| Categoria | Exemplo | Onde deve viver |
|---|---|---|
| Comum a todos os ambientes | Taxas de experiência, regras de evento, opções de item | Repositório Git, versionado, idêntico em todo lugar |
| Específico de cada ambiente | IP/host do banco, senha, porta, chave de licença | Variável de ambiente ou cofre de segredos, nunca no Git |
Misturar as duas categorias no mesmo arquivo é o que causa a maior parte dos problemas — um arquivo de configuração de evento não deveria conter, na mesma estrutura, a senha do banco de produção.
Estrutura de templates de configuração
Em vez de manter um arquivo de configuração completo por ambiente, mantenha um template versionado com placeholders, e gere o arquivo final no momento do deploy substituindo os placeholders pelos valores do ambiente:
; template: GameServerInfo.template.ini
[Database]
Server={{DB_HOST}}
Database=MuOnline
User={{DB_USER}}
Password={{DB_PASSWORD}}
[Rates]
ExperienceRate=1.0
DropRate=0.7
ZenRate=1.0
[Server]
ServerName={{SERVER_NAME}}
MaxConnections={{MAX_CONNECTIONS}}
As taxas de experiência e drop são iguais em staging e produção (para que o teste seja representativo); o host do banco e o nome do servidor mudam por ambiente.
Gerando o arquivo final por ambiente
Um script simples de substituição de placeholders, usando variáveis de ambiente específicas de cada lugar:
#!/bin/bash
set -euo pipefail
ENV_FILE=".env.$1" # ex: .env.staging ou .env.producao
source "$ENV_FILE"
envsubst < config/GameServerInfo.template.ini > /opt/mu-server/config/GameServerInfo.ini
echo "[sync] Configuração gerada para o ambiente: $1"
Cada ambiente tem seu próprio arquivo .env (nunca commitado no Git — apenas um .env.example com placeholders vai para o repositório), garantindo que os valores sensíveis fiquem fora do controle de versão mas a estrutura permaneça idêntica.
# .env.staging (não versionado)
DB_HOST=10.1.2.10
DB_USER=gameserver_svc_staging
DB_PASSWORD=SenhaStaging123
SERVER_NAME=MU-Staging
MAX_CONNECTIONS=50
# .env.producao (não versionado)
DB_HOST=10.0.3.10
DB_USER=gameserver_svc
DB_PASSWORD=SenhaProducaoForte!2026
SERVER_NAME=MU-Producao
MAX_CONNECTIONS=1000
Fluxo de promoção de mudanças entre ambientes
Toda mudança de configuração comum (taxas, eventos, regras) deve seguir um fluxo de promoção, nunca ser editada diretamente em produção:
- A mudança é feita no template versionado, em uma branch de desenvolvimento.
- O template é aplicado em staging primeiro, gerando o arquivo final com as variáveis de staging.
- A equipe testa o comportamento em staging (evento, taxa nova, item novo).
- Se aprovado, a mudança é mesclada (merge) na branch principal.
- O pipeline de deploy aplica o mesmo template em produção, com as variáveis de produção.
Esse fluxo garante que produção nunca recebe uma configuração que não passou por staging antes — eliminando a divergência silenciosa.
Comparando ambientes automaticamente
Para detectar divergências que já existem (arquivos editados manualmente no passado, fora do processo), um script de comparação estrutural ajuda a identificar o que diverge além do esperado:
#!/bin/bash
# Compara as chaves presentes em cada ambiente, ignorando valores esperados como diferentes
diff <(grep -oP '^\w+(?==)' /opt/mu-server-staging/config/GameServerInfo.ini | sort) \
<(grep -oP '^\w+(?==)' /opt/mu-server-producao/config/GameServerInfo.ini | sort)
Se a saída do diff não estiver vazia, significa que uma chave existe em um ambiente e não no outro — um sinal claro de configuração que saiu de sincronia.
Tabela de configurações típicas e sua categoria
| Arquivo/chave | Categoria | Observação |
|---|---|---|
| Taxas de experiência/drop/zen | Comum | Deve ser idêntico entre staging e produção para testes representativos |
| Regras de evento (horário, recompensa) | Comum | Versionado; horários podem ter override específico em staging para testes rápidos |
| Host/porta/senha do banco | Específico | Nunca versionado; vem de .env ou cofre de segredos |
| Nome do servidor exibido no cliente | Específico | Staging deve deixar claro que não é produção |
| Chave de licença do emulador | Específico | Cada ambiente com sua própria licença, se aplicável |
| Limite de conexões simultâneas | Específico | Staging tipicamente bem menor que produção |
Sincronizando o schema de banco entre ambientes
Além dos arquivos de configuração, o schema do banco (tabelas, colunas, stored procedures) também precisa estar sincronizado. Use o mesmo conjunto de migrações versionadas (ver o tutorial de deploy contínuo) aplicado em ambos os ambientes, na mesma ordem, nunca alterando o schema manualmente direto em produção depois de já ter testado em staging.
Lidando com dados sensíveis ao sincronizar staging com produção
Quando staging precisa de uma cópia de dados de produção para testes mais realistas (não apenas configuração, mas dados), nunca copie o dump bruto. Anonimize antes:
-- Rodar apenas no banco de staging, após restaurar uma cópia
UPDATE Account SET Password = 'hash_generico_de_teste', Email = 'teste+' + CAST(AccountID AS VARCHAR) + '@staging.local';
UPDATE MEMB_STAT SET bloc1='0',bloc2='0',bloc3='0',bloc4='0' WHERE 1=1; -- exemplo de zerar campos sensíveis de pagamento, se existirem
Documente esse script de anonimização como parte do processo de sincronização de dados, não como uma etapa manual "lembrada de cabeça".
Ferramentas que ajudam a formalizar esse processo
Para equipes maiores, ferramentas de gestão de configuração (Ansible, Terraform para infraestrutura, ou até um simples sistema de templates com Jinja2/envsubst como mostrado acima) tornam esse processo auditável e repetível. O importante não é qual ferramenta, mas o princípio: nenhuma configuração deve existir apenas na cabeça ou no terminal de um administrador — tudo deve estar versionado, com um processo claro de como vai de um ambiente para o outro.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Bug aparece em produção mas não em staging | Configuração divergente entre ambientes (taxa, regra) | Rode o script de comparação estrutural e alinhe pelos templates |
| Senha de banco vazou no repositório Git | Valor sensível colocado direto no template em vez de variável | Mova para .env/cofre de segredos e reescreva o histórico do Git se necessário |
| Staging não reflete o comportamento real de produção | Taxas/regras de staging diferentes das de produção "para facilitar teste" | Use as mesmas taxas comuns; ajuste apenas o necessário (limite de conexões, por exemplo) |
| Mudança aplicada em produção sem passar por staging | Ausência de processo de promoção formal | Implemente o fluxo de merge + deploy descrito neste tutorial |
| Dados de teste em staging expõem informação real de jogadores | Cópia de produção usada sem anonimização | Rode o script de anonimização antes de disponibilizar o dump em staging |
Checklist de sincronização de ambientes
- Configurações classificadas entre "comum" e "específica de ambiente".
- Templates versionados no Git, sem segredos embutidos.
- Arquivos
.envpor ambiente, fora do controle de versão. - Fluxo de promoção (staging antes de produção) documentado e seguido.
- Script de comparação estrutural rodado periodicamente para detectar divergência.
- Schema de banco sincronizado via migrações versionadas, não edição manual.
- Processo de anonimização definido para dados copiados de produção para staging.
Com as configurações sincronizadas de forma confiável entre ambientes, o próximo passo é conectar esse processo ao pipeline de deploy automatizado — veja o tutorial de script de deploy contínuo para servidor de MU Online para fechar o ciclo entre configuração, build e publicação em produção.
Perguntas frequentes
Qual a diferença entre sincronizar e simplesmente copiar arquivos de config entre ambientes?
Copiar cegamente arrasta valores específicos de um ambiente (como IP do banco de produção) para outro, quebrando o destino. Sincronizar significa manter a estrutura e os valores não sensíveis idênticos, enquanto valores específicos de cada ambiente (hosts, senhas, chaves) vêm de variáveis próprias de cada lugar.
Staging precisa ter exatamente os mesmos dados de produção?
Não, e geralmente não deve. Staging deve ter a mesma estrutura de configuração e schema de banco, mas com dados sintéticos ou uma cópia anonimizada — nunca senhas reais de jogadores nem histórico de pagamento real.
Como evitar que um administrador esqueça de aplicar uma mudança de configuração em produção depois de testar em staging?
Trate toda mudança de configuração como uma mudança de código: versionada em Git, revisada por outra pessoa (pull request) e aplicada por um processo de deploy definido, não por edição manual direta no servidor. Isso elimina a dependência de memória humana.
Onde guardar segredos (senhas, chaves de API) se eles não podem ir para o repositório Git?
Use variáveis de ambiente injetadas no momento do deploy, ou um cofre de segredos dedicado (Vault, AWS Secrets Manager, Azure Key Vault). O repositório deve conter apenas templates com placeholders, nunca os valores reais dos segredos.
Vale a pena ter mais de dois ambientes (ex. dev, staging, produção)?
Depende do tamanho da equipe. Para um servidor pequeno com um ou dois administradores, dev e staging podem ser combinados. Para equipes maiores ou servidores com alta frequência de mudanças, separar os três reduz o risco de uma alteração instável chegar direto à produção.