What Docker actually buys you
The real wins are unglamorous and substantial: pinned versions, so a server does not silently change under you; a config you can commit, so the setup is described in a file rather than in someone's memory; and portability, so moving to a different host means copying a compose file and a data directory rather than reinstalling Java and rediscovering every setting. Rolling back a bad update becomes changing a tag instead of an archaeology project.
What it does not buy you is performance. A JVM in a container runs at essentially native speed — anyone promising a speed-up from containerisation is selling something. If your server is slow, profile it; the packaging is not the cause.
The three things to get right
| Volumes | The server's data directory must live on a named volume or bind mount. Anything else dies with the container |
| Memory | Container limit must exceed the JVM heap by roughly a gigabyte, or the kernel kills the process |
| Port publishing | Publishing binds on the host, by default on every interface — this is how backends end up public |
| Restart policy | Set one, so the server comes back after a host reboot without manual intervention |
| Version pinning | Pin the image tag and the Minecraft version. `latest` means your server changes when you were not looking |
| EULA | Accepted via an environment variable in every mainstream image — a first-run failure, not a mystery |
Volumes: the one that eats worlds
A container's own filesystem is disposable by design. Everything written inside it that is not on a volume disappears when the container is removed — and you remove containers routinely, because that is how you change an environment variable or update an image. The failure is not exotic: someone edits a setting, recreates the container, and the world is gone.
Mount the server's data directory to a named volume or a bind mount on the host, and confirm it works before you have anything to lose. Stop the container, remove it, start a fresh one, and check the world is still there. Doing this deliberately on day one is much better than discovering it on day ninety. Whatever you choose, back the data up somewhere off the host — a volume protects you from container churn, not from the disk failing.
Memory: two limits that must not match
There are two independent numbers here and setting them equal is a trap. The JVM heap (`-Xmx`) is what Minecraft allocates into. The container memory limit is what the kernel permits the whole process to use — and the process needs more than the heap: metaspace, thread stacks, direct byte buffers, and the JVM's own overhead.
Set the container limit equal to the heap and the process will exceed it under load and be killed, producing a server that dies at peak hour with no Java error to explain it. Leave roughly a gigabyte of headroom between the two. The RAM guide covers how to pick the heap size itself — and the same warning applies here as everywhere: bigger is not better.
Networking: how backends end up on the public internet
This is the security footgun. Publishing a container port maps it onto the host, and unless you say otherwise, it binds on all interfaces. For a single public server that is what you want. For a backend behind a proxy, it is exactly wrong: you have taken a server that should only accept connections from your proxy and made it reachable by anyone who scans the address.
That matters far more than it sounds, because backends behind a proxy typically run with online-mode disabled — the proxy does the authentication. A publicly reachable backend in that state will let anyone connect as any username, including an administrator, as covered in the server.properties reference.
- Put the proxy and its backends on a shared Docker network and do not publish backend ports at all — the proxy reaches them by container name.
- If you must publish, bind to a specific interface rather than every address.
- Publish only the proxy's port to the world. It is the single public entry point by design.
- Do not rely on the host firewall alone — published container ports can bypass firewall rules in ways that surprise people. Verify from outside the host that a backend port is genuinely closed.
Pterodactyl is this, with a panel on top
If you would rather not manage compose files, Pterodactyl runs each server in its own container and gives you a web panel, users and per-server resource limits over the top. The same fundamentals apply underneath — volumes hold the data, containers have memory limits, ports are published — and its allocation model is a nicer way to handle the port question than raw publishing. Protecting one is covered in Pterodactyl DDoS protection.
Containers are not a security boundary against attacks
Worth being blunt about: Docker isolates processes from each other on a host. It does nothing about traffic arriving at that host. A volumetric flood saturates the uplink and takes down every container on the machine at once, and a bot join-flood reaches the containerised server exactly as it would a bare-metal one. If anything, a single host running several containerised servers concentrates the blast radius. Filtering belongs upstream, on a network built to absorb it — the container is where your server runs, not what protects it.
Common questions
Should I run my Minecraft server in Docker?+
It is a good fit if you value reproducibility — pinned versions, a config you can commit, and a server you can move to another machine by copying two things. It adds little overhead for a Java process. It is a poor fit if you are not comfortable with volumes and networking, because the failure modes involve deleting worlds and exposing ports rather than merely not working.
How do I stop Docker from deleting my Minecraft world?+
Put the server's data directory on a named volume or bind mount, never inside the container's writable layer. Anything not on a volume lives and dies with the container, so the moment you rebuild to change a setting, an unmounted world is gone. Verify it by stopping and removing the container deliberately, then starting a new one and confirming the world is still there.
How much memory should I give a Minecraft Docker container?+
Set the container limit above the JVM heap, not equal to it. The JVM needs metaspace, thread stacks and buffers beyond -Xmx, so a container capped at exactly the heap size will be killed by the kernel under load. Leaving roughly a gigabyte of headroom between the heap and the container limit avoids a whole category of confusing restarts.
Why can people connect to my Docker Minecraft server directly, bypassing my proxy?+
Because the container is publishing its port to every interface. Publishing binds the port on the host, and by default that means all addresses — so the backend that should only be reachable from your proxy is reachable from the internet. Bind published ports to a specific interface, or use a Docker network so backends are only reachable from the proxy container.
Does Docker protect my Minecraft server from DDoS attacks?+
No. A container is a process isolation boundary, not a network defence. Attack traffic that reaches the host reaches the container, and a saturated uplink takes everything on the machine offline regardless of how it is packaged. Containerisation and DDoS protection solve unrelated problems.
Containerised, pinned and backed up — and still one flood away from offline? Start free with Arvoris — one DNS record, no plugin, works with any host or container setup.