So machst du aus einer Docker-Compose-Datei ein Architekturdiagramm

Eine compose.yaml listet Services, Netzwerke und Volumes bereits auf; so machst du daraus ein Diagramm, findest die versteckten Aufrufe und hältst das Bild aktuell.

22.10.2026

So machst du aus einer Docker-Compose-Datei ein Architekturdiagramm

Eine Compose-Datei ist oft die ehrlichste Beschreibung eines Systems, die du hast. Sie ist das, was auf dem Laptop, in der CI und manchmal in Produktion tatsächlich startet. Sie ist aber auch eine Wand aus YAML, und wer neu im Team ist, muss trotzdem fragen, welcher Service mit welchem spricht.

Dieser Guide macht aus einer Compose-Datei ein Architekturdiagramm, dem du vertrauen kannst: Rendere die Datei, die Compose wirklich ausführt, ordne jeden Schlüssel einem Diagrammelement zu, ergänze die Aufrufe, die die Datei nicht ausdrücken kann, und halte die Zeichnung im Gleichschritt mit der Datei. Am Ende holen wir uns mit dem kostenlosen Tool von Archboard in Sekunden einen ersten Entwurf.

Das Beispiel: ein kleiner shop-Stack

Das ist die compose.yaml, die wir zeichnen. Sie ist kurz, enthält aber die üblichen Fallen: einen Service in zwei Netzwerken, eine Abhängigkeit, die nur in einer Konfigurationsdatei existiert, und ein Tool, das nur für die Entwicklung gedacht ist.

name: shop

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
    networks: [frontend]

  api:
    build: ./api
    environment:
      DATABASE_URL: postgres://shop:${POSTGRES_PASSWORD}@db:5432/shop
      REDIS_URL: redis://cache:6379/0
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    networks: [frontend, backend]

  worker:
    build: ./api
    command: ["node", "worker.js"]
    environment:
      DATABASE_URL: postgres://shop:${POSTGRES_PASSWORD}@db:5432/shop
      REDIS_URL: redis://cache:6379/0
    depends_on:
      - db
    deploy:
      replicas: 2
    networks: [backend]

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: shop
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U shop"]
      interval: 5s
    networks: [backend]

  cache:
    image: redis:7
    networks: [backend]

  adminer:
    image: adminer
    ports:
      - "8081:8080"
    profiles: [debug]
    networks: [backend]

volumes:
  db-data:

networks:
  frontend:
  backend:

Schritt 1: Die Datei rendern, die Compose tatsächlich ausführt

Teams führen selten eine einzelne Datei so aus, wie sie geschrieben ist. Eine Override-Datei ergänzt Ports, eine .env-Datei füllt Variablen, und extends übernimmt Felder aus einem anderen Service. Bevor du zeichnest, frag Compose nach dem Ergebnis:

docker compose config > rendered.yaml

docker compose config führt die Override-Dateien zusammen, setzt die Variablen ein und löst extends auf; anschließend gibt es das Modell aus, das Compose ausführen wird. Zeichne nach dieser Ausgabe, nicht nach der Datei, die du gerade zufällig offen hast.

Eine Warnung: Die Ausgabe enthält die echten Werte deiner Variablen, auch alles Geheime aus .env. Behandle rendered.yaml wie die .env-Datei selbst: nicht committen, nicht teilen.

Schritt 2: Compose-Schlüssel auf Diagrammelemente abbilden

Der größte Teil des Diagramms ergibt sich direkt aus der Datei:

Compose-Schlüssel Diagrammelement
services.<name> Eine Karte pro Service, benannt nach seinem Schlüssel
image / build Auf der Karte: das Image-Tag oder der Build-Kontext
ports (8080:80) Auf der Karte und an der Kante von außen: :8080 → 80
deploy.replicas / scale Eine Replika-Zahl auf der Karte, keine zusätzlichen Boxen
networks Ein Frame pro Netzwerk; jeder Service liegt im Frame seines ersten Netzwerks
Benannte volumes Ein Volume-Node, verbunden mit den Services, die es einbinden
secrets, configs Nodes, verbunden mit den Services, die sie nutzen, nur mit Namen
depends_on Startreihenfolge, auf der Karte notiert oder als gestrichelte Kante
profiles Optionale Services: weglassen oder als optional kennzeichnen

Zwei Regeln halten das Bild ehrlich. Ein Service, der zwei Netzwerken beitritt, wie api, ist die Brücke zwischen ihnen. Setz ihn deshalb an den Rand des Frames seines ersten Netzwerks und lass seine Verbindungen in das andere hineinreichen. Und Replikas sind eine Zahl, kein Stapel Boxen: worker ×2 bleibt korrekt, wenn du auf fünf skalierst.

Schritt 3: Die Aufrufe ergänzen, die die Datei nicht zeigt

Diesen Schritt kann dir kein Tool abnehmen. Bei depends_on geht es um die Startreihenfolge: Compose startet db vor api und wartet mit condition: service_healthy, bis der Healthcheck erfolgreich ist. Darüber, wer zur Laufzeit wen aufruft, sagt es nichts.

Die echten Aufrufe verstecken sich an drei Stellen:

  • Connection-Strings. DATABASE_URL und REDIS_URL nennen Hosts (db, cache) und Ports. Jeder davon ist eine Kante.
  • In Container eingebundene Konfigurationsdateien. nginx.conf enthält proxy_pass http://api:3000;. Das ist die Kante von web zu api, und sie steht außerhalb der Compose-Datei.
  • Code. Ein Service kann einen anderen aufrufen, ohne dass dafür eine Zeile in Compose steht. worker nutzt REDIS_URL, hat aber kein depends_on auf cache. Startet Redis zu spät, scheitert der Worker beim Start, und das Diagramm ist die erste Stelle, an der diese Lücke sichtbar wird.

Eine schnelle Suche findet die meisten davon:

grep -rnE "://([^/@[:space:]]*@)?(api|web|db|cache)[:/]|proxy_pass" --include="*.conf" --include="*.yaml" --include="*.yml" --include="*.env" .

Bestätige sie dann mit den Ownern der jeweiligen Services. Zeichne Laufzeitaufrufe als durchgezogene Kanten, beschriftet mit Protokoll und Port, und halte depends_on als Notiz oder gestrichelte Kante fest, damit niemand die Startreihenfolge mit Traffic verwechselt.

Schritt 4: Entscheiden, was wegfällt

Eine Compose-Datei mischt das System mit den Tools drumherum. Meist lässt du Folgendes weg:

  • Reine Dev-Services hinter profiles, etwa adminer, Mail-Catcher oder Debug-Proxys.
  • Einmalige Jobs wie Migrationen oder Seeder, außer das Diagramm dreht sich um das Deployment.
  • Bind-Mounts für Quellcode und Konfigurationsdateien. Zeig eine Konfigurationsdatei nur über die Abhängigkeit, die sie trägt, wie hier die proxy_pass-Kante aus nginx.conf.
  • Werte von Umgebungsvariablen. Variablennamen können eine Kante erklären; Werte gehören in deinen Secret-Store, nicht in ein Diagramm.

Schritt 5: Layout aufbauen

Leg den Traffic von links nach rechts an: der Browser, dann der veröffentlichte Port, dann die Services dahinter. Zeichne jedes Netzwerk als Frame, damit ein Aufruf, der Netzwerkgrenzen überquert, sofort auffällt. Fasse die Datenspeicher zu einer Gruppe zusammen und setz Volumes unter den Service, der sie einbindet. Beschrifte jede Kante mit Protokoll und Port, zum Beispiel HTTP :3000 oder SQL :5432.

Den ersten Entwurf mit dem kostenlosen Tool erstellen

Die Karten musst du nicht von Hand zeichnen. Füge die Datei (oder die gerenderte Ausgabe; das Tool liest keine Werte von Umgebungsvariablen) in das kostenlose Tool Docker Compose als Diagramm ein. Zum Ansehen brauchst du kein Konto. Services werden zu Karten mit Image, Ports und Replikas, Netzwerke werden zu Frames, benannte Volumes, Secrets und Configs werden mit den Services verbunden, die sie nutzen, und aus depends_on werden Verbindungen zwischen Services.

Das Tool zeichnet nur, was in der Datei steht. Es zeigt keine Laufzeitaufrufe, liest weder Werte von Umgebungsvariablen noch Inhalte aus env_file, folgt keinem include, und bei einem Service mit extends zeichnet es nur die Felder, die in diesem Service selbst stehen. Deshalb bleiben die Schritte 1 und 3 wichtig.

Mit einem kostenlosen Konto öffnest du das Ergebnis in Archboard als neues Diagramm, ergänzt dann die Laufzeitkanten aus Schritt 3 und entfernst das Rauschen aus Schritt 4. So sieht der shop-Stack nach diesem Durchgang aus:

Docker-Diagramm eines Compose-Projekts: Der Browser erreicht web (nginx) auf Port 8080, web leitet an api weiter, und api sowie ein worker mit zwei Replikas rufen db (PostgreSQL) und cache (Redis) im Netzwerk backend auf. Das Volume db-data ist in db eingebunden.

10 Komponenten · 7 Verbindungen

In Archboard öffnen
Diagramminhalt
  • Browser
  • frontend
  • backend
  • web
  • api
  • cache
  • db
  • worker
  • db-data
  • HTTP :8080 → 80
  • proxy_pass :3000
  • SQL :5432
  • RESP :6379
  • jobs :6379
  • /var/lib/postgresql/data
Der shop-Stack aus diesem Guide: Services in den Frames ihrer Netzwerke, das Datenbank-Volume und die Laufzeitaufrufe aus nginx.conf und den Verbindungs-URLs, die die Compose-Datei allein nicht zeigt.

Die Karten stammen aus dem Docker-Pack, der Browser aus dem Netzwerk-Pack, und das ganze Diagramm bleibt innerhalb der 15 Diagramm-Nodes des Free-Plans. Ein weiteres Docker-Layout mit Containern, einer Registry und einem Load Balancer zeigt das Beispiel Docker Runtime Mesh.

Aktuell halten

Ein Diagramm, das aus einer Compose-Datei gezeichnet wurde, veraltet an dem Tag, an dem jemand einen Service hinzufügt. Drei Gewohnheiten helfen:

  • Ergänze eine Zeile im Pull-Request-Template: „Kommt ein Service, ein Netzwerk, ein veröffentlichter Port oder ein Connection-String hinzu? Diagramm aktualisieren.“
  • Führ bei Reviews docker compose config erneut aus und vergleiche die Service-Liste mit dem Diagramm.
  • Verlinke das Live-Diagramm im README, statt einen Screenshot einzufügen, damit es nur eine Kopie gibt, die du aktualisieren musst.

Wenn der Stack auf Kubernetes umzieht, gilt dieselbe Methode für Manifeste; siehe Von Kubernetes-YAML zum Architekturdiagramm.

FAQ

Bedeutet depends_on, dass ein Service einen anderen aufruft? Nein. Es steuert die Startreihenfolge und wartet mit condition: service_healthy zusätzlich auf einen Healthcheck. Laufzeitaufrufe ergeben sich aus Connection-Strings, Konfigurationsdateien und Code.

Kann ich mehrere Compose-Dateien auf einmal als Diagramm darstellen? Rendere sie zuerst mit docker compose config; der Befehl führt Override-Dateien zu einem Modell zusammen. Das kostenlose Tool liest jeweils eine Datei.

Liest das Tool meine .env-Datei? Nein. Variablen werden nicht ersetzt: Ein Image-Tag oder Port mit Variable, etwa image: shop-api:${TAG}, erscheint genau so, wie er geschrieben ist, und Werte unter environment und in env_file werden nicht gelesen.

Soll ich eine Box pro Container zeichnen? Zeichne eine Karte pro Service und schreib die Replika-Zahl darauf. Einzelne Container kommen und gehen; das Team denkt in Services.

Aktualisiert sich das Diagramm, wenn ich compose.yaml ändere? Nein. Es ist ein Ausgangspunkt. Halte es mit den Gewohnheiten von oben aktuell oder zeichne es mit dem Tool neu und übertrage deine Laufzeitkanten.

Kostenlos starten — ein Seat, keine Kreditkarte.

Ähnliche Beiträge

← Zurück zum Blog

In einer Minute ein Canvas öffnen

Melden Sie sich mit Google oder GitHub an. Kostenlos für einen Sitzplatz. Upgrade, wenn das Team dazukommt.