How to Set Up a Minecraft Server on Linux (Docker, Backups and Letting Friends In)

A Minecraft server for the kids and their friends is the classic reason to own a home server. The itzg/minecraft-server Docker image does all the hard parts — it downloads the right version, accepts the licence, and restarts cleanly — so the whole thing is a compose file and some memory.
Quick reference
| Task | What |
|---|---|
| Java edition | itzg/minecraft-server, port 25565/tcp |
| Bedrock (consoles, phones) | itzg/minecraft-bedrock-server, port 19132/udp |
| Memory | MEMORY: 4G — leave at least 2 GB for the rest of the server |
| Console | docker attach mc (detach with Ctrl + P, Ctrl + Q) |
| Whitelist | WHITELIST: name1,name2 + ENFORCE_WHITELIST: "true" |
| Backups | itzg/mc-backup sidecar container |
1. The compose file (Java edition)
mkdir -p ~/docker/minecraft && cd ~/docker/minecraft
nano compose.yaml
services:
mc:
image: itzg/minecraft-server
container_name: mc
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: "TRUE"
TYPE: PAPER
VERSION: LATEST
MEMORY: 4G
MOTD: "The family server"
DIFFICULTY: normal
WHITELIST: "steve_123,alex_456"
ENFORCE_WHITELIST: "true"
OPS: "steve_123"
TZ: Europe/London
volumes:
- ./data:/data
restart: unless-stopped
- TYPE: PAPER is a faster, plugin-capable server that behaves exactly like vanilla. Use VANILLA if you prefer.
- MEMORY is the Java heap. A 4 GB server runs five or six players comfortably.
- WHITELIST means only named players can join — essential if the port is open to the internet.
docker compose up -d
docker compose logs -f
First start downloads the server and generates the world; wait for "Done" in the log.
2. Join it
On the home network, Multiplayer → Add Server, address 192.168.1.50. It appears in the list.
3. The console
docker attach mc
Type server commands: list, whitelist add name, op name, say Dinner in 5, stop. Detach without stopping the server with Ctrl + P then Ctrl + Q. Or run a single command: docker exec mc rcon-cli list.
4. Bedrock (Switch, Xbox, PlayStation, phones)
Those play the other edition. A second service:
bedrock:
image: itzg/minecraft-bedrock-server
ports:
- "19132:19132/udp"
environment:
EULA: "TRUE"
SERVER_NAME: "Family Bedrock"
ALLOW_LIST: "true"
volumes:
- ./bedrock:/data
restart: unless-stopped
Consoles can't type an address, so they need a trick: on the console, add a DNS override or use a "BedrockConnect" server. Phones and PCs just enter the IP under Servers.
5. Automatic backups
Add a sidecar that backs up the world without stopping the server:
backup:
image: itzg/mc-backup
environment:
BACKUP_INTERVAL: "6h"
PRUNE_BACKUPS_DAYS: 14
RCON_HOST: mc
volumes:
- ./data:/data:ro
- /mnt/backup/minecraft:/backups
depends_on:
- mc
6. Friends from outside
Two options:
- Port forward 25565/tcp on the router to the server, give friends your DuckDNS name (tutorial 48), and keep the whitelist on. Minecraft gets scanned constantly; the whitelist is what keeps strangers out.
- No forwarding: have them install Tailscale and share the server device with them (tutorial 47). Safer, slightly more setup on their side.
Troubleshooting
"Can't keep up! Is the server overloaded?" Not enough CPU or memory, or view-distance is high. Lower VIEW_DISTANCE: 8 in the environment.
Friends can't connect from outside. Port forward missing, or it's forwarded as UDP (Java needs TCP). Test from your phone on mobile data.
Version mismatch. The client auto-updates; pin VERSION: 1.21.4 on the server (and tell players), or let LATEST follow.
World corrupted after a power cut. Restore from /mnt/backup/minecraft — stop the server, replace ./data/world, start.
Wrapping up
One compose file with a whitelist and a memory limit, a sidecar for backups, and a port forward or Tailscale for friends. The server takes care of versions and restarts; you just decide who's allowed in.
