Files

AdGuard Home Helm Chart

A Helm chart for deploying AdGuard Home, a network-wide DNS ad and tracker blocker, on Kubernetes.

Introduction

This chart deploys AdGuard Home on a Kubernetes cluster using the Helm package manager. AdGuard Home is a self-hosted DNS server that blocks ads and trackers for every device on your network, and can also act as a DHCP server, DNS-over-TLS/HTTPS/QUIC resolver, and DNSCrypt server.

Source code: https://github.com/rtomik/helm-charts/tree/main/charts/adguard-home

Prerequisites

  • Kubernetes 1.19+
  • Helm 3.0+
  • PV provisioner support (if persistence is needed)
  • A way to route real LAN clients to the DNS Service (LoadBalancer/MetalLB, NodePort, or hostNetwork: true) if you intend to use it as your network's resolver

Installing the Chart

helm repo add rtomik https://rtomik.github.io/helm-charts
helm install adguard-home rtomik/adguard-home

Uninstalling the Chart

helm uninstall adguard-home

Configuration Examples

Minimal Installation (admin UI only, no DNS exposed on the LAN)

persistence:
  work:
    enabled: true
    size: 2Gi
  conf:
    enabled: true
    size: 100Mi

ingress:
  enabled: true
  hosts:
    - host: adguard.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - hosts:
        - adguard.example.com
      secretName: adguard-tls

Expose DNS to the LAN via LoadBalancer (e.g. MetalLB)

service:
  type: LoadBalancer
  loadBalancerIP: 192.168.1.53
  annotations:
    metallb.universe.tf/allow-shared-ip: adguard-home

hostNetwork: true  # preserves real client IPs in the query log/filters

Enable DNS-over-TLS / DNS-over-QUIC and DNS-over-HTTPS

ports:
  dot:
    enabled: true
  https:
    enabled: true

Enable the DHCP server

DHCP requires hostNetwork: true - it cannot be proxied through a ClusterIP/LoadBalancer Service.

hostNetwork: true
ports:
  dhcp:
    enabled: true

Use an existing PVC

persistence:
  work:
    existingClaim: "adguard-work-pvc"
  conf:
    existingClaim: "adguard-conf-pvc"

Parameters

Global Parameters

Name Description Default
nameOverride Override the release name ""
fullnameOverride Fully override the release name ""

Image Parameters

Name Description Default
image.repository AdGuard Home image repository adguard/adguardhome
image.tag Image tag v0.107.79
image.pullPolicy Image pull policy IfNotPresent
imagePullSecrets Image pull secrets []

Deployment Parameters

Name Description Default
replicaCount Number of replicas (keep at 1 - AdGuard Home is not multi-writer safe) 1
revisionHistoryLimit Revisions to retain 3
podSecurityContext.runAsNonRoot Run as non-root true
podSecurityContext.runAsUser User ID 1000
podSecurityContext.runAsGroup Group ID 1000
podSecurityContext.fsGroup Filesystem group ID 1000
containerSecurityContext.capabilities.add Capabilities added (NET_BIND_SERVICE for ports < 1024) ["NET_BIND_SERVICE"]
hostNetwork Use host networking (required for DHCP, recommended for accurate client IPs) false
nodeSelector Node selector {}
tolerations Tolerations []
affinity Affinity rules {}

Ports Parameters

Name Description Default
ports.web.port Admin dashboard / setup wizard 3000
ports.dns.port Plain DNS (TCP+UDP) 53
ports.dot.enabled Enable DNS-over-TLS / DNS-over-QUIC false
ports.dot.port DoT/DoQ port (TCP+UDP) 853
ports.https.enabled Enable DNS-over-HTTPS / HTTPS admin dashboard false
ports.https.port HTTPS port (TCP+UDP) 443
ports.dnscrypt.enabled Enable DNSCrypt false
ports.dnscrypt.port DNSCrypt port (TCP+UDP) 5443
ports.dhcp.enabled Enable DHCP server (67/68 UDP, requires hostNetwork: true) false
ports.pprof.enabled Enable the debug pprof API false
ports.pprof.port pprof port 6060

Service Parameters

Name Description Default
service.type Service type ClusterIP
service.annotations Service annotations {}
service.loadBalancerIP Static LoadBalancer IP (e.g. for MetalLB) ""

Ingress Parameters

Name Description Default
ingress.enabled Enable ingress (routes to the admin dashboard only) false
ingress.className Ingress class name ""
ingress.annotations Ingress annotations See values.yaml
ingress.hosts Ingress hosts See values.yaml
ingress.tls TLS configuration See values.yaml

Persistence Parameters

Name Description Default
persistence.work.enabled Persist /opt/adguardhome/work (query log, filter cache, stats) true
persistence.work.existingClaim Use an existing PVC instead of creating one ""
persistence.work.storageClass Storage class ""
persistence.work.accessMode Access mode ReadWriteOnce
persistence.work.size PVC size 1Gi
persistence.conf.enabled Persist /opt/adguardhome/conf (AdGuardHome.yaml) true
persistence.conf.existingClaim Use an existing PVC instead of creating one ""
persistence.conf.storageClass Storage class ""
persistence.conf.accessMode Access mode ReadWriteOnce
persistence.conf.size PVC size 100Mi

Resource Parameters

Name Description Default
resources Resource limits and requests {}

Health Check Parameters

Name Description Default
probes.liveness.enabled Enable liveness probe (TCP check on the admin web port) true
probes.liveness.initialDelaySeconds Liveness initial delay 15
probes.liveness.periodSeconds Liveness period 30
probes.readiness.enabled Enable readiness probe (TCP check on the admin web port) true
probes.readiness.initialDelaySeconds Readiness initial delay 5
probes.readiness.periodSeconds Readiness period 10

Other Parameters

Name Description Default
extraEnv Additional environment variables []
extraVolumeMounts Additional volume mounts []
extraVolumes Additional volumes []

Notes

  • AdGuard Home has no supported way to bootstrap its admin account or DNS settings via environment variables - complete the setup wizard once at http://<web-service>:3000 after the first install. The resulting AdGuardHome.yaml is written to the conf PVC, so it survives pod restarts/upgrades.
  • Because AdGuard Home stores state on disk and isn't multi-writer safe, do not scale replicaCount beyond 1.
  • If you plan to use this as your network's DNS resolver, prefer hostNetwork: true (or a LoadBalancer Service with externalTrafficPolicy: Local) so AdGuard Home sees real client IPs rather than a single Service/NAT IP for every device.

Troubleshooting

  • Clients all show up as the same IP / filters by client don't work: enable hostNetwork or use externalTrafficPolicy: Local on a LoadBalancer Service.
  • DHCP doesn't hand out leases: DHCP only works with hostNetwork: true.
  • Setup wizard settings don't persist: verify persistence.conf.enabled is true and the PVC is bound.
kubectl logs -f deployment/adguard-home
kubectl describe pod -l app.kubernetes.io/name=adguard-home