O maior portal de MU Online do Brasil — desde 2003
Tutorial Avançado Infra

Como orquestrar os serviços do seu servidor de MU Online com Docker Compose

Containerize e orquestre ConnectServer, JoinServer, GameServer, banco de dados e web com Docker Compose, com exemplos de docker-compose.yml, redes internas, volumes persistentes e boas práticas de produção.

RO Rodrigo · Atualizado em 11 jul 2020 · ⏱ 17 min de leitura
Resposta rápida

Servidores de MU Online tradicionalmente rodam como uma coleção de processos soltos em uma máquina Windows: ConnectServer, JoinServer, GameServer, banco de dados e, às vezes, um painel web separado. Isso funciona, mas dificulta backups consistentes, atualizações sem downtime e replicação do ambiente

Servidores de MU Online tradicionalmente rodam como uma coleção de processos soltos em uma máquina Windows: ConnectServer, JoinServer, GameServer, banco de dados e, às vezes, um painel web separado. Isso funciona, mas dificulta backups consistentes, atualizações sem downtime e replicação do ambiente em outra máquina. Docker Compose resolve esse problema orquestrando todos esses serviços como containers definidos em um único arquivo declarativo, com redes internas isoladas e volumes persistentes. Este tutorial mostra como estruturar essa orquestração na prática, com exemplos de configuração e cuidados específicos para a stack de um servidor de MU.

Por que containerizar um servidor de MU Online

Containerizar traz três ganhos concretos: (1) reprodutibilidade — o ambiente inteiro (versões de banco, dependências) fica descrito em arquivo, não na memória de quem configurou a máquina originalmente; (2) isolamento — um problema no banco de dados não derruba o GameServer, e vice-versa; (3) portabilidade — mover o servidor inteiro para outra máquina ou provedor se resume a copiar os arquivos de configuração e os volumes de dados.

Visão geral da arquitetura de serviços

ServiçoFunçãoDepende de
dbBanco de dados (MSSQL/MySQL) com contas e personagens
connectserverPonto de entrada do cliente, lista de servidoresdb
joinserverAutenticação e roteamento para o GameServerdb, connectserver
gameserverLógica principal do jogodb, joinserver
webPainel/site (cadastro, ranking, loja)db

Estrutura de diretórios recomendada

mu-infra/
├── docker-compose.yml
├── .env
├── db/
│   └── init/            # scripts de inicialização do schema
├── connectserver/
│   └── Data/
├── gameserver/
│   └── Data/
└── web/
    └── (código do painel)

Manter cada serviço em sua própria pasta com um volume dedicado facilita tanto o backup individual quanto a substituição isolada de um componente.

Exemplo de docker-compose.yml

version: "3.9"

services:
  db:
    image: mysql:8.0
    container_name: mu_db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: mu_online
    volumes:
      - db_data:/var/lib/mysql
      - ./db/init:/docker-entrypoint-initdb.d
    networks:
      - mu_internal

  connectserver:
    build: ./connectserver
    container_name: mu_connectserver
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "44405:44405"
    networks:
      - mu_internal

  gameserver:
    build: ./gameserver
    container_name: mu_gameserver
    restart: unless-stopped
    depends_on:
      - db
      - connectserver
    ports:
      - "55901:55901"
    volumes:
      - ./gameserver/Data:/app/Data
    networks:
      - mu_internal

  web:
    build: ./web
    container_name: mu_web
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "8080:80"
    networks:
      - mu_internal

networks:
  mu_internal:
    driver: bridge

volumes:
  db_data:

Variáveis de ambiente e o arquivo .env

Nunca deixe senhas de banco ou tokens hardcoded no docker-compose.yml. Centralize em um arquivo .env na raiz do projeto:

DB_ROOT_PASSWORD=troque-esta-senha
DB_USER=mu_app
DB_PASSWORD=outra-senha-forte
GAMESERVER_PORT=55901

O Compose lê automaticamente o .env na mesma pasta e substitui as variáveis ${...} referenciadas no YAML.

Redes internas e exposição de portas

Todos os serviços compartilham a rede mu_internal, o que permite que se comuniquem entre si pelo nome do serviço (por exemplo, o GameServer acessa o banco via host db, não localhost). Apenas as portas realmente necessárias ao cliente do jogo e ao painel web devem ser mapeadas para o host com ports: — o banco de dados não deve ter porta exposta externamente em produção, apenas acessível pela rede interna do Compose.

Persistência de dados com volumes

O volume nomeado db_data garante que o conteúdo do banco sobreviva a recriações do container (docker compose down seguido de up). Já os volumes de bind mount (como ./gameserver/Data:/app/Data) permitem editar arquivos de configuração do GameServer diretamente do host, sem precisar entrar no container — essencial para ajustes rápidos de drop rate, experiência e eventos.

Rotina de backup do banco de dados

Adicione um serviço auxiliar de backup agendado, ou rode externamente via cron um comando como:

docker exec mu_db mysqldump -u root -p"$DB_ROOT_PASSWORD" mu_online > backups/mu_online_$(date +%Y%m%d_%H%M).sql

Automatize isso com um cron no host (ou um container dedicado com cron + o mesmo comando) e mantenha uma política de retenção — por exemplo, backups diários dos últimos 14 dias e semanais dos últimos 3 meses.

Atualizando serviços sem downtime total

Para atualizar apenas o painel web, por exemplo, sem afetar o GameServer:

docker compose build web
docker compose up -d --no-deps web

Isso rebuilda e reinicia apenas o container web, mantendo gameserver, connectserver e db rodando normalmente. Mudanças de schema do banco, porém, exigem coordenação cuidadosa — teste sempre em um ambiente de staging com uma cópia do banco antes de aplicar em produção.

Monitoramento básico dos containers

Comandos essenciais para operação do dia a dia:

ComandoFunção
docker compose psVer status de todos os serviços
docker compose logs -f gameserverAcompanhar logs do GameServer em tempo real
docker statsVer consumo de CPU/memória por container
docker compose restart connectserverReiniciar um serviço específico
docker compose down && docker compose up -dRecriar a stack inteira (dados persistem via volume)

Erros comuns e soluções

SintomaCausa provávelSolução
GameServer não conecta ao bancoNome de host errado (usando localhost em vez do nome do serviço)Use o nome do serviço (db) como host dentro da rede Compose
Dados somem após recriar containersVolume não declarado ou removido com -vDeclare volumes nomeados e evite docker compose down -v sem necessidade
Porta do banco acessível externamenteMapeamento de porta desnecessário em produçãoRemova ports: do serviço db em ambiente de produção
Senha exposta no repositórioCredenciais hardcoded no docker-compose.ymlMova tudo para .env e adicione .env ao .gitignore
Atualização de um serviço derruba os outrosUso de docker compose down completo para trocar um serviçoUse up -d --build <serviço> para atualizar isoladamente

Checklist de orquestração com Docker Compose

  • Arquitetura de serviços mapeada (db, connectserver, joinserver, gameserver, web).
  • docker-compose.yml com redes internas e apenas portas necessárias expostas.
  • Variáveis sensíveis centralizadas em .env e fora do controle de versão.
  • Volumes nomeados para dados persistentes do banco.
  • Rotina de backup automatizada e testada (restore validado ao menos uma vez).
  • Processo de atualização isolada por serviço documentado.
  • Monitoramento básico de logs e uso de recursos configurado.

Com a stack orquestrada e reprodutível, o próximo passo natural é aplicar esse mesmo rigor de infraestrutura ao restante do projeto — veja o tutorial de como criar um servidor de MU Online para revisar a configuração completa dos serviços que agora estão containerizados.

Perguntas frequentes

Preciso rodar o MU Server inteiro em Docker mesmo sendo baseado em Windows?

É possível usar containers Windows (Windows Server Core) para emuladores compilados para Windows, ou rodar via Wine em containers Linux para alguns componentes. A abordagem mais estável costuma ser containerizar o banco de dados e serviços web em Linux, e avaliar caso a caso o binário do emulador.

Docker Compose substitui um orquestrador como Kubernetes para esse caso?

Para um servidor de MU de porte pequeno a médio, Docker Compose é suficiente e muito mais simples de manter. Kubernetes só se justifica em cenários de múltiplas instâncias, alta disponibilidade real ou escala que exija scheduling automático entre vários hosts.

Como faço backup do banco de dados rodando em container?

Use o volume nomeado do banco (ex.: mssql_data ou mysql_data) e rode dumps periódicos com um serviço adicional no compose ou um cron externo que executa docker exec do comando de backup, salvando fora do container.

É seguro expor as portas do GameServer diretamente do container?

Sim, desde que você mapeie apenas as portas necessárias no host e mantenha um firewall configurado. Evite expor portas de banco de dados e de administração para fora da rede interna do Docker Compose.

Como atualizar um serviço sem derrubar o servidor inteiro?

Com Docker Compose, você pode rebuildar e reiniciar um serviço específico (ex.: docker compose up -d --build web) sem afetar os demais containers, desde que eles não dependam de uma mudança de schema do banco compartilhado.

RO
Fundador e editor-chefe

Rodrigo mantém o ViciadosMU desde os primórdios do portal. Especialista em criação e administração de servidores de MU Online, história do jogo e a evolução das seasons — escreveu boa parte do acervo antes de 2024.

Continue lendo

Artigos relacionados