Minecraft on the Homelab: Creative, Survival, and a Cluster Upgrade
It started with a simple request from the kids: they wanted their own Minecraft world — actually, two of them. One for Creative mode to build without limits, and one for Survival mode to do things “the real way.” Easy enough to spin up on the homelab.
The bigger ask was being able to play with friends from school — not just each other, but actual multiplayer sessions with their classmates joining in.
iPads and Bluetooth Controllers
They've been playing mostly on iPads, with an Xbox controller paired over Bluetooth for a more console-like feel, which turned out to work great for Bedrock edition.
Running Bedrock on the RK1
On the infrastructure side, I got both servers running on the RK1 cluster using itzg's Minecraft Bedrock Docker image, running under emulation since the RK1 nodes are ARM. It worked, but we started running into an odd issue: kids at a distance (like actual friends connecting from off-network) would have trouble joining reliably. I honestly wasn't sure if it was an emulation problem or something else — dropping the render/view distance down to 4 seemed to clear up some of the issues. Googling didn't turn up much useful, and troubleshooting with AI pointed toward emulation overhead as the likely suspect, though it was never fully confirmed.
The Deployment
Both servers are deployed the same way: an Ansible role wraps the itzg image in a Deployment, a Longhorn-backed PVC, and a kube-vip LoadBalancer Service on UDP. No vault secrets are needed for any of this — no database, no API keys, nothing to store. Player allowlists and IPs are trimmed out below since they're not anyone else's business.
The Playbook (Creative)
---
# Deploy Minecraft Bedrock Server (Creative)
# Usage: ansible-playbook playbooks/33-deploy_minecraft_bedrock.yml
#
# itzg/minecraft-bedrock-server, allowlisted, Longhorn-backed world.
# Vault secrets required: none -- no database, no API keys.
- name: Deploy Minecraft Bedrock Server
hosts: localhost
connection: local
gather_facts: false
vars_files:
- ../group_vars/talos_cluster.yml
roles:
- role: minecraft-bedrock
vars:
minecraft_antiaffinity_group: minecraft-creative
minecraft_tolerations:
- key: dedicated
operator: Equal
value: minecraft
effect: NoSchedule
minecraft_node_selector:
node.example.net/workload: minecraft
minecraft_resources_requests_cpu: "1500m"
minecraft_resources_requests_memory: "6Gi"
minecraft_resources_limits_memory: "6Gi"
minecraft_max_threads: 4
The Playbook (Survival)
---
# Deploy Minecraft Bedrock Server (Survival)
# Usage: ansible-playbook playbooks/34-deploy_minecraft_survival.yml
#
# Second Bedrock server, same role, own release name/PVC/Deployment so the
# worlds stay fully independent from the creative one. Runs on a dedicated
# node with real CPU cores (no ARM emulation) after an earlier join-reliability
# issue turned up on the original RK1 cluster.
# Vault secrets required: none -- no database, no API keys.
- name: Deploy Minecraft Bedrock Server (Survival)
hosts: localhost
connection: local
gather_facts: false
vars_files:
- ../group_vars/talos_cluster.yml
roles:
- role: minecraft-bedrock
vars:
minecraft_release_name: minecraft-survival
minecraft_level_name: "survival"
minecraft_antiaffinity_group: minecraft-survival
minecraft_tolerations:
- key: dedicated
operator: Equal
value: minecraft
effect: NoSchedule
minecraft_node_selector:
node.example.net/workload: minecraft
minecraft_gamemode: "survival"
minecraft_difficulty: "normal"
minecraft_allow_cheats: "false"
minecraft_view_distance: 8
minecraft_max_threads: 4
Tuning Defaults
# roles/minecraft-bedrock/defaults/main.yml (excerpt)
minecraft_image: itzg/minecraft-bedrock-server
minecraft_image_tag: "2026.8.2"
minecraft_version: "LATEST" # BDS re-checks/downloads on every start
minecraft_gamemode: "creative"
minecraft_force_gamemode: "true" # re-applies gamemode on every join
minecraft_difficulty: "easy"
minecraft_online_mode: "true" # Xbox Live auth required to connect
minecraft_allow_list: "true" # only allowlisted accounts may connect
minecraft_view_distance: 8
minecraft_player_idle_timeout: 0
minecraft_storage_class: longhorn
minecraft_storage_size: 20Gi
Adding an N150 and Moving the Worlds
The fix ended up being a good excuse for a cluster upgrade: I added an N150 mini PC as a new node in the Talos cluster. Created a new machine config profile for it, joined it in, and then just moved the Minecraft workloads over. Since the worlds are stored on Longhorn PVCs, the migration was seamless — same worlds, same builds, zero data loss, just running on native x86 hardware instead of emulation. Since making the move, I've bumped the view distance back up to 8, and so far, zero issues.