Como containerizar seu servidor de MU Online com Docker
Empacote MySQL, GameServer, ConnectServer, JoinServer e DataServer em containers Docker isolados, com docker-compose, volumes persistentes e rede interna, facilitando deploy, backup e migração do servidor de MU Online.
Rodar um servidor de MU Online direto no sistema operacional funciona, mas cria um problema recorrente: dependências do MySQL, do .NET/VC++ redistributable e dos binários do emulador ficam espalhadas e difíceis de reproduzir em outra máquina. Containerizar o servidor com Docker resolve isso — cada c
Rodar um servidor de MU Online direto no sistema operacional funciona, mas cria um problema recorrente: dependências do MySQL, do .NET/VC++ redistributable e dos binários do emulador ficam espalhadas e difíceis de reproduzir em outra máquina. Containerizar o servidor com Docker resolve isso — cada componente (banco de dados, ConnectServer, JoinServer, GameServer, DataServer) roda isolado, com suas próprias dependências, e todo o ambiente pode ser recriado em minutos com um único comando. Este tutorial mostra como estruturar um docker-compose completo para um servidor de MU, dos Dockerfiles individuais à persistência de dados e à rede interna entre os serviços.
Por que containerizar um servidor de MU Online
Um servidor de MU tradicional (baseado em emuladores como MuEmu ou IGCN) é composto por vários processos que precisam rodar simultaneamente e se comunicar: MySQL, DataServer, JoinServer, ConnectServer e GameServer. Sem containers, migrar esse conjunto para outra máquina significa reinstalar manualmente cada dependência, reconfigurar caminhos e torcer para que as versões batam. Com Docker, cada peça vira uma imagem versionada, com suas dependências declaradas em um Dockerfile — o ambiente inteiro fica reproduzível, testável em uma máquina de desenvolvimento e migrável para um servidor novo com docker-compose up.
Pré-requisitos
- Docker Engine e Docker Compose instalados (Linux nativo, ou Docker Desktop com WSL2 no Windows).
- Binários do emulador de MU (GameServer, ConnectServer, JoinServer, DataServer) já funcionando fora de container, para servir de base aos Dockerfiles.
- Backup completo do banco de dados atual antes de migrar para o ambiente containerizado.
- Conhecimento básico de rede Docker (bridge networks, exposição de portas).
Visão geral da arquitetura em containers
| Serviço | Imagem base | Portas expostas | Volume persistente |
|---|---|---|---|
mu-mysql | mysql:5.7 ou mariadb:10.6 | 3306 | mu-db-data |
mu-dataserver | mcr.microsoft.com/windows/servercore ou Wine/Linux | 55757 (interna) | mu-data-files |
mu-joinserver | Windows/Wine | 44405 | — |
mu-connectserver | Windows/Wine | 44405 (cliente) | — |
mu-gameserver | Windows/Wine | 55901+ | mu-game-logs |
Todos os serviços compartilham uma rede Docker interna (mu-network), o que permite que se comuniquem por nome de serviço em vez de IP fixo — essencial para portabilidade entre ambientes de desenvolvimento e produção.
Estruturando o docker-compose.yml
version: "3.8"
services:
mu-mysql:
image: mysql:5.7
container_name: mu-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "senha_forte_aqui"
MYSQL_DATABASE: "MuOnline"
volumes:
- mu-db-data:/var/lib/mysql
- ./sql/init:/docker-entrypoint-initdb.d
networks:
- mu-network
ports:
- "3306:3306"
mu-gameserver:
build: ./gameserver
container_name: mu-gameserver
restart: unless-stopped
depends_on:
- mu-mysql
environment:
DB_HOST: mu-mysql
DB_USER: root
DB_PASS: "senha_forte_aqui"
volumes:
- mu-game-logs:/app/logs
networks:
- mu-network
ports:
- "55901:55901"
networks:
mu-network:
driver: bridge
volumes:
mu-db-data:
mu-game-logs:
mu-data-files:
Esse arquivo é o ponto central: ele descreve todos os serviços, suas dependências (depends_on), variáveis de ambiente e a rede compartilhada.
Escrevendo o Dockerfile do GameServer
FROM mcr.microsoft.com/windows/servercore:ltsc2022
WORKDIR /app
COPY ./bin/GameServer.exe .
COPY ./bin/Data/ ./Data/
COPY ./bin/Config/ ./Config/
EXPOSE 55901
CMD ["GameServer.exe"]
Para emuladores compilados em C++/Delphi para Windows, essa é a rota mais simples: usar uma imagem base Windows Server Core e copiar os binários já compilados. Em ambientes Linux, muitos administradores optam por rodar os binários Windows sob Wine dentro de um container Linux, o que reduz o consumo de recursos comparado a uma imagem Windows completa.
Persistência de dados com volumes
Nunca deixe o banco de dados ou os arquivos de configuração dentro do sistema de arquivos "efêmero" do container. Um docker-compose down sem volumes nomeados apaga todo o progresso dos jogadores. Sempre declare volumes nomeados (mu-db-data, mu-game-logs) e, se possível, monte pastas do host diretamente para arquivos de configuração que você edita com frequência:
volumes:
- ./config/GameServerInfo.dat:/app/Config/GameServerInfo.dat
Isso permite editar a configuração no host, sem precisar reconstruir a imagem a cada ajuste pequeno.
Configurando a rede interna entre os serviços
Dentro da rede mu-network, cada container enxerga os outros pelo nome do serviço definido no Compose. Isso significa que, na string de conexão do GameServer com o banco, em vez de 127.0.0.1 você usa mu-mysql:
[Database]
Host = mu-mysql
Port = 3306
User = root
Password = senha_forte_aqui
Esse é o ajuste mais comum ao migrar uma configuração existente para Docker: qualquer referência a localhost no banco precisa virar o nome do serviço correspondente.
Backup e restauração do banco containerizado
# Backup
docker exec mu-mysql mysqldump -u root -psenha_forte_aqui MuOnline > backup_$(date +%F).sql
# Restauração
docker exec -i mu-mysql mysql -u root -psenha_forte_aqui MuOnline < backup_2026-07-30.sql
Automatize esse comando com um cron job no host, gravando os arquivos .sql fora do container — assim, mesmo destruindo e recriando o container do MySQL, o backup permanece seguro no host.
Logs e monitoramento dos containers
Use docker logs -f mu-gameserver para acompanhar o comportamento do GameServer em tempo real, e docker stats para monitorar consumo de CPU/memória de cada serviço. Para produção, vale integrar com uma stack de observabilidade (Prometheus + Grafana) coletando métricas dos containers, especialmente uso de CPU do GameServer em horários de pico, que costuma ser o gargalo em servidores com muitos jogadores simultâneos.
Atualizando o servidor sem downtime longo
Ao lançar uma nova versão do emulador ou uma correção de configuração, o fluxo recomendado é: reconstruir apenas a imagem do serviço alterado (docker-compose build mu-gameserver), depois recriar apenas esse container (docker-compose up -d --no-deps mu-gameserver), mantendo o MySQL e os demais serviços no ar. Isso reduz o tempo de indisponibilidade a segundos, em vez de derrubar toda a stack para um ajuste pontual.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| GameServer não conecta ao banco | String de conexão ainda aponta para localhost | Troque para o nome do serviço Docker (mu-mysql) |
Dados somem após docker-compose down | Volume não declarado ou removido com -v | Use volumes nomeados e evite down -v em produção |
| Container reinicia em loop | Configuração inválida ou dependência não pronta | Adicione depends_on com healthcheck no MySQL |
| Performance ruim em containers Windows | Overhead de imagem Windows Server Core completa | Avalie Wine em container Linux para reduzir consumo |
| Portas não acessíveis externamente | Falta de mapeamento de portas no compose | Confirme ports: mapeando porta do host para o container |
Checklist de containerização
- Docker e Docker Compose instalados e testados.
- Dockerfiles criados para cada serviço (MySQL, GameServer, ConnectServer, JoinServer).
- docker-compose.yml com rede interna e volumes nomeados definidos.
- Strings de conexão atualizadas para nomes de serviço.
- Rotina de backup do banco automatizada e testada.
- Logs e métricas de cada container sendo monitorados.
- Processo de atualização sem downtime documentado e testado.
Com o servidor rodando em containers, o próximo passo natural é padronizar esse ambiente como base para novos deploys — inclusive para quem está montando o projeto do zero. Veja o tutorial de criação de servidor de MU Online para alinhar essa infraestrutura containerizada aos fundamentos do emulador.
Perguntas frequentes
Docker no Windows funciona bem para MuServer, que normalmente roda em Windows Server?
Sim, via Docker Desktop com containers Windows, mas é bem menos comum e mais pesado que containers Linux. A abordagem mais usada na comunidade é rodar o MySQL em container Linux e manter os binários do GameServer/ConnectServer (que dependem de Windows) rodando nativamente ou em uma VM Windows, containerizando só a parte que suporta Linux.
Containerizar o servidor deixa ele mais lento?
O overhead de um container Docker é mínimo comparado a rodar direto no host, geralmente abaixo de 5% de diferença. O ganho em portabilidade, isolamento e facilidade de deploy compensa amplamente essa perda marginal de performance para a maioria dos servidores privados de MU.
Como faço backup do banco de dados quando ele está em um container?
Use um volume Docker nomeado para o diretório de dados do MySQL, e rode docker exec com mysqldump apontando a saída para um arquivo no host, fora do container. Isso garante que o backup sobrevive mesmo se o container for recriado ou destruído.
Preciso reescrever a configuração do MuServer para rodar em Docker?
Não reescrever, mas ajustar strings de conexão. Em vez de apontar o GameServer para localhost no banco, você aponta para o nome do serviço definido no docker-compose (por exemplo, mu-mysql), já que os containers se comunicam por nome de serviço na rede interna do Compose.
Docker Compose substitui um servidor de produção de verdade?
Para produção com muitos jogadores simultâneos, o ideal é evoluir para orquestração mais robusta (Docker Swarm, Kubernetes) ou pelo menos monitoramento e reinício automático bem configurados. Docker Compose sozinho é excelente para desenvolvimento, testes e servidores pequenos/médios, mas produção séria pede camadas extras de resiliência.