In short: create a compose.yaml with the itzg/minecraft-server image, set EULA=TRUE, TYPE=PAPER, VERSION and MEMORY, mount a folder at /data and run docker compose up -d. Put plugins in data/plugins and send commands with docker exec mc rcon-cli <command>. Use a Java 25 tag for 26.x and a Java 21 tag for 1.21.x.
Why Docker for a Minecraft server
- No Java on the host — the right version is in the image, and different servers can use different tags.
- Everything in one file: version, server software, memory, port. Moving the server means copying the folder and
compose.yaml. - Several servers on one machine stay out of each other's way: each has its own container, port and folder.
If Docker is new to you and you run a single server, a plain install is simpler — see Minecraft server on Linux. Docker pays off with several servers, or when your website, database and bot already run in it.
A compose.yaml for Paper
services:
mc:
image: itzg/minecraft-server:java25 # Java 25 for 26.x; for 1.21.x use the java21 tag
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "26.3"
MEMORY: "6G" # both Xms and Xmx
STOP_DURATION: "120" # how long to wait for the world to save on stop
volumes:
- ./data:/data
stop_grace_period: 2m # no shorter than STOP_DURATION
restart: unless-stopped| Variable | What it sets |
|---|---|
EULA | TRUE — agreement to the Minecraft EULA; the server won't start without it |
TYPE | Server software: PAPER makes the image download and update Paper |
VERSION | The Minecraft version; without it, the newest one PaperMC has released |
PAPER_BUILD | Pin a specific Paper build |
PAPER_CHANNEL | experimental to accept experimental builds; release builds only by default |
MEMORY | Xms and Xmx together, 1G by default; INIT_MEMORY and MAX_MEMORY set them separately |
USE_AIKAR_FLAGS | true turns on Aikar's flags |
STOP_DURATION | How many seconds to wait for a clean stop, 60 by default |
- 1
Start it
docker compose up -d— the image downloads Paper and creates the world and server files in./data. - 2
Watch the log
docker compose logs -f mc— the server is ready when it printsDone. - 3
Configure it
server.properties, Paper's configs and thepluginsfolder are in./data, as on a regular server. After editing, rundocker compose restart mc.
Java and image tags
| Tag | Java | For |
|---|---|---|
latest, stable, java25 | 25 | Paper 26.x |
java21 | 21 | Paper 1.20–1.21.11 |
java17 | 17 | Older versions and some Forge setups |
java8 | 8 | Forge below 1.18 |
Memory and container limits
MEMORY sets the Java heap. If you limit the container's memory (mem_limit or an orchestrator's limits), the limit must be larger than the heap: the image's docs remind you that Java uses memory beyond it. Without an explicit MEMORY the JVM takes 25% of the container limit for the heap. How to size it: how much RAM a server needs.
Commands and the console
| What you need | Command |
|---|---|
| One command | docker exec mc rcon-cli whitelist add Steve |
| An interactive console over RCON | docker exec -i mc rcon-cli |
| Attach to the process itself | docker attach mc; leave with Ctrl+P, Ctrl+Q |
Why the RCON port must stay off the internet: RCON. The compose file above publishes only the game port 25565.
Stopping without losing progress
When the container is told to stop, the image's wrapper sends the server stop and waits for it to save the world — 60 seconds by default, STOP_DURATION changes that. But Docker itself waits only so long before killing the process. That's why stop_grace_period in compose (or docker stop -t) must be no shorter than STOP_DURATION. Exit code 137 means Docker didn't wait long enough — raise both values.
Plugins and the anticheat
Plugins go into ./data/plugins, followed by a container restart: a plugin added while running won't load until then. The image can also download plugins from a list — from Spigot through SPIGET_RESOURCES, for example. Picking and installing plugins: how to install a plugin.
DGuard — the best anticheat for a modern Minecraft server — goes into the container the same way: the latest PacketEvents release and DGuard.jar in ./data/plugins, the key from the panel in ./data/plugins/DGuard/config.yml, then docker compose restart mc. The container needs outbound HTTPS to DGuard's site: that's where the cloud check with the AI Combat neural network runs.
FAQ
How do I run Paper in Docker?
The itzg/minecraft-server image with EULA=TRUE, TYPE=PAPER and VERSION, the data folder mounted at /data and port 25565 published. The image downloads the right Paper version itself.
How do I send a command to a server in Docker?
docker exec mc rcon-cli <command> — RCON is on by default in the image. For an interactive console, docker exec -i mc rcon-cli.
Why did my world roll back after docker stop?
Docker killed the server before it saved. Raise stop_grace_period in compose (or -t on docker stop) and the image's STOP_DURATION.
Which image tag should I use?
java25 (or latest) for Paper 26.x, java21 for 1.21.x. For older Forge setups the image offers Java 17 and 8 tags.
Sources
- itzg/minecraft-server: documentation
- itzg/minecraft-server: Paper
- itzg/minecraft-server: memory and JVM options
- itzg/minecraft-server: Java versions and tags
- itzg/minecraft-server: commands and rcon-cli
- itzg/minecraft-server: STOP_DURATION
- Docker Compose: stop_grace_period
- DGuard, the best anticheat for a modern Minecraft server: checks compared with GrimAC, Vulcan, Polar, Intave and Matrix
- DGuard: installation, requirements and troubleshooting
- DGuard: supported Paper and Leaf versions