---
title: Running a Minecraft Server
publishedDate: 2023-03-23
updatedDate:
    - 2023-03-28
    - 2025-02-11
tags:
    - projects
    - sysadmin
---
I'm on a student society's committee at university. During the Easter break that's right around the corner, we (committee) decided that we wanted to run a limited-duration Minecraft server, and I took on the role of setting that all up.

That also meant I was going to find some possible way to over-engineer something about it.

# Where to host?

Whereas most people would default to a game-server hosting company for ease of use, I gravitated towards [Hetzner](https://hetzner.com) to rent a VPS to function as my Minecraft server.

It was kinda the obvious choice - it's good value for our limited budget, I'm already familiar with the company and I'm totally able to handle the sysadmin stuff.<sup id="marker-1">[1](#footnote-1)</sup>

The VPS option that I went with was the CPX21 option - 3vCPU, 4GB RAM and 80GB storage, all for 8.64 EUR a month, plus IPv4 rental.<sup id="marker-2">[2](#footnote-2)</sup> I get the feeling it might be overkill for a relatively small-scale Minecraft server - I only expect 10 concurrent players, maximum - but since we're only running it for a month it doesn't matter *too* too much.

# plz how 2 minceraft

To run the actual Minecraft server, I'm using the [itzg/docker-minecraft-server](https://github.com/itzg/docker-minecraft-server) Docker image to do it all for me. It was very simple - would recommend if you're ever wanting to run one yourself.

I made some small modifications to the `server.properties` file, mostly just to enable a whitelist as we want our server to be members-only. I also added a datapack from [VanillaTweaks](https://vanillatweaks.net) for single-player sleep, though I can't seem to get the automatic installation that working quite right, so I just add it manually when a new world is generated.

# Automatically Adding People to the Whitelist

I don't really want to have to manually go and add people to the whitelist whenever someone new wants to join the server, and I definitely don't want to keep people waiting if I'm asleep or otherwise busy. To avoid these pitfalls of being a human being, I built a Discord bot to whitelist people for me! :D

It's written with Go, and makes use of [bwmarrin/discordgo](https://github.com/bwmarrin/discordgo) and the [Docker Engine SDK](https://docs.docker.com/engine/api/sdk/) (more on that later).

The bot works by exposing a single slash command that allows users to input their Minecraft username. This kicks off a train of events that validates their username<sup id="marker-3">[3](#footnote-3)</sup>, makes a record of their username and Discord user ID (for moderation purposes) and adds them to the whitelist.

Actually adding someone to the whitelist is done with the Docker Engine API - since we're running our Minecraft server in a Docker container, the best way is to run a command inside of the container to add somebody to the whitelist - in fact, the command is `mc-send-to-console whitelist add <username>`.

I chose to use the API because a) I know it exists and b) I want to Dockerise the bot.<sup id="marker-4">[4](#footnote-4)</sup> It's actually surprisingly simple, though it did take more steps than anticipated:

```go
client, err := docker.NewClientWithOpts(docker.WithHost(Config.DockerSocket)) // Config.DockerSocket can be replaced with "unix:///var/run/docker.sock" on most Linux systems if you're running your app on bare-metal.
if err != nil {
    return err
}
defer client.Close()

ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
defer cancel()

id, err := client.ContainerExecCreate(ctx, Config.ContainerName, types.ExecConfig{
    Cmd: cmd, // cmd is a []string
})
if err != nil {
    return err
}

if err := client.ContainerExecStart(ctx, id.ID, types.ExecStartCheck{Detach: true}); err != nil {
    return err
}
```

All-in-all, the end bot looks like this from the perspective of a regular user:

![Running the slash command](1.png)

![Working...](2.png)

![Final result](3.png)

You can find the source code for the bot [here](https://git.tdpain.net/codemicro/lgbtq-minecraft/-/tree/main/whitelister).

---

# Update: 2023-03-28

Now there's a backup script too! It's run with a Cron job every day, and manages gracefully stopping the server (with an in-game warning), creating and uploading archives and restarting the server. The script, called `backup.sh`, is in the source repository.

---

1. <span id="footnote-1">I mean - this website *is* also run on a very similar VPS from Hetzner using a very similar setup.</span> [↝](#marker-1)
2. <span id="footnote-2">Update 2023-03-28: This ended up falling flat on its face as soon as we launched because of the demand on it, so we upgraded to a CPX31 system with 4vCPUs, 8GB RAM and 80GB of storage, for 15.72 EUR a month. That's been running very nicely since.</span> [↝](#marker-2)
3. <span id="footnote-3">`^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]{3,16}$` :)</span> [↝](#marker-3)
4. <span id="footnote-4">This means I'll be passing `/var/run/docker.sock` into the bot container so it can control the host's Docker daemon. If I didn't want to Dockerise the bot, I'd probably stick to running `docker exec mc ...` instead.</span> [↝](#marker-4)
