Rodando um servidor de minecraft no Azure
Tags: azure, minecraft, docker, containers
Published: 2021-09-02 10:15:05

Para inaugurar o meu blog aqui no dev.to, decidi escrever um artigo mais leve, unindo duas grandes paixões: Minecraft e Containers!

Eu comecei a jogar Minecraft ainda na versão beta, em 2010, por indicação do meu amigo Thiago Duarte. Na época joguei um pouco, mas acabei perdendo o interesse. Na época paguei 5 dólares pela licença. 

Com a pandemia, e buscando atividades para fazer com meu filho, lembrei que tinha conta no Minecraft, e começamos a jogar em familia, eu, ele e minha esposa, mas sempre tinhamos o problema de quem ia rodar o servidor, acabava que alguém sempre um de nós tinha que deixar o servidor aberto no computador, mesmo que não quisesse jogar.

Para resolver isso, resolvi subir um servidor de Minecraft na Azure, aproveitando o benefício de ser MCT (Microsoft Certified Trainer) e ter alguns créditos todos os meses. 

Inicialmente, subi o servidor em uma VM, baixando localmente o servidor, o Java e rodando tudo manual, mas o processo é muito lento e manual, então, sendo um grande fã de containers, fui correr atrás de como rodar ele em containers. Por sorte, temos uma ótima imagem docker para rodar um servidor de minecraft, com todas as opções possíveis, que pode ser visto neste excelente repositório do github: [itzg/docker-minecraft-server](https://github.com/itzg/docker-minecraft-server)

Esse container permite rodar o servidor de minecraft com poucas configurações, e é fácil rodar a versão tradicional (vanilla), assim como várias opções com mods. 

Inicialmente, aproveitei a VM que tinha, instalei o docker e comecei a rodar lá o container, mas sempre ficou a idéia de como rodar ele no [Azure Container Instances (ACI)](https://azure.microsoft.com/pt-br/services/container-instances/). Como não achei nenhum tutorial fácil de como fazer isso, resolvi escrever esse artigo, e aproveitei para aprender um pouco sobre o [bicep](https://github.com/Azure/bicep), nova linguagem para fazer o deploy na Azure.

Para rodar o servidor do minecraft no ACI, e manter os dados salvos quando baixamos ele, precisamos de 2 recursos, um Container Group que vai rodar o servidor e uma Storage Account, que vai guardar os arquivos entre as paradas do servidor.

O primeiro recurso que temos é a storage account, onde declaramos apenas o tipo, localidade, nome e SKU (desculpem pela falta de syntax highlight, o dev.to não suporta ainda a linguagem bicep):

```bicep
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: 'exemplominestorage'
  location: 'brazilsouth'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}
```

Além disso, precisamos declarar um storage share (compartilhamento do Azure Files), que será anexado ao container. Esse share depende da storage account, e declara o nome do share apenas:

```bicep
resource storageShare 'Microsoft.Storage/storageAccounts/fileServices/shares@2019-06-01' = {
  name:  'exemplominestorage/default/minecraftdata'
  dependsOn: [ 
    storageAccount 
  ]
}
```

Por fim declaramos o ContainerGroup, ele depende do storage share, declara um container e liga o storage share nele, alem de colocar algumas variaveis de ambiente mais comuns:

 
```bicep
var whitelist = ''//coloque aqui seus usuarios separados com ,
 
resource containerGroup 'Microsoft.ContainerInstance/containerGroups@2019-12-01' = {
  name: 'exemplomine'
  location: 'brazilsouth'
  dependsOn: [
    storageShare 
  ]
  properties: {
    containers: [
      {
        name: 'exemplomine'
        properties: {
          image: 'itzg/minecraft-server'
          environmentVariables: [
            {
                name: 'WHITELIST' // Lista de jogadores que podem conectar
                value: whitelist
            }
            {
                name: 'OPS' // Lista de jogadores que podem dar comandos
                value: whitelist
            }
            {
                name: 'MAX_PLAYERS' // Quantidade maxima de jogadores
                value: '2'
            }
            {
                name: 'ENABLE_COMMAND_BLOCK'
                value: 'true'
            }
            {
                name: 'MOTD' // Mensagem mostrada no server
                value: 'Ola da Azure'
            }
            {
                name: 'MEMORY' // Memoria alocada no java
                value: '3G' // Usar menos memoria que a disponivel no container, não funciona se for o mesmo
            }
            {
              name: 'EULA' // é obrigatorio o aceite do EULA do minecraft
              value: 'true'
            }
            {
              name: 'VERSION' // Versao do minecraft a ser rodada
              value: 'LATEST'
            }
            
          ]
          resources: {
            requests: { // CPU e memória alocada para o minecraft
              cpu: 1 
              memoryInGB: 4
            }
          }
          ports: [
            {
              port: 25565 // Liberar a porta para acesso publico
            }
          ]
          volumeMounts: [ // Ligar o volume de dados no container
            {
              name: 'acishare'
              mountPath: '/data'
              readOnly: false
            }
          ]
        }
      }
    ]
    osType: 'Linux'
    ipAddress: { // Liberar a porta no firewall e dar um nome publico pra ele
      type: 'Public'
      ports: [
        {
          protocol: 'TCP'
          port: 25565
        }
      ]
      dnsNameLabel: 'exemplomine'
    }
    restartPolicy: 'Never'
    volumes: [
      { // Ligacao com o fileshare criado
        name: 'acishare'
        azureFile: {
          readOnly: false
          shareName: 'minecraftdata' // nome do share
          storageAccountName: storageAccount.name // account
          storageAccountKey: listKeys(storageAccount.name, storageAccount.apiVersion).keys[0].value // obtem dinamicamente a chave de acesso para o account
        }
      }
    ]
  }
}
```

Pronto, depois disso é só compilar o bicep e transformá-lo em ARM template, e de posse do ARM, importar ele como template na Azure.

Se você preferir usar um ARM pronto, é só clicar nesse botão, preencher as variáveis e fazer o deploy:

[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fandreracz%2Fminecraft-on-azure%2Fmaster%2Fvanilla-aci.json)

Depois de terminado o deploy, entre no recurso criado, obtenha o FQDN:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t3hp0ofr4luovwam03bb.png)

Acesse no modo multiplayer do minecraft, em Add Server, digite o nome e a URL do seu servidor, clique em Done:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g55zhf8saggghj2y0ba2.png)

Pronto, seu server está pronto para iniciar. Happy Mining!

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u17l0txi4vq5i6bhcztx.png)

Não esqueça de parar o servidor quando não estiver usando, para não gastar seus créditos! 

Deixo aqui também o link pro github que criei com esse projeto, já com parametros para facilitar a nossa vida: [andreracz/minecraft-on-azure](https://github.com/andreracz/minecraft-on-azure). 

Se você quer ver mais posts, sobre como rodar servidores com MODs, como automatizar a subida e a descida to Container, ou outros sobre Minecraft, deixe seu like e comente neste post!