The safe update model
An update changes at least two things: the container image and the server software selected by TYPE and VERSION. Plugins, configuration formats, Java, and world data may change too.
The safe workflow is therefore:
- pin the current and target versions
- take an application-aware backup and a complete stopped copy
- update one version step at a time
- inspect startup before players reconnect
- restore both configuration and data if validation fails
Do not rely on changing VERSION back after a failed start. A newer server may already have migrated the world.
Prerequisites
- a Compose service named
mc - server data mounted at
./data:/data - enough free space for a complete copy of
./data - working RCON for command-based checks
- a tested backup workflow such as docker-mc-backup
Pin the starting point
Avoid VERSION: LATEST for production. The image documentation states that LATEST can download a newer server JAR on restart.
This example pins Paper and Java explicitly:
services:
mc:
image: itzg/minecraft-server:java25
restart: unless-stopped
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: PAPER
VERSION: "26.1.2"
volumes:
- ./data:/data
Replace the example with a version and Java image that match your server. Check the effective configuration before proceeding:
docker compose config
docker compose exec mc rcon-cli version
docker compose ps
Step 1: check compatibility before downtime
Read the release notes for the target server version and every critical plugin. Do not combine a Minecraft update, a server-type migration, and unrelated configuration changes in one maintenance window.
For Paper, update compatible plugins in the same planned restart. Paper explicitly warns against replacing server or plugin JARs while the server is running.
Step 2: create two restore points
First trigger the regular coordinated backup:
docker compose exec backup backup now
docker compose logs --tail=100 backup
Then stop all services that touch the data and create a complete cold archive. This second copy also preserves plugin JARs and configuration files that a world-focused backup may exclude:
docker compose stop backup mc
pre_update_archive="pre-update-$(date +%Y%m%d-%H%M%S).tgz"
tar -czf "$pre_update_archive" compose.yml data
tar -tzf "$pre_update_archive" | head
The final command lists the archive before you trust it.
Keep the old archive until the updated server has run successfully for long enough to cover normal player activity.
Step 3: apply the update
Change VERSION and, only when required, the Java image tag. Then validate and start:
docker compose config
docker compose pull mc
docker compose up -d
docker compose logs -f mc
Wait for the normal ready message. Do not let players reconnect merely because the container is shown as running.
Step 4: validate the result
Run checks through the same service you just updated:
docker compose exec mc rcon-cli version
docker compose exec mc rcon-cli list
docker compose exec mc rcon-cli save-all flush
docker compose logs --since=10m mc
Also verify:
- the expected world and dimensions loaded
- every required plugin is enabled
- a player can join, move, interact, and reconnect
- a fresh backup completes after the update
Roll back safely
If startup or gameplay validation fails, stop the stack immediately. Preserve the failed state for diagnosis, then restore the complete pre-update state:
docker compose down
mv data "data.failed-$(date +%Y%m%d-%H%M%S)"
tar -xzf pre-update-YYYYMMDD-HHMMSS.tgz
docker compose up -d
docker compose logs -f mc
Replace the archive name literally. Because that archive contains both compose.yml and data, the old software selection and the old world return together. For a backup-only recovery, follow the full Docker restore runbook.
Troubleshooting
| Symptom | Likely cause | Safe response |
|---|---|---|
| Newer version appears after a normal restart | VERSION was left at LATEST | Pin an explicit version and restore if data was migrated |
| Server exits before ready | Java, server version, or plugin mismatch | Read the first startup error; fix compatibility on a copy |
| Plugins are red or missing | Incompatible, duplicated, or missing dependency JAR | Restore or install the compatible plugin set while stopped |
| World looks reset | Wrong LEVEL, mount, or working directory | Stop immediately; inspect mounts and restore before anyone plays |
| Old version refuses the world | Newer software already migrated data | Restore the matching pre-update data; do not force a downgrade |
Next steps
- Manage the plugin lifecycle with Paper plugins and Docker Compose.
- Protect the next maintenance window with automatic Minecraft backups.
- If the target is a modpack, use the Modrinth modpack runbook instead of treating it like Paper.