Backing Up Your Minecraft Server in Ubuntu

FireI wrote an earlier post on how to create a Minecraft Server on Ubuntu. It’s been pretty popular, so this article will describe a very simple way to ensure that you take hourly automated backups of your Minecraft server(s).

This is incredibly useful for a number of reasons :

  1. Some random punter has griefed your server beyond recognition and you need to roll it back to its former glory.
  2. A fire has started on the other side of the map, you didn’t notice it, and now your world is a charred, devastated ruin.
  3. You fell into a lava pit with your all your coolest stuff on and can’t bear the thought of having to do without.
  4. You accidentally hit a zombie pigman in the Nether and now there’s an angry mob at the portal preventing you from progressing.

FacepalmThese are the kind of calamities that stop you playing Minecraft for weeks, or make you ditch your hard earned world to start over, with heavy heart.

Backup!

So what do you do? Well the Minecraft games directory is actually really, really straight forward, so taking a backup is actually as simple as running a little tar command and putting the resultant file somewhere safe!

Here’s my tar command :

tar -cpvzf /home/mc/Minecraft/Backups/Server1/minecraft-day0.tar.gz /home/mc/Minecraft/Games/Server1

So, you can see that my server has a Minecraft directory. In there, I have Backups and Games. And inside Games, I’m backing up the Server1 server directory. Simple! When I run that command, the Backups directory gets a minecraft-day0.tar.gz file in it.

So, pop into your server directory and create a file called something like backup-server1-daily, put that tar command in it, then make it exectuable, by either using nautilus, or running “chmod +x backup-server1-daily”.

So how do I make this run? With the built-in linux scheduler, cron. And how, exactly, do you do that? Well, I cheat actually. I install Webmin, then use a web browser to configure it via the GUI. If you want the quick method, however, you can simply do this in a terminal :

crontab -e

Add this line :

@daily /home/mc/Minecraft/Games/Server1/backup-daily-server1 #Make daily backup of Minecraft server1

Now, when you do a crontab -l, you’ll see your script is ready to run each day, at midnight.

Hourly

Now things get a little more complex if we want to run things hourly. Why? Well, because if you fall into the lava pit at 13:59, you’ll only have one minute or less to exit the game and restore your server before the hourly backup is run and you’re back to square one, crying into your coffee.

So, we have to run a script hourly, which rotates 24 times, saving off the old backups in succession.

Here’s a script to do so :

cd /home/mc/Minecraft/Backups/Server1
rm -f minecraft.tar.gz.24
mv minecraft-hour23.tar.gz minecraft-hour24.tar.gz
mv minecraft-hour22.tar.gz minecraft-hour23.tar.gz
mv minecraft-hour21.tar.gz minecraft-hour22.tar.gz
mv minecraft-hour20.tar.gz minecraft-hour21.tar.gz
mv minecraft-hour19.tar.gz minecraft-hour20.tar.gz
mv minecraft-hour18.tar.gz minecraft-hour19.tar.gz
mv minecraft-hour17.tar.gz minecraft-hour18.tar.gz
mv minecraft-hour16.tar.gz minecraft-hour17.tar.gz
mv minecraft-hour15.tar.gz minecraft-hour16.tar.gz
mv minecraft-hour14.tar.gz minecraft-hour15.tar.gz
mv minecraft-hour13.tar.gz minecraft-hour14.tar.gz
mv minecraft-hour12.tar.gz minecraft-hour13.tar.gz
mv minecraft-hour11.tar.gz minecraft-hour12.tar.gz
mv minecraft-hour10.tar.gz minecraft-hour11.tar.gz
mv minecraft-hour9.tar.gz minecraft-hour10.tar.gz
mv minecraft-hour8.tar.gz minecraft-hour9.tar.gz
mv minecraft-hour7.tar.gz minecraft-hour8.tar.gz
mv minecraft-hour6.tar.gz minecraft-hour7.tar.gz
mv minecraft-hour5.tar.gz minecraft-hour6.tar.gz
mv minecraft-hour4.tar.gz minecraft-hour5.tar.gz
mv minecraft-hour3.tar.gz minecraft-hour4.tar.gz
mv minecraft-hour2.tar.gz minecraft-hour3.tar.gz
mv minecraft-hour1.tar.gz minecraft-hour2.tar.gz
mv minecraft-hour0.tar.gz minecraft-hour1.tar.gz
tar -cpvzf /home/mc/Minecraft/Backups/Server1/minecraft-hour0.tar.gz /home/mc/Minecraft/Games/Server1 --exclude '/home/mc/Minecraft/Games/Server1/plugins/dynmap'

I’ll cover that –exclude option in a moment. What we’re doing here is deleting the oldest backup, then renaming every to be one hour older, then using pretty much the same tar command as before in order to create the newest backup.

So, because we’re doing this hourly, it’ll be more likely to happen when someone is playing on your server. So we want it to run really quickly. What I’ve found is that some plugins create an absolutely epic amount of data when you run them with CraftBukkit, and one of those plugins is Dynmap. So when we take the Daily backup, we backup everything, but when we do the hourly backup, we exclude the really big directories that probably haven’t changed anyway!

There’s one more trick, which is to ensure that a player isn’t making a change while the backup is taking place. To do so, we need to issue the save-off command to the server before the backup is run, then issue a save-on afterwards.

This will also let us notify any users that a backup is taking place. However, in order to do that, we need to run each Minecraft server in its own terminal using an identifier. As it turns out, Ubuntu has such a facility available into it, called Screen.

Screen

The idea behind Screen is to multi-task using just a single terminal window. In that terminal, you create instances with the screen command, then switch to them as required. What’s cool about this is that each instance can be tagged with a name, so that you can recall these instances in scripts (and cron!) as required.

To install Screen, just use sudo apt-get install screen.

Now, I run three or four Minecraft servers, and the way I set them up is like so – run a terminal, then type the following :

cd Minecraft\Games
screen -R Server1
<the screen clears with a "new terminal" message at the bottom>
cd Server1
./start_server

Then I type CTRL-A, then CTRL-D. At this point, I’ve detached from the “Server1” screen and I’m back in my normal terminal window. I can then issue a screen -ls to see what screen instances are available to reconnect back into. Or carry on, repeating the above for Server2, Server3 and so on.

Then later, I can screen -R Server1 to get back to my Minecraft server. Perhaps to stop it, or issue a console command.

Note that I match my screen tagnames to the directory I run the server in. You don’t have to do this, but I find it helps when you have a decent number of screens to manage.

What’s nice about this set up is that I can close my main terminal window at any point, then later open a terminal, type screen -ls, to see what’s still running, then use screen -R to get back to any session I need.

You can see why this is useful generally, but it’s great for Minecraft servers, because now we can use the stuff command to send messages into our Minecraft games!

Here’s my full script, then, sending a message to all players that a backup is taking place, turning off Minecraft saving, performing the backup, informing the players that the backup is complete and turning Minecraft saving back on again.

screen -R Server1 -X stuff "say Backup starting. World no longer saving... $(printf '\r')"
screen -R Server1 -X stuff "save-off $(printf '\r')"
screen -R Server1 -X stuff "save-all $(printf '\r')"
sleep 3

cd /home/sadmin/Misc/Apps/Games/Minecraft/Backups/Cave
rm -f minecraft.tar.gz.24
mv minecraft-hour23.tar.gz minecraft-hour24.tar.gz
mv minecraft-hour22.tar.gz minecraft-hour23.tar.gz
mv minecraft-hour21.tar.gz minecraft-hour22.tar.gz
mv minecraft-hour20.tar.gz minecraft-hour21.tar.gz
mv minecraft-hour19.tar.gz minecraft-hour20.tar.gz
mv minecraft-hour18.tar.gz minecraft-hour19.tar.gz
mv minecraft-hour17.tar.gz minecraft-hour18.tar.gz
mv minecraft-hour16.tar.gz minecraft-hour17.tar.gz
mv minecraft-hour15.tar.gz minecraft-hour16.tar.gz
mv minecraft-hour14.tar.gz minecraft-hour15.tar.gz
mv minecraft-hour13.tar.gz minecraft-hour14.tar.gz
mv minecraft-hour12.tar.gz minecraft-hour13.tar.gz
mv minecraft-hour11.tar.gz minecraft-hour12.tar.gz
mv minecraft-hour10.tar.gz minecraft-hour11.tar.gz
mv minecraft-hour9.tar.gz minecraft-hour10.tar.gz
mv minecraft-hour8.tar.gz minecraft-hour9.tar.gz
mv minecraft-hour7.tar.gz minecraft-hour8.tar.gz
mv minecraft-hour6.tar.gz minecraft-hour7.tar.gz
mv minecraft-hour5.tar.gz minecraft-hour6.tar.gz
mv minecraft-hour4.tar.gz minecraft-hour5.tar.gz
mv minecraft-hour3.tar.gz minecraft-hour4.tar.gz
mv minecraft-hour2.tar.gz minecraft-hour3.tar.gz
mv minecraft-hour1.tar.gz minecraft-hour2.tar.gz
mv minecraft-hour0.tar.gz minecraft-hour1.tar.gz

tar -cpvzf /home/mc/Minecraft/Backups/Server1/minecraft-hour0.tar.gz /home/mc/Minecraft/Games/Server1 --exclude '/home/mc/Minecraft/Games/Server1/plugins/dynmap'

screen -R Server1 -X stuff "save-on $(printf '\r')"
screen -R Server1 -X stuff "say Backup complete. World now saving. $(printf '\r')"

And here’s the result, when it all comes together!

A minecraft backup taking place.

Of course, you can do this for your daily backups too and enjoy the piece of mind that you can roll back any of your servers to any hour in the last 24 hours, or perhaps any midnight in the last 7 days! Just  ensure that you have enough disk space for the undertaking!

Restore

Of course, a backup isn’t much use with a way to restore it. But remember that the tar command we ran just copied the whole directory, so while there’s probably some ninja-script-fu that you can run to restore everything, I have to admit that for the rare cases I need to restore, I’m just lazy. Here’s my procedure :

1. Stop the minecraft server you’re about to restore.

2. Rename the directory from Server1 to Server1-old

3. Find the backup tar file that you’re going to use to restore your server. Right click on that file and choose “Extract Here”. You will see a new Server1 directory appear in your backup directory.

4. Cut that Server1 directory from your Backups directory and paste it into your Game directory.

5. Start the server.

Note that if you’re restoring an hourly backup and you used my “exclude” option, then you’ll also have to restore everything you excluded from the Server1-old directory.

Once you’re happy that the server is working as you expect, you can delete the Server1-old directory, or perhaps consign it to an archive directory for prosperity, as a dark reminder of what can go wrong in the world of Minecraft.

If you have questions, shout me in the comments.