Sunday, May 10, 2020

Automatically Start Local Minecraft Server on Linux (Fedora) At Boot

Running your own Minecraft server on Linux is pretty simple.  You simply download the jar file from Minecraft.net and run it from the command line.  However, if you run it straight from the command line you'll need to stay logged in and not kill the terminal otherwise it will stop the Minecraft server.

The way to work around it is to use something like tmux or screen and run Minecraft from there.  That allows you to detach the session, logout, and come back to it at a later time so you now have a "headless" Mindcraft server running.

The final step is to make it so that it automatically starts when the server boots up and shut it down when the server shuts down.  On Fedora, that means using systemd.

I'm assuming you're running Minecraft as user minecraft and the Minecraft jar file is located in ~minecraft.
$ sudo adduser minecraft
$ sudo passwd minecraft
Because SELinux is enabled by default, we need to put our Minecraft files in another directory that isn't the user home directories since SELinux policy blocks systemd access to them.  Instead, let's put it in /opt/mcserver.

Start-Up/Shut-down Scripts


First, let's create a start-up script in /opt/mcserver/start_server.sh:

#!/bin/sh
/usr/bin/tmux new-session -s minecraft -d
tmux send -t minecraft "/usr/bin/java -Xmx1024M -Xms1024M -jar /opt/mcserver/minecraft_server.1.8.3.jar --nogui" ENTER
This starts a new tmux session in detached mode and calling the session minecraft.  Then it sends to the tmux session the command to start the Minecraft server in text (non-gui) mode.

Let's make a shutdown script in /opt/mcserver/stop_server.sh:

#!/bin/sh
/usr/bin/tmux send -t minecraft /save-all ENTER
/usr/bin/tmux send -t minecraft /stop ENTER
echo "Killing minecraft session"
/usr/bin/tmux kill-session -t minecraft
This sends a command to the tmux session named minecraft to
  1. Save the current state of the server (save-all).
  2. Shutdown the minecraft server (/stop).
  3. Stop the tmux session.
Make both scripts executable:

chmod u+x start_server.sh
chmod u+x stop_server.sh

Automatically Start Your Server


To automatically start and stop the tmux session for Minecraft, create /usr/lib/systemd/system/minecraft.service:

[Unit]
Description=Start tmux in detached session running Minecraft.

[Service]
Type=forking
User=minecraft
ExecStart=/opt/mcserver/start_server.sh
ExecStop=/opt/mcserver/stop_server.sh
WorkingDirectory=/opt/mcserver

[Install]
WantedBy=multi-user.target
Now link it to the right place:

cd /etc/systemd/system
ln -s /usr/lib/systemd/system/minecraft.service minecraft.service
Now we can run it and enable it to start at boot:

systemctl start minecraft.service
systemctl enable minecraft.service

Configure the Firewall


Now the server is running, you might realize that your Minecraft client cannot connect to it because of the firewall.  To open the firewall to allow clients to connect to your server

$ firewall-cmd --get-active-zones 
$ sudo firewall-cmd --permanent --zone=[zone from above] --add-port=25565/tcp
$ sudo firewall-cmd reload
We can name this as a service called minecraft by creating a file called /etc/firewalld/minecraft.xml with:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>minecraft</short>
  <description>Port used to allow remote connections to a Minecraft server running on this machine.</description>
  <port protocol="tcp" port="25565"/>
</service>
Then tell firewalld to load it permanently:

$ sudo firewall-cmd --zone=[Name of your zone] --permanent --name=minecraft --new-service-from-file=/etc/firewalld/minecraft.xml
$ sudo firewall-cmd --reload

Backup Your Save File


I also suggest having a backup script that regularly back up your world:

#!/bin/sh
printf "Starting backup..."
date +%D
cd /opt/mcserver
tmux send -t minecraft /save-off ENTER
tar -czvf $HOME/backup/world-`date +%m%d%y_%H_%M_%S`.tar.gz world
tmux send -t minecraft /save-on ENTER
With a cron job as follows:

0 15 * * * /home/minecraft/backup.sh >> /home/minecraft/backup/backup.log 2>&1

This says to run the job at 3pm every day and copy the output to backup.log.

The saved archive (even compressed) can get pretty big and can easily eat up disk space so you might want to only keep the a few of the most recent save and automatically delete the old ones (or move old archives somewhere else).  That can be done with another cron job with a one line script:

ls -tr world-*.tar.gz | head -n -5 | xargs --no-run-if-empty rm
This will delete all but the 5 most recent files and do nothing if there are less then 5 archive files.  This can be put into a script with some logging /home/minecraft/cleanup_backup.sh:

#!/bin/sh
printf "Deleting old backups..."
date +%D
cd $HOME/backup
ls -tr world-*.tar.gz | head -n -5 | xargs --no-run-if-empty rm -v
and have a cron job as follows to run nightly:

# Delete old backup files at 11:20pm but keeping a few most recent ones.
20 23 * * * /home/minecraft/cleanup_backup.sh >> /home/minecraft/backup/backup.log 2>&1

Now each time your server boots, it will automatically run the Minecraft server as user minecraft and once a day it will back up your Minecraft data while removing old archives.



No comments:

Post a Comment