My son is very active on Minecraft for years now. We decided to move away from running Minecraft Server on my Synology NAS and instead we set up a Virtual Machine on Microsoft Azure. The power of the NAS just wasn’t sufficient to run more than 1 instance. On the NAS I had run the server both native as well as in Docker containers over time. However: he wanted to run 3 instances simultaneously, for different purposes, so I decided it was time to leave the NAS (as far as it concerned Minecraft at least) and provide him with a dedicated VM in the cloud.
Running the server itself is a piece of cake. There are a few things you need to take into account though. Of course my son is not running the plain vanilla server: he wants all kinds of special versions, plugins, mods, you name it. However: for the sake of readability I am not going into all of that in this article, and my examples will show only the vanilla version of Minecraft Server.
First thing to do is to make sure you have Java installed on the machine and you download the latest version of Minecraft Server Java Edition.
After installing Java, copy the .jar file (which is the Minecraft Server binary) and store that in an easy location, e.g. on your datadisk of the VM. Then, to run the server, open a Command Prompt window, navigate to that folder and run the following command:
java -Xmx1024M -Xms1024M -jar minecraft_server.1.17.1.jar
This will start the server and it will allocate 1 Gb of memory for it. It can be easy if you paste this command in a .bat file that you can easily double click to launch the server in the future, but that’s entirely up to you.
On a clean machine, the firewall will most likely now prompt that you need to allow incoming traffic. Needless to say: you should allow that, as you want people from “outside” to access your instance of the server. You now have the Minecraft Server running and waiting for incoming connections.
But in this particular case, we are running it on a VM in Microsoft Azure, so there is more to do before connections are allowed. The Azure Portal itself also contains a firewall. All ports by default are closed (except for RDP) so you need to go into the Azure Portal and allow the port on which Minecraft is running. You can see the proper port number in the server.properties file of your Minecraft server folder. By default it is 25565, but in case you will have more than 1 instance, you need to vary that between instances. Write down which server will listen to which port as you will need that information later on. In the screenshot below, you will see 3 ports: 24565, 25565 and 26565. Each port represents a Minecraft server instance, and we have put all 3 in 1 rule. You only need to open up those ports for the TCP-protocol.
Accessing the server
Now that the server is running and you have opened up the port(s), you should be ready to connect to it for the first time. In order to connect your Minecraft game to the remote server, you will need the hostname of the machine, or the IP-address it runs on. In the example image below, I am connecting to a server that listens to IP 18.104.22.168 and port 25565. Of course you need to change these values accordingly.
If the Message Of The Day (motd in the server.properties) appears, then you know it responds and you are able to connect to your Minecraft server. If no connection can be made, you need to check the following things:
- Is the Minecraft application still running, or did it crash?
- Did you open the correct port in Azure Portal?
- Did you allow the application in Windows Defender firewall?
DNS A-records to listen on domain-names
Now that you have the application technically available, we are ready for the really fun part! In case you have registered a domain-name, you can have every instance of Minecraft Server listen to its own subdomain. Another advantage of doing that, is that your users (the people who will join the game on your server) are not bothered with those portnumbers. We are going to connect a portnumber to a subdomain, so that sharing the information about your Minecraft servers becomes super easy!
First of all, every instance needs its own subdomain-record. Often you would do this with a CNAME-record, which connects a subdomain-name to another hostname, e.g. minecraft.johndoe.com could point to server12345.yourhostingcompany.com. However: because we are going to need so-called SRV-records, we should not be using CNAMEs as according to the specifications, only A-records are allowed here. So, let’s just create an A-record for every subdomain which points to a target IP-address. E.g. [fantasy] points to 22.214.171.124. If we want to have multiple subdomains all hosted on that same server, we want to add an A-record for every subdomain. E.g. [minigames] points to 126.96.36.199 as well, etc. etc. DNS-management in Azure is perfect for that by the way, just look at the records highlighted below to illustrate the A-records.
To test your A-records, you could connect your local Minecraft game to the subdomain, followed by the appropriate portnumber, e.g. minecraft.johndoe.com:25565. Again: if the Message of the Day appears, you know the name is being resolved properly and the port is open. Now, there is just one additional step we need to take which eliminates the use of the portnumbers: add some SRV-records!
DNS SRV-records to connect ports to names
Eliminating the port numbers, at least: not bothering your users with those port numbers, is done through so-called SRV-records.Minecraft neatly implemented that technique, which we will now benefit from. Take a close look at the image below to see the records I created.
Configuring these records was my biggest challenge. I have done some DNS-activities before, but SRV-records were new to me. At first I attempted to combine all 3 directives in 1 record, and I couldn’t figure out why it just would not work. Eventually I tried adding 3 separate records and that finally did the trick. Let me try to explain what this means.
Minecraft server is set up to listen to those “_minecraft._tcp.” prefixes. Whenever you start an SRV-record with that, you need to make sure the postfix is the same as the subdomain. So in this example, “_minecraft._tcp.fantasy”, “_minecraft._tcp.minigames” and “_minecraft._tcp.smp” were all added as names. The Type of course is SRV.
Then the value needs to be set properly as well. The first two numbers are the priority and the weigth. This determines which of the names would be served if more than 1 record would match a request. In this example that can not happen, so using 10 & 5, 10 & 10 and 10 & 15 is fine. The most important part is the portnumber that the instance is listening on and the name you intent to use. That subdomain name, which is the prefix of the total domainname, should match the postfix of the record name. If that mismatches, this approach will not work. I learned that the hard way 🙂