Skip to main content

Minecraft on the Homelab: Creative, Survival, and a Cluster Upgrade

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.

Get new posts delivered to your inbox