Treat the pack as the version authority
A modpack is not just a list of mods. It couples a Minecraft version, a loader, mod versions, configuration, and often a required Java version. Start with the pack's server instructions rather than choosing those parts independently.
The itzg/minecraft-server image can resolve a Modrinth pack, select the loader, install files, and clean files removed by a later pack version. Pin the pack version before players create valuable data.
Prerequisites
- a Modrinth pack that explicitly supports servers
- the project slug or ID and a tested version ID
- the pack's documented memory and Java requirements
- enough disk space for downloads, world data, and backups
- the matching client pack for the join test
Do not use a client-only optimization pack as a server pack. Check the project page and the selected version's supported environment.
Compose baseline
The following small server-only example was verified with Minecraft 26.1.2. Treat it as a working deployment sample, not as a general pack recommendation:
services:
mc:
image: itzg/minecraft-server:java25
restart: unless-stopped
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: MODRINTH
MODRINTH_MODPACK: essentially-optimized-server
MODRINTH_VERSION: DR4Y3FOc
MEMORY: 2G
volumes:
- ./data:/data
The pinned ID selects Essentially Optimized Server 1.0.0 for Minecraft 26.1.2. When you choose another pack, replace the project, version, Java image, and memory together according to its requirements. MODRINTH_MODPACK also accepts a project or version page URL, an .mrpack URL, and a mounted local .mrpack.
Use the Java image tag required by the pack. If startup reports class-version errors, consult the Minecraft Java version guide instead of guessing.
Test the pack away from production
Use an empty data directory for the first start. Never point an untested pack at an existing production world.
mkdir -p data
docker compose config
docker compose up -d
docker compose logs -f mc
The first start can be slow because the image resolves and downloads the pack. Wait for the normal ready message, not just a running container state.
Validate the resolved stack
Check the effective version and installed files:
docker compose exec mc rcon-cli version
docker compose exec mc sh -c 'find /data/mods -maxdepth 1 -type f -name "*.jar" | wc -l'
docker compose logs --since=15m mc
Then join with the matching client pack and verify:
- the client and server report the same pack release
- custom blocks, items, dimensions, and recipes work
- no required server-side files are marked as client-only
- the world saves and the player can reconnect
Create the first backup only after that test succeeds.
Overrides and exclusions
Some packs incorrectly label a client-only file for the server. The image supports MODRINTH_EXCLUDE_FILES for targeted exclusions. Use it only after identifying the exact file in the startup error and confirming that the server does not need it.
MODRINTH_FORCE_SYNCHRONIZE can force a fresh synchronization while troubleshooting. Do not leave it enabled casually: synchronization is intended to make the installed set match the selected pack, including cleanup.
Update the pack
Back up first, stop the service, change only MODRINTH_VERSION, and start again under supervision. Keep the previous Compose file and full /data copy together so you can restore both.
Follow the Docker update and rollback runbook. An older loader or pack must never be started against world data already migrated by the newer pack.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No compatible version found | Project, Minecraft version, or loader constraints conflict | Use a version ID published for the intended server pack |
| Unsupported class-file version | Wrong Java image tag | Select the Java release required by the pack |
| Server crashes on a client-only mod | Pack metadata is wrong for that file | Confirm with the author, then exclude only that exact file |
| Client cannot join | Client pack, loader, or pack version differs | Install the exact matching client release |
| Mods disappear after a change | Synchronization cleaned unmanaged files | Keep custom additions declared and backed up separately |
Next steps
- Learn when to choose a mod loader instead of Paper in the server software comparison.
- Move an existing world only after reading the Docker migration runbook.
- Add automatic backups before inviting players.