> ## Content Index
> Fetch the complete content index at: https://sakis.tech/llms.txt
> Use this file to discover other available public pages before exploring further.

# Pi-hole + Unbound per Docker Compose: DNS ohne Google & Co.
- URL: https://sakis.tech/pi-hole-unbound-docker-compose/
- Published: 2026-09-11T10:10:57.000Z
- Updated: 2026-09-11T10:30:20.000Z
- Description: Pi-hole blockt Werbung, reicht jede andere Frage aber an Google oder den Provider weiter. Mit Unbound daneben löst dein Server die Namen selbst auf, geprüft per DNSSEC. Zwei Container, eine Compose-Datei, und ein Fehlercode, über den du dich freuen wirst.
- Author: Sakis
- Tags: homelab, pi-hole, docker

Tipp `sakis.tech` in die Adresszeile, und bevor ein einziges Byte dieser Seite bei dir ankommt, stellt dein Rechner eine Frage: Welche IP-Adresse gehört zu diesem Namen? Wer sie beantwortet, hast meist nicht du entschieden, sondern dein Router. Der reicht sie an den Provider weiter, oder an Google, Cloudflare, Quad9\. Jede Seite, jede App, jeder Update-Check: eine Frage an denselben Fremden, mit Uhrzeit und Absender.

Pi-hole kennst du vielleicht als Werbeblocker fürs ganze Netz. Was dabei gern untergeht: Ab Werk reicht auch Pi-hole jede Frage, die es nicht blockt, an genau so einen Fremden weiter. Unbound ändert das. Es ist ein DNS-Server, der die Antwort selbst sucht, bei den Stellen, die sie offiziell wissen. Beides zusammen passt in eine Compose-Datei, und die bauen wir jetzt.

**Kurz gesagt:** Am Ende laufen Pi-hole und Unbound als zwei Container auf deinem Server. Pi-hole filtert Werbung und Tracker für alle Geräte im Netz, Unbound löst jeden Namen selbst auf und prüft die Antworten per DNSSEC; kein Google, kein Cloudflare, kein Provider-DNS mehr in der Kette. Dauer: rund 30 Minuten. Stufe: Standard, du kennst Docker und die Kommandozeile im Groben. Stand: Pi-hole 6.4.3 (Docker-Image 2026.07.2), Unbound 1.26.0 (Image klutchell/unbound), geprüft am 11-09-2026.

![Schaubild: Pi-hole und Unbound in drei Schritten: Compose-Datei mit FTLCONF_dns_upstreams unbound schreiben, starten und per dig die DNSSEC-Prüfung belegen, im Router die IP des Docker-Rechners als DNS eintragen](https://sakis.tech/content/images/2026/09/grafik-17.png)

Der ganze Weg auf einen Blick: Rezept schreiben, starten und prüfen, Router umstellen.

## Was Unbound anders macht als der DNS deines Providers

Der DNS-Server deines Providers ist eine Auskunft: Du fragst, er kennt die Antwort oder holt sie, und er merkt sich, wer wann was gefragt hat. Unbound ist die Auskunft, die du selbst betreibst. Für `sakis.tech` fragt es zuerst die Root-Server: Wer ist für `.tech` zuständig? Dann den Zuständigen für `.tech`: Wer kennt `sakis.tech`? Und zuletzt den Server, auf dem der Name wirklich liegt. Drei Fragen statt einer, aber an drei Stellen, von denen keine das ganze Bild sieht.

**Rekursiver Resolver?** Ein DNS-Server, der die Antwort nicht bei einem anderen DNS-Server abholt, sondern sie Schritt für Schritt bei den zuständigen Stellen zusammensucht. So wie du eine Wohnung nicht bei der Auskunft erfragst, sondern erst im Stadtplan die Straße suchst und dann am Klingelschild den Namen. Unbound ist so ein Server, klein genug für einen Raspberry Pi.

Unbound schickt dabei nur so viel, wie die jeweilige Stelle wissen muss: Die Root-Server bekommen die Frage nach `.tech`, nicht den vollen Namen. Das heißt QNAME-Minimierung und ist laut Unbound-Handbuch von Haus aus an. Dazu prüft Unbound die Antworten per DNSSEC, also anhand digitaler Unterschriften, ob sie wirklich vom Zuständigen stammen und unterwegs niemand daran gedreht hat. Die Pi-hole-Doku bringt den Grund für das Ganze auf eine Frage: Wem willst du vertrauen? Mit Unbound lautet die Antwort: dem Kasten unter deinem Schreibtisch.

Zwei Dinge gehören ehrlich dazu. Verschlüsselt ist der Weg nicht: Unbound redet mit den zuständigen Servern über normales DNS, wer die Leitung mitschneidet, sieht die Pakete weiterhin. Was sich ändert, ist, dass niemand mehr dein komplettes Anfrage-Protokoll an einer Stelle bekommt. Und die erste Anfrage zu einer neuen Domain dauert länger, weil Unbound erst die Kette abklappert; die Pi-hole-Doku sagt das offen. Danach kommt die Antwort aus dem Cache, und die Konfiguration, die wir nehmen, frischt oft gefragte Einträge auf, bevor sie ablaufen.

Handy, Laptop, TV→ fragen Port 53 →Pi-hole→ blockt oder reicht weiter →Unbound→ fragt Root, .tech, Zuständigen →Internet

## Was du brauchst

- Einen Linux-Rechner, der durchläuft, mit Docker und Docker Compose v2\. Ein Raspberry Pi reicht; beide Images gibt es für amd64, arm64 und die 32-Bit-ARM-Varianten. Wer Docker noch nicht hat: [Bei Paperless-ngx](https://sakis.tech/paperless-ngx-mit-docker-installieren-schritt-fur-schritt/) steht der Weg ausführlich.
- Die Ports 53 und 80 frei. Port 53 ist DNS, Port 80 die Weboberfläche von Pi-hole.
- Rund 50 MB Download: Das Pi-hole-Image hat 41 MB, Unbound 7.
- Zugriff auf deinen Router, um am Ende den DNS umzustellen. Für die FritzBox gibt es dafür [einen eigenen Beitrag](https://sakis.tech/pi-hole-fritzbox-einrichten/).

**So liest du diese Anleitung:** Alles, was du selbst tun sollst, steht in einem farbigen Kasten. **\[ per klick \]** heißt: Das erledigst du mit der Maus in einer Web-Oberfläche, hier das Pi-hole-Dashboard im Browser. **\[ über die shell \]** heißt: Den Befehl kopieren, ins Terminal einfügen, Enter. Stehen beide Kästen direkt untereinander, führen sie zum selben Ergebnis. Du gehst EINEN davon, nicht beide.

Die beiden prüfbaren Punkte klärst du mit drei Befehlen auf dem Server:

```bash
docker --version
docker compose version
sudo ss -tulpn | grep -E ':53 |:80 '
```

Die ersten beiden Zeilen liefern je eine Versionsnummer. Die dritte muss leer bleiben. Kommt dort eine Zeile mit `127.0.0.53`, läuft auf deinem Rechner systemd-resolved, der Standard bei Ubuntu; was dann zu tun ist, steht unten bei „Wo es klemmt“. Alles andere auf Port 53 oder 80 muss vorher weichen, und [so findest du heraus, wer da sitzt](https://sakis.tech/port-belegt-so-findest-du-den-schuldigen-und-gibst-ihn-frei/).

Alle Befehle rechnen mit denselben Beispielwerten. Wo sie unten auftauchen, setzt du deine ein:

- IP-Adresse des Docker-Rechners: `192.168.178.20`
- Ordner für alles: `~/pihole`
- Passwort der Weboberfläche: `bitte-aendern` (du nimmst ein eigenes)
- Zeitzone: `Europe/Berlin`

## Schritt 1: Ordner und Compose-Datei anlegen

Ein Ordner für die Compose-Datei. Den Datenordner darin legt Pi-hole beim ersten Start selbst an.

```bash
mkdir -p ~/pihole
cd ~/pihole
```

Jetzt das Rezept. Grundlage ist das Pi-hole-Beispiel aus dem Repository des Unbound-Images, abgeglichen mit der Docker-Doku von Pi-hole. Drei Dinge aus dem Original fehlen absichtlich, und eine Zeile ist neu; beides erkläre ich unter der Datei.

Datei anlegen:

```bash
nano docker-compose.yml
```

Inhalt einfügen, das Passwort durch ein eigenes ersetzen, mit Strg+O und Enter speichern, mit Strg+X schließen:

```yaml
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
    environment:
      TZ: "Europe/Berlin"
      # Passwort für die Weboberfläche – vor dem Start ändern
      FTLCONF_webserver_api_password: "bitte-aendern"
      # Upstream ist der Unbound-Container nebenan, erreichbar über seinen Dienstnamen
      FTLCONF_dns_upstreams: "unbound"
      # Im Docker-Bridge-Netz muss Pi-hole auf allen Schnittstellen lauschen
      FTLCONF_dns_listeningMode: "ALL"
      # Die Uhr stellt der Host selbst; dafür bräuchte der Container Sonderrechte
      FTLCONF_ntp_sync_active: "false"
    volumes:
      - ./etc-pihole:/etc/pihole
    depends_on:
      - unbound
    restart: unless-stopped

  unbound:
    container_name: unbound
    image: klutchell/unbound:latest
    healthcheck:
      test: ["CMD", "drill-hc", "@127.0.0.1", "dnssec.works"]
      interval: 30s
      timeout: 30s
      retries: 3
      start_period: 30s
    restart: unless-stopped
```

Ob Compose die Datei versteht, zeigt eine Probe ohne Start:

```bash
docker compose config --quiet && echo OK
```

Kommt `OK`, stimmen Einrückung und Anführungszeichen. Kommt eine Fehlermeldung mit Zeilennummer, ist es fast immer ein Leerzeichen zu viel oder zu wenig.

Die Zeile, um die sich alles dreht, ist `FTLCONF_dns_upstreams: "unbound"`. Pi-hole liest seine Einstellungen aus Umgebungsvariablen, die mit `FTLCONF_` beginnen; laut Doku wird aus dem Eintrag `upstreams` im Abschnitt `dns` der Name `FTLCONF_dns_upstreams`. Als Wert steht dort kein Google und kein Cloudflare, sondern `unbound`, der Name des zweiten Containers. Docker löst den Namen im internen Netz auf, und die Doku erlaubt ausdrücklich Hostnamen an dieser Stelle. Der Unbound-Container hat keine `ports`\-Zeilen: Ihn erreicht nur Pi-hole, kein Gerät im Netz und niemand von außen.

`listeningMode: "ALL"` braucht Pi-hole, weil die Anfragen im Bridge-Netz von Dockers eigener Brücke kommen und nicht direkt von deinen Geräten; die Docker-Doku von Pi-hole nennt das als Standard für diesen Fall. Die neue Zeile ist `FTLCONF_ntp_sync_active: "false"`. Pi-hole 6 bringt einen NTP-Client mit, der die Uhr des Rechners stellen will. Dafür bräuchte der Container das Recht `SYS_TIME`, und ohne das Recht schreibt Pi-hole beim Start einen Fehler ins Log, dass der NTP-Client nicht verfügbar sei. Dein Linux stellt seine Uhr ohnehin selbst, also bleibt die Funktion aus, und das Log bleibt sauber.

Weggelassen habe ich aus dem Original den Port 443 (Pi-hole würde dort ein selbstsigniertes Zertifikat anbieten, im Heimnetz reicht Port 80, und für außen kommt später ohnehin ein Reverse Proxy), den Port 67 samt dem Recht `NET_ADMIN` (laut Doku nur nötig, wenn Pi-hole dein DHCP-Server werden soll; das bleibt der Router) und das Recht `SYS_NICE` (laut Doku optional). Ein Container bekommt bei mir nur die Rechte, die er für seine Arbeit braucht.

Der `healthcheck` unter Unbound stammt aus dem Beispiel des Image-Autors: Alle 30 Sekunden fragt ein kleines Werkzeug im Container Unbound nach `dnssec.works`, und erst wenn die Antwort kommt, gilt der Container als gesund. Du siehst das gleich in der Statusspalte.

## Schritt 2: Starten und den ersten Beweis holen

```bash
docker compose up -d
docker compose ps
```

In der Spalte `STATUS` muss bei beiden Containern `Up` mit `(healthy)` stehen. Bei Unbound dauert das bis zu einer Minute; solange steht dort `(health: starting)`. Nach dem Start braucht Pi-hole etwa eine halbe Minute, bis es auf Port 53 und 80 antwortet. Dann einmal `docker compose ps` wiederholen. Bleibt es länger dabei, zeigt das Log, was Unbound fehlt:

```bash
docker compose logs unbound
```

Läuft beides, kommt der eigentliche Beweis. Das Pi-hole-Image bringt `dig` mit, das Standardwerkzeug für DNS-Fragen, also musst du auf dem Rechner nichts nachinstallieren. Die erste Frage geht an Pi-hole selbst:

```bash
docker compose exec pihole dig heise.de @127.0.0.1
```

```text
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43210
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
```

Zwischen den beiden Zeilen steht im `ANSWER SECTION` eine IP-Adresse. `NOERROR` heißt: Pi-hole hat die Frage angenommen, an Unbound weitergereicht, und Unbound hat sich die Antwort bei den zuständigen Servern geholt. Wenn das beim ersten Versuch klappt, freue ich mich und werde gleichzeitig misstrauisch. Deshalb der zweite Test, der zeigt, dass wirklich Unbound antwortet und nicht irgendein Cache:

```bash
docker compose exec pihole dig fail01.dnssec.works @unbound
docker compose exec pihole dig +ad dnssec.works @unbound
```

```text
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 17321
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58004
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
```

Das sind die beiden Prüfdomains aus der Pi-hole-Doku. `fail01.dnssec.works` trägt absichtlich eine kaputte Unterschrift; ein Resolver, der DNSSEC prüft, verweigert die Antwort mit `SERVFAIL`, und genau das willst du sehen. Ein Google-DNS hätte hier auch abgelehnt, ein Provider-DNS ohne DNSSEC hätte brav eine IP geliefert. Die zweite Domain ist korrekt unterschrieben und kommt mit `NOERROR` zurück, und in der `flags`\-Zeile steht das kleine `ad`: Authenticated Data, Unbound hat die Unterschrift geprüft. Ich kenne keinen anderen Fehlercode, über den man sich so freut wie über diesen `SERVFAIL`.

## Schritt 3: Die Weboberfläche

Im Browser `http://192.168.178.20/admin/` öffnen, mit dem Passwort aus der Compose-Datei anmelden. Du landest auf dem Dashboard mit den Kacheln **Total Queries**, **Queries Blocked** und **Domains on Lists**. Links unter **Settings** auf **DNS**: Bei den großen Anbietern ist nichts angehakt, unter **Custom DNS servers** steht `unbound`, und das Feld lässt sich nicht bearbeiten. Stand Pi-hole 6.4.

![Die Anmeldeseite von Pi-hole unter /admin/ mit einem Passwortfeld und dem Knopf Log in.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-01-2026-09-11.png)

(1) Passwort aus der Compose-Datei; (2) Log in

![Das Pi-hole-Dashboard nach dem Anmelden mit den Kacheln Total Queries, Queries Blocked, Percentage Blocked und Domains on Lists, links das Menü mit Settings und Tools.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-02-2026-09-11.png)

(1) Total Queries; (2) Queries Blocked; (3) Domains on Lists

![Die DNS-Einstellungen von Pi-hole: Bei den großen Anbietern ist kein Haken gesetzt, unter Custom DNS servers steht unbound in einem grauen, nicht bearbeitbaren Feld.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-03-2026-09-11.png)

(1) unbound, nicht änderbar; (2) Custom DNS servers; (3) Nichts angehakt

Das `/admin/` in der Adresse ist Pflicht. Die nackte IP liefert eine Fehlerseite, weil Pi-hole laut Quellcode nur seinen eigenen Namen `pi.hole` auf die Oberfläche umleitet; bei jedem anderen Host tut es absichtlich nichts, damit die Sperrseite für geblockte Domains funktioniert. Und dass sich der Upstream in der Oberfläche nicht ändern lässt, ist Absicht: Was per Umgebungsvariable gesetzt ist, wird laut Doku schreibgeschützt, damit es nur eine Wahrheit gibt, nämlich deine Compose-Datei. Willst du etwas ändern, änderst du die Datei und startest mit `docker compose up -d` neu.

## Schritt 4: Ein Gerät umstellen, dann der Router

Bevor das ganze Haus über den neuen DNS geht, fragt ein einzelnes Gerät ihn von Hand. Das geht von jedem Rechner im Netz aus, ohne irgendetwas umzustellen:

Unter Windows in der Eingabeaufforderung:

```bash
nslookup heise.de 192.168.178.20
```

Unter Linux oder macOS im Terminal:

```bash
dig heise.de @192.168.178.20
```

Beide melden als antwortenden Server die `192.168.178.20` und liefern eine IP. Damit weißt du: Der Weg von deinen Geräten über Port 53 zu Pi-hole steht. Fehlt die Antwort, sitzt zwischen Gerät und Server meist eine Firewall auf dem Docker-Rechner, die Port 53 nicht durchlässt.

Jetzt der Router. Dort trägst du die `192.168.178.20` als DNS-Server ein, den der Router per DHCP an alle Geräte verteilt. Bei der FritzBox stehen die Klicks, IPv6 und das Gastnetz [im eigenen Beitrag](https://sakis.tech/pi-hole-fritzbox-einrichten/); bei anderen Routern heißt die Stelle meist DHCP-Server oder LAN-Einstellungen, und das Feld DNS-Server. Nach einer Weile zählt auf dem Dashboard **Total Queries** hoch, und unter **Query Log** tauchen Anfragen von Geräten auf, die du kennst. Das ist der zweite Beweis.

## Was am Ende eingestellt ist

Pi-hole läuft, Unbound antwortet. Fünf Dinge würde ich jetzt noch klären, bevor der Rechner in Vergessenheit gerät.

**1\. Das Passwort steht im Klartext in der Datei.** Das ist bei diesem Weg so, und es ist in Ordnung, solange nur du die Datei lesen kannst. Ein Handgriff, und die Datei gehört dir allein:

```bash
chmod 600 ~/pihole/docker-compose.yml
```

**2\. Die Blocklisten.** Bei einer Installation ohne Rückfragen, und das ist Docker, trägt Pi-hole laut seinem Installationsskript eine Liste ein: die von StevenBlack gepflegte Hosts-Datei. Deshalb steht bei **Domains on Lists** schon nach dem ersten Start eine fünf- bis sechsstellige Zahl. Für den Anfang reicht das. Wer mehr will, holt sich weitere Listen, und mehr Listen heißt immer auch mehr Fehlalarme, die man dann von Hand freigibt.

Links **Lists** öffnen, die Adresse der Liste ins Feld eintragen, **Add blocklist**. Danach unter **Tools** auf **Update Gravity**, sonst kennt Pi-hole die neue Liste noch nicht. Auf der Seite, die sich öffnet, liest erst der breite Knopf **Update** die Listen ein. Stand Pi-hole 6.4.

![Die Seite Lists von Pi-hole mit dem leeren Feld Address, dem Knopf Add blocklist und darunter der vorinstallierten StevenBlack-Liste.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-04-2026-09-11.png)

(1) Adresse der Liste eintragen; (2) Add blocklist

![Die Seite Update Gravity von Pi-hole unter Tools mit dem breiten Knopf Update, der die Blocklisten neu einliest.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-05-2026-09-11.png)

(1) Update; (2) Tools, dann Update Gravity

**3\. Nur für das eigene Netz.** Mit `listeningMode: "ALL"` nimmt Pi-hole Anfragen von jeder Schnittstelle an, und die Doku hängt an diese Einstellung ein Ausrufezeichen: für eine Firewall sorgen. Konkret heißt das: Im Router darf es keine Portfreigabe für 53 oder 80 auf diesen Rechner geben. Ein DNS-Server, der aus dem Internet erreichbar ist, wird für Angriffe auf andere missbraucht, weil er auf kleine Fragen große Antworten schickt. Wer Pi-hole unterwegs nutzen will, nimmt ein VPN, nicht eine Freigabe.

**4\. Updates von Hand.** Beide Images laufen auf `latest`, aber nichts aktualisiert sich von allein, und das ist gut so: Die Pi-hole-Doku rät ausdrücklich von Watchtower und jeder unbeaufsichtigten Aktualisierung ab, weil ein DNS-Server, der nach einem nächtlichen Update nicht mehr hochkommt, das ganze Haus offline nimmt. Der Weg ist: Release Notes lesen, dann ziehen und neu starten.

```bash
cd ~/pihole
docker compose pull && docker compose up -d
```

**5\. Das Backup.** Alles, was Pi-hole weiß, liegt in `~/pihole/etc-pihole`: die Datenbanken, die Listen, die Einstellungen. Der Ordner gehört in dein normales Backup. Dazu einmal den Teleporter benutzen, das ist Pi-holes eingebauter Export als Zip-Datei, den man in einer frischen Installation wieder einspielen kann. Ich weiß, der Backup-Satz steht in jedem Beitrag. Bei einem DNS-Server, den das ganze Haus benutzt, steht er zu Recht.

**Settings**, dann **Teleporter**, dann **Export**. Die Zip-Datei landet im Download-Ordner deines Browsers; leg sie zum Backup. Sie enthält Geheimnisse, und die Langzeit-Datenbank `pihole-FTL.db` steckt nicht darin; die kommt über den Ordner mit. Stand Pi-hole 6.4.

![Die Teleporter-Seite von Pi-hole unter Settings: links der Kasten Export your Pi-hole's configuration mit zwei Warnhinweisen und unten rechts darin dem Knopf Export, rechts daneben der Import.](https://sakis.tech/content/images/2026/09/labor-pi-hole-unbound-docker-compose-07-2026-09-11.png)

(1) Export your Pi-hole's configuration; (2) Settings, dann Teleporter

Was hier bewusst fehlt: der Zugriff von unterwegs und die Weboberfläche mit HTTPS. Beides ist ein eigener Beitrag, und beides braucht erst die Grundlagen aus dem [Reverse-Proxy-Erklärstück](https://sakis.tech/was-ist-ein-reverse-proxy-einfach-erklart-furs-homelab/).

## Wo es klemmt

**Port 53 ist belegt, der Start bricht mit „address already in use“ ab.** Auf Ubuntu und Fedora sitzt dort systemd-resolved, ein kleiner DNS-Vermittler des Systems. Die Pi-hole-Doku hat dafür drei Befehle: Sie schalten den Vermittler auf Port 53 ab und hängen die Namensauflösung des Rechners direkt an die Datei, die systemd ohnehin pflegt.

```bash
sudo sh -c 'mkdir -p /etc/systemd/resolved.conf.d && printf "[Resolve]\nDNSStubListener=no\n" | tee /etc/systemd/resolved.conf.d/no-stub.conf'
sudo sh -c 'rm -f /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
sudo systemctl restart systemd-resolved
```

Danach noch einmal:

```bash
docker compose up -d
```

**Unbound bleibt bei „health: starting“ oder wird „unhealthy“.** Der Healthcheck fragt `dnssec.works` mit DNSSEC ab, und dafür muss Unbound selbst nach draußen reden: auf Port 53, mit Servern, die nicht deinem Provider gehören. Eine Firewall, die ausgehendes DNS nur dem Router erlaubt, macht Unbound stumm. `docker compose logs unbound` zeigt dann Zeitüberschreitungen statt Antworten.

**Nach einem Unbound-Update antwortet Pi-hole nicht mehr.** Wenn ich den Code des in Pi-hole steckenden dnsmasq richtig lese, wird der Name `unbound` beim Start einmal in eine IP-Adresse übersetzt, nicht bei jeder Anfrage. Bekommt der Unbound-Container beim Neubau eine andere interne Adresse, hält Pi-hole an der alten fest. Die Kur ist ein Neustart von Pi-hole, dann löst es den Namen neu auf:

```bash
docker compose restart pihole
```

Nach dem Neustart braucht Pi-hole etwa eine halbe Minute, bis es wieder auf Port 53 antwortet.

**Die erste Seite lädt spürbar langsamer als früher.** Kein Fehler. Unbound kennt beim Start nichts und muss für jede neue Domain die ganze Kette abfragen. Nach ein paar Stunden Alltag liegt das Meiste im Cache, und der Rest ist ein Wimpernschlag. Wer es nach einem Tag noch spürt, sieht sich `docker compose logs unbound` an.

Zwei Container, eine Datei, und aus dem Werbeblocker wird eine eigene Auskunft. Was mir an dem Setup gefällt, ist nicht die Technik, sondern die Antwort auf die Frage aus der Pi-hole-Doku: Wem vertraust du? Ab heute einem Rechner, den du selbst neu starten kannst.

Welchen DNS hat dein Netz heute: den vom Provider, Cloudflare, Quad9, oder läuft bei dir schon ein Resolver? Und hast du gemerkt, als du umgestellt hast, oder erst beim nächsten Werbebanner, der fehlte? Schreib es in die Kommentare.

Wenn Pi-hole bei dir lieber ohne Docker laufen soll, etwa als eigener Container auf dem Proxmox-Host, dann ist [die LXC-Anleitung](https://sakis.tech/pi-hole-proxmox-lxc-installieren/) der passende Weg; Unbound lässt sich dort genauso danebenstellen.

sakis@homelab:\~$ echo "bleib neugierig — und mach backups" 

## Quellen

- [Pi-hole-Doku: Pi-hole as All-Around DNS Solution (Unbound-Guide, Prüfdomains, „Whom can you trust?“)](https://docs.pi-hole.net/guides/dns/unbound/?ref=sakis.tech)
- [Pi-hole-Doku: Docker Configuration (FTLCONF\_-Schema, Variablen per Umgebung sind schreibgeschützt)](https://docs.pi-hole.net/docker/configuration/?ref=sakis.tech)
- [Pi-hole-Doku: Docker Tips and Tricks (systemd-resolved, Watchtower-Warnung)](https://docs.pi-hole.net/docker/tips-and-tricks/?ref=sakis.tech)
- [Pi-hole-Doku: FTL-Konfiguration (dns.upstreams mit Hostnamen, dns.listeningMode, ntp.sync.active)](https://docs.pi-hole.net/ftldns/configfile/?ref=sakis.tech)
- [pi-hole/docker-pi-hole auf GitHub (Compose-Beispiel, Anmerkungen zu NET\_ADMIN, SYS\_TIME, SYS\_NICE, Tags)](https://github.com/pi-hole/docker-pi-hole?ref=sakis.tech)
- [docker-pi-hole: Release 2026.07.2](https://github.com/pi-hole/docker-pi-hole/releases/tag/2026.07.2?ref=sakis.tech)
- [Pi-hole Core: Release v6.4.3](https://github.com/pi-hole/pi-hole/releases/tag/v6.4.3?ref=sakis.tech)
- [pi-hole/pi-hole: basic-install.sh (installDefaultBlocklists, StevenBlack-Liste bei Installation ohne Rückfrage)](https://github.com/pi-hole/pi-hole/blob/master/automated%20install/basic-install.sh?ref=sakis.tech)
- [klutchell/unbound-docker auf GitHub (README, Konfiguration)](https://github.com/klutchell/unbound-docker?ref=sakis.tech)
- [klutchell/unbound-docker: Pi-hole-Beispiel (Compose, Healthcheck)](https://github.com/klutchell/unbound-docker/blob/main/examples/pi-hole/docker-compose.yml?ref=sakis.tech)
- [klutchell/unbound-docker: unbound.conf des Images (rekursiv, DNSSEC, prefetch, access-control)](https://github.com/klutchell/unbound-docker/blob/main/rootfs%5Foverlay/etc/unbound/unbound.conf?ref=sakis.tech)
- [Docker Hub: klutchell/unbound (Tag 1.26.0, Architekturen, Größe)](https://hub.docker.com/r/klutchell/unbound/tags?ref=sakis.tech)
- [Docker Hub: pihole/pihole (Architekturen, Größe)](https://hub.docker.com/r/pihole/pihole/tags?ref=sakis.tech)
- [NLnet Labs: unbound.conf(5) (qname-minimisation, prefetch, do-ip6)](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html?ref=sakis.tech)
- [pi-hole/FTL: src/ntp/client.c (Fehlermeldung ohne CAP\_SYS\_TIME)](https://github.com/pi-hole/FTL/blob/master/src/ntp/client.c?ref=sakis.tech)
- [pi-hole/FTL: src/webserver/webserver.c (Umleitung auf /admin/ nur für pi.hole)](https://github.com/pi-hole/FTL/blob/master/src/webserver/webserver.c?ref=sakis.tech)
- [pi-hole/FTL: src/dnsmasq/option.c (Hostname im server=-Eintrag wird beim Einlesen aufgelöst)](https://github.com/pi-hole/FTL/blob/master/src/dnsmasq/option.c?ref=sakis.tech)