--- title: "Dockerizing my Minecraft Server + Geyser: from 'no space left' to stable releases" date: 2025-09-29T09:06:29Z draft: false tags: ["minecraft", "docker", "paper", "papermod", "geyser", "linux", "lvm"] categories: ["Homelab", "Games"] toc: true summary: "How I containerized a Java Minecraft server with Geyser, hit a /var space wall, and locked the server to the latest stable release." --- ## Why I’ve 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** Here’s exactly what I did. --- ## Folder layout ```bash ~/minecraft/ ├─ docker-compose.yml ├─ .env └─ plugins/ ``` --- ## `.env` (secrets & knobs) Use the **latest stable** (not snapshots/pre-releases) by setting `VERSION=LATEST`. ```env # 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 don’t use a whitelist, so no `WHITELIST`/`ENFORCE_WHITELIST` variables. --- ## `docker-compose.yml` ```yaml 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 ```bash 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: ```bash 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 ```bash docker system df docker system prune -f docker builder prune -af sudo apt-get clean sudo journalctl --vacuum-size=100M ``` If that’s not enough, you have two good options: ### Option A — Move Docker’s data off `/var` ```bash 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: ```bash sudo rm -rf /var/lib/docker/* ``` ### Option B — Grow `/var` (LVM) Check free space in the VG: ```bash sudo vgdisplay # look for "Free PE / Size" ``` If available, extend `/var` by +5G: ```bash 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: ```env VERSION=LATEST_RELEASE ``` 2. Recreate: ```bash docker compose down docker compose pull docker compose up -d ``` 3. Verify: ```bash 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 you’ve validated). --- ## No whitelist Because I don’t set `WHITELIST`/`ENFORCE_WHITELIST`, anyone can join (subject to online-mode, bans, and Geyser/Floodgate auth settings). Manage ops/permissions via: ```bash 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: ```bash docker compose pull && docker compose up -d ``` - Watch space: ```bash 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 Docker’s data-root**, or **extending `/var`** via LVM. - Verify version in logs after each change. Happy block-breaking! 🧱🚀 --- {{< sigdl >}}