Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Server & Netzwerk 02.06.2026 · 10 min Lesezeit

Pi-hole mit Docker: netzwerkweiter Werbe- und Tracker-Blocker

Pi-hole mit Docker Compose betreiben und Werbung sowie Tracker im ganzen Netz per DNS blockieren: compose.yaml, Port-53-Konflikt, Web-Admin, Blocklisten, Update und Backup. Getestet mit Pi-hole 2026.09.0.

Geprüft am 29.09.2026 · für pi-hole 2026.09.0

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Kleiner Rechner und Router auf einem Holzsideboard, daneben ein Metallsieb als Sinnbild für DNS-Filterung im Heimnetz

Pi-hole blockiert Werbe- und Tracker-Domains auf DNS-Ebene und schützt damit alle Geräte im Netz, auch Smart-TVs und IoT-Geräte, ohne Browser-Plugins. Sie betreiben Pi-hole als zentralen DNS-Server und stellen Router und Clients darauf um. Anfragen an bekannte Werbe-, Tracking- und Malware-Domains beantwortet Pi-hole dann mit einer leeren Adresse. Diese Anleitung zeigt die Einrichtung auf Debian 12 oder Ubuntu 24.04 mit Docker Compose: Port 53 gegenüber systemd-resolved freigeben, Persistenz, Web-Admin, Blocklisten, lokale DNS-Einträge, Update und Backup. Getestet mit dem Image pihole/pihole:2026.09.0 (Core 6.4.3, FTL 6.7.1).

Voraussetzungen

Pi-hole ist sehr sparsam und läuft auch auf einem Raspberry Pi. Eine GPU ist nicht nötig. Sie brauchen einen kleinen, dauerhaft laufenden Server im LAN.

  1. Server: Linux mit Docker und Docker Compose (Debian 12 oder Ubuntu 24.04). Weitere Software ist nicht nötig.
  2. RAM: 512 MB genügen. Im Test belegte der Container nach dem Start rund 20 MB.
  3. CPU: 1 Kern, x86-64 oder ARM (arm64, armv7).
  4. Speicher: 1 GB frei für Image und Daten, mehr nur für lange Query-Historien.
  5. Netzwerk: idealerweise eine feste IP-Adresse für den Server, denn Router und Clients zeigen später dauerhaft auf diese Adresse als DNS-Server.
  6. Optional: eine Domain mit Reverse-Proxy und HTTPS, falls Sie den Web-Admin von außen erreichen wollen.

Fehlt Docker noch, lesen Sie vorab unsere Grundlagen zu Docker Compose und Stacks.

Schritt 1: Port 53 freigeben (systemd-resolved)

Auf Ubuntu 24.04 (und Debian 12 mit aktiviertem systemd-resolved) belegt der lokale Stub-Resolver Port 53. Pi-hole scheitert dann mit address already in use. Prüfen Sie zuerst mit sudo ss -tulpn | grep ':53 ', ob der Port belegt ist. Wenn ja, deaktivieren Sie den Stub-Listener vor dem Container-Start per Drop-in-Datei:

sudo sh -c 'mkdir -p /etc/systemd/resolved.conf.d && printf "[Resolve]\nDNSStubListener=no\n" | tee /etc/systemd/resolved.conf.d/no-stub.conf'

Damit der Host selbst weiter Namen auflöst, verlinken Sie /etc/resolv.conf auf die von resolved erzeugte Datei und starten den Dienst neu:

sudo sh -c 'rm -f /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
sudo systemctl restart systemd-resolved
sudo ss -tulpn | grep ':53'

Verifizieren: Der Befehl oben gibt keine Zeile mit Port 53 mehr aus, und getent hosts debian.org liefert auf dem Host weiterhin eine IP-Adresse.

Schritt 2: Verzeichnis und compose.yaml anlegen

Legen Sie ein Projektverzeichnis an. Das Volume legt Docker relativ zu diesem Ordner an:

mkdir -p /opt/pihole
cd /opt/pihole

Die folgende compose.yaml entspricht der offiziellen Vorlage. Passen Sie Passwort und Zeitzone an:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest   # alternativ fixes Tag, z. B. pihole/pihole:2026.09.0
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      - "443:443/tcp"          # optional, HTTPS Web-UI
    environment:
      TZ: 'Europe/Berlin'
      FTLCONF_webserver_api_password: 'BITTE-AENDERN'
      FTLCONF_dns_listeningMode: 'ALL'
    volumes:
      - './etc-pihole:/etc/pihole'
    cap_add:
      - NET_ADMIN
      - SYS_TIME
      - SYS_NICE
    restart: unless-stopped

Die wichtigsten Punkte:

  1. image: pihole/pihole:latest zieht die neueste Stable-Version. Für reproduzierbare Updates schreiben Sie ein datumsbasiertes Tag fest, etwa pihole/pihole:2026.09.0 (Stand September 2026). nightly ist der Entwicklungszweig.
  2. ports: 53/tcp und 53/udp sind für DNS zwingend, 80 für den Web-Admin. 443 ist optional für die HTTPS-Web-UI. Belegt bereits ein Reverse-Proxy Port 80/443, mappen Sie den Web-Admin auf einen freien Port, etwa "8080:80/tcp". Für DHCP oder NTP über Pi-hole ergänzen Sie 67:67/udp bzw. 123:123/udp.
  3. volumes: ./etc-pihole:/etc/pihole enthält Konfiguration, Datenbanken und Adlists. Ohne dieses Volume gehen sie bei jeder Neuerstellung verloren. Das früher übliche ./etc-dnsmasq.d ist in Pi-hole v6 nicht mehr nötig.
  4. FTLCONF_webserver_api_password: setzt das Admin-Passwort (Pi-hole v6). Ohne die Variable vergibt FTL ein zufälliges Passwort und schreibt es ins Log. Solange die Variable gesetzt ist, lässt sich das Passwort nur über sie ändern.
  5. FTLCONF_dns_listeningMode: 'ALL': im Docker-Default-Bridge-Netz zwingend, sonst beantwortet Pi-hole Anfragen Ihrer Clients nicht, weil sie aus Sicht des Containers aus einem fremden Subnetz kommen.
  6. cap_add: NET_ADMIN (nur für den DHCP-Server), SYS_TIME (nur, wenn Pi-hole als NTP-Client die Host-Uhr stellen soll) und SYS_NICE (CPU-Priorität). Nicht benötigte Capabilities können Sie weglassen. --privileged ist nicht nötig.

Verifizieren: docker compose config -q im Projektordner gibt keine Fehlermeldung aus.

Schritt 3: Container starten und Passwort prüfen

Starten Sie den Stack im Hintergrund:

docker compose up -d

Beim ersten Start legt Pi-hole die Datenbanken an und lädt die Standard-Blockliste (StevenBlack-Hosts). Den Fortschritt zeigen die Logs:

docker compose logs -f pihole
docker compose ps

Haben Sie FTLCONF_webserver_api_password nicht gesetzt, steht das zufällige Passwort im Log. Sie ändern es dann ohne Neuerstellung des Containers:

docker exec -it pihole pihole setpassword 'NEUES-PASSWORT'

Ist die Variable gesetzt, bricht dieser Befehl mit webserver.api.password set by environment variable ab. Ändern Sie dann den Wert in der compose.yaml und führen Sie docker compose up -d aus.

Verifizieren: docker compose ps zeigt Up (healthy) nach etwa einer Minute. docker exec pihole pihole version gibt die Versionen von Core, Web und FTL aus.

Schritt 4: Web-Admin aufrufen und einrichten

Rufen Sie den Web-Admin unter http://SERVER-IP/admin auf, mit Port 443 alternativ unter https://SERVER-IP/admin (selbstsigniertes Zertifikat). Melden Sie sich mit dem Passwort aus FTLCONF_webserver_api_password an.

Das Dashboard zeigt DNS-Anfragen, Anteil geblockter Domains und die aktivsten Clients. Solange keine Clients auf Pi-hole zeigen, bleibt es leer, das ändert sich in Schritt 6. Wichtige Bereiche:

  1. Settings -> DNS: hier legen Sie die Upstream-Resolver fest (z. B. Quad9, Cloudflare oder ein eigener Resolver).
  2. Lists: Verwaltung der Blocklisten (Adlists).
  3. Settings -> Local DNS Records / Local CNAME Records: eigene Namen im LAN auflösen.
  4. Query Log: live nachvollziehen, welche Domains angefragt und geblockt werden.

Verifizieren: curl -sI http://SERVER-IP/admin/ liefert 302 Found mit Location: /admin/login, die Anmeldung im Browser öffnet das Dashboard.

Schritt 5: Blocklisten und lokale DNS-Einträge pflegen

Pi-hole bringt von Haus aus die StevenBlack-Hosts-Liste mit. Weitere Listen fügen Sie im Web-Admin unter Lists hinzu: Adlist-URL eintragen, speichern und anschließend die Gravity-Datenbank neu aufbauen. Das geht per Button Update Gravity in der UI oder auf der Kommandozeile:

docker exec -it pihole pihole -g

Die Listen aktualisiert ein Cron-Job im Container wöchentlich. Manuell ist der Lauf nur nach dem Hinzufügen einer Liste nötig. Wenige gepflegte Listen verursachen weniger Fehlblockaden (false positives) als viele.

Mit lokalen DNS-Einträgen lösen Sie eigene Hostnamen im LAN auf. In Pi-hole v6 finden Sie das unter Settings -> Local DNS Records (A-Records, z. B. nas.heimnetz.lan auf eine interne IP) und Local CNAME Records (Aliase auf bestehende Namen).

Verifizieren: docker exec pihole pihole -g endet mit [✓] Done., und ein angelegter lokaler Eintrag wird per nslookup nas.heimnetz.lan SERVER-IP mit der hinterlegten IP beantwortet.

Schritt 6: Router und Clients auf Pi-hole zeigen

Ohne diesen Schritt blockiert Pi-hole nichts: Ihre Geräte müssen Pi-hole als DNS-Server nutzen. Am einfachsten verteilen Sie die Pi-hole-IP zentral über den Router.

  1. Empfohlen, über den Router: Tragen Sie im DHCP-Bereich des Routers die Pi-hole-IP als lokalen DNS-Server ein. Alle Clients beziehen die Adresse dann automatisch. Bei manchen Routern (z. B. FRITZ!Box) hinterlegen Sie den DNS-Server in den Internet- bzw. DNS-Einstellungen.
  2. Alternativ pro Gerät: Setzen Sie auf einzelnen Clients die Pi-hole-IP als bevorzugten DNS-Server.

Tragen Sie nur die Pi-hole-IP ein. Ein zweiter, öffentlicher DNS-Server als Fallback wird von Clients mitbenutzt und umgeht Pi-hole. Geräte mit fest eingetragenem DNS und Browser mit DNS-over-HTTPS (DoH) umgehen Pi-hole ebenfalls. Funktionstest von einem Client aus:

nslookup doubleclick.net SERVER-IP

Verifizieren: Für die geblockte Domain antwortet Pi-hole mit 0.0.0.0, nslookup example.com SERVER-IP liefert echte Adressen, und im Query Log erscheint der Client.

Schritt 7: Reverse-Proxy und HTTPS (Sicherheit)

Der Web-Admin gehört nicht ungeschützt ins Internet, und Pi-hole darf kein offener Resolver sein. Betreiben Sie Pi-hole nur im LAN. Soll der Web-Admin extern erreichbar sein, stellen Sie einen Reverse-Proxy mit TLS und Authentifizierung davor. Port 53 geben Sie nie nach außen frei.

Traefik mit automatischem Let's-Encrypt-Zertifikat beschreibt unsere Anleitung Traefik als Docker-Reverse-Proxy mit HTTPS einrichten. Für reinen Fernzugriff ist ein VPN meist einfacher und sicherer, siehe WireGuard-VPN für Homeoffice und Standortanbindung einrichten. Der Web-Admin bleibt dann im internen Netz.

Verifizieren: Von einem Gerät außerhalb Ihres Netzes (z. B. Smartphone im Mobilfunk) beantwortet nslookup example.com IHRE-ÖFFENTLICHE-IP keine Anfrage, und der Web-Admin ist nur über VPN oder Proxy mit Anmeldung erreichbar.

Schritt 8: Update-Workflow

Für ein Update ziehen Sie das neue Image und erstellen den Container neu. Die Konfiguration im Volume ./etc-pihole bleibt erhalten:

docker compose pull && docker compose up -d
docker image prune -f   # optional, alte Images aufraeumen

Verzichten Sie bei Pi-hole auf automatische Updates per Watchtower. Aktualisieren Sie kontrolliert mit festem Tag und lesen Sie vorher die Release Notes.

Verifizieren: docker exec pihole pihole version zeigt die neuen Versionen, docker compose ps meldet Up (healthy).

Schritt 9: Backup

Der gesamte Zustand von Pi-hole – Konfiguration, Adlists und die Query-Datenbank – steckt im Volume ./etc-pihole. Für ein konsistentes Backup stoppen Sie den Container kurz, packen das Verzeichnis und starten wieder:

docker compose down && tar czf pihole-backup-$(date +%F).tar.gz ./etc-pihole && docker compose up -d

Alternativ nutzen Sie den eingebauten Teleporter im Web-Admin unter Settings -> Teleporter -> Export. Er erzeugt ein Archiv mit allen Einstellungen, das Sie auf einer neuen Pi-hole-Instanz einspielen. Sichern Sie die Backups auf ein externes Ziel.

Verifizieren: tar tzf pihole-backup-*.tar.gz | head listet etc-pihole/pihole.toml und etc-pihole/gravity.db. Gehören Dateien im Volume nicht Ihrem Benutzer, führen Sie tar mit sudo aus.

Troubleshooting

  1. Container startet nicht, address already in use auf Port 53: systemd-resolved belegt noch Port 53. Setzen Sie DNSStubListener=no (Schritt 1) und starte systemd-resolved neu. Mit sudo ss -tulpn | grep ':53' prüfen, dass der Port frei ist.
  2. Host kann nach Schritt 1 keine Namen mehr auflösen: Der Symlink für resolv.conf fehlt. Setzen Sie ihn auf /run/systemd/resolve/resolv.conf und starte systemd-resolved neu.
  3. Clients werden ignoriert: FTLCONF_dns_listeningMode auf ALL setzen.
  4. Passwort unbekannt: Wurde kein FTLCONF_webserver_api_password gesetzt, steht das zufällige Passwort in docker logs pihole. Neu setzen mit docker exec -it pihole pihole setpassword 'NEUES-PASSWORT'. Meldet der Befehl set by environment variable, ändern Sie den Wert in der compose.yaml.
  5. Es wird nichts geblockt: Clients nutzen einen anderen DNS-Server oder DoH. Nur die Pi-hole-IP eintragen (Schritt 6).
  6. Alte Anleitung mit WEBPASSWORD / ServerIP / DNS1: Das sind v5-Variablen. In Pi-hole v6 gelten FTLCONF_*, vor allem FTLCONF_webserver_api_password.
  7. Permission-Fehler mit SELinux (Fedora/RHEL): Mount als ./etc-pihole:/etc/pihole:z angeben.

Häufige Fragen

Brauche ich eine GPU oder starke Hardware für Pi-hole?

Nein. Pi-hole braucht keine GPU, 512 MB RAM und 1 GB Speicher genügen, ein Raspberry Pi reicht.

Warum scheitert der Start mit „address already in use“?

Weil systemd-resolved Port 53 belegt. Die Lösung beschreibt Schritt 1.

Was ist der Unterschied zwischen FTLCONF_webserver_api_password und WEBPASSWORD?

WEBPASSWORD gilt nur für v5, in v6 gilt FTLCONF_webserver_api_password. Generische FTLCONF_<setting>-Variablen überschreiben die pihole.toml. Ohne Passwort-Variable vergibt FTL ein zufälliges Passwort.

Wie sichere ich Pi-hole, wenn ich von außen zugreifen will?

Über ein VPN wie WireGuard oder einen Reverse-Proxy mit TLS und Anmeldung, siehe Schritt 7. Port 53 bleibt im LAN.

Wie aktualisiere ich Pi-hole und meine Blocklisten?

Pi-hole aktualisieren Sie mit docker compose pull && docker compose up -d. Die Blocklisten aktualisiert Pi-hole wöchentlich selbst, manuell mit docker exec -it pihole pihole -g.

Was ist der Unterschied zu AdGuard Home?

AdGuard Home (adguard/adguardhome) ist eine ähnliche Alternative mit eingebautem DoH/DoT und Setup-Assistent. Pi-hole ist ausgereift, gut dokumentiert und deckt mit Adlists, lokalen DNS-/CNAME-Records und Teleporter den Bedarf kleiner Unternehmen ab.

Fazit

Mit Docker Compose richten Sie Pi-hole in rund einer halben Stunde als netzwerkweiten Werbe- und Tracker-Blocker ein. Entscheidend sind der freie Port 53, die FTLCONF_*-Variablen und das Volume ./etc-pihole. Sobald Router und Clients auf die Pi-hole-IP als DNS zeigen, filtert Pi-hole für jedes Gerät im Netz. Halten Sie die Blocklisten schlank, geben Sie den Dienst nicht ins Internet frei und sichern Sie vor Updates per Backup oder Teleporter-Export.

Weiterführende Anleitungen und Quellen

  1. Docker Compose Grundlagen: Stacks verstehen und betreiben
  2. Traefik als Docker-Reverse-Proxy mit HTTPS einrichten
  3. WireGuard-VPN für Homeoffice und Standortanbindung einrichten
  4. Weitere Anleitungen in der Kategorie Netzwerk

Quellen:

  1. Pi-hole – Offizielle Docker-Doku (compose-Beispiel, ENV-Variablen, Setup)
  2. Pi-hole – Docker Tips and Tricks (systemd-resolved / Port 53)
  3. GitHub: pi-hole/docker-pi-hole (README, Image-Tags)
  4. GitHub Releases (aktuelle Tags, z. B. 2026.05.0)