𝔩𝔢𝔩𝕠𝔭𝔢𝔷
Theme

Homelab

Minecraft Plugin Updates

Refreshing Stale Geyser, Floodgate, and Paper Plugins on a Minecraft Kubernetes Server

Overview

Long-running Minecraft pods accumulate plugin drift because the itzg image's PLUGINS URLs only re-resolve when the container starts. This procedure restarts the pod so REMOVE_OLD_MODS: TRUE1 wipes the stale jars and the entrypoint downloads the current upstream builds of Geyser2 and Floodgate3.

Tip

Verified on MC 1.21.11 Paper, May 31, 2026 — refreshed to Geyser 2.10.0-b1158, Floodgate 2.2.5-SNAPSHOT b132, ViaVersion 5.9.1.

Before You Begin

Prerequisites

  • Minecraft Paper Server completed
  • Pod with AGE more than a few weeks (the jars are downloaded on container start, so anything long-running is a candidate)

Why This Approach

The itzg image's refresh mechanism is restart-driven, not runtime-driven. There is no in-pod "reload plugins" command that re-pulls the PLUGINS URLs. Editing the HelmRelease and reconciling Flux works too, but if the URLs haven't changed Flux has nothing to apply. kubectl rollout restart terminates the pod, lets the entrypoint re-execute the download with REMOVE_OLD_MODS: TRUE wiping the old jars, and brings up a pod with current upstream builds.

Diagnose Plugin Staleness

Pod Uptime

kubectl get pods -n minecraft

Observed (2026-05-31): AGE 53d — 7+ weeks since the last container start.

Plugin Jar Dates

kubectl exec -n minecraft deploy/minecraft -- ls -la /data/plugins | grep -iE 'geyser|floodgate'

Observed (2026-05-31):

-rw-rw-r--.  1 minecraft 2000 11559667 Apr  8 09:06 floodgate-spigot.jar
-rw-rw-r--.  1 minecraft 2000 18214145 Apr  8 09:06 Geyser-Spigot.jar

Save the World

RCON: save-all

kubectl exec -n minecraft deploy/minecraft -- rcon-cli "save-all"

Expected: Saving the game (this may take a moment!)Saved the game

Restart the Pod

Kubectl: Rollout Restart

kubectl rollout restart deployment -n minecraft minecraft

Observed (2026-05-31): PodSecurity warning about the playit-agent sidecar's allowPrivilegeEscalation and capability drop — namespace is in WARN mode, rollout proceeded.

Watch the Rollout

kubectl get pods -n minecraft -w

Expected: new pod reaches 2/2 Running within 2-5 minutes as plugins re-download.

Diagnose the Sidecar Crash

On the 2026-05-31 rollout, the new pod went CrashLoopBackOff 11 seconds after start — too fast for Paper to be the failure point.

Pod Events

POD=$(kubectl get pod -n minecraft -l app=minecraft -o jsonpath='{.items[0].metadata.name}')
kubectl describe pod -n minecraft $POD | sed -n '/Events:/,$p'

Observed: Back-off restarting failed container playit-agent — the minecraft container itself was Running.

Sidecar Logs

kubectl logs -n minecraft $POD -c playit-agent --tail=50

Observed:

INFO playitd::daemon: Starting playitd socket_path=None secret_path=None version=1.0.5
playitd error: IPC error: Failed to bind to socket: Permission denied (os error 13)

playit-agent 1.0.5 hardcodes its IPC socket to /var/run/playitd.sock4, which is not writable in this container.

Compare With a Working Sidecar

kubectl get pods -n factorio -o json | jq -r '.items[].status.containerStatuses[] | select(.name=="playit-agent") | "image:    \(.image)\nimageID:  \(.imageID)"'

Observed: factorio's running digest 84d8ea84… differed from minecraft's failed pull 188c2129… (the upstream 1.0.5 tag). Factorio is on an older registry-untagged digest cached locally — :latest rolled forward only on minecraft's fresh pull.

Pin the Sidecar

HelmRelease: Pin Image and Socket Path

k8s/apps/minecraft/helmrelease.yaml (postRenderers patch):

# ... existing postRenderers + patches header ...
            patch: |
              - op: add
                path: /spec/template/spec/containers/-
                value:
                  name: playit-agent
                  image: ghcr.io/playit-cloud/playit-agent:1.0.5  # was :latest
                  args:                                            # new
                    - "--socket-path"
                    - "/tmp/playitd.sock"
                  env:
                    - name: SECRET_KEY
                      valueFrom:
                        secretKeyRef:
                          name: playit-secret
                          key: secret-key

Git: Commit and Push

git add k8s/apps/minecraft/helmrelease.yaml
git commit -m "fix(minecraft): pin playit-agent to 1.0.5, route IPC socket to /tmp"
git push

Flux: Reconcile

flux reconcile source git flux-system && flux reconcile kustomization sync

Reconciliation replaces the pod; both containers restart and plugins re-download a second time.

Verify Plugin Refresh and Bedrock Connection

Pod Status

kubectl get pods -n minecraft

Expected: 2/2 Running.

Sidecar Startup

kubectl logs -n minecraft deploy/minecraft -c playit-agent --tail=30

Expected: socket_path=Some("/tmp/playitd.sock") on the first line, followed by agent registered. The playit.gg dashboard flips both Minecraft Java and Bedrock tunnels back to green.

Plugin Startup Banners

kubectl logs -n minecraft -l app=minecraft -c minecraft --tail=500 | grep -iE 'loading server plugin|geyser version'

Expected: current upstream versions for floodgate, ViaVersion, Geyser-Spigot.

Bedrock Connection

After a Bedrock player retries:

kubectl logs -n minecraft -l app=minecraft -c minecraft --tail=200 | grep -iE 'geyser|floodgate'

Expected: [Geyser-Spigot] Player connected with username <name> followed by [floodgate] Floodgate player logged in as .<name> joined (UUID: 00000000-0000-0000-xxxx-xxxxxxxxxxxx). Whitelisting Bedrock players is covered in Server Management.

Resources

Footnotes

  1. itzg, "Docker Minecraft Server — Plugins and Mods," github.com. Accessed: May 31, 2026. [Online]. Available: https://docker-minecraft-server.readthedocs.io/en/latest/mods-and-plugins/

  2. GeyserMC, "Geyser Downloads," geysermc.org. Accessed: May 31, 2026. [Online]. Available: https://geysermc.org/download/?project=geyser

  3. GeyserMC, "Floodgate Downloads," geysermc.org. Accessed: May 31, 2026. [Online]. Available: https://geysermc.org/download/?project=floodgate

  4. playit-cloud, "playit-agent — playit-ipc/src/paths.rs (v1.0.5)," github.com. Accessed: May 31, 2026. [Online]. Available: https://github.com/playit-cloud/playit-agent/blob/v1.0.5/packages/playit-ipc/src/paths.rs

Previous
Minecraft Server Management