Managing a Simple Family Minecraft Server

Created: 2021-01-16

In summary, I use my ratcraft script to manage a Minecraft server in the "cloud".

Virtual hardware

I have a Linode shared virtual instance with the following specs: 4 GB RAM, 2 Cores, 80 GB SSD, at $20 per month. Cheaper instances may work, but we’ve had no problem with four or more people playing on this instance.

Hosting on an in-house computer works great (and would be cheaper after about a year or so), but having the "cloud" instance is so much easier to manage and getting friends outside of the house connected is 100% easier.

The instance runs Slackware Linux and I do all server management at the command line through SSH.

I also gave it a DNS subdomain so it’s real easy to tell friends how to access it.

Minecraft Server

We’ve experimented with mods (and creating them), so we’ve run Spigot servers locally. But on the always-on family server, we run the so-called "vanilla" Minecraft server (Java Edition).

Launching the server

The server is a Java executable that needs to be kept running in a process. I’ve opted to manage the process with the GNU terminal multiplexer screen. The start command would look something like this:

# screen -S session_name -dm bash -c "cd worlddir; java -Xms512M -Xmx1024M -XX:ParallelGCThreads=1 -jar serverxxx.jar nogui"

Obviously I’m not going to type that more than once, so I wrote a little application (a wee Bash script) to manage this for me called ratcraft.

It’s about 130 lines of Bash and has a handful of commands:

# Usage: ratcraft ( start | stop | status | backup | watch | cmd <command> )

Server upgrades

The Minecraft clients automatically update to the latest version as soon as it’s out.

Getting the latest server to match is as simple as grabbing the tarball link from minecraft.net/download/server and downloading it on the host:

# wget https://launcher.mojang.com/v1/objects/1b55...73ced/server.jar
# mv server.jar minecraft_server.1.16.5.jar
# ls
bin/                         minecraft_server.1.16.1.jar  minecraft_server.1.16.4.jar  old_server/
mcserver/                    minecraft_server.1.16.2.jar  minecraft_server.1.16.5.jar
minecraft_server.1.15.2.jar  minecraft_server.1.16.3.jar  minecraft_server.1.16.jar

As you can see, I manually rename the server to the version number and keep the old ones around. It’s really unlikely I need to do that, but it works and I’m sticking with the process at this point.

I have to manually edit (yup, manually edit!) the ratcraft script to update the server version:

jar=~/minecraft_server.1.16.5.jar

Then I just restart (stop and start) the server with ratcraft:

# ratcraft stop
Stopping server...
[20:03:24] [Server thread/INFO]: ThreadedAnvilChunkStorage (world2): All chunks are saved
[20:03:24] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM-1): All chunks are saved
[20:03:24] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM1): All chunks are saved
Server stopped
# ratcraft start
Starting server...
To see how it's going, try: ratcraft watch

In a few moments, the server is ready for the updated clients.

It’s not a commercial-grade solution, but it’s:

  • Simple enough for me to understand when I come back to it every couple months

  • Automated enough to not be a total pain to use

Backups

The ratcraft script has a backup feature. I call it daily via a cron job in Slackware’s /etc/cron.daily directory. The script simply calls:

/theuserdir/bin/ratcraft backup

The backup tells the Minecraft server to stop saving, makes a .tgz with tar -cpvzf of the "world" directory and saves it in a "backups" directory.

The backup command also performs simple backup rotation so the server doesn’t fill up. Occasionally we might want to save an important epoch in our world, so I just rename one of the backups so it doesn’t get removed in the rotation.