Zum Hauptinhalt springen
Self-Hosting & Privatsphäre

Docker Compose Netzwerke erklärt

Zwei Container auf demselben Host konnten sich gegenseitig erreichen, und eigentlich sollte keiner von beiden das können. Beide waren im Standard-Bridge-Netzwerk gelandet.

milanbuha0021. August 20266 Min. LesezeitRead in English
TeilenXin
Docker Compose Netzwerke erklärt

Zwei Container auf demselben Host konnten sich gegenseitig erreichen, und eigentlich sollte keiner von beiden das können. Niemand hatte eine Firewall-Regel dafür geschrieben — es funktionierte einfach, weil beide Container zufällig im Standard-Bridge-Netzwerk von Docker Compose gelandet waren, und dieses Netzwerk fragt nicht um Erlaubnis, bevor es Dinge verbindet.

TL;DR

  • Jedes docker compose up erstellt automatisch ein eigenes Bridge-Netzwerk; jeder Dienst in dieser Datei tritt ihm bei und kann jeden anderen Dienst über seinen Namen erreichen.
  • Zwei separate Compose-Projekte sind standardmäßig voneinander isoliert — die Gefahr liegt innerhalb eines Projekts, nicht zwischen ihnen.
  • internal: true entfernt den ausgehenden Internetzugriff eines Netzwerks komplett — die richtige Wahl für eine Datenbank.
  • external: true lässt zwei unabhängige Compose-Stacks bewusst ein Netzwerk teilen, ohne dass einer der beiden es bei docker compose down zerstört.
  • Dieses Homelab gibt jedem Stack ein eigenes internes Netzwerk, plus ein geteiltes externes Netzwerk, dem nur der Reverse Proxy beitritt.

KEY-STAT: 1 — geteiltes externes Netzwerk reicht aus, damit ein einziger Reverse Proxy jeden isolierten Stack in diesem Homelab erreicht, ohne sie auf ein Netzwerk zusammenzulegen

Der Standard: ein Bridge-Netzwerk pro Compose-Projekt

Führen Sie docker compose up ohne jeden networks:-Block aus, erstellt Compose ein Bridge-Netzwerk, benannt nach dem Projektverzeichnis, und legt jeden Dienst dieser Datei hinein. Container erreichen sich gegenseitig über ihren Dienstnamen — Dockers eingebautes DNS löst vaultwarden zur internen IP dieses Containers auf, ohne dass jemand eine Adresse fest einträgt. Zwei separate docker compose-Projekte auf demselben Host bekommen zwei separate Standardnetzwerke und können sich nicht sehen, solange Sie sie nicht ausdrücklich verbinden. Diese Isolation leistet mehr, als die meisten denken: Die Gefahr liegt nicht zwischen Stacks, sondern innerhalb eines Stacks, wo jeder Dienst jeden anderen erreichen kann, ob nötig oder nicht.

Warum dieser Standard mit einem Reverse Proxy nicht mehr ausreicht

Ein Reverse Proxy wie Caddy oder Traefik muss Container erreichen, die in anderen Compose-Projekten liegen — den Jellyfin-Stack, den Vaultwarden-Stack, den n8n-Stack, jeweils in eigener Datei definiert. Alles auf ein flaches Netzwerk zu legen, damit der Proxy überall hinkommt, hebt genau die Isolation auf, die Compose eigentlich gratis mitliefert — jetzt können Vaultwarden und n8n auch miteinander sprechen, aus keinem Grund, den irgendjemand bewusst gewählt hätte.

Die reale Topologie dieses Homelabs: ein internes Netzwerk pro Stack, ein geteiltes Netzwerk für den Proxy

Der tatsächliche Aufbau in diesem Homelab, ursprünglich nach dem Einsteiger-Guide zum Homelab-Aufbau errichtet: Jeder Stack — Medien, Zugangsdaten, Automatisierung — bekommt sein eigenes privates Netzwerk, das diese Compose-Datei nie verlässt. Caddy tritt einem zweiten, separaten Netzwerk bei, dem auch jeder Stack beitritt, und nur diesem. Nichts im Medien-Stack kann etwas im Zugangsdaten-Stack erreichen; beide können Caddy erreichen, und Caddy kann beide erreichen.

Die Compose-Datei des Proxy-Stacks deklariert das geteilte Netzwerk als extern und tritt nur diesem bei:

networks:
  proxy_net:
    external: true

services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    networks:
      - proxy_net
    ports:
      - "80:80"
      - "443:443"

Die Compose-Datei des Vaultwarden-Stacks tritt dann demselben geteilten Netzwerk bei, plus ihrem eigenen privaten:

networks:
  proxy_net:
    external: true
  vw_internal:
    driver: bridge

services:
  vaultwarden:
    image: vaultwarden/server:latest
    restart: unless-stopped
    networks:
      - proxy_net
      - vw_internal

Vaultwarden tritt beiden Netzwerken bei: proxy_net, damit Caddy es erreichen kann, und seinem eigenen vw_internal-Netzwerk für alles andere in diesem Stack (zum Beispiel einen Backup-Sidecar), das im Medien- oder Automatisierungs-Stack nichts zu suchen hat. Die n8n- und Jellyfin-Stacks folgen demselben Muster, jeweils mit eigenem internem Netzwerknamen.

Tip

Nennen Sie das geteilte Netzwerk etwas Spezifisches wie proxy_net, nicht internet oder web — eine Namenskollision zwischen zwei unabhängigen Compose-Projekten, die beide ein Netzwerk mit demselben generischen Namen anlegen wollen, ist ein echter, verwirrender Fehlerfall.

Dienstnamen-DNS: wie Container sich gegenseitig finden

Innerhalb eines geteilten Netzwerks löst Composes eingebautes DNS einen Dienstnamen zur aktuellen IP dieses Containers auf — keine statischen IPs, kein Editieren von /etc/hosts, und es übersteht sogar Container-Neustarts, obwohl sich die zugrunde liegende IP ändern kann. Das funktioniert nur für Container im selben Netzwerk; ein Container in vw_internal kann keinen Dienst auflösen oder erreichen, der nur bei den Nachbar-Stacks auf proxy_net existiert. Diese Unterscheidung zählt beim Debuggen: curl: could not resolve host bedeutet, dass die beiden Container gar kein gemeinsames Netzwerk teilen, während connection refused bedeutet, dass sie ein Netzwerk teilen, der Zieldienst aber nicht lauscht oder nicht läuft — prüfen Sie zuerst dessen Restart-Status, wie im Restart-Policies-Guide beschrieben, bevor Sie einen Netzwerk-Bug vermuten.

internal: true — das Netzwerk ohne Internetzugang

Ein Netzwerk mit internal: true zu markieren, entfernt seine ausgehende Route komplett — Container darin können miteinander sprechen, aber nichts in diesem Netzwerk erreicht das öffentliche Internet, und nichts von außerhalb des Hosts erreicht hinein. Das ist die richtige Einstellung für einen Datenbank-Container, der keinen legitimen Grund hat, nach Hause zu telefonieren:

networks:
  db_net:
    driver: bridge
    internal: true

services:
  postgres:
    image: postgres:17
    restart: unless-stopped
    networks:
      - db_net

Warning

internal: true blockiert ausgehenden Traffic vollständig, einschließlich der eigenen Update-Prüfungen des Images oder Telemetrie-Aufrufen, die manche Software beim Start macht. Startet ein Container nach dieser Änderung plötzlich nicht mehr, prüfen Sie zuerst dessen Logs auf eine blockierte ausgehende Verbindung, bevor Sie einen Compose-Bug vermuten.

external: true — Infrastruktur nutzen, die Compose nicht selbst besitzt

external: true sagt Compose: "Dieses Netzwerk existiert bereits, nutze es, und erstelle oder zerstöre es niemals als Teil des Lebenszyklus dieses Projekts." Legen Sie es einmal von Hand an, bevor einer der Stacks startet:

docker network create proxy_net

Ab dann referenzieren sowohl die Compose-Datei des Proxys als auch jede App-Stack-Compose-Datei proxy_net als external: true. Ein docker compose down bei irgendeinem von ihnen lässt das geteilte Netzwerk unangetastet — nur ein stack-eigenes internes Netzwerk wird mit seinem Stack abgebaut.

Entscheidungstabelle: welches Netzwerk-Setup für welche Situation

SituationSetupWarum
Ein einzelner, in sich geschlossener Stack ohne Reverse ProxyStandardnetzwerk, kein networks:-Block nötigNichts zu isolieren — der Standard isoliert Sie bereits von anderen Projekten
Eine Datenbank oder ein Backend-Dienst ohne Grund, das Internet zu erreichenEigenes Netzwerk mit internal: trueEntfernt eine ganze Klasse von Exfiltrations- und Update-Risiken
Mehrere unabhängige Stacks hinter einem Reverse ProxyEin external: true-geteiltes Netzwerk, plus ein privates Netzwerk pro StackProxy erreicht alles; Stacks erreichen sich untereinander nicht
Zwei Stacks, die legitim miteinander sprechen müssen (z. B. eine App und ihr dedizierter Cache)Ein zweites, gezielt benanntes internes Netzwerk, dem nur diese zwei Dienste beitretenEnger gefasst als ein homelab-weites geteiltes Netzwerk, trotzdem von allem anderen isoliert

Debugging: Netzwerkproblem oder Restart-Problem?

Bevor Sie ein Netzwerkproblem jagen, bestätigen Sie erst, dass der Zielcontainer überhaupt läuft: docker compose ps — ein Exited-Status bedeutet, dass keine Restart-Policy ihn zurückgeholt hat, ein Restart-Policy-Problem, kein Netzwerkproblem. Zeigt er Up, bestätigen Sie mit docker network inspect <netzwerkname>, dass beide Container ein Netzwerk teilen, und prüfen Sie die Containers-Liste. Testen Sie die Erreichbarkeit dann direkt aus einem Container heraus:

docker compose exec caddy ping -c 2 vaultwarden

Ein erfolgreicher Ping mit aufgelöstem DNS bedeutet, dass die Netzwerkebene in Ordnung ist und das Problem eine Ebene höher liegt — vermutlich eine Port- oder App-Fehlkonfiguration, kein Compose-Netzwerkproblem.

Fazit

Lassen Sie Composes automatisches Projekt-Netzwerk Single-Stack-Setups übernehmen, greifen Sie zu internal: true, sobald ein Dienst keinen Grund hat, mit dem Internet zu sprechen, und nutzen Sie ein bewusst geteiltes external: true-Netzwerk — nie ein komplett flaches — sobald ein Reverse Proxy mehr als einen Stack bedienen muss.

Häufig gestellte Fragen

Teilen sich Container in derselben Docker-Compose-Datei standardmäßig ein Netzwerk?

Ja. Compose erstellt automatisch ein Bridge-Netzwerk pro Projekt und lässt jeden Dienst dieser Datei beitreten, sodass sie sich ohne zusätzliche Konfiguration über ihren Dienstnamen erreichen können.

Was macht internal: true in einem Docker-Compose-Netzwerk?

Es entfernt die ausgehende Route des Netzwerks vollständig. Container darin können sich weiterhin gegenseitig erreichen, aber keiner von ihnen erreicht das öffentliche Internet, und nichts von außerhalb des Hosts erreicht hinein.

Wie verbinden Sie zwei separate Docker-Compose-Stacks mit demselben Netzwerk?

Legen Sie das Netzwerk einmal von Hand mit docker network create <name> an und referenzieren Sie es dann in beiden Compose-Dateien als external: true. Keines der Projekte wird dieses Netzwerk als Teil seines eigenen Lebenszyklus erstellen oder zerstören.

Warum erreicht mein Reverse Proxy keinen Container in einem anderen Compose-Projekt?

Fast immer, weil die beiden Projekte kein gemeinsames Netzwerk teilen. Jedes docker compose up erstellt sein eigenes isoliertes Standardnetzwerk, sodass ein Proxy in einem Projekt keinen Dienst in einem anderen Projekt auflösen oder erreichen kann, solange nicht beide ausdrücklich einem gemeinsamen external: true-Netzwerk beitreten.

Ähnliche Artikel

Mehr aus Self-Hosting & Privatsphäre

Bleiben Sie auf dem Laufenden

Erhalten Sie die neuesten Artikel direkt in Ihr Postfach. Kein Spam, jederzeit abbestellbar.

Als Nächstes lesen

Docker Compose Volumes und Backups erklärt

Ich führte docker compose down -v aus, um einen Stack aus Gewohnheit sauber neu zu starten. Hier war das Flag nicht harmlos — es löschte ein benanntes Volume samt den Containern.

Weiterlesen