mysite/content/posts/minecraft_server.md

4.8 KiB
Raw Permalink Blame History

title date draft tags categories toc summary
Dockerizing my Minecraft Server + Geyser: from 'no space left' to stable releases 2025-09-29T09:06:29Z false
minecraft
docker
paper
papermod
geyser
linux
lvm
Homelab
Games
true How I containerized a Java Minecraft server with Geyser, hit a /var space wall, and locked the server to the latest stable release.

Why

Ive been running a Java Minecraft world (with Bedrock players via Geyser) in tmux. I moved it to Docker for easier updates, backups, and restarts. Along the way I hit:

  • failed to register layer: ... no space left on device
  • Client saying: “Outdated client, please use 1.21.9 Pre-Release 2”
  • Wanting config in a neat .env and no whitelist

Heres exactly what I did.


Folder layout

~/minecraft/
├─ docker-compose.yml
├─ .env
└─ plugins/

.env (secrets & knobs)

Use the latest stable (not snapshots/pre-releases) by setting VERSION=LATEST.

# Minecraft server configuration
EULA=TRUE
TYPE=PAPER
VERSION=LATEST
MEMORY=4G
USE_AIKAR_FLAGS=true

# RCON (remote console)
ENABLE_RCON=true
RCON_PASSWORD=superSecretPassword123

I dont use a whitelist, so no WHITELIST/ENFORCE_WHITELIST variables.


docker-compose.yml

services:
  mc:
    image: itzg/minecraft-server:latest
    container_name: mc
    restart: unless-stopped
    ports:
      - "25565:25565"        # Java
      - "19132:19132/udp"    # Bedrock via Geyser plugin
    env_file:
      - .env
    volumes:
      - mc-data:/data
      - ./plugins:/plugins:ro
volumes:
  mc-data: {}

The version: key in Compose is obsolete now, so I dropped it.


Add Geyser (and optional Floodgate) as plugins

mkdir -p ~/minecraft/plugins
cd ~/minecraft/plugins

# Geyser (Spigot/Paper)
wget https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot   -O Geyser-Spigot.jar

# Floodgate (optional: Bedrock accounts without Java linking)
wget https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot   -O Floodgate-Spigot.jar

Start it up:

docker compose up -d

On first run, Geyser writes its config to /data/plugins/Geyser-Spigot/. Open UDP 19132 on your firewall.


Hit a wall: /var ran out of space

Docker stores layers at /var/lib/docker by default. My /var LV was tiny:

/dev/mapper/ubuntu--vg-var   3.9G  3.4G  333M  92% /var

Quick cleanup

docker system df
docker system prune -f
docker builder prune -af
sudo apt-get clean
sudo journalctl --vacuum-size=100M

If thats not enough, you have two good options:

Option A — Move Dockers data off /var

sudo systemctl stop docker
sudo mkdir -p /home/docker
sudo rsync -aHAX --info=progress2 /var/lib/docker/ /home/docker/
echo '{ "data-root": "/home/docker" }' | sudo tee /etc/docker/daemon.json
sudo systemctl start docker
docker info | grep "Docker Root Dir"

If all looks good, free the old space:

sudo rm -rf /var/lib/docker/*

Option B — Grow /var (LVM)

Check free space in the VG:

sudo vgdisplay   # look for "Free PE / Size"

If available, extend /var by +5G:

sudo lvextend -L +5G /dev/mapper/ubuntu--vg-var
sudo resize2fs /dev/mapper/ubuntu--vg-var

The version mismatch: pre-release vs stable

My logs showed:

Starting minecraft server version 1.21.9 Pre-Release 2

That happens if the server pulls a pre-release build (or if VERSION=LATEST). Fix:

  1. Ensure .env has:
    VERSION=LATEST_RELEASE
    
  2. Recreate:
    docker compose down
    docker compose pull
    docker compose up -d
    
  3. Verify:
    docker logs mc | grep "Starting minecraft server version"
    # -> Starting minecraft server version 1.21.1   (example)
    

Tip: If you want to pin and avoid auto-updates entirely, set VERSION=1.21.1 (or whatever stable youve validated).


No whitelist

Because I dont set WHITELIST/ENFORCE_WHITELIST, anyone can join (subject to online-mode, bans, and Geyser/Floodgate auth settings). Manage ops/permissions via:

docker exec -it mc rcon-cli "op YourJavaIGN"

(or edit /data/ops.json).


Backup & updates

  • World/data live under the mc-data volume → back up /data regularly.
  • Update cleanly:
    docker compose pull && docker compose up -d
    
  • Watch space:
    watch -n5 'df -h /var; docker system df'
    

TL;DR

  • Put Geyser/Floodgate jars in ./plugins and expose 19132/udp.
  • Keep configs in .env.
  • Fix /var space by pruning, moving Dockers data-root, or extending /var via LVM.
  • Verify version in logs after each change.

Happy block-breaking! 🧱🚀


{{< sigdl >}}