# Scale the whole chart down without uninstalling it: scaleDown: true renders # every Deployment/StatefulSet with replicas: 0 (and suspends CronJobs) and # takes precedence over any per-workload replicas value. PVCs, Secrets and # Services stay in place; scaleDown: false brings the workloads back up. scaleDown: false # Replica count for this workload; 0 is allowed and scales it down. # The chart-global scaleDown flag takes precedence. replicas: 1 # This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ service: # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types type: ClusterIP # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports port: 80 # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ ingress: # MUTUALLY EXCLUSIVE WITH httpRoute.enabled - the render aborts when both are # true, and the message names both value paths. enabled: false # Ingress class; set to "" to omit ingressClassName from the rendered Ingress. # NOT READ IN GATEWAY MODE: the class is a property of the Gateway there, and # the Gateway belongs to the platform. className: nginx # NOT READ IN GATEWAY MODE either, and this is the one to be aware of: the # Gateway API has no annotation channel for controller behaviour, so # everything put here is simply gone in that mode. This chart sets nothing # itself, and the installation this repository serves does not deploy # homeassistant at all (checked 2026-10-12), so there is no operator-supplied # annotation here today that the switch would drop - unlike its siblings in # the same sweep. That is an absence of evidence about this installation, not # a guarantee about yours: whatever you put here disappears in Gateway mode. annotations: {} # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" # THE PUBLIC NAMES OF THIS RELEASE, AND READ IN BOTH MODES. # # This chart is the documented ingress exception (README): it keeps upstream's # flexible host list rather than the repository's required # domain/clusterIssuer pair, and that exception stays. The consequence for # Gitea #114 is that httpRoute has NO hostnames key - a chart-global hostname # list could not say which host entry, and therefore which set of paths, it # belonged to. So this list is where the hostnames live in BOTH modes, and in # Gateway mode the chart renders ONE HTTPRoute PER ENTRY, with one rule per # path of that entry. # # pathType IN GATEWAY MODE, because the default below is the awkward value. # Ingress has Exact, Prefix and ImplementationSpecific; the Gateway API has # Exact, PathPrefix and RegularExpression. Exact and Prefix map cleanly. # ImplementationSpecific means "ask the controller" and has NO counterpart, # so: # - on the path "/" it is rendered as PathPrefix (every controller treats a # root ImplementationSpecific path as a prefix match, so the default # below works in Gateway mode unchanged); # - on ANY OTHER path the render ABORTS and asks you to say which you mean. # In ingress-nginx an ImplementationSpecific sub-path is a REGEX and # PathPrefix is not one, so mapping it silently would change how the path # matches while the render stayed green. # RegularExpression is deliberately not offered: its support level is # Implementation-specific and would bind this chart to one Gateway # implementation. hosts: - host: chart-example.local paths: - path: / pathType: ImplementationSpecific # NOT READ IN GATEWAY MODE: the certificate sits on the Gateway's listener. tls: [] # - secretName: chart-example-tls # hosts: # - chart-example.local # THE GATEWAY-API ALTERNATIVE TO THE INGRESS (Gitea #114). # # Mutually exclusive with ingress.enabled - the render aborts when both are # true. The chart renders ONLY HTTPRoutes with parentRefs: no Gateway, no # class, no Certificate, and no implementation-specific policy object. Class # and certificate sit on the Gateway and its listeners and belong to the # platform (cluster-config), which is what keeps the Gateway implementation # replaceable without touching this chart again. # # TWO KEYS ONLY, and the missing third one is deliberate: there is no # httpRoute.hostnames here, because this chart has no ingress.domain either. # The hostnames and the paths come from ingress.hosts above - see the comment # there, including the pathType mapping. This is the freesailarr shape from # group 2 of the sweep, for the same reason. # # ONE HTTPRoute PER ENTRY of ingress.hosts, named # -homeassistant-httproute for the first and ...-httproute- for # the rest. REORDERING ingress.hosts RENAMES ROUTES and so deletes and # recreates them on the next upgrade instead of editing them - harmless, # because a route holds no state and no certificate, but worth knowing before # it looks like a bug. # # THE GATEWAY-API CRDs MUST BE PRESENT. The chart cannot detect them # (.Capabilities.APIVersions is unreliable at template time) and an HTTPRoute # without them fails at install, so this is a value and not a guess. httpRoute: enabled: false # The Gateway(s) EVERY route of this release attaches to - a platform object, # usually in another namespace, whose listener must allow this namespace in # allowedRoutes. Entries are the Gateway API's ParentReference (name, and # optionally namespace, sectionName, port, group, kind), passed through # unchanged: # # parentRefs: # - name: public # namespace: gateway # sectionName: https # # REQUIRED while httpRoute.enabled is true - the render aborts on an empty # list, because a route without a parent is created, is valid and routes # nothing, with no event to say so. The same list is used for every route # this chart renders; the hosts differ, the Gateway does not. parentRefs: [] # Documented deviation from the repo-wide hardening standard: the official # Home Assistant container must start as root — it boots via the s6-overlay # init system, which performs its setup as uid 0 (the image supports no # non-root user), so runAsNonRoot/runAsUser are deliberately not set. # Everything else is hardened: no privilege escalation, all capabilities # dropped and a read-only root filesystem with writable emptyDirs for # /tmp and /run (s6-overlay state). NET_RAW is added back because Home # Assistant's device discovery (DHCP watcher, ping/arp integrations) uses # raw sockets and logs "Operation not permitted" without it. securityContext: pod: {} container: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL add: - NET_RAW resources: # Limits are optional: memory and ephemeral-storage limits default to # limitFactor x the request, an explicitly set limit always wins, and a # CPU limit is only set when configured explicitly under "limits". limitFactor: 3 requests: cpu: 0.2 memory: 512Mi ephemeralStorage: 128Mi # This is to setup the liveness, readiness and startup probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ livenessProbe: httpGet: path: / port: http periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: / port: http periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # The startup probe gates liveness/readiness. Home Assistant can take a while to # start up, so grant a generous budget: 10s * 30 = 300s. startupProbe: httpGet: path: / port: http periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 30 # Extra environment variables, appended to the ones the chart always sets. # Values are rendered through tpl; value, secretKeyRef and configMapKeyRef # forms are supported. env: [] # Additional volumes on the output Deployment definition. volumes: [] # - name: foo # secret: # secretName: mysecret # optional: false # Additional volumeMounts on the output Deployment definition. volumeMounts: [] # - name: foo # mountPath: "/etc/foo" # readOnly: true nodeSelector: {} tolerations: [] affinity: {} core: timezone: "UTC" storage: size: 5Gi storageClass: "default" # Must include the following keys: # - config # - http-config # - recorder-config # # Changing the op:// path below IS covered: the StatefulSet carries a # checksum/secret-ref annotation over the rendered OnePasswordItem, so pointing # this value at a different vault item restarts the pod. # # Known limitation (#82): changing the CONTENT of that item in the vault does # NOT restart Home Assistant. The operator updates the Kubernetes Secret, but # the running pod keeps the old files - they are mounted with subPath, which the # kubelet never refreshes, and Home Assistant reads its configuration only at # start. The change then takes effect at some unrelated later restart, possibly # months afterwards, and a broken value surfaces long after the edit that caused # it. That is especially likely for this release, which is currently kept at # zero replicas via scaleDown: whoever brings it back up gets whatever the vault # holds at that moment. # # The checksum/config mechanism the other charts use cannot close this gap: # Helm never sees the content (the operator fills the Secret in-cluster after # rendering), so there is nothing to hash. The operator's own # "operator.1password.io/auto-restart" annotation does not close it either - it # only ever restarts Deployments, never StatefulSets. Verified against # onepassword-operator 1.12.0: pkg/onepassword/secret_update_handler.go lists # exactly one workload type (appsv1.DeploymentList), and the PR adding # StatefulSets is still open. Setting the annotation here would look like a fix # and do nothing, so this chart deliberately does not set it. # # After changing the item, restart Home Assistant by hand: # kubectl rollout restart statefulset -homeassistant-sfs secrets: configSecretRef: null