mysite/public-onion/sources/posts/minecraft_server.md

200 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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
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
```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 dont 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 thats not enough, you have two good options:
### Option A — Move Dockers 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 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:
```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 Dockers data-root**, or **extending `/var`** via LVM.
- Verify version in logs after each change.
Happy block-breaking! 🧱🚀
---
{{< sigdl >}}