Running your own Minecraft server means no monthly fees, no player limits, full control over mods and plugins, and a world that exists as long as you want it to. With Docker, you can have one running in under five minutes.
Why Docker for Minecraft?
- Easy updates — pull a new image, restart, done
- Isolated — doesn’t pollute your host system with Java versions
- Portable — move your server between machines by copying one folder
- Multiple servers — run Java and Bedrock side by side without conflicts
Hardware Requirements
Minecraft servers are RAM-hungry. Plan for:
| Players | RAM | CPU | Storage |
|---|---|---|---|
| 1-5 | 2-4 GB | 2 cores | 5 GB |
| 5-10 | 4-6 GB | 2-4 cores | 10 GB |
| 10-20 | 6-8 GB | 4 cores | 20 GB |
| 20+ | 8-16 GB | 4+ cores | 30+ GB |
A Raspberry Pi 4 (4GB) can handle 2-4 players. For bigger groups, use a proper server or mini PC.
Java Edition Setup
The itzg/minecraft-server image is the gold standard — actively maintained, incredibly configurable.
mkdir -p ~/minecraft && cd ~/minecraft
# docker-compose.yml
version: "3.8"
services:
minecraft:
image: itzg/minecraft-server
container_name: minecraft
restart: unless-stopped
ports:
- "25565:25565"
volumes:
- ./data:/data
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "LATEST"
MEMORY: "4G"
MAX_PLAYERS: 10
MOTD: "Welcome to our server!"
DIFFICULTY: "normal"
VIEW_DISTANCE: 12
SPAWN_PROTECTION: 0
ENABLE_COMMAND_BLOCK: "true"
SERVER_NAME: "Home Minecraft"
tty: true
stdin_open: true
docker compose up -d
Wait 1-2 minutes for the world to generate, then connect at your-server-ip:25565.
Why Paper?
Setting TYPE: "PAPER" uses PaperMC instead of vanilla Minecraft. Paper is a high-performance fork that:
- Runs significantly faster than vanilla
- Fixes many exploits and bugs
- Supports Bukkit and Spigot plugins
- Has better chunk loading and entity handling
Other server types available: VANILLA, SPIGOT, BUKKIT, FABRIC, FORGE, PURPUR.
Bedrock Edition Setup
For players on Xbox, PlayStation, Switch, or mobile:
# docker-compose.yml
version: "3.8"
services:
bedrock:
image: itzg/minecraft-bedrock-server
container_name: minecraft-bedrock
restart: unless-stopped
ports:
- "19132:19132/udp"
volumes:
- ./bedrock-data:/data
environment:
EULA: "TRUE"
SERVER_NAME: "Home Bedrock Server"
GAMEMODE: survival
DIFFICULTY: normal
MAX_PLAYERS: 10
ONLINE_MODE: "true"
Connect from any Bedrock client using your server’s IP and port 19132.
Running Both Editions
Want Java and Bedrock players on the same server? Use GeyserMC as a plugin on your Paper server:
environment:
TYPE: "PAPER"
PLUGINS: |
https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot
https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot
This lets Bedrock players join your Java server — one world, all platforms.
Performance Tuning
JVM Flags
The itzg/minecraft-server image uses Aikar’s optimized JVM flags by default. For additional tuning:
environment:
MEMORY: "4G"
JVM_XX_OPTS: "-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200"
USE_AIKAR_FLAGS: "true"
Server Properties
Fine-tune performance vs. quality:
environment:
VIEW_DISTANCE: 10 # Lower = better performance (default 10)
SIMULATION_DISTANCE: 8 # How far entities are active
MAX_TICK_TIME: 60000 # Crash timeout in ms
NETWORK_COMPRESSION_THRESHOLD: 256
ENTITY_BROADCAST_RANGE_PERCENTAGE: 75 # Reduce for better perf
Paper-Specific Tuning
After first start, edit data/config/paper-global.yml:
chunk-loading-basic:
player-max-chunk-load-rate: 100.0
player-max-concurrent-chunk-loads: 4.0
And data/config/paper-world-defaults.yml:
chunks:
max-auto-save-chunks-per-tick: 8
prevent-moving-into-unloaded-chunks: true
entities:
spawning:
monster-spawn-range: 6
Whitelist and Security
Enable Whitelist
Only allow approved players:
environment:
WHITELIST: "player1,player2,player3"
ENFORCE_WHITELIST: "TRUE"
ENABLE_WHITELIST: "TRUE"
Or manage it via the console:
docker exec minecraft rcon-cli whitelist add PlayerName
Operator Permissions
Grant admin access:
environment:
OPS: "your_minecraft_username"
Online Mode
Keep ONLINE_MODE: "true" (default) to verify players against Mojang’s servers. This prevents unauthorized access. Only disable it if you specifically need cracked client support.
Managing the Server
Console Access
Send commands to the running server:
# Single command
docker exec minecraft rcon-cli say Hello everyone!
# Interactive console
docker exec -it minecraft rcon-cli
Common commands:
whitelist add/remove PlayerNameop/deop PlayerNamedifficulty peaceful/easy/normal/hardgamerule keepInventory truesave-all— force savestop— graceful shutdown
Viewing Logs
# Live logs
docker logs -f minecraft
# Last 100 lines
docker logs --tail 100 minecraft
Backups
Your world data lives in ./data. Back it up regularly:
#!/bin/bash
# backup.sh — run via cron
BACKUP_DIR=~/minecraft-backups
DATE=$(date +%Y%m%d-%H%M)
# Tell server to save and disable auto-save temporarily
docker exec minecraft rcon-cli save-all
docker exec minecraft rcon-cli save-off
# Create backup
mkdir -p $BACKUP_DIR
tar czf $BACKUP_DIR/minecraft-$DATE.tar.gz -C ~/minecraft data/
# Re-enable auto-save
docker exec minecraft rcon-cli save-on
# Keep only last 7 backups
ls -t $BACKUP_DIR/minecraft-*.tar.gz | tail -n +8 | xargs -r rm
echo "Backup complete: minecraft-$DATE.tar.gz"
Schedule it:
# Every 6 hours
0 */6 * * * /home/youruser/minecraft/backup.sh
Installing Mods and Plugins
Paper/Spigot Plugins
Add plugins via environment variable:
environment:
TYPE: "PAPER"
PLUGINS: |
https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot
https://github.com/EssentialsX/Essentials/releases/latest/download/EssentialsX.jar
Or drop .jar files into ./data/plugins/.
Popular plugins:
- EssentialsX — homes, warps, kits, economy
- WorldEdit — in-game building tools
- Dynmap — live web map of your world
- CoreProtect — block logging and rollback (anti-grief)
- LuckPerms — permissions management
Fabric Mods
Switch to Fabric for client-side mod compatibility:
environment:
TYPE: "FABRIC"
MODRINTH_PROJECTS: |
lithium
starlight
ferrite-core
Adding a Web Map with Dynmap
Dynmap renders a Google Maps-style view of your world:
services:
minecraft:
# ... existing config ...
ports:
- "25565:25565"
- "8123:8123" # Dynmap web interface
environment:
PLUGINS: |
https://github.com/webbukkit/dynmap/releases/latest/download/Dynmap.jar
Visit http://your-server:8123 to see a live map of your world. Share it with players so they can coordinate without being in-game.
Remote Access
Local Network
Players on your home network connect using your server’s local IP: 192.168.1.x:25565.
Remote Players
Option 1: Port Forward Forward port 25565 (TCP) on your router to your server. Players connect with your public IP.
Option 2: Tailscale (Recommended) Install Tailscale on your server and each player’s device. Players connect using the Tailscale IP — no port forwarding, no exposing your network.
Option 3: Playit.gg Free tunneling service designed for game servers. No port forwarding needed:
# Add to your compose
playit:
image: peelz/playit
restart: unless-stopped
volumes:
- ./playit:/etc/playit
Monitoring
Check if your server is healthy:
# Quick status
docker exec minecraft rcon-cli list
# Resource usage
docker stats minecraft --no-stream
For continuous monitoring, add a health check:
services:
minecraft:
# ... existing config ...
healthcheck:
test: mc-health
interval: 30s
timeout: 10s
retries: 3
Wrapping Up
A self-hosted Minecraft server gives you complete control — install any mods, set any rules, and keep your world running as long as you want. The Docker setup means updates are painless and backups are straightforward.
Start with a basic Paper server, add plugins as you need them, and set up automated backups from day one. Your world is worth preserving.