Configure Minecraft Server with Systemd and Backups on Ubuntu 22.04


This post is in the category: Guides

Posts here are mostly step-by-step guides on how to replicate something I have set up in the past. Read over my About page to see how I show commands/output and read the disclaimer.


Base OS

Install Ubuntu 22.04 Server. At setup, create your preferred user for managing the server. We will create a user specific to the Minecraft service later.

Update and install some software.

[root]$ export NEEDRESTART_MODE=a
[root]$ apt update && apt -y dist-upgrade
[root]$ apt -y install git htop openjdk-17-jre-headless screen rdiff-backup

Minecraft Server Setup

Add a user.

[root]$ useradd -m -s /bin/bash bukkit

Create some directories.

[bukkit]$ mkdir -p /home/bukkit/{minecraft,mcbackup,scripts}

Download the server jar.

[bukkit]$ cd /home/bukkit/minecraft
[bukkit]$ wget https://download.getbukkit.org/craftbukkit/craftbukkit-1.20.4.jar
[bukkit]$ ln -s craftbukkit-1.20.4.jar minecraft_server.jar

Create the eula file. This is necessary to run for the first time.

[bukkit]$ echo "eula=true" > /home/bukkit/minecraft/eula.txt

Test run? You can do that by running this:

[bukkit]$ java -Xmx1024M -Xms1024M -jar /home/bukkit/minecraft/minecraft_server.jar nogui

Once the world generates, feel free to join from the client. This is a good checkpoint before moving into the service/backup configurations.

Once done, type “stop” into the running server to stop it.

Systemd Service

The service is pretty easy, just basically creating a few files. You don’t have to use vim; use your editor of choice and paste in the contents for each file.

This file allows you to start/stop/monitor the service and logs.

[root]$ vim /etc/systemd/system/minecraft.service

File contents:

[Unit]
Description=Minecraft Server

[Service]
Type=simple
WorkingDirectory=/home/bukkit/minecraft
ExecStart=java -Xmx1024M -Xms1024M -jar /home/bukkit/minecraft/minecraft_server.jar nogui
ExecStop=/home/bukkit/scripts/stop.sh
KillSignal=SIGINT
SendSIGKILL=no
TimeoutStopSec=300
User=bukkit
Restart=on-failure
Sockets=minecraft.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

The stop command needs to be in its own script for some reason.

[bukkit]$ vim /home/bukkit/scripts/stop.sh
#!/usr/bin/bash

echo "stop" > /run/minecraft.stdin
sleep 45
[bukkit]$ chmod +x /home/bukkit/scripts/stop.sh

Adding a socket that will allow sending commands to the running service. Finding how to do this is what finally got me away from using “screen” to hold the running process.

[root]$ vim /etc/systemd/system/minecraft.socket

File contents:

[Unit]
PartOf=minecraft.service

[Socket]
ListenFIFO=%t/minecraft.stdin

Allow the bukkit user to manage the service

The following will walk you through creating a sudoers file that will allow the bukkit user to run service commands, but only for the minecraft service.

[root]$ vim /etc/sudoers.d/bukkit

Add this:

bukkit ALL=(ALL) NOPASSWD:/usr/bin/systemctl start minecraft
bukkit ALL=(ALL) NOPASSWD:/usr/bin/systemctl stop minecraft
bukkit ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart minecraft
bukkit ALL=(ALL) NOPASSWD:/usr/bin/systemctl status minecraft
bukkit ALL=(ALL) NOPASSWD:/usr/bin/journalctl -u minecraft -f

Fix the permissions.

[root]$ chmod 0440 /etc/sudoers.d/bukkit

Command Reference

Starts the service if it wasn’t running.

[bukkit]$ sudo systemctl start minecraft

Stops the service.

[bukkit]$ sudo systemctl stop minecraft

Restarts the service.

[bukkit]$ sudo systemctl restart minecraft

Get the status of the service.

[bukkit]$ sudo systemctl status minecraft

Watch the log output.

[bukkit]$ sudo journalctl -u minecraft -f

Send a command to the service.

[bukkit]$ echo "say hellooooooo" > /run/minecraft.stdin

Most of the Systemd configuration was found in this StackExchange Answer.

Local Backup

I backup the VM routinely, however, I backup the world files hourly. This can be done locally.

Create this file.

[bukkit]$ vim /home/bukkit/scripts/mcbackup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
 
# remove old backups #
rdiff-backup --remove-older-than 7D --force /home/bukkit/mcbackup/
 
# save any chunks in memory #
echo "save-all" > /run/minecraft.stdin
sleep 10
 
# disable level saving while the backup runs #
echo "say ** Backup Yo Stuffz! May lag a sec during backup. **" > /run/minecraft.stdin
echo "save-off" > /run/minecraft.stdin
 
# run the local backup #
rdiff-backup --exclude /home/bukkit/minecraft/plugins/dynmap/web /home/bukkit/minecraft /home/bukkit/mcbackup
 
# enable disk writes again #
echo "save-on" > /run/minecraft.stdin
echo "say ** Done **" > /run/minecraft.stdin
[bukkit]$ chmod +x /home/bukkit/scripts/mcbackup.sh

Consider adding the script to bukkit’s crontab.

Test a Restore

Run the script manually a few times or let the cron go a few times. Then run the below rdiff-backup command (just the first line) and see the output.

[bukkit]$ rdiff-backup --list-increments ~/mcbackup
Found 3 increments:
    increments.2024-01-13T03:29:55Z.dir   Sat Jan 13 03:29:55 2024
    increments.2024-01-13T03:30:46Z.dir   Sat Jan 13 03:30:46 2024
    increments.2024-01-13T03:32:21Z.dir   Sat Jan 13 03:32:21 2024
Current mirror: Sat Jan 13 03:32:33 2024

The below command will restore the most recent backup available (Sat Jan 13 03:32:33 2024) based on the above output. Useful if you just died or something 🙂

[bukkit]$ sudo systemctl stop minecraft
[bukkit]$ rdiff-backup --force -r now /home/bukkit/mcbackup /home/bukkit/minecraft
[bukkit]$ sudo systemctl start minecraft

Refer to rdiff-backup documentation for more restore options.

This entry was posted in Guides on by .

About Andrew Wells

I have been developing on the LAMP stack since about 2006. I run Ubuntu XFCE on my desktop and have a history of managing Ubuntu and CentOS servers. I code web applications mostly in PHP but have experience with other languages as well. When I'm not working, I can be found working in my home lab or out snowboarding, hiking, camping, or biking depending on the season.

Leave a Reply

Your email address will not be published. Required fields are marked *