feat: Add CraftyController (Minecraft server manager) #31

Open
opened 2026-06-17 20:34:34 +00:00 by znibb · 2 comments
Owner

Overview

Deploy Crafty Controller — a web-based GUI for managing Minecraft servers. Allows starting/stopping servers, uploading worlds, managing mods/plugins, and viewing live console output from a browser.

How it works in Kubernetes

A community Helm chart is available on ArtifactHub:

The chart runs Crafty as a non-root container (OpenShift/Kubernetes compatible) with PVCs for server data. The recommended pattern is one Crafty instance per Minecraft server for resource isolation and clean port management.

Ports to expose

Crafty itself uses:

  • 8443 — HTTPS web UI
  • 8080 — HTTP redirect

Each Minecraft server (Java) needs:

  • 25565 (default, TCP) — or a custom port per server

These game server ports must be declared in the Helm chart values and exposed via a Service. Since Traefik does not proxy raw TCP by default, a LoadBalancer service via MetalLB is likely the cleanest approach for game ports, or configure Traefik TCP entrypoints.

Files to create

kubernetes/apps/crafty/
  namespace.yaml
  helmrelease.sh    # Helm install script (like newt pattern)
  values.yaml       # PVC size, port mapping, resource limits
  ingressroute.yaml # Traefik IngressRoute for web UI (port 8443)

Considerations

  • Default image tag is latest in the chart — pin to a specific version for stability.
  • PVC size: Minecraft worlds can grow large; start with 20–50 Gi.
  • If running multiple servers, use separate Crafty deployments or the multi-server feature within one instance.
  • MetalLB IP needed for direct TCP game port access (cannot go through Traefik HTTP ingress).

References

## Overview Deploy [Crafty Controller](https://craftycontrol.com/) — a web-based GUI for managing Minecraft servers. Allows starting/stopping servers, uploading worlds, managing mods/plugins, and viewing live console output from a browser. ## How it works in Kubernetes A community Helm chart is available on ArtifactHub: - [drewburr-labs/craftycontroller](https://artifacthub.io/packages/helm/drewburr-labs-helm-charts/craftycontroller) The chart runs Crafty as a non-root container (OpenShift/Kubernetes compatible) with PVCs for server data. The recommended pattern is **one Crafty instance per Minecraft server** for resource isolation and clean port management. ## Ports to expose Crafty itself uses: - `8443` — HTTPS web UI - `8080` — HTTP redirect Each Minecraft server (Java) needs: - `25565` (default, TCP) — or a custom port per server These game server ports must be declared in the Helm chart values and exposed via a Service. Since Traefik does not proxy raw TCP by default, a `LoadBalancer` service via MetalLB is likely the cleanest approach for game ports, or configure Traefik TCP entrypoints. ## Files to create ``` kubernetes/apps/crafty/ namespace.yaml helmrelease.sh # Helm install script (like newt pattern) values.yaml # PVC size, port mapping, resource limits ingressroute.yaml # Traefik IngressRoute for web UI (port 8443) ``` ## Considerations - **Default image tag is `latest`** in the chart — pin to a specific version for stability. - PVC size: Minecraft worlds can grow large; start with 20–50 Gi. - If running multiple servers, use separate Crafty deployments or the multi-server feature within one instance. - MetalLB IP needed for direct TCP game port access (cannot go through Traefik HTTP ingress). ## References - [Crafty Controller website](https://craftycontrol.com/) - [Helm chart on ArtifactHub](https://artifacthub.io/packages/helm/drewburr-labs-helm-charts/craftycontroller) - [Docker image (arcadiatechnology/crafty-4)](https://hub.docker.com/r/arcadiatechnology/crafty-4)
Author
Owner

Is there another service like CraftyController that works better with Minecraft servers on Kubernetes? I don't want multiple crafty instances, that defeats the purpose of the crafty controller.

Is there another service like CraftyController that works better with Minecraft servers on Kubernetes? I don't want multiple crafty instances, that defeats the purpose of the crafty controller.
Author
Owner

Här är ett förslag på kommentar du kan klistra in:


Uppdatering: alternativ till CraftyController

Efter att ha grävt i det här lite mer landar jag på att skippa CraftyController helt. Crafty är byggt kring att vara en GUI-instans som hanterar flera servrar internt — att då köra en instans per server (som rekommenderas i Helm-chartet) känns fel i ett Kubernetes-sammanhang och ger onödig overhead.

Lösning: mc-router + itzg/minecraft-server

  • itzg/mc-router — lättviktig TCP-proxy som routar Minecraft-klienter baserat på hostname i handshake-paketet (samma princip som SNI/virtual hosting, men inbyggt i Minecraft-protokollet). En enda router-instans för hela klustret.
  • Varje värld blir en vanlig itzg/minecraft-server StatefulSet via itzg/minecraft-server-charts — helt deklarativt, ingen extra GUI per server.
  • mc-router auto-discoverar backends i klustret via service-annotationen mc-router.itzg.me/externalServerName, så nya världar läggs till genom att bara deploya en ny StatefulSet + Service med rätt annotation. Inget att röra i routerns config.

Alternativ som övervägdes men valts bort för nu:

  • Shulker — fullskalig K8s-operator med CRDs (MinecraftServer/MinecraftCluster), bygger på Agones. Mer K8s-native men drar in Agones som extra beroende — överkurs för vårt antal världar just nu. Värt att titta på igen om vi vill ha proxies/spelarmigrering mellan servrar.
  • kubernetes-minecraft-operator (JamesLaverack) — enklare CRD-baserad operator utan Agones, men mindre featurerik.

Bonus: riktiga domännamn via Pangolin

Eftersom mc-router läser hostname direkt ur Minecraft-handshaken kan vi multiplexa flera domäner över en och samma offentliga port:

  1. En Raw TCP/UDP-resurs i Pangolin på port 25565 → Newt-tunnel → mc-router-servicen i klustret.
  2. DNS A-records för mc1.kobbo.se, mc2.kobbo.se osv, alla pekande mot samma publika IP.
  3. mc-router läser hostnamnet klienten skrev in och routar internt till rätt StatefulSet.

Ingen separat Pangolin-resurs behövs per värld — bara en TCP-resurs totalt. Om vi vill ha spelarnas riktiga IP-adresser ända in (för ban-loggar etc.) kan vi kedja PROXY protocol hela vägen: Pangolin har "Enable Proxy Protocol" på TCP-resurser, och mc-router stödjer --receive-proxy-protocol / --use-proxy-protocol.

Nästa steg / filstruktur

kubernetes/apps/minecraft/
  mc-router/
    helmrelease.yaml   # itzg/minecraft-server-charts mc-router
    values.yaml
  worlds/
    survival/
      helmrelease.yaml # itzg/minecraft-server-charts minecraft
      values.yaml
      pvc.yaml

Vill du att jag justerar tonen, kortar ner det, eller lägger till något (t.ex. specifika version-pins eller PVC-storlekar)?

Här är ett förslag på kommentar du kan klistra in: --- **Uppdatering: alternativ till CraftyController** Efter att ha grävt i det här lite mer landar jag på att skippa CraftyController helt. Crafty är byggt kring att vara en GUI-instans som hanterar flera servrar internt — att då köra en instans per server (som rekommenderas i Helm-chartet) känns fel i ett Kubernetes-sammanhang och ger onödig overhead. **Lösning: mc-router + itzg/minecraft-server** - [itzg/mc-router](https://github.com/itzg/mc-router) — lättviktig TCP-proxy som routar Minecraft-klienter baserat på hostname i handshake-paketet (samma princip som SNI/virtual hosting, men inbyggt i Minecraft-protokollet). En enda router-instans för hela klustret. - Varje värld blir en vanlig `itzg/minecraft-server` StatefulSet via [itzg/minecraft-server-charts](https://github.com/itzg/minecraft-server-charts) — helt deklarativt, ingen extra GUI per server. - mc-router auto-discoverar backends i klustret via service-annotationen `mc-router.itzg.me/externalServerName`, så nya världar läggs till genom att bara deploya en ny StatefulSet + Service med rätt annotation. Inget att röra i routerns config. Alternativ som övervägdes men valts bort för nu: - **Shulker** — fullskalig K8s-operator med CRDs (`MinecraftServer`/`MinecraftCluster`), bygger på Agones. Mer K8s-native men drar in Agones som extra beroende — överkurs för vårt antal världar just nu. Värt att titta på igen om vi vill ha proxies/spelarmigrering mellan servrar. - **kubernetes-minecraft-operator** (JamesLaverack) — enklare CRD-baserad operator utan Agones, men mindre featurerik. **Bonus: riktiga domännamn via Pangolin** Eftersom mc-router läser hostname direkt ur Minecraft-handshaken kan vi multiplexa flera domäner över en och samma offentliga port: 1. En **Raw TCP/UDP-resurs** i Pangolin på port 25565 → Newt-tunnel → mc-router-servicen i klustret. 2. DNS A-records för `mc1.kobbo.se`, `mc2.kobbo.se` osv, alla pekande mot samma publika IP. 3. mc-router läser hostnamnet klienten skrev in och routar internt till rätt StatefulSet. Ingen separat Pangolin-resurs behövs per värld — bara en TCP-resurs totalt. Om vi vill ha spelarnas riktiga IP-adresser ända in (för ban-loggar etc.) kan vi kedja PROXY protocol hela vägen: Pangolin har "Enable Proxy Protocol" på TCP-resurser, och mc-router stödjer `--receive-proxy-protocol` / `--use-proxy-protocol`. **Nästa steg / filstruktur** ```text kubernetes/apps/minecraft/ mc-router/ helmrelease.yaml # itzg/minecraft-server-charts mc-router values.yaml worlds/ survival/ helmrelease.yaml # itzg/minecraft-server-charts minecraft values.yaml pvc.yaml ``` --- Vill du att jag justerar tonen, kortar ner det, eller lägger till något (t.ex. specifika version-pins eller PVC-storlekar)?
Sign in to join this conversation.
No labels
gitops-rework
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
znibb/kobbo-homelab#31
No description provided.