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 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.1
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.2 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 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 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 and the Docker Engine 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 username3, 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 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.4 It's actually surprisingly simple, though it did take more steps than anticipated:
1client, 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.
2if err != nil {
3 return err
4}
5defer client.Close()
6
7ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
8defer cancel()
9
10id, err := client.ContainerExecCreate(ctx, Config.ContainerName, types.ExecConfig{
11 Cmd: cmd, // cmd is a []string
12})
13if err != nil {
14 return err
15}
16
17if err := client.ContainerExecStart(ctx, id.ID, types.ExecStartCheck{Detach: true}); err != nil {
18 return err
19}
All-in-all, the end bot looks like this from the perspective of a regular user:
You can find the source code for the bot here.
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.
- I mean - this website is also run on a very similar VPS from Hetzner using a very similar setup. ↝
- 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. ↝
^[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]{3,16}$
:) ↝- 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 runningdocker exec mc ...
instead. ↝