Home Assistant¶
Home Assistant runs the house. Upstream publishes no Helm chart and the community ones are repackagers, so this is a Deployment, a Service, a PVC and a ConfigMap around the official image, per Conventions → Official upstream sources only.
At a glance¶
| URL | home.k8s.wlkr.ch |
| Authentication | Authentik proxy outpost, in front of Home Assistant's own login |
| Storage | 5Gi rook-ceph-block PVC for /config |
| Database | CloudNativePG Cluster home-assistant-db, for the recorder |
| Files | home-assistant/ |
State¶
| State | Where | Rebuildable? |
|---|---|---|
Registries, users, tokens, integration config (/config/.storage) |
The home-assistant-config PVC |
No. Losing it means re-pairing every device |
| History and long-term statistics | PostgreSQL, via CloudNativePG | Only from a backup |
configuration.yaml |
A ConfigMap, in Git | Yes |
Configuration¶
| Setting | Why |
|---|---|
| Plain manifests, no chart | Home Assistant is one stateful process with one volume and one port; a Deployment is less work than auditing a third-party chart on every bump |
| Recorder on CloudNativePG, not SQLite | SQLite's locking on a network block device is the usual cause of a Home Assistant that feels slow. purge_keep_days is raised because the default of 10 is shorter than the moment you look for a graph. See the contract |
secrets.yaml written by an init container on every start |
Home Assistant has no !env_var tag, so the database URL reaches configuration.yaml through !secret, from CloudNativePG's Secret. Anything added to that file by hand is lost at the next restart; secrets belong in OpenBao |
use_x_forwarded_for with the pod CIDR in trusted_proxies |
Requests arrive from Cilium's Envoy and the outpost. Without it every request has one source address, so the ban list and rate limiting count the household as one user |
HTTPRoute targets authentik-server, not the app |
The outpost authenticates and forwards to home-assistant.home-assistant.svc:8123. Home Assistant is the one proxied app with a login of its own, so browser users log in twice: defence in depth, not SSO |
CiliumNetworkPolicy admits 8123 from the authentik namespace only |
No fromEntities: ingress, so a request straight from the Gateway cannot skip the outpost |
Policy admits cnpg-system to the database pod on 8000, at sync wave -2 |
The operator polls the instance manager there; without the rule the Cluster never goes Healthy and the sync deadlocks. See Sync stuck on the database |
Usage¶
The ConfigMap is mounted over /config/configuration.yaml and read once at
startup, so a merged change does nothing until the pod restarts:
The UI's own restart button does the same from inside.
Health check¶
The database should report Cluster in healthy state. A pod stuck in Init
is waiting on it: the init container cannot write secrets.yaml until
CloudNativePG has produced the Secret.
Pitfalls¶
The API is not behind Authentik
The companion apps and every webhook authenticate with a long-lived token and cannot complete an interactive login, so skip_path_regex on the provider lets /api/, /auth/token and the external-auth callback through. Home Assistant's own accounts are the only thing guarding those paths. Revoking an Authentik account does not revoke a Home Assistant token; do that under Settings → People.
- No local device discovery. mDNS and SSDP need host networking, which
needs a
privilegednamespace. Add devices by IP, or through an integration that does not rely on broadcast. - No USB devices. A Zigbee or Z-Wave stick pins the pod to one machine. Use a network-attached coordinator instead.
- The cluster is now a dependency of the lights. A Ceph rebalance that pauses I/O pauses Home Assistant with it.