- PaperMC 26.1.2 via itzg/minecraft-server:2026.7.0 - Namespace: minecraft, Service: journey-into-imagination - TCP port 10182 (non-standard) via ingress-nginx tcp forwarding - Pure Storage CSI PVC (pure-block, 50Gi) for world data - World seed hardcoded: -5177989977648707969 - RCON password via ExternalSecret + 1Password Connect - SleepMost v5.6.2 plugin for single-player sleep - Whitelist off at launch, toggle-ready - ExternalDNS annotations for internal Technitium record - Manual steps: UniFi port forward WAN:10182→10.1.71.80:10182, Cloudflare A record + SRV for journey-into-imagination.mk-labs.cloud
9.9 KiB
Journey Into Imagination — Minecraft Server Deployment Plan
Application: PaperMC Minecraft Server
Namespace: minecraft
Deployment name: papermc
Service / DNS name: journey-into-imagination
ArgoCD path: cluster/applications/minecraft/
Reviewed: Pending Ryan approval
Version Pinning
| Component | Version |
|---|---|
| itzg/minecraft-server image | 2026.7.0 |
| PaperMC (Minecraft version) | 1.21.4 (build 232 — last stable 1.21.x) |
| SleepMost plugin | 5.6.2 (auto-downloaded at server start) |
Note on PaperMC versioning: PaperMC migrated to a new version scheme (
26.x) as of mid-2026. The task requested 1.21.x, so we pinVERSION=1.21.4. When you're ready to upgrade to the latest stable, changeVERSIONindeployment.yamlandconfigmap.yamlto26.2and bump the image tag to the latestitzg/minecraft-serverrelease. Check plugin compatibility (SleepMost) before upgrading.
Storage
- StorageClass:
pure-block(confirmed live —kubectl get storageclass) - PVC size: 50Gi — expandable via Pure Storage CSI if the world grows
- Mount:
/datainside the container (worlds, plugins, configs all live here)
Networking Architecture
Internet (players)
|
| DNS: journey-into-imagination.mk-labs.cloud → WAN IP (Cloudflare A record)
|
UniFi UDM Pro
| Port Forward: WAN:25565 → 10.1.71.80:25565 (TCP)
|
ingress-nginx LoadBalancer (10.1.71.80)
| tcp-services ConfigMap: 25565 → minecraft/journey-into-imagination:25565
|
journey-into-imagination Service (ClusterIP, minecraft namespace)
|
papermc Pod (port 25565)
Prerequisites — Manual Steps Before Deploying
1. Generate a real RCON password
# Generate a secure password
openssl rand -base64 24
# Output example: abc123... (save this — you'll need it)
# Base64-encode it for the Secret
echo -n 'YOUR_GENERATED_PASSWORD' | base64
Edit cluster/applications/minecraft/secret.yaml and replace the placeholder value:
data:
rcon-password: <your-base64-encoded-password>
⚠️ Do NOT commit real credentials in plaintext. If this is a concern long-term, migrate to ExternalSecrets + 1Password (Day 2 operation).
2. UniFi Port Forward (Ryan — manual step)
In UniFi Network → Firewall & Security → Port Forwarding:
- Name:
minecraft-papermc - Protocol: TCP
- External Port: 25565
- Internal IP: 10.1.71.80 (ingress-nginx LoadBalancer)
- Internal Port: 25565
- Enabled: Yes
3. Cloudflare DNS Records (Ryan — manual step)
In Cloudflare Dashboard → mk-labs.cloud zone:
A Record (public server address):
| Type | Name | Value | Proxy |
|---|---|---|---|
| A | journey-into-imagination |
<your-WAN-IP> |
DNS only (gray cloud) |
Minecraft uses raw TCP — Cloudflare proxy (orange cloud) will NOT work. Use DNS-only mode (gray cloud).
SRV Record (allows clients to connect without specifying port):
| Type | Name | Service | Proto | Priority | Weight | Port | Target |
|---|---|---|---|---|---|---|---|
| SRV | _minecraft._tcp.journey-into-imagination |
_minecraft |
_tcp |
0 | 5 | 25565 | journey-into-imagination.mk-labs.cloud |
The SRV record allows players to connect using
journey-into-imagination.mk-labs.cloudwithout specifying:25565. Most modern Minecraft clients resolve SRV records.
4. Internal DNS (Technitium — automated via ExternalDNS)
The Service in service.yaml has this annotation:
external-dns.alpha.kubernetes.io/hostname: journey-into-imagination.local.mk-labs.cloud
ExternalDNS (Technitium provider) will create the internal A record automatically when ArgoCD syncs. No manual action required for internal DNS.
Deployment Steps
Step 1: Update the RCON Secret
Complete prerequisite #1 above, then commit the updated secret.
Step 2: Commit and Push to Gitea
cd ~/git/homelab
git status # review what changed
git add cluster/applications/minecraft/ cluster/platform/ingress-nginx/values.yaml
git commit -m "feat(minecraft): add Journey Into Imagination PaperMC server
- Namespace, Deployment, Service (journey-into-imagination), PVC, Secret, ConfigMap
- ArgoCD Application at cluster/applications/minecraft/
- ingress-nginx TCP forwarding: 25565 -> minecraft/journey-into-imagination:25565
- PaperMC 1.21.4, itzg/minecraft-server:2026.7.0, SleepMost 5.6.2
- StorageClass: pure-block, 50Gi PVC for world data"
git push
Step 3: Verify ArgoCD Discovers and Syncs
ArgoCD app-of-apps auto-discovers cluster/applications/minecraft/application.yaml.
# Watch ArgoCD pick it up (from carousel-of-progress)
kubectl get application minecraft -n argocd -w
# Or check ArgoCD UI at argocd.local.mk-labs.cloud
Wait for status: Synced / Healthy
Step 4: Watch the Pod Start Up
First startup will download the PaperMC jar — this can take 2-3 minutes.
kubectl get pods -n minecraft -w
# Tail the logs to watch PaperMC boot
kubectl logs -n minecraft -l app.kubernetes.io/component=papermc -f
Look for:
[Server thread/INFO]: Done (X.XXXs)! For help, type "help"
Step 5: Install SleepMost Plugin (auto via PLUGINS env var)
The PLUGINS env var in the ConfigMap points to the SleepMost JAR download URL.
itzg/minecraft-server downloads and installs it automatically on startup.
Verify it loaded:
kubectl exec -n minecraft -it deployment/papermc -- rcon-cli
# In rcon console:
plugins
# Should list: SleepMost
Step 6: Verify Connectivity
Internal test (from carousel-of-progress):
# Port probe — should succeed
nc -zv journey-into-imagination.local.mk-labs.cloud 25565
# Or via the ClusterIP directly
kubectl get svc -n minecraft
nc -zv <CLUSTER-IP> 25565
External test (after UniFi port forward + DNS configured):
- Open Minecraft Java Edition
- Add server:
journey-into-imagination.mk-labs.cloud - Should connect and show MOTD: "Journey Into Imagination"
Plugin Details
SleepMost v5.6.2
- Source: https://github.com/mrgeneralq/sleep-most
- Download: https://github.com/mrgeneralq/sleep-most/releases/download/v5.6.2/SleepMost-5.6.2.jar
- Compatibility: PaperMC 1.8 through 1.21.x (use 5.6.2 for 1.21.x; 5.7.0+ drops backward compat)
- Configuration: Lives at
/data/plugins/SleepMost/config.ymlafter first boot
Default behavior: configurable percentage of online players must sleep to skip night. To tune (exec into the pod after first start):
kubectl exec -n minecraft -it deployment/papermc -- bash
cat /data/plugins/SleepMost/config.yml
# Edit as needed, then /sleepmost reload in rcon
Geyser compatibility note: SleepMost 5.x does NOT require Geyser to function. If you add Geyser later for Bedrock crossplay, SleepMost is compatible.
Day 2 Operations
Enabling the Whitelist
When ready to lock the server to approved players:
-
Edit
cluster/applications/minecraft/configmap.yaml:WHITE_LIST: "true" ENFORCE_WHITELIST: "true" -
Add players via RCON (live, no restart needed):
kubectl exec -n minecraft -it deployment/papermc -- rcon-cli whitelist add <player_name> whitelist list -
Commit the ConfigMap change for GitOps consistency. Note: the Deployment will restart when the ConfigMap changes (env var reload). Players will be briefly disconnected — plan accordingly.
Console / RCON Access
# Interactive RCON (from inside the pod)
kubectl exec -n minecraft -it deployment/papermc -- rcon-cli
# One-shot command
kubectl exec -n minecraft -it deployment/papermc -- rcon-cli "list"
kubectl exec -n minecraft -it deployment/papermc -- rcon-cli "say Server restarting in 5 minutes"
Upgrading PaperMC Version
- Check PaperMC API:
curl -sA 'Mozilla/5.0' https://fill.papermc.io/v3/projects/paper/versions | head - Update
VERSIONindeployment.yamlenv vars and the comment header - Update image tag if a new
itzg/minecraft-serverrelease is out - Verify SleepMost compatibility with the new version
- Commit, push — ArgoCD handles the rolling restart (Recreate strategy)
Expanding PVC Storage
Pure Storage CSI supports online volume expansion:
kubectl patch pvc papermc-world-data -n minecraft \
-p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'
No pod restart required.
Backups
No automated backup is configured in this skeleton.
Recommended Day 2 addition: CronJob that runs rcon-cli save-all + rcon-cli save-off,
copies /data/world* to a separate PVC or object store, then rcon-cli save-on.
Troubleshooting
| Symptom | Check |
|---|---|
Pod stuck in Init / slow start |
kubectl logs -n minecraft -l app.kubernetes.io/component=papermc — jar download may be slow |
| Port 25565 connection refused externally | Verify UniFi port forward is active; kubectl get svc -n minecraft shows correct ClusterIP |
| Players can't authenticate | ONLINE_MODE=true requires Mojang auth; check player has a valid Java account |
| World data lost after pod restart | Verify PVC is Bound; check pure-block StorageClass is healthy |
| EULA error in logs | EULA=TRUE is set in deployment.yaml — this should not occur; check env var injection |
File Manifest Summary
| File | Purpose |
|---|---|
namespace.yaml |
minecraft namespace |
application.yaml |
ArgoCD Application (sync-wave 20) |
pvc.yaml |
50Gi pure-block PVC for world data |
secret.yaml |
RCON password (⚠️ placeholder — update before deploy) |
configmap.yaml |
server.properties overrides + SleepMost plugin download |
deployment.yaml |
PaperMC Deployment (Recreate strategy, resource limits set) |
service.yaml |
ClusterIP Service named journey-into-imagination |
../../../platform/ingress-nginx/values.yaml |
Added tcp: 25565 forwarding entry |