Neu veröffentlicht: E-Commerce mit Power Pages, Stripe & Analytics

· David Göschel · DevOps  · 5 minuten Lesezeit

Traefik als einziger Einstiegspunkt im Docker Compose Stack

Ich habe den Stack so umgebaut, dass Browser und Extension nur noch Traefik sehen. Der Rest läuft über zwei Docker Netze, klare Labels und keine direkten Host-Ports mehr.

Ich habe den Stack so umgebaut, dass Browser und Extension nur noch Traefik sehen. Der Rest läuft über zwei Docker Netze, klare Labels und keine direkten Host-Ports mehr.

Inhalt

Traefik als einziger Einstiegspunkt im Docker Compose Stack

Am Anfang war der Stack noch simpel genug, um ihn direkt zu verstehen. Frontend auf einem Port, Backend auf einem Port, Zitadel auf einem Port. Lokal war das bequem. Für eine kurze Demo war das auch völlig in Ordnung.

Genau an diesem Punkt entsteht aber oft der erste Denkfehler. Ein Port ist kein Architekturmodell. Ein Port ist nur ein sichtbarer Einstieg. Sobald mehrere Services dazukommen, wird aus einer bequemen Abkürzung schnell ein System, das sich nur noch über Sonderfälle erklären lässt.

Ich habe den Stack deshalb auf eine klarere Form umgestellt. Es gibt nur noch einen öffentlichen Einstiegspunkt. Alles andere läuft intern.

Die neue Topologie

Die Zielarchitektur ist einfach.

Browser
Browser Extension


      Traefik

 ┌──────┼─────────────┐
 ▼      ▼             ▼
Frontend Backend    Zitadel

Das heißt in der Praxis:

  1. Der Browser kennt nur app.localhost, api.localhost und auth.localhost.
  2. Die Extension sendet Daten nur an http://api.localhost/ingest.
  3. Traefik entscheidet, welcher Container die Anfrage bekommt.
  4. Interne Services wie Redis, Qdrant, Postgres und Ollama bleiben komplett privat.

Die eigentliche Trennung passiert über zwei Docker Netze.

networks:
  traefik_net:
    name: traefik_net

  internal_net:
    name: internal_net

traefik_net ist für alles, was Traefik routen muss. internal_net ist für Infrastruktur, die niemals direkt nach außen gehört.

Was auf welches Netz gehört

Die Regel ist einfach.

  1. Frontend gehört nur auf traefik_net.
  2. Backend gehört auf traefik_net und internal_net.
  3. Zitadel gehört auf traefik_net und internal_net.
  4. MinIO gehört auf beide Netze.
  5. Redis, Qdrant, Postgres und Ollama gehören nur auf internal_net.

So bleibt das Frontend sauber getrennt. Es kann keine Datenbank direkt sehen. Es kann nur mit Traefik sprechen. Das ist genau die Art von Begrenzung, die später auch auf Hetzner noch Sinn ergibt.

Wie Traefik die Routes erkennt

Traefik liest seine Konfiguration direkt aus Docker Labels.

frontend:
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.frontend.rule=Host(`app.localhost`)"
    - "traefik.http.routers.frontend.entrypoints=web"
    - "traefik.http.services.frontend.loadbalancer.server.port=80"

Das gleiche Muster gilt für Backend und Zitadel. Dadurch liegt die Route direkt beim Service. Kein zweites Konfigurationssystem. Keine verstreuten Sonderfälle.

Für mich ist das der eigentliche Gewinn. Wenn ich später einen neuen Dienst ergänze, muss ich nicht erst drei Dateien durchsuchen, um herauszufinden, wo die Route definiert wird. Der Dienst trägt seine Route selbst.

Warum das für Hetzner gut passt

Die Struktur ist lokal schon so aufgebaut, wie ich sie später in Produktion weiterverwenden kann.

Das bedeutet:

  1. Die Domains ändern sich, nicht die Architektur.
  2. HTTP wird später zu HTTPS.
  3. Traefik bleibt die zentrale Schicht davor.
  4. Interne Service Kommunikation bleibt gleich.

Wenn ich also später app.localhost durch app.example.com ersetze, muss ich keine Infrastruktur neu erfinden. Ich ändere nur die Domainwerte und die Zertifikatskonfiguration.

Das ist genau die Art von Vorarbeit, die ein Projekt später ruhig macht.

Was ich aus dem Traefik Einstiegspunkt gelernt habe

Ein Compose Stack wird nicht dadurch produktionsreif, dass er lokal startet. Er wird produktionsreif, wenn die Topologie schon die richtigen Grenzen kennt.

Ich brauche dafür kein größeres Tooling. Ich brauche zuerst ein sauberes Modell.

Traefik ist dabei nicht nur ein Reverse Proxy. Es ist die Schicht, die aus einzelnen Containern ein lesbares System macht.

Traefik als zentraler Einstiegspunkt vor dem Docker Compose Stack mit Label basiertem Routing zu Backend und Frontend

Die Grafik zeigt den einen öffentlichen Einstiegspunkt vor dem Stack. Browser und Extension sprechen nur mit Traefik. Die internen Services bleiben auf privaten Docker Netzen.

Alle Artikel der Serie

  1. Vision und Systemübersicht: Chrome Extension, RAG-Architektur, Projekthintergrund: Artikel lesen
  2. RAG-System Aufbau: Qdrant, Embeddings, Cosine-Ähnlichkeit in TypeScript: Artikel lesen
  3. AI Provider Abstraktion: Ollama vs. OpenAI, Interface-Design, kein Vendor-Lock-in: Artikel lesen
  4. Chrome Extension MV3: Drei isolierte Laufzeitkontexte, Message Passing, Strategy Pattern: Artikel lesen
  5. Docker Compose Strategie: Override-Pattern, von lokal zu Azure: Artikel lesen
  6. Ollama lokal vs. Docker: Die Entscheidung und ihre Konsequenzen: Artikel lesen
  7. Ollama Auto-Pull Entrypoint: Automatisiertes Modell-Setup beim Container-Start: Artikel lesen
  8. tsconfig und Vite: Node16 vs. bundler, warum Vite eigene Regeln hat: Artikel lesen
  9. Instagram Caption mit MutationObserver vollständig laden: Artikel lesen
  10. Chrome Extension Foundation mit Health-Dot und Retry-Queue: Artikel lesen
  11. Phase 2 Features: Shadow DOM Overlay, Tailwind v4, Duplicate Detection: Artikel lesen
  12. Race Condition bei der Plattformerkennung: Wie ein UI-Event die Instagram-Erkennung bricht: Artikel lesen
  13. PostId-Extraktion in zwei Instagram-Layouts: querySelector vs. Ancestor-Traversal: Artikel lesen
  14. Instagram Karussell vollständig erfassen mit MutationObserver: Lazy-Loading, Observer-before-click, Timeout-Fallback: Artikel lesen
  15. Notiz und Tags beim Screenshot-Speichern: Artikel lesen
  16. Instagram Tastatur-Shortcuts blockieren Chrome Extension Eingaben: Artikel lesen
  17. Lowercase-Normalisierung und Duplikat-Erkennung im Tag-Input: Artikel lesen
  18. Zitadel Login V2 in Docker Compose: drei versteckte Fehler: Artikel lesen
  19. PKCE OAuth in einer Chrome MV3 Extension: Artikel lesen
  20. React Frontend mit react-oidc-context und Zitadel: Artikel lesen
  21. Vite Build-Time-Umgebungsvariablen in Docker: Artikel lesen
  22. Event-Driven Ingestion mit BullMQ und Redis: Artikel lesen
  23. MinIO statt Azurite: S3-kompatible Objektspeicherung lokal und auf Hetzner: Artikel lesen
  24. access_token, id_token und der Userinfo-Endpoint: was wohin gehört: Artikel lesen
  25. Qdrant Multi-Tenancy: Pro Nutzer eine eigene Collection: Artikel lesen
  26. Wenn Backend und Frontend unterschiedliche Typen kennen: Artikel lesen
  27. Zitadel Bootstrap entfernt: Host-Header-Bug und manuelles Setup: Artikel lesen
  28. Backend Code Review: sechs Probleme vor dem Launch behoben: Artikel lesen
  29. Traefik statt NGINX: Reverse Proxy für einen wachsenden Docker-Compose-Stack: Artikel lesen
  30. Zweischichtiges Rate Limiting: Traefik und express-rate-limit mit Redis: Artikel lesen
  31. DSGVO Art. 17 korrekt implementieren: Promise.allSettled und Export-Batching: Artikel lesen
  32. Embedding-Modell-Lock-in: Warum mxbai-embed-large eine Produktionsentscheidung für immer ist: Artikel lesen
  33. Docker Volumes in Produktion: Named Volumes, Bind Mounts und der Hetzner-Volume-Trick: Artikel lesen
  34. Zwei Sicherheitslücken vor dem Launch: Redis ohne Auth und ein offener Qdrant-Admin-Port: Artikel lesen
  35. Traefik als einziger Einstiegspunkt im Docker Compose Stack: (dieser Artikel)
  36. Zitadel hinter Traefik richtig verdrahten mit Issuer, JWKS und Login V2: Artikel lesen
  37. Frontend reparieren wenn der nginx Healthcheck an localhost scheitert: Artikel lesen
  38. Observability für meinen Docker Compose Stack mit Bull Board und Dozzle: Artikel lesen
  39. Qdrant Dashboard sicher öffnen mit lokalem Traefik und SSH Tunnel: Artikel lesen
  40. Diagnose: Warum mein Chunking trotz Tokenisierung noch scheiterte: Artikel lesen
  41. Entscheidung: Warum ich den Chunk auf 1500 Tokens gesetzt habe: Artikel lesen
  42. Implementierung: Wie ich den Embedding Workflow in mehrere saubere Schritte zerlegt habe: Artikel lesen
  43. Validierung: Wie ich Chunking, Speicherung und Suche wieder zusammenbringe: Artikel lesen

Du baust gerade einen ähnlichen Multi-Service-Stack und fragst dich, wie du Routing und TLS sauber löst? Lass uns das gemeinsam einschätzen.

Zurück zum Blog

Ähnliche Beiträge

Alle Beiträge ansehen
Traefik statt NGINX für einen wachsenden Docker-Compose-Stack

Traefik statt NGINX für einen wachsenden Docker-Compose-Stack

Ab acht Services im Docker-Compose-Stack wird nginx.conf zur Wartungslast. Traefik liest Service-Konfiguration direkt aus Docker-Labels, terminiert TLS automatisch über ACME und braucht keine separate Konfigurationsdatei. Warum ich gewechselt habe und wie die Konfiguration aussieht.