Skip to content

Minecraft Server: Build Handoff (2026-04-24)

Outcome

Cross-platform vanilla Minecraft server stood up on Finn. Java + Bedrock + Switch all supported. World data on /mnt/workspace/minecraft/. Daily backup wired to /mnt/storage/minecraft-backups/. Server is running and reachable on the LAN, needs router port-forwards to be public.

Where it lives

  • CT 110 on Finn, hostname minecraft, IP 192.168.86.23, alias ssh minecraft
  • Debian 13 unprivileged LXC, 8 GB RAM / 4 cores / 32 GB rootfs
  • Docker → itzg/minecraft-server:java21
  • Paper 1.21.4 (latest stable)
  • Geyser-Spigot 2.9.5 (Bedrock translation, UDP 19132)
  • Floodgate 2.2.5 (Bedrock players don't need a Java account)
  • Compose: /opt/minecraft/docker-compose.yml inside CT
  • World: /data (CT) ↔ /mnt/workspace/minecraft/ (Finn workspace NVMe)

Decisions made

Choice Why
Paper, not Fabric/NeoForge Justin chose vanilla, no mods. Paper = lightest + best plugin support if QoL is added later.
Version 1.21.4 Latest stable Paper at build time. Newer Bedrock versions may need ViaVersion later.
Geyser + Floodgate via direct GeyserMC URL Modrinth Geyser doesn't ship a "paper" loader variant, direct download URL is the canonical install path.
Public BedrockConnect (104.238.130.180) for Switch Justin doesn't use AdGuard for DNS. Self-hosting BedrockConnect adds an LXC + DDNS for marginal benefit. Trade-off: Switch DNS goes through 3rd party; gameplay traffic still direct.
IP 192.168.86.23 Initially placed at .83 → conflict with immich CT 107. Moved to .85, all clean.
Whitelist OFF Per Justin's request. Can flip on later via whitelist on from console.
No DDNS Skipped for now. Add when WAN IP changes break access.

Public access, wired via UPnP (not manual port-forward)

Google Home device picker never showed the minecraft CT (Proxmox virtual MAC, hostname not picked up, even after DHCP flip + rename attempts). Bypassed the UI entirely: Google Fiber has UPnP/IGD enabled at http://192.168.86.1:5000/, so the CT punches its own port forwards via upnpc: - TCP 25565 → 192.168.86.23:25565 - UDP 19132 → 192.168.86.23:19132

Verified externally with check-host.net hitting WAN port 25565 from Spain (122ms) + Miami (46ms). Daily cron in CT (/etc/cron.d/upnp-mc-keepalive) re-asserts the 7-day IGD lease. Inspect with ssh minecraft 'upnpc -l'.

Things Justin still needs to do

  1. Tell players:
  2. Mac/Win Java: connect to 136.60.22.116
  3. Win Bedrock: connect to 136.60.22.116 port 19132
  4. Switch: change DNS to 104.238.130.180, tap a featured server, hit "+ Add Server" in BedrockConnect, add 136.60.22.116 port 19132

Risks flagged

  • Public + no whitelist = anyone who knows the IP can attempt to join. Online-mode is ON (Mojang auth required), so random griefers need real accounts, but it's not zero risk. Recommend turning whitelist on once the friend list is known.
  • Geyser version warning: Geyser internally targets Java 1.21.11; we're on 1.21.4. Today's Bedrock clients connect fine; if very-new Bedrock clients fail later, add ViaVersion to PLUGINS.
  • Hot rsync backups, script uses save-off / save-all flush / save-on to checkpoint before rsync. Should be consistent. If we ever see corruption, switch to a snapshot-based approach (Proxmox volume snapshot of the bind-mount).

Files created

  • /opt/minecraft/docker-compose.yml (in CT 110)
  • /home/justinwieb/forge/scripts/integrations/minecraft/backup.sh
  • /home/justinwieb/.claude/projects/-home-justinwieb-forge/memory/reference_minecraft_server.md
  • UDev crontab: 0 4 * * * /home/justinwieb/forge/scripts/integrations/minecraft/backup.sh
  • SSH alias minecraft in ~/.ssh/config

Future enhancements (when/if needed)

  • ViaVersion + ViaBackwards plugins for forward/backward Bedrock client compat
  • DuckDNS or Cloudflare DDNS for stable hostname
  • DynMap plugin (web-based world map on a port)
  • CoreProtect plugin (anti-grief rollback)
  • Whitelist + ops list once friend list known

[Claude Code]