Zum Inhalt

Pi-hole per Docker installieren: Netzweite Werbeblocker-Zentrale für Zuhause

Veröffentlicht am 25. September 2026 · Geschätzte Lesezeit: 6 Minuten

Werbung, Tracker und Malware-Domains filtert Pi-hole auf DNS-Ebene für alle Geräte im Heimnetz – ohne Browser-Erweiterung, ohne App pro Gerät, ohne Konfiguration jedes Smartphones. Einmal den Router-DNS umgestellt, funktioniert es für Windows, macOS, Linux, Android, iOS, Smart-TVs und Spielkonsolen.[1] Die Einrichtung dauert rund 25 Minuten.

Pi-hole v6 (seit Februar 2025) läuft als einzelne FTL-Binary mit eingebautem Webserver – kein separater lighttpd/PHP-Stack mehr, das Image ist kleiner und startet schneller.[3]

Voraussetzungen

  • Ein Server mit Docker und Docker Compose (NAS, Mini-PC, Raspberry Pi, VPS)
  • Die Ports 53 (TCP+UDP) und 80 (TCP) im Heimnetz frei
  • Eine feste IP-Adresse für den Docker-Server (am besten per DHCP-Reservierung im Router)
  • Grundkenntnisse im Terminal und Router-Menü

1. Statische IP sicherstellen

Pi-hole als DNS-Server braucht eine feste Adresse, sonst verlieren die Clients nach einem Neustart des Servers den Zugang. Vergib die IP am einfachsten per DHCP-Reservierung im Router (Fritz!Box: Heimnetz → Netzwerk → IPv4-Adressen). Der Server selbst braucht keine manuelle Netzwerkkonfiguration, wenn der Router die Reservierung kennt.

2. Projektordner anlegen

Öffne ein Terminal auf deinem Docker-Server und lege einen eigenen Ordner an:

mkdir -p ~/pihole
cd ~/pihole

Der erste Befehl erstellt den Ordner pihole in deinem Benutzerverzeichnis. Der zweite wechselt direkt hinein. Alle weiteren Befehle führst du in diesem Ordner aus.

3. Compose-Datei erstellen

Lege im Ordner ~/pihole eine Datei mit dem Namen compose.yaml an:

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      # DNS – wird von allen Geräten im Netz angefragt
      - "53:53/tcp"
      - "53:53/udp"
      # Web-Oberfläche (Admin-Panel)
      - "80:80/tcp"
      # HTTPS (optional – FTL erzeugt selbstsigniertes Zertifikat)
      - "443:443/tcp"
    environment:
      TZ: 'Europe/Berlin'
      # Sicheres Passwort für das Web-Interface – mindestens 12 Zeichen
      FTLCONF_webserver_api_password: '<dein-passwort>'
      # Im Docker-Bridge-Modus zwingend nötig
      FTLCONF_dns_listeningMode: 'ALL'
      # Upstream-DNS (durch Semikolon getrennt)
      FTLCONF_dns_upstreams: '1.1.1.1;9.9.9.9'
      # DNSSEC einschalten
      FTLCONF_dns_dnssec: 'true'
    volumes:
      # Enthält Datenbank, Konfiguration (pihole.toml) und Blocklisten
      - ./etc-pihole:/etc/pihole
    cap_add:
      # Nur nötig, wenn Pi-hole als DHCP-Server dienen soll
      - NET_ADMIN
      # Nur nötig, wenn Pi-hole die Systemzeit des Hosts stellen darf
      - SYS_TIME
      # Optional – etwas mehr Rechenzeit für FTL
      - SYS_NICE
    restart: unless-stopped

Erklärung der wichtigsten Zeilen:

  • image: pihole/pihole:latest – Das offizielle Image, aktuell immer die neueste stabile Version. Stand September 2026 liegt bei 2026.07.x (v6). Möchtest du eine bestimmte Version verwenden, ersetze latest durch z. B. 2026.07.1.[3][4]
  • FTLCONF_webserver_api_password – Setzt das Passwort für die Admin-Oberfläche (ersetze <dein-passwort> durch ein sicheres Passwort). Wird die Variable weggelassen, erzeugt Pi-hole ein zufälliges Passwort und schreibt es ins Log (docker logs pihole).[1][2]
  • FTLCONF_dns_listeningMode: 'ALL' – Zwingend im Docker-Bridge-Modus, sonst antwortet Pi-hole nicht auf Anfragen von außerhalb des Containers. Ohne diese Einstellung landen eingehende DNS-Anfragen im Nichts.[1]
  • FTLCONF_dns_upstreams – Welche öffentlichen DNS-Server Pi-hole befragen darf, wenn eine Domain nicht in den Blocklisten ist. Die Adressen 1.1.1.1 (Cloudflare) und 9.9.9.9 (Quad9) sind datenschutzfreundlich und schnell. Trenne mehrere Einträge mit Semikolon.[1][2]
  • ./etc-pihole:/etc/pihole – Einziger nötiger Datenordner in v6. Hier liegen die SQLite-Datenbank (Anfragen, Blocklisten) und die Hauptkonfiguration pihole.toml. Bei v5 war zusätzlich ./etc-dnsmasq.d:/etc/dnsmasq.d nötig – bei einem Neustart mit v6 entfällt das.[1][3]

Port 80 / 443 schon belegt?

Läuft auf dem Host bereits ein Webserver (Apache, Nginx, Caddy), ändere die Host-Ports in der compose.yaml auf freie Ports, z. B. "8080:80" und "8443:443". Die Web-Oberfläche erreichst du unter http://192.168.1.100:8080/admin (ersetze 192.168.1.100 durch die IP deines Docker-Servers).

4. Container starten

Lade das Image und starte Pi-hole im Hintergrund:

docker compose up -d

Prüfe, ob der Container läuft:

docker compose ps

In der Spalte STATUS sollte Up (seit …) stehen. Falls nicht, zeigen die letzten Logzeilen meist die Ursache:

docker compose logs --tail=50

systemd-resolved blockiert Port 53

Ubuntu 17.10+ und viele aktuelle Distributionen belegen Port 53 bereits mit systemd-resolved. Erscheint ein Fehler wie address already in use, deaktiviere den Stub-Listener:

sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved

Damit der Rechner selbst noch DNS auflösen kann, setze in /etc/resolv.conf einen öffentlichen DNS wie nameserver 1.1.1.1 oder – sobald Pi-hole läuft – die IP des Pi-hole-Containers.

5. Router-DNS umstellen

Damit alle Geräte im Heimnetz Pi-hole nutzen, stellst du den DNS-Server im Router um – nicht auf jedem Endgerät einzeln.

Fritz!Box: Internet → Zugangsdaten → DNS-Server → IPv4-DNS-Server auf die feste IP deines Docker-Servers setzen (z. B. 192.168.1.100). Die IPv6-DNS-Adresse (falls vorhanden) ebenfalls auf Pi-hole setzen.

Andere Router: Suche nach DNS, DHCP oder Nameserver. Trag dort die Pi-hole-IP ein. Manche Router (z. B. TP-Link) erlauben das nur unter DHCP → DNS-Einstellungen.

Einige Router verteilen IPv6-DNS-Adressen, die an Pi-hole vorbei gehen. Prüfe nach der Umstellung auf heimnetz.de/dns-leak, ob nur deine Pi-hole-IP als DNS erscheint. Falls nötig, IPv6-DNS ebenfalls auf Pi-hole setzen.

Neustart der Clients

Nach der Router-Änderung müssen sich die Clients neu anmelden, damit sie den neuen DNS erhalten. Ein kurzer Neustart oder das Ein-/Ausschalten der WLAN-Verbindung reicht.

6. Web-Oberfläche einrichten

Öffne auf einem Computer im gleichen Heimnetz die Adresse http://192.168.1.100/admin (ersetze 192.168.1.100 durch die feste IP deines Docker-Servers). Melde dich mit dem in Schritt 3 gesetzten Passwort an.

Erste Schritte im Dashboard:

  1. Unter Tools → Update Gravity (oder docker exec pihole pihole -g) lädst du die Standard-Blocklisten.
  2. Unter Adlists kannst du weitere Blocklisten hinzufügen – für den Anfang reichen die vorbelegten Listen (OISD, Firebog, etc.). Mehr Listen bedeuten nicht immer bessere Blockierung, sondern auch mehr false positives.[1]
  3. Im Query Log siehst du live alle DNS-Anfragen und welche davon geblockt wurden.

7. Pi-hole aktualisieren und sichern

Update:

docker compose pull
docker compose up -d

Daten bleiben durch das Volume ./etc-pihole erhalten.

Backup:

tar czf pihole-backup-$(date +%F).tar.gz compose.yaml etc-pihole

Kopiere das Archiv auf ein anderes Gerät – eine Sicherung auf derselben Festplatte schützt nicht vor einem Laufwerksausfall.[3]

Wiederherstellung:

docker compose down
mv etc-pihole etc-pihole-vor-wiederherstellung
tar xzf pihole-backup-2026-09-25.tar.gz
docker compose up -d

Typische Fehler

  1. systemd-resolved blockiert Port 53 – siehe Schritt 4.
  2. FTLCONF-Variablen falsch geschrieben – Pi-hole v6 erwartet FTLCONF_* und nicht mehr WEBPASSWORD oder DNS1=. Alte v5-Variablen werden in v6 ignoriert.[3]
  3. dns listeningMode fehlt – Ohne FTLCONF_dns_listeningMode: 'ALL' antwortet Pi-hole im Docker-Bridge-Modus nicht auf externe Anfragen.
  4. Port‑80‑Konflikt – Läuft bereits ein Webserver auf Port 80, binde den Admin-Port auf einen anderen Host-Port (z. B. 8080).
  5. IPv6‑DNS umgeht Pi-hole – Viele Router verteilen IPv6-DNS separat. Prüfe und setze ggf. auch den IPv6-DNS auf Pi-hole.

Fertig

Ab jetzt filtert Pi-hole Werbung, Tracker und bekannte Schadseiten für alle Geräte in deinem Heimnetz. Das siehst du sofort:

  1. Dashboard aufrufen: http://192.168.1.100/admin – die Zusammenfassung zeigt, wie viel Prozent der Anfragen geblockt werden.
  2. DNS testen: Auf einem Client nslookup doubleclick.net – sollte auf 0.0.0.0 oder [::] aufgelöst werden (geblockt).
  3. Query Log öffnen: Unter Query Log im Web-Interface siehst du in Echtzeit jede DNS-Anfrage – sehr aufschlussreich bei Smart-TVs, Streaming-Sticks und IoT-Geräten.

Quellen

[1] Pi-hole Docker-Dokumentation – https://docs.pi-hole.net/docker/ [2] Pi-hole Docker-Konfiguration (Umgebungsvariablen) – https://docs.pi-hole.net/docker/configuration/ [3] Offizielles GitHub-Repository docker-pi-hole – https://github.com/pi-hole/docker-pi-hole [4] Docker Hub – pihole/pihole – https://hub.docker.com/r/pihole/pihole [5] jacar.es – How to Install Pi-hole with Docker – https://jacar.es/en/how-to-install-pi-hole-with-docker [6] Pi My Life Up – Installing and Running Pi-Hole using Docker (YouTube) – https://www.youtube.com/watch?v=0X4mxj-uYsc

Sources

[1] https://docs.pi-hole.net/docker [2] https://docs.pi-hole.net/docker/configuration [3] https://github.com/pi-hole/docker-pi-hole [4] https://hub.docker.com/r/pihole/pihole [5] https://jacar.es/en/how-to-install-pi-hole-with-docker [6] https://www.youtube.com/watch?v=0X4mxj-uYsc