Appearance
Deploy on Kubernetes (Helm)
charts/pantahub in the pantahub-base repository is a Helm translation of the repo's docker-compose.yml: the same services, same names and ports, running on a Kubernetes cluster instead of one Docker host. It targets dev/test clusters (k3d, minikube, kind, or a shared dev cluster); all images are public, so no pull secrets are needed.
The chart ships its own detailed docs — charts/pantahub/GUIDE.md (step-by-step) and charts/pantahub/README.md (compose-to-chart mapping and caveats). This page is the short version.
Prerequisites
kubectland Helm v3.A cluster with ~6 GB of RAM to spare and a default StorageClass (the chart creates 7 PVCs). For example:
shk3d cluster create pantahub --agents 1 # ships local-path storage # or: minikube start --memory 8192 --cpus 4 # or: kind create cluster --name pantahub
Configure
Your values file plays the role of .env.local: everything under env: is merged over the defaults in values.yaml (which mirror env.default, including the dev-only JWT/JWE keys — replace those for any cluster other people can reach).
yaml
# my-values.yaml
env:
PANTAHUB_SA_ADMIN_SECRET: "changeme"
kibana:
enabled: true # log UI (the compose "logs" profile)
base:
tag: develop # any pantahub-base image tagMind the demo accounts: without PANTAHUB_PRODUCTION set, base runs in dev mode and enables all built-in accounts with their code defaults — including admin/admin. The PANTAHUB_DEMOACCOUNTS_PASSWORD_* variables only apply in production mode (PANTAHUB_PRODUCTION: "yes"), which disables any account without an explicit password. Set both before exposing the cluster.
Every other credential of the backing stack is also a value, defined in exactly one place and rendered wherever it's used (mongo user creation, kafka-connect connector configs, kibana.yml): the app mongo user (env.MONGO_USER/MONGO_PASS), the mongo root user (mongo.env.*), the kafka-connect mongo users (mongo.connectUsers.*), the replica-set keyfile (mongo.keyfileKeys) and kibana's encryption keys (kibana.encryptionKeys.*). Two gotchas: mongo users are created on first bring-up only (changing a password later doesn't update an existing data volume), and mongo passwords end up inside mongodb:// URIs — keep them URL-safe.
Install
sh
helm install pantahub ./charts/pantahub -n pantahub \
--create-namespace -f my-values.yaml
kubectl -n pantahub get pods -wFirst bring-up takes several minutes. Kubernetes has no depends_on, so ordering works the way the compose entrypoints already did — wait loops: mongo initializes rs0, kafka creates topics, kafka-connect uploads the connector configs, phs waits for them, and base has an initContainer waiting on mongo, fluentd and elasticsearch. Some early CrashLoopBackOff cycles on the kafka side are expected and self-heal.
Access the services
The chart keeps the compose ports; port-forward what you need:
sh
kubectl -n pantahub port-forward svc/base 12365:12365 # API
kubectl -n pantahub port-forward svc/www 3000:80 # Web UI
kubectl -n pantahub port-forward svc/pvr 12367:12367 # pvrThe www defaults assume exactly these forwards, so with the three running the UI at http://localhost:3000 works out of the box. On a local cluster you can also enable the ingress without a domain — it falls back to the hosts api.localhost / hub.localhost / pvr.localhost.
Accessed this way the cluster is a development environment: fine for the web UI, the API and pvr, but real Pantavisor devices cannot connect to it — devices require a TLS endpoint with a certificate they trust, which localhost port-forwards and *.localhost hosts can't provide. You can still populate it with simulated devices using pantavisor-mocker (init --host localhost --port 12365 against the forwarded API). For real hardware, continue to the next section.
Going public: a domain with Let's Encrypt
To serve real clients — above all, real devices — the chart can expose the three client-facing services on subdomains of your own domain, with TLS certificates requested and renewed by cert-manager:
api.<domain>→ base (devices and API clients)hub.<domain>→ www (the web UI)pvr.<domain>→ pvr
Once per cluster, install an ingress controller and cert-manager — on stock k3s you can skip the ingress controller, since its bundled traefik is the default IngressClass and the chart uses the cluster default when ingress.className is left empty. Point api., hub. and pvr.<domain> — or a wildcard — at the ingress controller's external IP (the node's public IP on single-node k3s). Let's Encrypt HTTP-01 validation needs the names to resolve publicly and port 80 reachable; with DNS in place before the install, issuance typically completes in under a minute. Then:
yaml
# my-values.yaml
ingress:
enabled: true
# className: nginx # only when not using the cluster default
domain: pantahub.example.com
letsencrypt:
email: you@example.com # ACME account emailSetting ingress.domain rewires the whole app automatically — PANTAHUB_HOST, PANTAHUB_SCHEME, PH_AUTH and the UI's REACT_APP_* URLs all switch to https://api./hub./pvr.<domain>, and base/gc/www roll to pick it up. The certificate for all three hosts lands in the pantahub-tls secret; watch progress with kubectl -n pantahub get certificate,order,challenge, and use the Let's Encrypt staging server (ingress.letsencrypt.server) while testing to avoid rate limits.
Two things to do before devices can use it:
- Lock the cluster down before it is publicly reachable: set
PANTAHUB_PRODUCTIONplus explicitPANTAHUB_DEMOACCOUNTS_PASSWORD_*values (dev mode ships open demo accounts,admin/adminincluded), and replace all the well-known dev credentials — the JWT/JWE keys, mongo users and replica-set keyfile, kafka-connect users, kibana encryption keys. Each is a single value inmy-values.yaml; see the credentials list in the Configure section and the chart README's "Dev secrets" caveat. - Build device images that talk to
api.<domain>instead ofapi.pantahub.com— see Devices for your own Hub.
Day-2 operations
- Config change — edit
my-values.yaml, thenhelm upgrade pantahub ./charts/pantahub -n pantahub -f my-values.yaml.baseandgcroll automatically whenenv:changes. - New image on a moving tag (e.g.
develop) —kubectl -n pantahub rollout restart deploy/base. - Run a cron endpoint now —
kubectl -n pantahub create job --from=cronjob/pantahub-publicdevices manual-run-1.
Smoke test
charts/pantahub/smoke-test.sh validates the whole cycle unattended: it creates a throwaway k3d cluster (with its own kubeconfig — yours is not touched), installs the chart, waits for every deployment, probes the services from inside the cluster, checks the mongo replica set, and tears the cluster down again. KEEP=true keeps the cluster to poke around; VALUES=overlay.yaml tests extra values.
The pantacor and Confluent images are amd64-only, so the full run needs an amd64 host. Every component has an enabled flag in values, so on arm64 you can still exercise the chart mechanics with the arm64-capable subset (mongo, elasticsearch, localstack) by disabling the rest — the chart's GUIDE ships a ready-made smoke-arm64.yaml for exactly that, plus a recipe for a full end-to-end run (including the Let's Encrypt flow) on a throwaway cloud VM.
Uninstall / reset
sh
helm uninstall pantahub -n pantahubPVCs — and therefore all data — deliberately survive uninstall. For a full wipe, kubectl -n pantahub delete pvc --all (or delete the namespace).
Things to know
- One release per namespace, and the service names (
mongo,kafka,base, …) are fixed — entrypoints and connector configs reference them. - PVCs stuck
Pendingmeans no default StorageClass — setglobal.storageClassor install one. - Elasticsearch needs
vm.max_map_count=262144; a privileged initContainer sets it (disable withelasticsearch.sysctlInit.enabled=falseand set it on the node yourself). - The chart bakes in several Kubernetes-specific fixes found by running it —
enableServiceLinks: false(Confluent images crash on injected*_PORTvars), base's bakedenv.defaultneutralized so ConfigMap env wins, headless mongo Services withpublishNotReadyAddresses— the chart README documents them; don't undo them. - The compose nginx mutual-TLS front is not translated — bring your own ingress config if you need client-certificate forwarding (TLS onboarding) on Kubernetes.
The full troubleshooting table lives in charts/pantahub/GUIDE.md.