Self-hosting Minecraft at home
Last year I spent more hours playing Minecraft than I care to admit. Being an introvert that I am, I play on a small private server with my partner and a few friends, and Minecraft Realms has been a great hosting for us, fast, cheap, secure, with backups. The only issue — it can’t have mods, and eventually we wanted to play with mods. After shopping around for hosting services and trying a couple of them we came away mildly disappointed: they were either very slow, or very expensive. I decided that I will simply move the server to my former gaming laptop, which has been sitting idle for the last year or so. It had plenty of power and, most importantly, RAM, while being fairly energy-efficient. The cost of electricity running it 24/7 was a couple of times smaller than a comparable hosting.
We wanted a few very specific things that may or may not be relevant to everyone:
- Minecraft Java Edition.
- Decent performance with 2-5 players online.
- Ability to run any mods we like.
- Frequent backups (they saved our world a few times in the past).
- Our friends should be able to connect without too much hassle.
This post will serve me as a reminder how on Earth our setup works.
🤚 Pause for a second
Self-hosting is great and may give you more control and flexibility in exchange for additional responsibility and risks:
- Your home network is less reliable than in a datacenter, which may be a bad time for your friends.
- Your hardware is likely less reliable as well.
- You need to manage the whole stack, from the OS to the game server itself, backups gateway.
- Letting people from the internet into your home network is generally a risky business, if you make a mistake and open up too much, bad actors will invite themselves into your home.
💽 Choosing OS
There wasn’t much deliberation here: Ubuntu Server 22.04 LTS. Mainly because I know how to cook it and it can be run pretty much hands-free. It also has been historically very good with hardware support, so that’s a plus too.
🎮 Running a Minecraft Server
The hosting we’ve previously used offered AMP, which was neither great nor terrible. It is a commercial software though, and I didn’t need most of its features. What I needed was:
- Easy installation.
- Open source, preferably written in a language I can understand and debug if the need be.
- Uses as little resources as possible. Those are better used for running the game :)
- Has a simple Web UI, which allows to create and monitor a Minecraft server.
Turns out there are plenty of options to choose from, whether you use Windows or Linux, or prefer CLI or Web UI. I went with PufferPanel, which ticked all my boxes and seemed to have minimal bloat. Installing it was as straightforward as it gets, starting a Minecraft instance also took no effort.
💾 Backups
That feature was conspicuously missing from PufferPanel feature list, as well as most of its competitors. I think AMP is the only one that officially had it, but on a rather primitive level: no retention policies, no incremental backups. And those features were rather important if you want to have more than 5-10 most recent snapshots.
We have also tried using some Minecraft mods like Textile Backup, but it was also missing retention policies and incremental backups, and it impacted game performance considerably while it was running. So I prepared to set something up on my own.
If I mentioned earlier that there are many Minecraft server management solutions, that’s peanuts compared to backups. There are a lot of options with various pros, cons, levels of maintenance and features. Restic, rdiff-backup, Duplicati and Kopia to name a few.
In the end it was a close call between Restic and Kopia, and I chose the latter mainly because I already had my eye on it for my DIY NAS project (which I one day will write about). I liked a few things about Kopia:
- It supports incremental backups and deduplication, which worked quite efficiently for Minecraft files.
- Support for a variety of remote storage types, including an append-only mode, which could be a good defence against a ransomware attack.
- General ease of setup and management.
- Support for Linux, Windows and MacOS. I could learn it once and then use across all my computers.
For now, I set it up with a local filesystem as a backup destination (though I should setup a remote backup too):
|
|
One interesting feature of this system is that once you’ve set up connection to your repository, you can backup and restore any path on your system. You don’t have to tell how to store each particular directory, it will automatically remember where it came from and will allow restoration to the original location (or somewhere else, if you want it).
All that remains is to build a bridge between PufferPanel and the backup system.
I wrote this simple python script to do that
Requirements: Python 3, oauthlib
1.3, requests
2.28, requests-oauthlib
3.2.
|
|
It connects to PufferPanel, enumerates all existing game servers and then triggers kopia as a subprocess to create a snapshot. To make sure the snapshot is consistent, it also uses PufferPanel API to send some commands to the Minecraft server console.
Save that script to /usr/local/bin/
, make it executable and add a Crontab
entry to make sure it runs regularly:
|
|
🌍 Remote access
One last challenge is making the machine hosted at our home accessible to friends outside of our home network. If you have a static IP, setting up port forwarding on your router is by far the easiest option. Unfortunately, this is not something our IPS provides, so I decided to tunnel the connection instead from my VPS.
Update: Apparently, there’s also https://playit.gg/, which supports TCP and UDP forwarding and doesn’t require you having a server with a public IP. I haven’t tried it, but it may be a good option for some people.
The easiest way of doing it is with SSH port forwarding (on your Minecraft
machine): ssh -N -R 25565:localhost:25565 minecraft@example.com
. Then
everybody connecting to example.com:25565
would connect to localhost:25565
,
which is where the Minecraft server is.
Update #2: Make sure that in server.properties
you set
prevent-proxy-connections=false
. If you don’t do this, everything will be
working fine for you, but any one of your friends outside of your home network
will not be able to log in with a
$username tried to join with an invalid session
error. I think this setting is
supposed to make evading IP bans harder, but because the tunnel we are about to
set up is a kind of a proxy, minecraft gets upset and refuses the connection.
Unfortunately, it wasn’t sufficient for us, because we have the Simple Voice Chat mod, which (like many VoIP applications) also requires a UDP port to work. The solution came in a form of https://github.com/snsinfu/reverse-tunnel. This project allows forwarding both TCP and UDP traffic to a destination behind NAT. It consists of a gateway that runs on a public-facing VPS and an agent that runs on a machine behind NAT, which establish a channel between them. The agent is able to handle reconnection automatically in case network temporarily drops out, which is nice. One last bit is making sure both the gateway and the agent start automatically with the system, which systemd can do for us.
Configuration on the public gateway server.
|
|
Ideally I would use a non-privileged user for the service, but maybe another time 🤷♂️.
Configuration on the Minecraft machine.
|
|
These last log lines confirm that the agent was successfully able to connect to the gateway and set up fort forwarding.
It’s important to note that the gateway and the agent must share a secret (make sure to generate a strong one!), so unauthorized actors won’t be able to piggyback on your gateway.
🏁 That’s all!
After all that I repointed my minecraft server domain to the new IP address and the whole migration went pretty much unnoticed by anyone except me and my partner who can now connect to the server via local network for better latency 😎