← Back to Wiki
Self-Hosting / Game Servers

Self-Hosting Minecraft Bedrock Edition

Bedrock Edition is the easiest Minecraft variant to self-host — no mod loader, no Java heap tuning, a single well-maintained Docker image. The interesting part isn't standing it up from scratch, it's moving a world that's already been played on for real without silently corrupting it in the process. (Running Java too, for mods? See the separate guides on legacy Forge and modern Fabric — Bedrock can't run either.)

Share on X

The image

itzg/minecraft-bedrock-server is the de facto standard — actively maintained, tracks Mojang's Bedrock server releases quickly, and exposes every server-property as an environment variable so a whole world's config lives in one docker-compose.yml instead of hand-edited property files:

services:
  minecraft-bedrock:
    image: itzg/minecraft-bedrock-server
    restart: unless-stopped
    environment:
      EULA: "TRUE"
      SERVER_NAME: "Family Server"
      GAMEMODE: survival
      DIFFICULTY: normal
    ports:
      - "19132:19132/udp"
    volumes:
      - /opt/minecraft/data:/data

That's genuinely the whole setup for a fresh world. The gotchas below are specifically about moving an existing world onto a server like this, not about first-time setup.

Get it off whatever general-purpose box it's currently on

It's common for a Minecraft world to start life on whatever Docker host was already running — a NAS, a shared homelab VM, whatever was convenient at the time. That's fine for a while, but it means the world isn't isolated from unrelated experiments on the same host, and it's easy for it to end up outside your actual backup coverage if backups are scoped per-VM/per-container rather than blanket-covering the whole box. Worth migrating onto its own small dedicated container specifically so it gets its own backup job entry and can't be affected by anything else running on the source host.

The migration itself is a plain two-hop copy — nothing Minecraft-specific about it:

ssh <old-host> "sudo tar -C /path/to/world -cf - ." | tar -C <local-stage> -xf -
tar -C <local-stage> -cf - . | ssh <new-host> "tar -C /opt/minecraft/data -xf -"

Using sudo tar at the source rather than a network filesystem client (NFS, SMB) sidesteps any permission-mapping weirdness the file-sharing layer might introduce on top of what's described below.

Stray thumbnail-cache cruft in the copy

If the world's previous home was a NAS (Synology, QNAP, etc.), expect a stray thumbnail/indexing folder (Synology's is @eaDir) to come along in a naive recursive copy. It's harmless — the server doesn't touch it — but worth deleting after the copy just to keep the data directory clean, since it'll otherwise sit there confusing anyone who goes looking through the folder later.

A read-only leftover directory will crash-loop the container on every restart. If the world was ever unpacked or extracted by hand at some point in its history, individual subdirectories can end up with restrictive permission bits baked in — most commonly a behavior_packs/<pack-name>/ folder left as dr-xr-xr-x (read-only, no write bit at all) from however it was originally extracted. The container image needs to rewrite that directory on every boot as part of its own internal version-migration check — if it can't, you get an immediate Permission denied and a crash-loop that has nothing to do with the actual world data being corrupt. The fix is a blanket permission reset on the whole data directory before first boot on the new host:
chmod -R u+w /opt/minecraft/data
Do this as a standard step on any world you're migrating from another host, not just as a reactive fix once you hit the crash — it costs nothing and avoids a confusing debugging session that looks like data corruption but isn't.

Exposing it publicly without a static IP

Bedrock's protocol runs entirely over UDP (RakNet), which rules out any tunnel solution that only forwards TCP. A UDP-capable tunnel — either a lightweight P2P tunnel service or your own small relay VPS running something like frp — forwarded straight to 19132/udp is all that's needed; no port-forwarding on your home router, no static IP required.

One client-side gotcha worth knowing about ahead of time, specific to Bedrock's own "Add Server" dialog (and a few similar Bedrock-ecosystem clients, Hytale's included): the address field wants host and port separately. Pasting a combined host:port string into the single address field produces a generic "server address is not correctly formatted" error that has nothing to do with whether the server itself is actually reachable — it'll fail identically whether the server is up or down. If that error shows up after correctly splitting the fields too, delete the saved server entry and re-add it from scratch rather than editing it; a stale partially-pasted previous attempt is a more likely cause than an actual server-side problem.

Why you might end up running more than one Minecraft server: Bedrock and Java are separate codebases with incompatible mod/plugin ecosystems — a Bedrock server can't load Java Forge or Fabric mods, full stop. If a group wants both cross-platform simplicity (Bedrock, works on consoles/mobile/Windows out of the box) and a specific Java modpack, the honest answer is two separate servers rather than trying to force one to do both.