setupmc.com

Update a Minecraft Server with Docker Compose and Roll Back Safely

Update an itzg/minecraft-server deployment without gambling with your world. This runbook covers version pinning, a cold backup, validation, and a real rollback path.

Docker Operations
setupmc.com Team

Need a cleaner Java baseline?

Generate a Java Compose setup before you keep patching by hand

If you are still refining the Java server baseline, use the Java configurator and then return to the guides for the next issue.

Open Java configurator

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:

  1. pin the current and target versions
  2. take an application-aware backup and a complete stopped copy
  3. update one version step at a time
  4. inspect startup before players reconnect
  5. 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

SymptomLikely causeSafe response
Newer version appears after a normal restartVERSION was left at LATESTPin an explicit version and restore if data was migrated
Server exits before readyJava, server version, or plugin mismatchRead the first startup error; fix compatibility on a copy
Plugins are red or missingIncompatible, duplicated, or missing dependency JARRestore or install the compatible plugin set while stopped
World looks resetWrong LEVEL, mount, or working directoryStop immediately; inspect mounts and restore before anyone plays
Old version refuses the worldNewer software already migrated dataRestore the matching pre-update data; do not force a downgrade

Next steps

Frequently asked questions

Short answers to the questions that usually come up while working through this topic.