Archive for the ‘Server Operations’ Category

Minecraft Server automated backups and automatic restart (Linux)

I like to run my Minecraft server from a cron job so that I can have a script check once a minute if it’s running (and restart if if necessary, without any manual intervention).  But that makes it very tricky to send commands to the server console to automate the backup.  What to do?

A colleague of mine suggested using the “screen” command (here’s an example of using screen to automate Minecraft backups), but I hit upon another solution that I like better: I use a simple script to read commands from a file and echo them, and I launch the Minecraft server by piping my command reader script to it.

Here’s the script I run as a cron job to keep my Minecraft server running:

#!/bin/sh
# check if the server is running and store that info in a variable:
RUNNING=`ps -ef | grep minecraft_server | grep -v grep`
cd /home/myusername/minecraft_server_folder
#
if [ -n "$RUNNING" ]; then
# log the fact that it is running:
date > running.txt
else
# relaunch sequence
# stop the command reader:
echo stop > cmdfile
# give the command reader time to stop:
sleep 10
# clear the command file, in case the command reader wasn't running:
truncate --size 0 cmdfile
# log the restart and try again:
date > restart.txt
/home/myusername/bin/commandReader.sh world | ./launchserver.sh
fi

I save that script in my bin folder as keepMinecraftRunning.sh and add this line to my crontab (using crontab -e):

* * * * * /home/myusername/bin/keepMinecraftRunning.sh

And here’s the commandReader.sh script that sends commands to the Minecraft server:

#!/bin/sh
#
STOP_CMD=stop
# set what time to make the backup:
BACKUP_TIME=0730
#
# make sure the command file exists:
touch cmdfile
#
while [ "$COMMAND" != "$STOP_CMD" ] ;
do
COMMAND=`cat cmdfile`
if [ -n "$COMMAND" ]; then
truncate --size 0 cmdfile ;
echo $COMMAND ;
fi
# wait a few seconds before reading the command file again:
sleep 5 ;
# if it's backup time, make the backup:
CURR_TIME=`date +%H%M` ;
if [ "$CURR_TIME" = "$BACKUP_TIME" ] ; then
echo save-all ;
echo save-off ;
CURR_DATE=`date +%Y%m%d` ;
# $1 is the argument, which should be the name of your world (eg. "world")
# This makes a daily tar of your world, in a file like world_20121021.tar
tar cf $1_$CURR_DATE.tar $1 ;
echo save-on ;
# wait a minute to avoid saving twice:
sleep 60 ;
fi
#
done
#
sleep 1

I save this script in my bin as commandReader.sh.  Aside from making the backup, the script simply reads whatever is in the file “cmdfile” (created in the minecraft server directory), pipes the command to the minecraft server, and clears the file.  So if I open any terminal on the machine running the server, I can simply send commands to my Minecraft server like so:

echo "time set 0" > /home/myusername/minecraft_server_folder/cmdfile

And echoing “stop” into the file stops both the Minecraft server and the command reader script.

In my minecraft server folder, I put a script called launchserver.sh. This can be just the standard launch command line (java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui), but I found the server performs better if I use a script that calculates the appropriate amount of memory — see the script here.

Then — with the server taking care of itself — I can get back to the important business of building castles!