Skip to content

Instantly share code, notes, and snippets.

@AugustMiller
Last active October 26, 2021 18:06
Show Gist options
  • Save AugustMiller/363d7f360ca72a9cb46daa179622a270 to your computer and use it in GitHub Desktop.
Save AugustMiller/363d7f360ca72a9cb46daa179622a270 to your computer and use it in GitHub Desktop.
Minecraft Bedrock Server ("BDS") configuration
#!/bin/bash
timestamp=$(date -Iseconds)
bedrock="/home/minecraft/bedrock"
serverlogfile="$bedrock/bin/current/log.txt"
lockfile="$bedrock/backups/lock"
# Test if our lock file is in place. We don't want concurrent backups running:
if [ -f $lockfile ]; then
exit 1
fi
# Create a lockfile for this backup:
touch $lockfile
# Notify server that a backup is starting:
screen -S minecraft -p bedrock -X stuff 'say §6Starting backup...\n'
# Pause modifications to the world:
screen -S minecraft -p bedrock -X stuff 'save hold\n'
# Wait for hold confirmation:
finished=""
while [[ $finished != *"Data saved."* ]]; do
screen -S minecraft -p bedrock -X stuff 'say Waiting for world lock...\n'
sleep 5s
screen -S minecraft -p bedrock -X stuff 'save query\n'
finished=$(tail -n 4 $serverlogfile)
done
# Let users know the world is locked:
screen -S minecraft -p bedrock -X stuff 'say §cThe world is temporarily locked while the backup is captured!\n'
# Copy World:
rsync -rvz "$bedrock/bin/current/worlds" "$bedrock/backups/worlds-$timestamp"
# Unlink + re-link latest copy for easy reference:
rm -f "$bedrock/backups/latest"
ln -s "$bedrock/backups/worlds-$timestamp" "$bedrock/backups/latest"
# Unlock:
screen -S minecraft -p bedrock -X stuff 'save resume\n'
# Clean up lockfile:
rm -f $lockfile
# Notify server of completed backup:
screen -S minecraft -p bedrock -X stuff 'say §aBackup complete!\n'
.
├── backup.sh
├── backups
│   ├── latest -> /home/minecraft/bedrock/backups/worlds-2020-04-04T19:30:01+00:00
│   ├── lock (When a backup is running)
│   ├── worlds-2020-04-03T23:31:10+00:00
│   ├── worlds-2020-04-03T23:31:10+00:00
│   ├── worlds-2020-04-04T00:00:01+00:00
│   ├── worlds-2020-04-04T18:30:01+00:00
│   ├── worlds-2020-04-04T19:00:01+00:00
│   ├── worlds-2020-04-04T19:30:01+00:00
│   └── ...
├── bin
│   ├── 1.14.32.1
│   └── current -> 1.14.32.1
│   └── (Lots of stuff, but most importantly: log.txt set up with `logrotate.d`)
├── papyrus
│   ├── bin
│   ├── node_modules
│   ├── papyrusjs
│   └── textures
├── render.sh
├── server.properties
├── start.sh
└── superops.txt
#!/bin/bash
bedrock=/home/minecraft/bedrock
screen -S minecraft -p bedrock -X stuff 'say §6Starting render...\n'
./papyruscs/PapyrusCs --world="$bedrock/backups/latest/worlds/Default/db" --output="/var/www/minecraft-map" --htmlfile="index.html"
screen -S minecraft -p bedrock -X stuff 'say §aRender complete!\n'
#!/bin/bash
# Follow symlink to "current" server binary:
cd /home/minecraft/bedrock/bin/current/
# Not sure why this is necessary, but it's recommended by Mojang in the guide:
LD_LIBRARY_PATH=.
# Launch server binary, directing output to stdout and `log.txt`:
./bedrock_server | tee log.txt
@AugustMiller
Copy link
Author

AugustMiller commented Apr 6, 2020

This setup is heavily dependent upon screen, and named sessions + windows.

Setup

Machine

This guide assumes some familiarity with Ubuntu 18.04 LTS.

  1. Get yourself a VPS from Linode or DigitalOcean. I'd recommend 2–4GB RAM, and at least 2 vCPUs. Maps can eat up disk space, but both options have attachable/configurable block storage that should make this a non-issue. (Disclosure: Referral links included!)
  2. Create a user named minecraft, and make them a sudoer for ease-of-access. This is also where you'll want to configure SSH access, and lock things down.
  3. Start up a named screen session: $ screen -S minecraft. You can kill this from within the screen instance with [Control + A], [d] and resume it later from any SSH session by running $ screen -r. ✌️

Server

  1. Download the latest BDS binary into /home/minecraft/bedrock/bin/, and create a symlink pointing to it: $ln -s /home/minecraft/bedrock/bin/1.14.32.1 /home/minecraft/bedrock/bin/current.
  2. Copy the contents of start.sh to /home/minecraft/bedrock/start.sh
  3. Create a new window in screen ([Control + A], c), and name it bedrock by entering [Control + A], [A], and providing bedrock.
  4. Run ./start.sh to boot the server.

It may not be this simple—This step is fairly "vanilla," though, and troubleshooting general server setup is beyond the purview of this guide!

Backups

This script is a crude method for pausing world edits, and copying files to a secondary snapshot. It currently does not implement the recommended "truncation" strategy. Running this script without a running server may produce unexpected results. There is crude protection in place for concurrent backups, so it should be save to run via cron.

  1. Copy backup.sh to /home/minecraft/bedrock/backup.
  2. Make a /home/minecraft/bedrock/backups directory.
  3. Run ./backup.sh to capture a backup. The script will output some in-game messages alerting players that a backup is being made.

Maps

Maps are rendered from the most recent backup. This helps keep the state of the world stable during a render.

  1. Get Apache set up with a web-root the minecraft user can write to. We assume /var/www/minecraft-map, here.
  2. Install papyruscs to /home/minecraft/bedrock/papyrus, and copy render.sh into /home/minecraft/bedrock.
  3. Capture a backup (see above), then render it by running ./render.sh.

Miscellany

I'm new to bash scripting. Please comment with improvements or questions! Hoping to use this as a platform for learning. 😸

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment