Netzwerk
Diese Seite erklärt, wie Dienste, die in isolierten Docker-Daemons laufen, aus dem Internet erreichbar werden. Sie behandelt das Reverse-Proxy-System, Docker-Labels für das Routing, TLS-Zertifikate, DNS und TCP/UDP-Portweiterleitung.
Wie Dienste ihre Loopback-IPs erhalten und das .rediacc.json-Slot-System funktioniert, erfahren Sie unter Dienste.
Funktionsweise
Rediacc verwendet ein Zwei-Komponenten-Proxy-System, um externen Traffic an Container weiterzuleiten:
- Route Server — ein systemd-Dienst, der laufende Container über alle Repository-Docker-Daemons hinweg erkennt. Er inspiziert Container-Labels und generiert Routing-Konfiguration, die als YAML-Endpunkt bereitgestellt wird.
- Traefik — ein Reverse Proxy, der den Route Server alle 5 Sekunden abfragt und die erkannten Routen anwendet. Er übernimmt HTTP/HTTPS-Routing, TLS-Terminierung und TCP/UDP-Weiterleitung.
Der Ablauf sieht so aus:
Internet → Traefik (Ports 80/443/TCP/UDP)
↓ fragt alle 5s ab
Route Server (erkennt Container)
↓ inspiziert Labels
Docker Daemons (/var/run/rediacc/docker-*.sock)
↓
Container (gebunden an 127.x.x.x Loopback-IPs)
Wenn Sie die richtigen Labels zu einem Container hinzufügen und ihn mit renet compose starten, wird er automatisch routbar — keine manuelle Proxy-Konfiguration nötig.
The route server binary is kept in sync with your CLI version. When the CLI updates the renet binary on a machine, the route server is automatically restarted (~1–2 seconds). This causes no downtime, Traefik continues serving traffic with its last known configuration during the restart and picks up the new config on the next poll. Existing client connections are not affected. Your application containers are not touched.
Docker-Labels
Das Routing wird über Docker-Container-Labels gesteuert. Es gibt zwei Stufen:
Stufe 1: rediacc.*-Labels (Automatisch)
Diese Labels werden automatisch von renet compose beim Starten von Diensten injiziert. Sie müssen sie nicht manuell hinzufügen.
| Label | Beschreibung | Beispiel |
|---|---|---|
rediacc.service_name | Dienst-Identität | myapp |
rediacc.service_ip | Zugewiesene Loopback-IP | 127.0.11.2 |
rediacc.network_id | Docker-Daemon-ID des Repositories | 2816 |
rediacc.repo_name | Repository name | marketing |
rediacc.tcp_ports | TCP ports the service listens on | 8080,8443 |
rediacc.udp_ports | UDP ports the service listens on | 53 |
Wenn ein Container nur rediacc.*-Labels hat (kein traefik.enable=true), generiert der Route Server eine Auto-Route unter Verwendung des Repository-Namens und der Maschinen-Subdomain:
{service}.{repoName}.{machineName}.{baseDomain}
Zum Beispiel erhält ein Dienst namens myapp in einem Repository namens marketing auf Maschine server-1 mit Basis-Domain example.com:
myapp.marketing.server-1.example.com
Jedes Repository hat seine eigene Subdomain-Ebene, sodass Forks und verschiedene Repos nie kollidieren. Wenn Sie ein Repository forken (z.B. marketing-staging), erhält der Fork automatisch eigene Routen. Für Dienste mit eigenen Domains verwenden Sie Stufe-2-Labels oder das rediacc.domain-Label.
Benutzerdefinierte Domain via rediacc.domain
Sie können eine benutzerdefinierte Domain für einen Dienst über das rediacc.domain-Label in Ihrer docker-compose.yml festlegen. Sowohl Kurznamen als auch vollständige Domains werden unterstützt:
labels:
# Kurzname, wird zu cloud.example.com aufgelöst unter Verwendung der baseDomain der Maschine
- "rediacc.domain=cloud"
# Vollständige Domain, wird wie angegeben verwendet
- "rediacc.domain=cloud.example.com"
Ein Wert ohne Punkte wird als Kurzname behandelt und die baseDomain der Maschine wird automatisch angehängt. Ein Wert mit Punkten wird als vollständige Domain verwendet.
Wenn machineName konfiguriert ist, erhalten Dienste mit benutzerdefinierter Domain zwei Routen: eine auf der Basis-Domain (cloud.example.com) und eine auf der Maschinen-Subdomain (cloud.server-1.example.com).
Stufe 2: traefik.*-Labels (Benutzerdefiniert)
Fügen Sie diese Labels in Ihre docker-compose.yml ein, wenn Sie benutzerdefiniertes Domain-Routing, TLS oder bestimmte Einstiegspunkte wünschen. Das Setzen von traefik.enable=true weist den Route Server an, Ihre benutzerdefinierten Regeln anstelle einer Auto-Route zu verwenden.
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure,websecure-v6"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
Diese verwenden die Standard-Traefik v3 Label-Syntax.
Tipp: Rein interne Dienste (Datenbanken, Caches, Nachrichtenwarteschlangen) sollten kein
traefik.enable=truehaben. Sie benötigen nurrediacc.*-Labels, die automatisch injiziert werden.
HTTP/HTTPS-Dienste bereitstellen
Voraussetzungen
-
Infrastruktur auf der Maschine konfiguriert (Maschineneinrichtung — Infrastruktur-Konfiguration):
# Gemeinsame Zugangsdaten (einmal pro Konfiguration, gilt für alle Maschinen) rdc config infra set -m server-1 \ --cert-email admin@example.com \ --cf-dns-token your-cloudflare-api-token # Maschinenspezifische Einstellungen rdc config infra set -m server-1 \ --public-ipv4 203.0.113.50 \ --base-domain example.com rdc config infra push -m server-1 -
DNS-Einträge, die Ihre Domain auf die öffentliche IP des Servers verweisen (siehe DNS-Konfiguration unten).
Labels hinzufügen
Fügen Sie traefik.*-Labels zu den Diensten hinzu, die Sie in Ihrer docker-compose.yml bereitstellen möchten:
services:
myapp:
image: myapp:latest
environment:
- LISTEN_ADDR=${MYAPP_IP}:8080
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.myapp.entrypoints=websecure,websecure-v6"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"
database:
image: postgres:17
command: ["-c", "listen_addresses=${DATABASE_IP}"]
# Keine Traefik-Labels, Datenbank ist nur intern
| Label | Zweck |
|---|---|
traefik.enable=true | Aktiviert benutzerdefiniertes Traefik-Routing für diesen Container |
traefik.http.routers.{name}.rule | Routing-Regel — typischerweise Host(\domain`)` |
traefik.http.routers.{name}.entrypoints | Auf welchen Ports gelauscht wird: websecure (HTTPS IPv4), websecure-v6 (HTTPS IPv6) |
traefik.http.routers.{name}.tls.certresolver | Zertifikat-Resolver — verwenden Sie letsencrypt für automatisches Let’s Encrypt |
traefik.http.services.{name}.loadbalancer.server.port | Der Port, auf dem Ihre Anwendung im Container lauscht |
Der {name} in den Labels ist ein beliebiger Bezeichner — er muss nur über zusammengehörige Router-/Service-/Middleware-Labels konsistent sein.
Hinweis: Die
rediacc.*-Labels (rediacc.service_name,rediacc.service_ip,rediacc.network_id) werden automatisch vonrenet composeinjiziert. Sie müssen sie nicht in Ihre Compose-Datei einfügen.
TLS-Zertifikate
TLS-Zertifikate werden automatisch über Let’s Encrypt mittels der Cloudflare DNS-01-Challenge bezogen. Die Zugangsdaten werden einmal pro Konfiguration eingerichtet (gemeinsam für alle Maschinen):
rdc config infra set -m server-1 \
--cert-email admin@example.com \
--cf-dns-token your-cloudflare-api-token
Auto-Routen verwenden Wildcard-Zertifikate auf Repository-Subdomain-Ebene (*.marketing.server-1.example.com) anstelle von Zertifikaten pro Dienst. Dies vermeidet Let’s Encrypt-Ratenlimits und beschleunigt den Start. Routen mit benutzerdefinierten Domains verwenden Maschinen-Wildcards (*.server-1.example.com).
Für Stufe-2-Routen mit traefik.http.routers.{name}.tls.certresolver=letsencrypt werden Wildcard-Domain-SANs automatisch basierend auf dem Hostnamen der Route injiziert.
Das Cloudflare DNS API-Token benötigt Zone:DNS:Edit-Berechtigung für die Domains, die Sie absichern möchten.
TCP/UDP-Portweiterleitung
Für Nicht-HTTP-Protokolle (Mailserver, DNS, extern bereitgestellte Datenbanken) verwenden Sie TCP/UDP-Portweiterleitung.
Schritt 1: Ports registrieren
Fügen Sie die erforderlichen Ports bei der Infrastruktur-Konfiguration hinzu:
rdc config infra set -m server-1 \
--tcp-ports 25,143,465,587,993 \
--udp-ports 53
rdc config infra push -m server-1
Dies erstellt Traefik-Einstiegspunkte namens tcp-{port} und udp-{port}.
Plain TCP Example (Database)
To expose a database externally without TLS passthrough (Traefik forwards raw TCP):
services:
postgres:
image: postgres:17
command: -c listen_addresses=${POSTGRES_IP} -c port=5432
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.mydb.entrypoints=tcp-5432"
- "traefik.tcp.routers.mydb.rule=HostSNI(`*`)"
- "traefik.tcp.services.mydb.loadbalancer.server.port=5432"
Port 5432 is pre-configured (see below), so no --tcp-ports setup is needed.
Security note: Exposing a database to the internet is a risk. Use this only when remote clients need direct access. For most setups, keep the database internal and connect through your application.
Nach dem Hinzufügen oder Entfernen von Ports führen Sie immer
rdc config infra pusherneut aus, um die Proxy-Konfiguration zu aktualisieren.
Schritt 2: TCP/UDP-Labels hinzufügen
Verwenden Sie traefik.tcp.*- oder traefik.udp.*-Labels in Ihrer Compose-Datei:
services:
mail-server:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
labels:
- "traefik.enable=true"
# SMTP (Port 25)
- "traefik.tcp.routers.mail-smtp.entrypoints=tcp-25"
- "traefik.tcp.routers.mail-smtp.rule=HostSNI(`*`)"
- "traefik.tcp.routers.mail-smtp.service=mail-smtp"
- "traefik.tcp.services.mail-smtp.loadbalancer.server.port=25"
# IMAPS (Port 993), TLS-Passthrough
- "traefik.tcp.routers.mail-imaps.entrypoints=tcp-993"
- "traefik.tcp.routers.mail-imaps.rule=HostSNI(`mail.example.com`)"
- "traefik.tcp.routers.mail-imaps.tls.passthrough=true"
- "traefik.tcp.routers.mail-imaps.service=mail-imaps"
- "traefik.tcp.services.mail-imaps.loadbalancer.server.port=993"
Wichtige Konzepte:
HostSNI(\*`)` stimmt mit jedem Hostnamen überein (für Protokolle, die kein SNI senden, wie unverschlüsseltes SMTP)tls.passthrough=truebedeutet, dass Traefik die rohe TLS-Verbindung weiterleitet, ohne zu entschlüsseln — die Anwendung übernimmt die TLS-Verarbeitung selbst- Einstiegspunkt-Namen folgen der Konvention
tcp-{port}oderudp-{port}
Vorkonfigurierte Ports
Die folgenden TCP/UDP-Ports haben standardmäßig Einstiegspunkte (kein Hinzufügen über --tcp-ports erforderlich). Einstiegspunkte werden nur für konfigurierte Adressfamilien generiert, IPv4-Einstiegspunkte erfordern --public-ipv4, IPv6-Einstiegspunkte erfordern --public-ipv6:
| Port | Protokoll | Häufige Verwendung |
|---|---|---|
| 80 | HTTP | Web (automatische Weiterleitung zu HTTPS) |
| 443 | HTTPS | Web (TLS) |
| 3306 | TCP | MySQL/MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
| 27017 | TCP | MongoDB |
| 11211 | TCP | Memcached |
| 5672 | TCP | RabbitMQ |
| 9092 | TCP | Kafka |
| 53 | UDP | DNS |
| 10000–10010 | TCP | Dynamischer Bereich (automatische Zuordnung) |
DNS-Konfiguration
Automatisches DNS (Cloudflare)
Wenn --cf-dns-token konfiguriert ist, erstellt rdc config infra push automatisch die erforderlichen DNS-Einträge in Cloudflare:
| Eintrag | Typ | Inhalt | Erstellt von |
|---|---|---|---|
server-1.example.com | A / AAAA | Öffentliche IP der Maschine | push-infra |
*.server-1.example.com | A / AAAA | Öffentliche IP der Maschine | push-infra |
*.marketing.server-1.example.com | A / AAAA | Öffentliche IP der Maschine | repo up |
Maschinen-Einträge werden von push-infra erstellt und decken Routen mit benutzerdefinierten Domains (rediacc.domain) ab. Pro-Repository-Wildcard-Einträge werden automatisch von repo up erstellt und decken Auto-Routen für dieses Repository ab.
Dies ist idempotent, bestehende Einträge werden aktualisiert, wenn sich die IP ändert, und bleiben unverändert, wenn sie bereits korrekt sind.
Der Basis-Domain-Wildcard (*.example.com) muss manuell erstellt werden, wenn Sie benutzerdefinierte Domain-Labels wie rediacc.domain=erp verwenden.
Manuelles DNS
Wenn Sie Cloudflare nicht verwenden oder DNS manuell verwalten, erstellen Sie A- (IPv4) und/oder AAAA- (IPv6) Einträge:
# Maschinen-Subdomain (für Routen mit benutzerdefinierter Domain wie rediacc.domain=erp)
server-1.example.com A 203.0.113.50
*.server-1.example.com A 203.0.113.50
*.server-1.example.com AAAA 2001:db8::1
# Pro-Repository-Wildcards (für Auto-Routen wie myapp.marketing.server-1.example.com)
*.marketing.server-1.example.com A 203.0.113.50
*.marketing.server-1.example.com AAAA 2001:db8::1
# Basis-Domain-Wildcard (für Dienste mit benutzerdefinierter Domain wie rediacc.domain=erp)
*.example.com A 203.0.113.50
Mit konfiguriertem Cloudflare DNS werden Pro-Repository-Wildcard-Einträge automatisch von repo up erstellt. Bei mehreren Maschinen erhält jede Maschine ihre eigenen DNS-Einträge, die auf ihre eigene IP verweisen.
Middlewares
Traefik-Middlewares modifizieren Anfragen und Antworten. Wenden Sie sie über Labels an.
HSTS (HTTP Strict Transport Security)
labels:
- "traefik.http.middlewares.myapp-hsts.headers.stsSeconds=15768000"
- "traefik.http.middlewares.myapp-hsts.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.myapp-hsts.headers.stsPreload=true"
- "traefik.http.routers.myapp.middlewares=myapp-hsts"
Pufferung für große Datei-Uploads
labels:
- "traefik.http.middlewares.myapp-buffering.buffering.maxRequestBodyBytes=536870912"
- "traefik.http.routers.myapp.middlewares=myapp-buffering"
Mehrere Middlewares
Verketten Sie Middlewares durch Kommatrennung:
labels:
- "traefik.http.routers.myapp.middlewares=myapp-hsts,myapp-buffering"
Die vollständige Liste verfügbarer Middlewares finden Sie in der Traefik-Middleware-Dokumentation.
Diagnose
Wenn ein Dienst nicht erreichbar ist, verbinden Sie sich per SSH mit dem Server und prüfen Sie die Route-Server-Endpunkte:
Gesundheitsprüfung
curl -s http://127.0.0.1:7111/health | python3 -m json.tool
Zeigt den Gesamtstatus, die Anzahl erkannter Router und Dienste und ob Auto-Routen aktiviert sind.
Erkannte Routen
curl -s http://127.0.0.1:7111/routes.json | python3 -m json.tool
Listet alle HTTP-, TCP- und UDP-Router mit ihren Regeln, Einstiegspunkten und Backend-Diensten auf.
Port-Zuordnungen
curl -s http://127.0.0.1:7111/ports | python3 -m json.tool
Zeigt TCP- und UDP-Port-Zuordnungen für dynamisch zugewiesene Ports.
Häufige Probleme
| Problem | Ursache | Lösung |
|---|---|---|
| Dienst nicht in Routen | Container läuft nicht oder Labels fehlen | Mit docker ps auf dem Repository-Daemon überprüfen; Labels prüfen |
| Zertifikat nicht ausgestellt | DNS zeigt nicht auf den Server oder ungültiges Cloudflare-Token | DNS-Auflösung überprüfen; Cloudflare-API-Token-Berechtigungen prüfen |
| 502 Bad Gateway | Anwendung lauscht nicht auf dem deklarierten Port | Überprüfen, ob die App an ihre {SERVICE}_IP gebunden ist und der Port mit loadbalancer.server.port übereinstimmt |
| TCP-Port nicht erreichbar | Port nicht in der Infrastruktur registriert | rdc config infra set --tcp-ports ... und push-infra ausführen |
| Route server running old version | Binary was updated but service not restarted | Happens automatically on provisioning; manual: sudo systemctl restart rediacc-router |
| STUN/TURN relay not reachable | Relay addresses cached at startup | Recreate the service after DNS or IP changes so it picks up the new network config |
Vollständiges Beispiel
Dieses Beispiel stellt eine Webanwendung mit einer PostgreSQL-Datenbank bereit. Die App ist öffentlich unter app.example.com mit TLS erreichbar; die Datenbank ist nur intern verfügbar.
docker-compose.yml
services:
webapp:
image: myregistry/webapp:latest
environment:
DATABASE_URL: postgresql://app:changeme@${POSTGRES_IP}:5432/webapp
LISTEN_ADDR: ${WEBAPP_IP}:3000
labels:
- "traefik.enable=true"
- "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
- "traefik.http.routers.webapp.entrypoints=websecure,websecure-v6"
- "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
- "traefik.http.services.webapp.loadbalancer.server.port=3000"
# HSTS
- "traefik.http.middlewares.webapp-hsts.headers.stsSeconds=15768000"
- "traefik.http.middlewares.webapp-hsts.headers.stsIncludeSubdomains=true"
- "traefik.http.routers.webapp.middlewares=webapp-hsts"
postgres:
image: postgres:17
environment:
POSTGRES_DB: webapp
POSTGRES_USER: app
POSTGRES_PASSWORD: changeme
command: -c listen_addresses=${POSTGRES_IP} -c port=5432
volumes:
- ./data/postgres:/var/lib/postgresql/data
# Keine Traefik-Labels, nur intern
Rediaccfile
#!/bin/bash
up() {
mkdir -p data/postgres
renet compose -- up -d
}
down() {
renet compose -- down
}
DNS
Erstellen Sie einen A-Eintrag, der app.example.com auf die öffentliche IP Ihres Servers verweist:
app.example.com A 203.0.113.50
Bereitstellung
rdc repo up --name my-app -m server-1 --mount
Innerhalb weniger Sekunden erkennt der Route Server den Container, Traefik übernimmt die Route, fordert ein TLS-Zertifikat an, und https://app.example.com ist live.