Create a Minecraft (PE)Bedrock Server in GCP
Introduction
My eldest daughter, plays with her friends a lot with the Minecraft Pocket Edition (PE). The PE Edition, really limits it to WiiU, xbox or ipad. This is the most connivent gaming version for them as they all have iPads.
Occasionally the world they are all playing on gets corrupted and she looses all the work they have done. There is ways to recover it, but its rather time consuming.
So thought I would look into making a server for them. This means we have more control over the backup process. I am not a GCP expert, but this was a great little process to get familiar with some of the functionality that comes with GCP.
Create a new Project
Navigate to Google Cloud Console
In the left side, there will be a drop down, and you can navigate here to Create a new project.
Google Cloud Console — Create New ProjectI named this project Minecraft.
The ProjectID that it generates is important for a future step, so you can copy and paste that to a notepad, or write it down.
On the left side there will be 3 horizontal lines, which we will refer to as the GCP Console, its the quick navigation to all the googles functionality.
Create the VM (Virtual Machine)
In the GCP console, click Compute Engine > VM Instances
Click create instance
We want to the below options to be input:
Under Management, security, disks, networking, sole tenancy.
Click first on Disks Click Add new Disk
We want to the below options to be input:
Click Done Click now on Networking
We want to the below options to be input:
Click Done Click Create
Setup the firewall
In the GCP console, Click on VPC Network > Firewall rules
Click on create firewall rule
We want to the below options to be input:
Click Create
Setup the VM
This disk is attached to the compute instance, but its not mounted.
Click on SSH to pop out a terminal and connect to your compute instance Create a directory that will become the mount point for the disk
sudo mkdir -p /home/minecraft
Then we need to format the disk run. The disk name may vary
fdisk -ls
in my case it was /dev/sda1
sudo mkfs.ext4 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sda1
To mount the disk run the following
sudo mount -o discard,defaults /dev/sda1 /home/minecraft
Update the OS repositories on the VM, runing the below
sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade
now install unzip, wget, screen, htop, headless JRE
sudo apt-get install -y default-jre-headless
sudo apt-get install zip unzip
sudo apt-get install wget
sudo apt-get install screen
sudo apt-get install htop
Now lets install the bedrock server (which is specific for Pocket Edition)
cd /home/minecraft
sudo mkdir downloads
sudo wget -O downloads/version.html https://minecraft.net/en-us/download/server/bedrock/
sudo DownloadURL=$(grep -o 'https://minecraft.azureedge.net/bin-linux/[^"]*' downloads/version.html)
sudo DownloadFile=$(echo "$DownloadURL"| sed 's#.*/##')
sudo wget -O "downloads/$DownloadFile""$DownloadURL"
sudo unzip -o "downloads/$DownloadFile"
Run the server
sudo LD_LIBRARY_PATH=. ./bedrock_server
Create Backups
In the GCP console, Click on Compute Engine > VM Instances
We already have the mc-server created, so click on SSH We want to create a global unique bucket name
export YOUR_BUCKET_NAME=<Enter your bucket name here>
gsutil mb gs://$YOUR_BUCKET_NAME-minecraft-backup
Now we want to create a backup shell script.
cd /home/minecraft
sudo nano /home/minecraft/backup.sh
The below code will enable you to save the world, to your backup bucket
#!/bin/bash
'/save-all\n/save-off\n'
/usr/bin/gsutil -m cp -R /home/minecraft/worlds/* gs://${YOUR_BUCKET_NAME}-minecraft-backup/world
'/save-on\n'
/usr/bin/gsutil -m cp -R /home/minecraft/server.properties gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/
/usr/bin/gsutil -m cp -R /home/minecraft/permissions.json gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/
/usr/bin/gsutil -m cp -R /home/minecraft/whitelist.json gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/
/usr/bin/gsutil -m cp -R /home/minecraft/valid_known_packs.json gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/
/usr/bin/gsutil -m cp -R /home/minecraft/*.sh gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/
Press Ctrl O, then Enter to Save, then Ctrl X to exit
We can then allow the script to execute
sudo chmod 755 /home/minecraft/backup.sh
We can test the script is working by running
. /home/minecraft/backup.sh
Then verify it in the Storage by navigating here https://console.cloud.google.com/storage/browser
Some other utility scripts I created are here;
#!/bin/bash
gsutil -m cp -R "gs://${YOUR_BUCKET_NAME}-minecraft-backup/config/*""/home/minecraft"
gsutil -m cp -R "gs://${YOUR_BUCKET_NAME}-minecraft-backup/worlds/*""/home/minecraft/worlds/"
# Change directory to server directory
sudo cd /home/minecraft
# Retrieve latest version of Minecraft Bedrock dedicated server
echo "Checking for the latest version of Minecraft Bedrock server ..."
# Test internet connectivity first
wget --quiet http://www.minecraft.net/ -O /dev/null
if [ "$?" != 0 ]; then
echo "Unable to connect to update website (internet connection may be down). Skipping update ..."
else
# Download server index.html to check latest version
sudo wget -O downloads/version.html https://minecraft.net/en-us/download/server/bedrock/
sudo DownloadURL=$(grep -o 'https://minecraft.azureedge.net/bin-linux/[^"]*' downloads/version.html)
sudo DownloadFile=$(echo "$DownloadURL" | sed 's#.*/##')
# Download latest version of Minecraft Bedrock dedicated server if a new one is available
if [ -f "downloads/$DownloadFile" ]
then
echo "Minecraft Bedrock server is up to date..."
else
echo "New version $DownloadFile is available. Updating Minecraft Bedrock server ..."
sudo wget -O "downloads/$DownloadFile" "$DownloadURL"
sudo unzip -o "downloads/$DownloadFile" -x "*server.properties*" "*permissions.json*" "*whitelist.json*" "*valid_known_packs.json*"
fi
fi
Start up scripts on server
Click on mc-server Click edit
Custom metadata add a new key/value pair
Key:
startup-script
Value:
#!/bin/bash
# Minecraft Bedrock server startup script using screen
sudo -i
sudo mount /dev/sda1 /home/minecraft
# Check if server is already started
if screen -list | grep -q "servername"; then
echo "Server is already started! Press screen -r servername to open it"
exit 1
fi
# Change directory to server directory
cd /home/minecraft
# Retrieve latest version of Minecraft Bedrock dedicated server
echo "Checking for the latest version of Minecraft Bedrock server ..."
# Test internet connectivity first
wget --quiet http://www.minecraft.net/ -O /dev/null
if [ "$?" != 0 ]; then
echo "Unable to connect to update website (internet connection may be down). Skipping update ..."
else
# Download server index.html to check latest version
wget -O downloads/version.html https://minecraft.net/en-us/download/server/bedrock/
DownloadURL=$(grep -o 'https://minecraft.azureedge.net/bin-linux/[^"]*' downloads/version.html)
DownloadFile=$(echo "$DownloadURL" | sed 's#.*/##')
# Download latest version of Minecraft Bedrock dedicated server if a new one is available
if [ -f "downloads/$DownloadFile" ]
then
echo "Minecraft Bedrock server is up to date..."
else
echo "New version $DownloadFile is available. Updating Minecraft Bedrock server ..."
wget -O "downloads/$DownloadFile" "$DownloadURL"
unzip -o "downloads/$DownloadFile" -x "*server.properties*" "*permissions.json*" "*whitelist.json*" "*valid_known_packs.json*"
fi
fi
echo "Starting Minecraft server. To view window type screen -r servername"
echo "To minimize the window and let the server run in the background, press Ctrl+A then Ctrl+D"
screen -dmS servername /bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server"
Key:
shutdown-script
Value:
#!/bin/bash
# Minecraft Server stop script - primarily called by minecraft service but can be ran manually
sudo -i
/home/minecraft/backup.sh
screen -Rd servername -X stuff "stop$(printf '\r')"
screen -S servername -X quit
Click Save
Create Auto Start/Shutdown Instance
In the GCP console, Click on Cloud Scheduler
Click on Create Job
For my server, I want it to start at 2pm, and close by 10pm.
We want to the below options to be input:
In the GCP console, Click on Cloud Functions Click on Create Functions
We want to the below options to be input:
Code:
from googleapiclient import discovery
def start_server_pubsub(event, context):
service = discovery.build('compute', 'v1')
print('VM Instance starting')
# Project ID for this request.
project = 'minecraft-xxxxxx'
# The name of the zone for this request.
zone = 'australia-southeast1-a'
# Name of the instance resource to start.
instance = 'mc-server'
request = service.instances().start(project=project, zone=zone, instance=instance)
response = request.execute()
print('VM Instance started')
Click on Create Functions
We want to the below options to be input:
Code:
from googleapiclient import discovery
def stop_server_pubsub(event, context):
service = discovery.build('compute', 'v1')
print('VM Instance stopping')
# Project ID for this request.
project = 'minecraft-xxxxxx'
# The name of the zone for this request.
zone = 'australia-southeast1-a'
# Name of the instance resource to start.
instance = 'mc-server'
request = service.instances().stop(project=project, zone=zone, instance=instance)
response = request.execute()
print('VM Instance stopped')
There is likely lots of improvements that can be made on this, so if you do have any recommendations let me know.