Cómo sincronizar configuraciones entre ambientes en tu servidor de MU Online
Mantén configuraciones consistentes entre staging y producción en tu servidor de MU Online, usando variables de ambiente, archivos de plantilla versionados y un proceso claro de promoción de cambios.
Un problema común en servidores de MU Online administrados por más de una persona es la divergencia silenciosa de configuración entre ambientes: el administrador prueba un cambio en staging, funciona, pero olvida aplicar el mismo cambio en producción —o peor, aplica una versión ligeramente diferente
Un problema común en servidores de MU Online administrados por más de una persona es la divergencia silenciosa de configuración entre ambientes: el administrador prueba un cambio en staging, funciona, pero olvida aplicar el mismo cambio en producción —o peor, aplica una versión ligeramente diferente, generando un bug que solo aparece frente a los jugadores. Sincronizar configuraciones entre ambientes de forma sistemática, con un proceso claro de "qué es igual en todas partes" versus "qué es específico de cada ambiente", elimina esta clase completa de error. Este tutorial muestra cómo estructurar ese proceso, desde los archivos de plantilla hasta el flujo de promoción de cambios.
El problema de la configuración divergente
Los servidores de MU suelen tener decenas de archivos de configuración dispersos: GameServerInfo.dat, ConnectServerInfo.dat, archivos .ini de balanceo (tasa de experiencia, drop, PvP), configuraciones de eventos, y las cadenas de conexión de la base de datos. Cuando cada ambiente (desarrollo, staging, producción) tiene esos archivos editados manualmente y sin control, es prácticamente seguro que divergen de formas no documentadas —y el día en que esto se descubre suele ser el día en que algo ya se rompió en producción.
Separando lo común de lo específico por ambiente
El primer paso conceptual es clasificar cada configuración en dos categorías:
| Categoría | Ejemplo | Dónde debe vivir |
|---|---|---|
| Común a todos los ambientes | Tasas de experiencia, reglas de evento, opciones de ítem | Repositorio Git, versionado, idéntico en todas partes |
| Específico de cada ambiente | IP/host de la base de datos, contraseña, puerto, clave de licencia | Variable de ambiente o cofre de secretos, nunca en Git |
Mezclar ambas categorías en el mismo archivo es lo que causa la mayoría de los problemas —un archivo de configuración de evento no debería contener, en la misma estructura, la contraseña de la base de datos de producción.
Estructura de plantillas de configuración
En vez de mantener un archivo de configuración completo por ambiente, mantén una plantilla versionada con placeholders, y genera el archivo final en el momento del despliegue sustituyendo los placeholders por los valores del ambiente:
; plantilla: 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}}
Las tasas de experiencia y drop son iguales en staging y producción (para que la prueba sea representativa); el host de la base de datos y el nombre del servidor cambian por ambiente.
Generando el archivo final por ambiente
Un script simple de sustitución de placeholders, usando variables de ambiente específicas de cada lugar:
#!/bin/bash
set -euo pipefail
ENV_FILE=".env.$1" # ej: .env.staging o .env.produccion
source "$ENV_FILE"
envsubst < config/GameServerInfo.template.ini > /opt/mu-server/config/GameServerInfo.ini
echo "[sync] Configuración generada para el ambiente: $1"
Cada ambiente tiene su propio archivo .env (nunca commiteado en Git —solo un .env.example con placeholders va al repositorio), garantizando que los valores sensibles queden fuera del control de versión pero la estructura permanezca idéntica.
# .env.staging (no versionado)
DB_HOST=10.1.2.10
DB_USER=gameserver_svc_staging
DB_PASSWORD=SenhaStaging123
SERVER_NAME=MU-Staging
MAX_CONNECTIONS=50
# .env.produccion (no versionado)
DB_HOST=10.0.3.10
DB_USER=gameserver_svc
DB_PASSWORD=SenhaProducaoForte!2026
SERVER_NAME=MU-Produccion
MAX_CONNECTIONS=1000
Flujo de promoción de cambios entre ambientes
Todo cambio de configuración común (tasas, eventos, reglas) debe seguir un flujo de promoción, nunca editarse directamente en producción:
- El cambio se hace en la plantilla versionada, en una rama de desarrollo.
- La plantilla se aplica primero en staging, generando el archivo final con las variables de staging.
- El equipo prueba el comportamiento en staging (evento, tasa nueva, ítem nuevo).
- Si se aprueba, el cambio se fusiona (merge) en la rama principal.
- El pipeline de despliegue aplica la misma plantilla en producción, con las variables de producción.
Este flujo garantiza que producción nunca recibe una configuración que no haya pasado antes por staging —eliminando la divergencia silenciosa.
Comparando ambientes automáticamente
Para detectar divergencias que ya existen (archivos editados manualmente en el pasado, fuera del proceso), un script de comparación estructural ayuda a identificar lo que diverge más allá de lo esperado:
#!/bin/bash
# Compara las claves presentes en 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)
Si la salida del diff no está vacía, significa que una clave existe en un ambiente y no en el otro —una señal clara de configuración que salió de sincronía.
Tabla de configuraciones típicas y su categoría
| Archivo/clave | Categoría | Observación |
|---|---|---|
| Tasas de experiencia/drop/zen | Común | Debe ser idéntico entre staging y producción para pruebas representativas |
| Reglas de evento (horario, recompensa) | Común | Versionado; los horarios pueden tener un override específico en staging para pruebas rápidas |
| Host/puerto/contraseña de la base de datos | Específico | Nunca versionado; viene de .env o cofre de secretos |
| Nombre del servidor mostrado en el cliente | Específico | Staging debe dejar claro que no es producción |
| Clave de licencia del emulador | Específico | Cada ambiente con su propia licencia, si aplica |
| Límite de conexiones simultáneas | Específico | Staging típicamente mucho menor que producción |
Sincronizando el esquema de base de datos entre ambientes
Además de los archivos de configuración, el esquema de la base de datos (tablas, columnas, stored procedures) también necesita estar sincronizado. Usa el mismo conjunto de migraciones versionadas (ver el tutorial de despliegue continuo) aplicado en ambos ambientes, en el mismo orden, nunca alterando el esquema manualmente de forma directa en producción después de haberlo probado en staging.
Manejando datos sensibles al sincronizar staging con producción
Cuando staging necesita una copia de datos de producción para pruebas más realistas (no solo configuración, sino datos), nunca copies el dump en bruto. Anonimízalo antes:
-- Ejecutar solo en la base de staging, después de restaurar una copia
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; -- ejemplo de vaciar campos sensibles de pago, si existen
Documenta este script de anonimización como parte del proceso de sincronización de datos, no como un paso manual "recordado de memoria".
Herramientas que ayudan a formalizar este proceso
Para equipos más grandes, las herramientas de gestión de configuración (Ansible, Terraform para infraestructura, o incluso un simple sistema de plantillas con Jinja2/envsubst como se mostró arriba) hacen este proceso auditable y repetible. Lo importante no es qué herramienta usar, sino el principio: ninguna configuración debe existir solo en la cabeza o en la terminal de un administrador —todo debe estar versionado, con un proceso claro de cómo pasa de un ambiente a otro.
Errores comunes y soluciones
| Síntoma | Causa probable | Solución |
|---|---|---|
| Aparece un bug en producción pero no en staging | Configuración divergente entre ambientes (tasa, regla) | Corre el script de comparación estructural y alinea según las plantillas |
| La contraseña de la base de datos se filtró en el repositorio Git | Valor sensible colocado directamente en la plantilla en vez de en una variable | Muévelo a .env/cofre de secretos y reescribe el historial de Git si es necesario |
| Staging no refleja el comportamiento real de producción | Tasas/reglas de staging diferentes de las de producción "para facilitar la prueba" | Usa las mismas tasas comunes; ajusta solo lo necesario (límite de conexiones, por ejemplo) |
| Cambio aplicado en producción sin pasar por staging | Ausencia de un proceso de promoción formal | Implementa el flujo de merge + despliegue descrito en este tutorial |
| Datos de prueba en staging exponen información real de jugadores | Copia de producción usada sin anonimización | Corre el script de anonimización antes de disponibilizar el dump en staging |
Lista de verificación de sincronización de ambientes
- Configuraciones clasificadas entre "común" y "específica de ambiente".
- Plantillas versionadas en Git, sin secretos embebidos.
- Archivos
.envpor ambiente, fuera del control de versión. - Flujo de promoción (staging antes de producción) documentado y seguido.
- Script de comparación estructural ejecutado periódicamente para detectar divergencias.
- Esquema de base de datos sincronizado vía migraciones versionadas, no edición manual.
- Proceso de anonimización definido para datos copiados de producción a staging.
Con las configuraciones sincronizadas de forma confiable entre ambientes, el siguiente paso es conectar este proceso al pipeline de despliegue automatizado —consulta el tutorial de script de despliegue continuo para servidor de MU Online para cerrar el ciclo entre configuración, build y publicación en producción.
Preguntas frecuentes
¿Cuál es la diferencia entre sincronizar y simplemente copiar archivos de configuración entre ambientes?
Copiar a ciegas arrastra valores específicos de un ambiente (como la IP de la base de datos de producción) hacia otro, rompiendo el destino. Sincronizar significa mantener la estructura y los valores no sensibles idénticos, mientras que los valores específicos de cada ambiente (hosts, contraseñas, claves) provienen de variables propias de cada lugar.
¿Staging necesita tener exactamente los mismos datos que producción?
No, y generalmente no debería. Staging debe tener la misma estructura de configuración y esquema de base de datos, pero con datos sintéticos o una copia anonimizada —nunca contraseñas reales de jugadores ni historial de pagos real.
¿Cómo evitar que un administrador olvide aplicar un cambio de configuración en producción después de probarlo en staging?
Trata todo cambio de configuración como un cambio de código: versionado en Git, revisado por otra persona (pull request) y aplicado por un proceso de despliegue definido, no por edición manual directa en el servidor. Esto elimina la dependencia de la memoria humana.
¿Dónde guardar secretos (contraseñas, claves de API) si no pueden ir al repositorio Git?
Usa variables de ambiente inyectadas en el momento del despliegue, o un cofre de secretos dedicado (Vault, AWS Secrets Manager, Azure Key Vault). El repositorio debe contener solo plantillas con placeholders, nunca los valores reales de los secretos.
¿Vale la pena tener más de dos ambientes (ej. dev, staging, producción)?
Depende del tamaño del equipo. Para un servidor pequeño con uno o dos administradores, dev y staging pueden combinarse. Para equipos más grandes o servidores con alta frecuencia de cambios, separar los tres reduce el riesgo de que un cambio inestable llegue directo a producción.