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.

  • annaliq

    i need help i lost my old name and my name is not player 2 i can not get my old wolds back 3 i can not do muiltaplay and it saids in the front when i log in it saids hello player and it said play demo

    • Neil Broadley (Scaine)

      Sorry, this post isn’t going to help you. It will only help you if you ran your own server (and took backups), and it doesn’t sound your situation. It sounds like your worlds are tied to your old username. You’ll have to login to that account to access them!

  • Tony

    Will this crontab approach work on a headless server which might get rebooted every so often and so no one is physically typing to logon on to the server and the server has a startup script to automatically start minecraft in screen?
    Second, what if the backup folder is not under /home but maybe in another folder – what permissions should I grant for that other folder? For example minecraft is here: /home/mineuser/minecraft backup folder is here /backups/minecraft_backups/

    • Neil Broadley (Scaine)

      To answer the first question – yes. My server isn’t “headless”, as such, but I run everything in this tutorial using “screen” commands – in other words, I might have access to a GUI, but I’m not using any GUI-based tools.

      Regarding the second question, I’m not certain. As long as the *mineuser* account is in the group assigned to /backups/minecraft_backups, I suppose that would work?

  • Caleb

    Help when I try to run screen it says permission denied.

    Cannot exec ‘/home/stephen/minecraft_servers/caveless’: Permission denied

    Here is the command: screen -R caveless /home/stephen/minecraft_servers/caveless sh start.sh

    I have already tried as sudo and it doesn’t work.

  • Joshua Pettus

    Thank-you for this tutorial, a lot of good ideas here, even if it’s a couple years old. I just wanted to add my thoughts though. First, screen is great for terminal multiplexing but tmux much newer and far better for that sort of thing and I can’t recommend it enough. (I run my server in a runlevel 3 equivalent with ubuntu’s systemd and it’s a must for multitasking)

    Second, if you are going to run a server all the time, terminal sessions are great and all, but they arn’t meant to be used that way. Far better would be to setup an init daemon to control the minecraft server. Of course how do you control the server without a terminal session? The answer is setup rcon for the server. There is a commandline application called mcrcon which is great for the client side of this and can send both single commands and run a whole session in a terminal. rcon on the minecraft server listens on a seperate port from the rest of the server and can be easily locked down in the iptable firewall so no one can connect to it but the localhost. Just tell mcrcon to connect to localhost with your commands and you are good to go.

  • Joshua Pettus

    Given what I said yesterday. I took the ideas in your script and made it a little cleaner with both scripts rolled into one. This way the daily is done at the same time while world saving is down. My own server is just default so I really am only interested in backing up the world level myself.

    #!/bin/bash

    #Let users know of the backup and turn off world saving temporarily
    /usr/local/bin/mcrcon -H localhost -p password “say Backup starting. World no longer saving..” save-off save-all
    sleep 3

    cd /srv/minecraft-server/mcbackup/hourly

    #Rotate hourly backups
    for (( X=23; X>=0; X– )); do
    if [ -e World-Hour-$X.tar.gz ]; then
    mv World-Hour-$X.tar.gz World-Hour-$(($X+1)).tar.gz
    fi
    done
    #do level backup
    tar -cpvzf /srv/minecraft-server/mcbackup/hourly/World-Hour-0.tar.gz /srv/minecraft-server/World

    #Copy newest backup to daily if it’s 12 am with datestamp
    H=$(date +%H) #get hour
    if [ “$H” == “00” ]; then
    cp -f ./World-Hour-0.tar.gz ../daily/World-Daily-$(date -d “today” +”%Y%m%d”).tar.gz
    fi

    #Let users know the backup is done and renable world saving
    /usr/local/bin/mcrcon -H localhost -p password save-on “say Backup complete. World now saving.” “say Time is now $H:00”

    exit 0