Skip to content

Heimdall

Application dashboard for organizing and launching self-hosted services. Heimdall provides a clean, customizable homepage where you can pin any web application as a tile, complete with icons, colors, and live status indicators. All configuration is stored in a SQLite database on a persistent volume — no external database required.

Key Features

  • Application tiles — pin any URL as an app tile with custom icons and colors
  • Enhanced apps — native integrations for popular self-hosted apps (stats, health)
  • LinuxServer.io image — PUID/PGID file ownership control for PVC compatibility
  • Persistent storage — SQLite database and all configuration in /config
  • S3 backup — scheduled archive of the full /config directory to S3-compatible storage
  • Ingress support — configurable TLS via cert-manager

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install heimdall helmforge/heimdall

OCI registry:

helm install heimdall oci://ghcr.io/helmforgedev/helm/heimdall

Deployment Examples

# values.yaml — Heimdall with Traefik ingress
heimdall:
  timezone: 'America/Sao_Paulo'
  puid: 1000
  pgid: 1000

persistence:
  enabled: true
  size: 1Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: dashboard.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Heimdall with daily S3 backup
# Backup covers the full /config directory including SQLite database and all tiles
heimdall:
  timezone: 'America/Sao_Paulo'

persistence:
  enabled: true
  size: 1Gi

backup:
  enabled: true
  schedule: '0 3 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: my-heimdall-backups
    prefix: heimdall
    existingSecret: heimdall-s3-credentials

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: dashboard.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Production Heimdall with TLS and backup
heimdall:
  timezone: 'America/Sao_Paulo'
  puid: 1000
  pgid: 1000

persistence:
  enabled: true
  size: 1Gi

backup:
  enabled: true
  schedule: '0 3 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: my-heimdall-backups
    existingSecret: heimdall-s3-credentials

resources:
  requests:
    cpu: 50m
    memory: 128Mi
  limits:
    memory: 256Mi

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: dashboard.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: heimdall-tls
      hosts:
        - dashboard.example.com

Configuration Reference

Core

ParameterTypeDefaultDescription
nameOverridestring""Override the chart name.
fullnameOverridestring""Override the full release name.
commonLabelsobject{}Extra labels added to all resources.

Image

ParameterTypeDefaultDescription
image.repositorystringdocker.io/linuxserver/heimdallHeimdall container image.
image.tagstring"2.7.6"Image tag.
image.pullPolicystringIfNotPresentImage pull policy.
imagePullSecretsarray[]Pull secrets for private registries.

Heimdall Configuration

ParameterTypeDefaultDescription
heimdall.puidinteger1000User ID used by the container process for file ownership in /config.
heimdall.pgidinteger1000Group ID used by the container process for file ownership in /config.
heimdall.timezonestringUTCContainer timezone for display purposes.
heimdall.extraEnvarray[]Extra environment variables for advanced configuration.
PUID/PGID must match the PVC file ownership

The LinuxServer.io image runs as the user and group defined by heimdall.puid and heimdall.pgid. If the PVC is created with a different owner (e.g. root, UID 0), the container will fail to write to /config and the application will not start correctly. The default 1000:1000 works with most dynamic provisioners. If you encounter permission errors in logs, verify the PVC ownership and adjust puid/pgid accordingly.

Persistence

Heimdall stores all configuration, application tiles, and the SQLite database in the /config directory.

ParameterTypeDefaultDescription
persistence.enabledbooleantrueEnable a PVC for /config (SQLite database and all tile config).
persistence.sizestring1GiPVC size.
persistence.storageClassstring""StorageClass for the PVC.
persistence.accessModestringReadWriteOncePVC access mode.
persistence.existingClaimstring""Use an existing PVC instead of creating one.
persistence.annotationsobject{}Annotations for the PVC.

Backup

The S3 backup CronJob archives the full /config directory, which includes the SQLite database, all configured application tiles, custom icons, and settings. This is a complete backup of the Heimdall instance.

ParameterTypeDefaultDescription
backup.enabledbooleanfalseEnable scheduled S3 backup CronJob.
backup.schedulestring"0 3 * * *"Cron schedule for backups.
backup.suspendbooleanfalseSuspend the CronJob without deleting it.
backup.concurrencyPolicystringForbidCronJob concurrency policy.
backup.successfulJobsHistoryLimitinteger3Number of successful Job records to keep.
backup.failedJobsHistoryLimitinteger3Number of failed Job records to keep.
backup.backoffLimitinteger1Job retry limit.
backup.archivePrefixstringheimdallPrefix for backup archive filenames.
backup.images.archiverstringdocker.io/library/alpine:3.22Image used for tar archive.
backup.images.uploaderstringdocker.io/helmforge/mc:1.0.0Image used for S3 upload.
backup.resourcesobject{}Resources for backup containers.
backup.s3.endpointstring""S3-compatible endpoint URL.
backup.s3.bucketstring""Target bucket name.
backup.s3.prefixstringheimdallKey prefix within the bucket.
backup.s3.createBucketIfNotExistsbooleantrueCreate the bucket automatically if it does not exist.
backup.s3.existingSecretstring""Existing secret containing S3 access and secret keys.
backup.s3.existingSecretAccessKeyKeystringaccess-keyKey in the existing secret for the S3 access key.
backup.s3.existingSecretSecretKeyKeystringsecret-keyKey in the existing secret for the S3 secret key.
backup.s3.accessKeystring""Inline S3 access key (ignored when existingSecret is set).
backup.s3.secretKeystring""Inline S3 secret key (ignored when existingSecret is set).

Service

ParameterTypeDefaultDescription
service.typestringClusterIPKubernetes service type.
service.portinteger80Service port exposed to the cluster.
service.annotationsobject{}Annotations for the Service.

Ingress

ingressClassName must be set explicitly

Unlike most HelmForge charts, ingress.ingressClassName defaults to an empty string. You must set it explicitly to your cluster’s ingress controller (e.g. traefik, nginx) for the Ingress resource to be picked up.

ParameterTypeDefaultDescription
ingress.enabledbooleanfalseEnable an Ingress resource.
ingress.ingressClassNamestring""Ingress class name. Must be set explicitly.
ingress.annotationsobject{}Annotations for the Ingress (e.g. cert-manager).
ingress.hostsarray[]Ingress host and path rules.
ingress.tlsarray[]TLS configuration (secret name and hosts).

Probes

Probes use the / root path.

ParameterTypeDefaultDescription
startupProbe.enabledbooleantrueEnable startup probe.
startupProbe.initialDelaySecondsinteger5Startup probe initial delay.
startupProbe.periodSecondsinteger5Startup probe period.
startupProbe.timeoutSecondsinteger3Startup probe timeout.
startupProbe.failureThresholdinteger12Startup probe failure threshold.
livenessProbe.enabledbooleantrueEnable liveness probe.
livenessProbe.initialDelaySecondsinteger0Liveness probe initial delay.
livenessProbe.periodSecondsinteger20Liveness probe period.
livenessProbe.timeoutSecondsinteger5Liveness probe timeout.
livenessProbe.failureThresholdinteger3Liveness probe failure threshold.
readinessProbe.enabledbooleantrueEnable readiness probe.
readinessProbe.initialDelaySecondsinteger0Readiness probe initial delay.
readinessProbe.periodSecondsinteger10Readiness probe period.
readinessProbe.timeoutSecondsinteger5Readiness probe timeout.
readinessProbe.failureThresholdinteger3Readiness probe failure threshold.

Resources and Security

ParameterTypeDefaultDescription
resourcesobject{}CPU and memory requests and limits.
podSecurityContextobject{}Pod-level security context.
securityContextobject{}Container-level security context.

Service Account

ParameterTypeDefaultDescription
serviceAccount.createbooleanfalseCreate a dedicated ServiceAccount.
serviceAccount.namestring""Override the ServiceAccount name.
serviceAccount.annotationsobject{}Annotations for the ServiceAccount.

Scheduling

ParameterTypeDefaultDescription
nodeSelectorobject{}Node selector for scheduling.
tolerationsarray[]Tolerations for scheduling.
affinityobject{}Affinity rules.
topologySpreadConstraintsarray[]Topology spread constraints.
priorityClassNamestring""PriorityClass for the pod.
terminationGracePeriodSecondsinteger30Termination grace period.
podLabelsobject{}Extra labels for the pod.
podAnnotationsobject{}Extra annotations for the pod.

Extra

ParameterTypeDefaultDescription
extraVolumesarray[]Extra volumes to attach to the pod.
extraVolumeMountsarray[]Extra volume mounts for the container.
extraManifestsarray[]Extra Kubernetes manifests deployed alongside the chart.

Common Issues

All dashboard tiles lost after pod restart without persistence

All configured application tiles, icons, and settings are stored in the SQLite database inside /config. If persistence.enabled is false or the PVC is not correctly bound, the entire dashboard configuration is lost when the pod restarts. Always verify persistence.enabled: true and that the PVC is in Bound state before configuring your dashboard.

Enhanced app integrations require API tokens

Heimdall supports enhanced tiles for apps like Sonarr, Radarr, Pi-hole, and others that display live statistics. These require an API token or key configured in the tile settings within the Heimdall UI. Check the Heimdall supported apps list for available integrations.

More Information