Routing to multiple Minecraft servers on a host header image

Routing to multiple Minecraft servers on a host


In my previous post I walked through the setup of a Minecraft server with docker. But now you might want to setup a few servers on the same host and route domains to them without different ports, a bit like reverse proxying.

By default Minecraft runs on port 25565, but when we have multiple servers running on the same host, they can't all expose port 25565 and so you end up with something like 25565, 25566, 25567 etc. With mc-router, we can route all those domains to 25565 and resolve them to the configured server!

The Environment

At a minimum you'll need Docker installed on the host, but we'll also be using Docker Compose. If you followed the previous post you're all set. If you need to install Docker Compose, you can follow their guide here.

This solution also requires at least one domain to route to our server. Point your desired domains or subdomains at the server ip hosting your servers. If you're experimenting with this locally, you can add an entry to your hosts file to point to localhost. In this post I'll be using the following example domains set in my hosts file:

nano /etc/hosts
mc.example.com
modded.example.com
events.example.com

Setting up the router

We'll be using another docker image from itzg, this time itzg/mc-router. So go a head an open you docker compose file. If you followed the previous post, we'll continue using the same docker-compose.yaml file.

First we're going to need to remove our ports definition for each server, we don't need to expose these any more as we'll make use of dockers internal networking. Then we can go ahead and add our mc-router service.

version: "3.8"
services:
vanilla:
container_name: vanilla
image: itzg/minecraft-server
environment:
EULA: "TRUE"
MEMORY: 2G
volumes:
- ./vanilla:/data
restart: unless-stopped
tty: true
stdin_open: true

mc-router:
image: itzg/mc-router
environment:
API_BINDING: ":25564"
ports:
- 25565:25565
# bind the API port to only loopback, this avoids external exposure
- 127.0.0.1:25564:25564
command: --mapping=mc.example.com=vanilla:25565,modded.example.com=modded:25565,events.example.com=events:25565

You can see in the command line, we've mapped our domains to our containers:

mc.example.com      -> vanilla
modded.example.com -> modded
events.example.com -> events

Now go ahead and startup the stack with docker compose up and test them out in your Minecraft client!

If you'd like to know a little more about how it works, I'd recommend taking a look at the itzg/mc-router doc where they include some diagrams and alternative configurations.