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:
- Sanitises the name (letters, digits,
-,_only) and refuses if/home/minecraft/<world-name>already exists. - 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.
- Auto-allocates the port: finds the highest
server-port=across all existingserver.propertiesand adds 2 (IPv6 port is always IPv4 + 1). - Downloads the latest Bedrock Linux server zip from the official Mojang API and unpacks it.
- Generates
server.propertiesand a systemd unitminecraft-<world-name>.service(runs as userminecraft,Restart=on-failure). - Chowns everything to
minecraftand runsdaemon-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).
- 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. - VPS firewall:
sudo ufw allow 19138/udpon the VPS. - VM firewall:
sudo ufw allow in on wg0 to any port 19138 proto udpon 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.
- 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:19138also 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.shand add the new directory to theSERVER_DIRECTORIESarray at the top. - Nothing else needed: kopia already snapshots all of
/home/minecraft/bedrock_backupsdaily 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, thensystemctl 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>/udpon VPS;ufw allow in on wg0 ... <port>on the VM - [ ] Add dir to
SERVER_DIRECTORIESinautoupdate.sh - [ ] Add entry to
SERVERSin the panel'sapp.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>/