When we initially set out on our journey to empower people to host their own applications, we focused on core infrastructure and useful tooling. While that is still our primary focus and our most common use case, we did consider there are plenty of things that developers may want to self-host, such as video games with server-side components.
While it may not be the most cost-effective way to do this if it lives by itself on a Kubernetes cluster, a Minecraft server can be a fun addition to a project or company’s Plural stack.
Why would you want to self-host your own Minecraft server?
Before we dive into the technical details of how this works, it’s worth explaining the advantages of hosting your own Minecraft server.
- Custom rules: Hosting your own server allows you to customize your game experience, as opposed to running the stock game on your local machine.
- Mods: By self-hosting, you can add mods to your server, allowing for various quality-of-life improvements, increased gameplay depth, and new experiences. Check out some of those mods on CurseForge here.
- Role-based access control (RBAC): While playing on a personal server, you have more robust control over user access and can set role-based access control.
And, while hosting your own Minecraft server is not a new concept, there are a few hurdles you’ll face when you get started using Kubernetes to deploy a Minecraft server.
Minecraft on Kubernetes
The first major hurdle to using a Kubernetes cluster to self-host your Minecraft server is figuring out how to dockerize a Minecraft server process. Fortunately, there’s some pretty amazing prior art from itzg that fully dockerizes a Minecraft server and includes some pretty common modsets, along with the ability to choose your server version and configure other important settings to the game.
Honestly, the difficulty of building that image far exceeds the difficulty of configuring Kubernetes to run it and Itzg deserves a lot of love for getting it working.
Minecraft is a relatively simple system when you break it open. It contains a single node that requires a persistent disk for storing game state and configuration files, and it needs some sort of network interface for Minecraft game clients to connect to the server.
The client-server protocol is built on Transmission Control Protocol (TCP), although there are ways in which it leverages User Datagram Protocol (UDP) as well. It’s fairly easy to convert this to a Kubernetes setup, and it illustrates some nice Kubernetes core concepts.
- A Statefulset for the Minecraft node. This simplifies binding a volume to the pod and technically gives a stable network address, although that’s not fully necessary for these purposes. You can use a deployment here, but I usually find statefulsets more straightforward for stateful workloads.
- A LoadBalancer service mapping to the pods of the statefulset in (1). Kubernetes ingress only supports Hypertext Transfer Protocol (HTTP) out-of-the-box, so this is the only k8s-native solution. In theory, you can also use more advanced networking solutions like istio, but unless you have experience working with it in the past It might be best to stay clear from this solution.
- An external Domain Name System. You will also need an external Domain Name System (DNS) annotation on the service to bind a DNS name to the attached load balancer, which you can see here. Note: If you are using Plural, you can also take advantage of our DNS service to set up the hostname, so there is no need to procure a domain.
It is worth calling out that there is one minor complication that does arise from Minecraft's reliance on TCP for client-server communication. For example, Amazon Web Services (AWS)doesn’t support TCP naturally with its bare-bones Elastic Load Balancing (ELB) or Application Load Balancer (ALB). However, you can do this by installing the aws-load-balancer-controller, which is also pretty easy to configure with a few annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing service.beta.kubernetes.io/aws-load-balancer-backend-protocol: TCP service.beta.kubernetes.io/aws-loadbalancer-type: external service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
Most other clouds have TCP compatible load balancers by default, but although it’s worth watching out for this issue. Also, other games will typically rely on TCP rather than HTTP protocols for communication with their clients as they were often developed with Local Area Network (LAN) in mind.
Things to keep in mind when deploying Minecraft on Kubernetes
Kubernetes is a fairly large system that typically has a high hurdle cost to run. On AWS, an EKS control plane alone costs around $50 per month. We don’t expect most hobbyists to be willing to spend that sort of money for a standalone Minecraft server. That said, it can still be a useful setup in two scenarios:
- You want a cluster to be available for you and your friends to run a set of games, such as Minecraft, Terraria, Valheim, or CS: GO. In that case, you might be unable to pack them all onto a single box, and using something like k8s to manage the cluster could keep things relatively healthy.
- You use a lightweight k8s distribution like k3s on a low-cost machine. In this scenario, you could theoretically also use docker-compose, but k8s would be a bit more robust and could support clustering if needed.
It’s ultimately a matter of personal preference, but for Kubernetes nerds like us, we think it can be a fun way to play with Kubernetes and some of your favorite games at the same time.
How to Install Minecraft on Plural
As for installing Minecraft on Plural, you can do this by running
plural bundle install minecraft minecraft-aws in a preexisting Plural installation on AWS.
For Azure or GCP, use the
minecraft-gcp bundle names, respectively.
plural build and
plural deploy, your server will be up and running.
If you don’t have a Plural installation yet, check out our quickstart guide here to get up and running.
A few things to watch out for:
- Make sure you’re updated to the latest version of the Java Minecraft launcher
- To connect to the server, you’ll directly connect to the address that it’s hosted at on Plural, e.g.
- Make sure to add a password to your server and add permissions before sharing the address, as anyone will be able to join if they know the address.
If you like what we are doing and want to contribute to our project, head over to our GitHub to learn more about Plural.
Be the first to know when we drop something new.