Palworld Operator by DataKnifeAI

Hold a world. Let friends find Pals.

One PalworldServer CR hosts a dedicated world on Kubernetes — so your crew can join, explore, and capture together.

Built for hosting a world

Not a game storefront — an operator that stands up the dedicated server your players join.

  • Declare × Reconcile

    Apply a CR. The controller builds Deployment, PVC, ConfigMap, Secret mounts, and Envoy Gateway routes.

  • Host × Persist

    Saves live on a PVC. Gateway address and game port surface in status for a clean share string.

  • Join × Capture

    Players open Palworld, direct-connect to your world, and get back to finding Pals — you keep the cluster side.

How it works

Three steps from CRD to a running world.

  1. Install the operator

    kubectl apply -k config/default — CRDs, RBAC, and controller land in your cluster.

  2. Declare a PalworldServer

    Apply a sample CR. The reconciler wires the dedicated server image, storage, passwords, and UDP routes.

  3. Share the address

    Read status.connectionAddress and status.connectionPort, then connect from inside the game.

Browse the sample CR →

Local / minimal PC

No Kubernetes required. Run the same official ghcr.io/pocketpairjp/palserver image with Docker Compose on a gaming PC or laptop — then graduate to the operator when you want cluster hosting. Guide: docs/LOCAL.md.

cp compose/.env.example compose/.env   # set SERVER_PASSWORD / ADMIN_PASSWORD
make compose-up
# Palworld → Join Multiplayer Game → 127.0.0.1:8211
make compose-down
  • Players Default max 4 — keep small on a shared PC
  • RAM ~8 Gi free recommended · compose cap 6g (raise if OOM)
  • Game port 8211 / UDP · REST/RCON on localhost only

Saves live under compose/Saved/. Passwords seed into PalWorldSettings.ini on first start from .env. Cluster path (Envoy Gateway + CR) stays the production default above.

Connect from inside Palworld

Once the CR is Ready, players join from the game client — not from kubectl. Full write-up: docs/CONNECT.md.

1. Read the address (admins)

kubectl get palworldserver -n game-servers
# ADDRESS + PORT columns map to status.connectionAddress / connectionPort

kubectl get palworldserver palworld-server -n game-servers \
  -o jsonpath='{.status.connectionAddress}:{.status.connectionPort}{"\n"}'

Share connectionAddress:connectionPort (default port 8211 UDP). Example: 192.168.14.187:8211.

2. Join Multiplayer Game

  1. Launch Palworld → choose Join Multiplayer Game.
  2. In the direct-connect field at the bottom, enter IP:PORT from status.
  3. If the world has a join password, enable Enter password, type the server-password Secret value, then click Connect.

3. Join password vs admin password

  • server-password Join / ServerPassword — share with players
  • admin-password Admin / RCON — keep private
# Secret name: status.credentialsSecretName (sample BYO name below)
kubectl get secret palworld-server-secrets -n game-servers \
  -o jsonpath='{.data.server-password}' | base64 -d; echo

kubectl get secret palworld-server-secrets -n game-servers \
  -o jsonpath='{.data.admin-password}' | base64 -d; echo

Bring-your-own Secret refs, or set spec.generateSecrets: true so the operator creates {cr-name}-secrets. Passwords are never written into status.

4. Community browser vs direct connect

Direct connect is the reliable path for private operator worlds. The Community Servers list needs spec.community.enabled: true and query port 27015 UDP — useful for public discovery and for consoles that cannot enter an IP.

Crossplay (Steam / Xbox / PS5 / Mac) is controlled by spec.crossplayPlatforms. Console clients usually still need community listing even when crossplay is on.

Ports

  • Game 8211 / UDP
  • Steam query 27015 / UDP
  • RCON 25575 / TCP
  • REST API 8212 / TCP

REST and RCON are for operators — keep them off the public internet unless you mean it. See CONNECT.md for password-prompt quirks and a share template.

FAQ

Short answers to issues we’ve hit hosting Palworld. Full write-up: docs/FAQ.md.

“Incapable version”

Client/server build mismatch — usually the server image is behind a Steam client update. Bump spec.serverImage to a current Pocketpair tag (e.g. v1.0.1.100619), or enable opt-in spec.update.autoUpdateImage. Wait for Ready, confirm REST version. Players: update the game on Steam.

“No password entered”

Enable Enter password and use the join Secret key server-password (not admin). Or set spec.generateSecrets: true and read the generated Secret.

Empty / different world after restart

The operator seeds DedicatedServerName from REST worldguid (or spec.dedicatedServerName) into GameUserSettings.ini. Confirm REST worldguid after rolls.

How do game patches reach the server?

Official image = new container tag, not SteamCMD on boot. Opt-in spec.update.autoUpdateImage polls GHCR and pins vX.Y.Z.W (optional cron windows, REST announce before roll). Community images may use updateOnBoot. Details in FAQ / PALWORLD_SERVER.md.

Open the full FAQ →