Skip to content

Provisioning a New Bedrock World

The recipe for standing up world number four (and five, and…). One script does the heavy lifting on the minecraft VM; the rest is follow-through so the world is reachable, backed up, and manageable from the admin panel.

Step 1 — Run create_mc_world.sh

On the minecraft VM (103):

sudo /home/minecraft/create_mc_world.sh <world-name>
# e.g. sudo /home/minecraft/create_mc_world.sh peaceful-paradise

It must run with sudo — it writes a systemd unit into /etc/systemd/system/. It needs jq and curl (already installed).

What it does, in order:

  1. Sanitises the name (letters, digits, -, _ only) and refuses if /home/minecraft/<world-name> already exists.
  2. Prompts interactively for server name (shown in the in-game list), gamemode (default survival), difficulty (default peaceful), max players, and whether the allowlist is on.
  3. Auto-allocates the port: finds the highest server-port= across all existing server.properties and adds 2 (IPv6 port is always IPv4 + 1).
  4. Downloads the latest Bedrock Linux server zip from the official Mojang API and unpacks it.
  5. Generates server.properties and a systemd unit minecraft-<world-name>.service (runs as user minecraft, Restart=on-failure).
  6. Chowns everything to minecraft and runs daemon-reload.

Then start it:

sudo systemctl enable --now minecraft-<world-name>.service

Port allocation pattern

World IPv4 (UDP) IPv6 (UDP)
creative-world 19132 19133
rorys-friends-creative 19134 19135
survival-classic 19136 19137
next world 19138 19139

Step 2 — Make it reachable from the internet

Players connect via the VPS, which passes Minecraft UDP straight through NPM (see VPS).

  1. NPM stream: in Nginx Proxy Manager on the VPS, add a new Stream — incoming port 19138, forward to the minecraft VM over WireGuard (10.10.0.2:19138), UDP enabled. Same pattern as the existing 19132/19134/19136 streams.
  2. VPS firewall: sudo ufw allow 19138/udp on the VPS.
  3. VM firewall: sudo ufw allow in on wg0 to any port 19138 proto udp on the minecraft VM.

Ignore the script's before.rules advice

The script's final "NEXT STEPS" output still suggests adding a forwarding rule to /etc/ufw/before.rules on the VPS — that was the old iptables approach. The live setup uses NPM UDP streams instead; don't add both.

  1. UniFi / LAN: nothing to open — traffic arrives over the WireGuard tunnel, not via port-forwarding on the home router. Consoles on the LAN connecting directly to 192.168.1.x:19138 also need no UniFi change (same L2 network). Only revisit this if you ever bypass the VPS.

Step 3 — Wire it into backups

Nightly backups come from autoupdate.sh, which loops over an explicit list of world directories, tars worlds/ server.properties allowlist.json permissions.json into /home/minecraft/bedrock_backups/<world-dir>/, and updates the server binaries.

  • Edit /home/minecraft/autoupdate.sh and add the new directory to the SERVER_DIRECTORIES array at the top.
  • Nothing else needed: kopia already snapshots all of /home/minecraft/bedrock_backups daily at 03:30 (keep 30 daily + 52 weekly) — new subdirectories are picked up automatically. See backups overview.
  • The world also rides along in the nightly 02:00 vzdump of the whole VM.

Skip this and the world has no per-world backups

The admin panel's Backups page and restore flow only see tarballs in bedrock_backups/<world-dir>/ — no SERVER_DIRECTORIES entry means no tarballs, and the only recovery is a full-VM vzdump restore.

Step 4 — Add it to the admin panel

Edit /home/minecraft/allowlist-web/app.py: add an entry to the SERVERS dict (key, label, dir, service name), then sudo systemctl restart minecraft-allowlist-web.service. The new world gets dashboard power controls, allowlist management, backups/restore, and logs for free. Details in the panel page.

Then add players to the allowlist via the panel, not by hand-editing allowlist.json — the panel restarts the server so the change actually takes effect.

Installing addons

addon_install.py syncs addon packs (.mcpack, .mcaddon, .zip) from a download folder into a server, prunes custom packs you've removed, and rebuilds the world's world_behavior_packs.json / world_resource_packs.json from pack manifests.

python3 /home/minecraft/addon_install.py

Paths are hardcoded — edit before running

The paths live at the top of main(): addons source /home/minecraft/addons-downloaded, target server folder, and the world name (must match level-name). They still point at an old bedrock-server layout, so update them to the world you're targeting before running, and restart that world's service afterwards.

Vanilla-pack protection: the prune step never touches packs whose folder names start with vanilla, chemistry, experimental, or editor — only your custom packs are managed. It's safe to run repeatedly; the managed-pack list is rebuilt from scratch each run.

Checklist

  • [ ] sudo create_mc_world.sh <name> on the minecraft VM, then systemctl enable --now
  • [ ] Note the assigned UDP port (pattern: previous highest + 2)
  • [ ] NPM UDP stream on the VPS → 10.10.0.2:<port>
  • [ ] ufw allow <port>/udp on VPS; ufw allow in on wg0 ... <port> on the VM
  • [ ] Add dir to SERVER_DIRECTORIES in autoupdate.sh
  • [ ] Add entry to SERVERS in the panel's app.py + restart the panel service
  • [ ] Allowlist the first players via mc-admin
  • [ ] (Optional) addons via addon_install.py — fix its paths first
  • [ ] Test from outside the LAN, then confirm the first nightly tarball appears in bedrock_backups/<dir>/