This guide is intended to supplement the official GCE documentation on setting up a Minecraft server. That guide is a great start but there are a few suboptimal things recommended in that document and a few things missing that most people will want to do.

This is a revised post of what was originally posted on 2018-09-08. Changes: new backup script that can deal with gigabyte sized Minecraft worlds.

Boot disk

That guide recommends an SSD boot disk. This isn't needed; Minecraft doesn't run from the boot disk.

/etc/fstab

The guide never has you place the Minecraft volume in the /etc/fstab so that it is automatically mounted again after boot. To do that, just add the disk to the /etc/fstab file on a new line:

$ cat /etc/fstab 
UUID=3b550ed9-dcc3-4874-b387-a64b31d29eec / ext4 defaults 1 1
UUID=[your UUID here] /home/minecraft ext4 discard,defaults 0 2

You can obtain the UUID of the disk by looking in /dev/disk/by-uuid . It's the UUID that isn't already in your /etc/fstab .

systemd service

The guide offers bad advice on how to configure Minecraft to start automatically at boot and shutdown in the section at the end titled Automate start up and shutdown procedures. Completely ignore that section. Implementing proper systemd units handles all of this automatically.

First, install tmux. We're going to use that to host the Minecraft server console inside of the systemd service:

sudo apt-get install tmux

Create a new file as root /etc/systemd/system/minecraft.service :

[Unit]
Description=Minecraft server

[Service]
WorkingDirectory=/home/minecraft
User=minecraft
Type=forking
ExecStart=/usr/bin/tmux new-session -s minecraft -d '/usr/bin/java -Xmx4096M -jar minecraft-[YOUR VERSION].jar'
ExecStop=/usr/bin/tmux send-keys -t minecraft:0.0 'say SERVER SHUTTING DOWN. Saving world...' C-m 'save-all' C-m 'stop' C-m
ExecStop=/bin/sleep 2

[Install]
WantedBy=multi-user.target

Then, start it for the first time:

sudo systemctl daemon-reload
sudo systemctl start minecraft

You can see if the server started by inspecting the status:

sudo systemctl status minecraft

If you don't see anything, look at the logs/latest.log in /home/minecraft .

If you want to attach the console to confirm that everything looks right, you can do this:

sudo -i -u minecraft tmux attach

Press CTRL-B D to detach from the console if it looks like it's working.

If that worked, enable it at boot time:

sudo systemctl enable minecraft

systemd will automatically shutdown your server gracefully when your instance is shutdown gracefully. You can try it with systemd stop minecraft .

Backup script

The guide has a rudimentary backup script that uses the old /etc/crontab . We can do much better.

First, make a new systemd unit in /etc/systemd/system/minecraft-backup.service :

[Unit]
Description=Minecraft server backup

[Service]
WorkingDirectory=/home/minecraft
User=minecraft
Type=oneshot
TimeoutStartSec=600
ExecStart=/home/minecraft/backup.sh

Then, create the backup.sh file:

#!/bin/bash

set -e

function cleanup {
    /usr/bin/tmux send-keys -t minecraft:0.0 'save-on' C-m 'save-all' C-m
}
trap cleanup EXIT

/usr/bin/tmux send-keys -t minecraft:0.0 'say Starting backup.' C-m 'save-all' C-m 'save-off' C-m
/bin/sleep 5 # This is to work-around a possible race since we can't be sure the save is complete.
set -x
/usr/bin/rsync -aAX --delete New\ World/ New\ World.backup/
/usr/bin/tmux send-keys -t minecraft:0.0 'save-on' C-m 'say Finished backup. Compressing file.' C-m 'save-all' C-m
NOW=$(date +%Y%m%d%H%M)
/bin/tar -czf backups/New\ World\ ${NOW}.tar.gz New\ World.backup
/usr/bin/tmux send-keys -t minecraft:0.0 'say Finished compressing file. Uploading backup.' C-m
/usr/bin/gsutil cp backups/New\ World\ ${NOW}.tar.gz gs://your-gs-bucket-name/
/usr/bin/tmux send-keys -t minecraft:0.0 'say Uploaded backup. Deleting old local backups.' C-m
/usr/bin/find backups/ -mtime +2 -exec rm {} \;
/usr/bin/tmux send-keys -t minecraft:0.0 'say Done!' C-m

This script will keep 2 days of rolling backups locally, in backups while still uploading to the Google Storage bucket suggested by the guide. What does this script do?

  1. Creates a function that will let the server continue saving the game, even if the script fails ( cleanup )
  2. Disables saves so we don't get a filesystem race while taking the backup
  3. Sets the bash script to exit without continuing if any one command returns a non-zero exit code.
  4. Rsync's the game files to a staging directory. This is done because save-off doesn't actually completely disable disk I/O and tar will blow up if the source directory is modified while it is compressing. Rsync is efficient so it can complete an incremental copy to the staging directory in a few seconds, each time. This is useful for worlds that are gigabytes in size.
  5. Enables saving again
  6. Compresses the staging directory in a tarball
  7. Uploads the new backup to a Google Storage bucket
  8. Deletes old backup files (we only get this far if everything exited with a 0 status)

Create that directory and New World.backup directory as the minecraft user (so it has write access to it) and chmod the script to +x :

mkdir backups
mkdir New\ World.backup
chmod +x backup.sh

Finally, add a systemd timer in /etc/systemd/system/minecraft-backup.timer and enable it:

[Unit]
Description=Run minecraft-backup.service every 4 hours

[Timer]
OnCalendar=*-*-* 00/4:00:00

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable minecraft-backup.timer

You can test the backup process manually with systemctl start minecraft-backup .

Don't forget to do the Automatically remove old backups step in the official guide so that your GS bucket doesn't fill up forever.

Shutdown manually

You can shutdown from systemd:

sudo systemctl stop minecraft

Or, you can attach to the running server, make an announcement to your players with say ... and then type stop :

sudo -i -u minecraft tmux attach

Bonus: serving texture/resource packs

If you have a texture pack that you want to serve to your players, you can add that to a new Cloud Storage bucket (not the same as your backups), make that bucket public, and then copy the theme pack URL into your server.properties file. The public URL is available from the Cloud Storage browse UI: it's a small link icon on the file listing next to the Public status once the ZIP file has been made publicly accessible. Don't forget to compute the SHA1 and also add that to your server properties.