Bis hierher ist kein einziger Dienst öffentlich erreichbar – und das ist gut so. SSH läuft über Tailscale, Komodo läuft über Tailscale, Port 22 ist im öffentlichen Internet geschlossen.

Jetzt brauchen wir den ersten kontrollierten Eingang von außen: einen Reverse Proxy. Er nimmt eingehende Anfragen entgegen, kümmert sich um HTTPS-Zertifikate, und leitet intern an den richtigen Container weiter. Über genau diesen einen Eingang werden später alle öffentlichen Apps laufen – Vaultwarden, Immich, Ghost. Container selbst veröffentlichen nichts mehr nach außen.

Wir nutzen Caddy. Konfiguration in einer einzigen Datei, Let's-Encrypt-Zertifikate vollautomatisch, sinnvolle Defaults für HTTP/2 und TLS 1.3. Und – wichtig für später – ein Community-Image mit eingebautem CrowdSec-Plugin. Das Plugin bleibt vorerst inaktiv, aber wir installieren Caddy einmal so, dass wir in Artikel 10 nichts neu aufsetzen müssen.

Am Ende hast du

  • Caddy läuft als UI-Defined Stack in Komodo
  • Image mit eingebautem CrowdSec-Plugin (vorbereitet, inaktiv)
  • DNS-Wildcard auf deinen VPS eingerichtet
  • UFW erlaubt gezielt 80/443 – der bewusste öffentliche Eingang
  • Eine Test-Subdomain ist über echtes Let's-Encrypt-HTTPS erreichbar
  • Ein Caddyfile mit Snippet-Struktur, in das die App-Artikel später nur noch ihre Routen ergänzen
  • Verstanden, wie du Caddy nach Änderungen neu lädst – ohne Container-Restart

Voraussetzungen

  • Artikel 02–06 abgeschlossen
  • Komodo läuft, Server vps-homelab ist eingebunden und aktiv
  • Eine eigene Domain (in den Beispielen deine.domain.de – ersetzt du durch deine echte Domain)
  • Zugriff auf die DNS-Verwaltung deiner Domain

1. Warum Caddy?

Was Caddy für dieses Setup mitbringt:

  • Automatisches HTTPS – Caddy bezieht und erneuert Let's-Encrypt-Zertifikate vollautomatisch. Kein Certbot, kein Cronjob, kein externes Tool.
  • Minimale Konfiguration – Eine Site mit Reverse Proxy ist im Caddyfile zwei Zeilen. Die ganze Routing-Logik für 10+ Apps liegt am Ende in einer Datei.
  • Native Docker-Integration – Service-Discovery über Container-Namen funktioniert sofort. reverse_proxy vaultwarden:80 reicht – keine IPs, kein DNS-Setup.
  • Sichere Defaults – HTTP/2 und TLS 1.3 sind an, HTTP wird automatisch auf HTTPS umgeleitet, Zertifikate werden gestaged getestet.
  • Plugin-fähig – über Plugins erweiterbar. Für uns relevant: das CrowdSec-Bouncer-Plugin, das im Image dieser Serie schon eingebaut ist.

2. Was sich gegenüber Artikel 05 ändert

In Artikel 05 hast du Port 22 aus dem öffentlichen Internet entfernt. SSH läuft nur noch über Tailscale. Jetzt machst du an einer kontrollierten Stelle wieder auf:

  • Vorher: Nur SSH (Port 22), und das auch nur über VPN
  • Jetzt: Zusätzlich Port 80 (HTTP) und 443 (HTTPS, TCP + UDP für HTTP/3) öffentlich

Klingt nach einem Rückschritt – ist aber genau das Gegenteil. Vorher hattest du keinen kontrollierten Eingang. Jetzt hast du einen, und der gehört ausschließlich Caddy. Alles dahinter läuft intern über homelab_net.

Das Sicherheitsmodell verschiebt sich:

Ebene Schutz
Netzwerk UFW erlaubt nur 80/443 öffentlich
TLS Caddy erzwingt HTTPS, leitet HTTP automatisch weiter
App-Zugriff Authelia mit 2FA (Artikel 09) für persönliche Apps
Angriffserkennung CrowdSec (Artikel 10) – Plugin ist im Caddy-Image schon eingebaut

Caddy ist die einzige Eingangstür zu deinen öffentlichen Apps. Alles, was nicht durch ihn durchgeht, kommt gar nicht erst an einen Container ran..

3. DNS vorbereiten – einmal Wildcard, fertig

Bevor wir Caddy starten, muss deine Domain auf den VPS zeigen. Beim DNS-Provider deiner Wahl legst du die folgenden Einträge an:

Typ Name Wert Funktion
A @ <VPS-IPv4> Die Apex-Domain selbst (deine.domain.de)
A * <VPS-IPv4> Alle Subdomains (vault.…, immich.…, blog.…)
AAAA (falls IPv6) @ <VPS-IPv6> IPv6 für die Apex-Domain
AAAA (falls IPv6) * <VPS-IPv6> IPv6 für alle Subdomains

Was passiert hier?

  • Der @-Eintrag (auch „Apex" oder „Root" genannt) macht deine.domain.de selbst erreichbar. Brauchst du z. B., wenn Ghost direkt auf der Hauptdomain laufen soll statt auf blog.deine.domain.de.
  • Der Wildcard-Eintrag * zeigt jede Subdomain auf deinen VPS. Du musst nicht für jede neue App in die DNS-Konsole zurück.

Brauchst du CNAMEs? Nein. CNAME-Einträge zeigen einen Namen auf einen anderen Namen statt auf eine IP – sinnvoll etwa, wenn www.deine.domain.de auf deine.domain.de zeigen soll. In diesem Setup deckt Wildcard plus Apex alles ab.

So sieht das bei Netcup im CCP aus

Im Customer Control Panel → Domains → DNS der jeweiligen Domain findest du in der Tabelle „DNS-Records" vorab schon Einträge: SOA, NS, ggf. MX (wenn Mailbox-Hosting gebucht ist). Diese nicht anfassen. Du ergänzt:

Host Typ Destination
@ A deine VPS-IPv4
* A deine VPS-IPv4
@ AAAA deine VPS-IPv6 (falls dein VPS einen hat)
* AAAA deine VPS-IPv6 (falls dein VPS einen hat)

Speichern. Netcup übernimmt die Änderungen typischerweise innerhalb von 1–5 Minuten in seine Nameserver. Andere DNS-Provider (Hetzner DNS, INWX, deSEC) folgen demselben Schema.

Check – auf deinem lokalen Rechner:

dig +short deine.domain.de
dig +short test.deine.domain.de

Erwartung: Beide Befehle geben deine VPS-IPv4 zurück. Wenn nichts kommt: Ein paar Minuten warten, dann erneut.

TTL-Tipp für die Einrichtungsphase

Wenn dein Provider eine TTL-Einstellung anbietet, kannst du die für die ersten Tage auf 300 Sekunden (5 Min) setzen. Falls du einen Eintrag korrigieren musst, propagiert die Korrektur schnell. Nach ein paar Wochen stabilen Betriebs → zurück auf Standardwert (meist 86400 = 24 h).

4. UFW – die zwei neuen Ports freigeben

Per SSH auf dem Server:

sudo ufw allow 80/tcp comment 'HTTP - Caddy'
sudo ufw allow 443/tcp comment 'HTTPS - Caddy'
sudo ufw allow 443/udp comment 'HTTP/3 - Caddy'
sudo ufw reload

Check:

sudo ufw status verbose

Erwartung:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                          Action      From
--                          ------      ----
Anywhere on tailscale0      ALLOW IN    Anywhere
80/tcp                      ALLOW IN    Anywhere                   # HTTP - Caddy
443/tcp                     ALLOW IN    Anywhere                   # HTTPS - Caddy
443/udp                     ALLOW IN    Anywhere                   # HTTP/3 - Caddy
Anywhere (v6) on tailscale0 ALLOW IN    Anywhere (v6)
80/tcp (v6)                 ALLOW IN    Anywhere (v6)              # HTTP - Caddy
443/tcp (v6)                ALLOW IN    Anywhere (v6)              # HTTPS - Caddy
443/udp (v6)                ALLOW IN    Anywhere (v6)              # HTTP/3 - Caddy

Warum auch UDP 443?

Caddy unterstützt HTTP/3 (QUIC). Das läuft über UDP 443 statt TCP. Wenn der Port zu ist, fallen Clients still auf HTTP/2 zurück – funktioniert, aber langsamer. Einmal mit aufgenommen, danach Ruhe.

5. Verzeichnis und Caddyfile anlegen

Bevor wir den Stack in Komodo bauen, legen wir das Caddyfile bereits an. Komodo verwaltet pro Stack nur Compose- und Env-Datei in der UI – zusätzliche Konfigurationsdateien (wie unser Caddyfile) legen wir manuell in das Stack-Verzeichnis, in das Komodo später Compose und Env schreiben wird.

Per SSH auf dem Server:

sudo mkdir -p /srv/docker/stacks/caddy
sudo chown -R martin:martin /srv/docker/stacks
nano /srv/docker/stacks/caddy/Caddyfile

Warum chown?

/srv/docker/ wurde in Artikel 03 als root angelegt. Damit du Caddyfile (und später weitere Konfigurationsdateien) ohne sudo bearbeiten kannst – auch bequem per VS Codium – übergeben wir das stacks-Verzeichnis einmalig deinem User. Komodo selbst läuft als root über den Docker-Socket und ist davon nicht betroffen. Ersetze martin durch deinen Usernamen, falls abweichend.

Inhalt:

# ============================================================
# Globale Optionen
# ============================================================
{
    email {$CADDY_EMAIL}

    # Caddy schreibt JSON-Access-Logs nach /var/log/caddy/access.log
    # Pro Site aktiviert über das (public)-Snippet weiter unten
    # Diese Logs liest später CrowdSec (Artikel 10)

    # CrowdSec-Plugin ist im Image enthalten, aber inaktiv.
    # Aktivierung erfolgt in Artikel 10 durch einen crowdsec-Block hier
    # und eine crowdsec-Direktive pro Route.
}

# ============================================================
# Snippet: Standard-Konfiguration für öffentliche Apps
# Wird per `import public` in jeder Site verwendet
# ============================================================
(public) {
    encode zstd gzip

    log {
        output file /var/log/caddy/access.log {
            roll_size 10MiB
            roll_keep 5
        }
        format json
    }

    header {
        Strict-Transport-Security "max-age=31536000;"
        X-Content-Type-Options    "nosniff"
        Referrer-Policy           "strict-origin-when-cross-origin"
        -Server
    }
}

# ============================================================
# Test-Endpunkt
# Wird in den nächsten Artikeln durch echte App-Routen ersetzt
# ============================================================
test.deine-domain.de {
    import public
    respond "Caddy läuft. HTTPS ist aktiv." 200
}

Mit Strg + X, Y, Enter speichern und schließen.

Was die einzelnen Blöcke machen:

Block Funktion
Globale Optionen E-Mail für Let's Encrypt; später erweitert um den CrowdSec-Block
(public) Snippet Wird per import public in jeder Site importiert. Bringt Komprimierung, Access-Logging im JSON-Format und HTTP-Sicherheitsheader mit
test.deine-domain.de Die Test-Site. Liefert eine simple Text-Antwort. Sobald in Artikel 12 Vaultwarden dazukommt, ersetzt du diesen Block.

Warum Snippets?

In den nächsten Artikeln kommen mehrere Apps dazu. Wenn du Komprimierung, Logging und Header in jeder Site einzeln definierst, verlierst du nach drei Apps die Übersicht. Das Snippet-Muster ist die einzige Art, ein Caddyfile auf 10+ Apps zu skalieren, ohne dass es zur Tapete wird. In Artikel 09 kommt das (auth)-Snippet dazu – für die Authelia-Direktive.

Optional: Caddyfile in VS Codium bearbeiten

Wer regelmäßig am Caddyfile arbeitet, kann statt nano auch VS Codium per SSH nutzen. Der Editor verbindet sich mit dem VPS, du bearbeitest die Datei lokal mit Syntax-Highlighting und Auto-Vervollständigung – die Datei lebt aber weiterhin auf dem Server.

Einmaliges Setup auf deinem Arbeitsrechner:

  1. VS Codium installieren – Download unter vscodium.com. VS Codium ist VS Code ohne die Telemetrie an Microsoft.

  2. Extension installieren: In VS Codium auf das Extension-Icon links, dann nach Open Remote - SSH suchen (Anbieter: jeanp413). Diese Extension ist die Open-Source-Alternative zu Microsofts proprietärer „Remote - SSH"-Extension, die auf VS Codium nicht läuft.

  3. SSH-Konfiguration prüfen: VS Codium liest deine Datei ~/.ssh/config. Wenn du Tailscale + SSH wie in Artikel 02/05 eingerichtet hast, sollte dort bereits ein Eintrag wie dieser stehen – oder du legst ihn jetzt an:

    Host homelab
        HostName 100.x.y.z          # deine Tailscale-IP des Servers
        User martin                  # dein User aus Artikel 02
        IdentityFile ~/.ssh/id_ed25519
    
  4. Verbinden: In VS Codium F1 (oder Strg+Shift+P) → „Remote-SSH: Connect to Host" → homelab wählen. Es öffnet sich ein neues Fenster, unten links steht jetzt SSH: homelab.

  5. Caddyfile öffnen: Über Datei → Ordner öffnen zu /srv/docker/stacks/caddy/ navigieren. Die Datei lädst du wie ein lokales File – Speichern schreibt direkt auf den Server.

  6. Empfohlene Extension auf dem Server-Profil: Caddyfile Support (Anbieter: matthewpi) für Syntax-Highlighting.

Reload nach dem Speichern: Im Integrierten Terminal von VS Codium (Strg+ö oder Terminal → Neues Terminal) – das öffnet sich automatisch auf dem Server, nicht lokal:

```
docker exec caddy caddy validate --config /etc/caddy/Caddyfile
docker exec caddy caddy reload --config /etc/caddy/Caddyfile
```

Wer lieber bei VS Code bleibt: Funktioniert mit der offiziellen „Remote - SSH"-Extension von Microsoft genauso, dann allerdings mit Telemetrie an Microsoft.

6. Stack-Anlage in Komodo

Ab hier passiert alles in der Komodo-UI.

In Komodo (http://homelab:9120 oder über deine Tailscale-IP):

  1. Links Stacks → oben rechts + New Stack
  2. Name: caddy
  3. Server: homelab
  4. Stack Type: UI Defined
  5. Create klicken

Du landest im Stack-Editor mit den Tabs für compose.yaml und .env.

7. compose.yaml

Im Compose-Tab:

name: caddy

services:
  caddy:
    image: ghcr.io/serfriz/caddy-crowdsec:2
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    env_file: .env
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config
      - ./logs:/var/log/caddy
    networks:
      - homelab_net

networks:
  homelab_net:
    external: true

Was passiert hier?

Block Erklärung
image: ghcr.io/serfriz/caddy-crowdsec:2 Community-Image mit eingebautem CrowdSec-Plugin. Funktional identisch zum offiziellen Caddy-Image, solange das Plugin nicht konfiguriert ist. Tag :2 pinnt auf Caddy v2 – Minor- und Patch-Updates kommen automatisch, ein potentieller Major-Sprung auf v3 wäre eine bewusste Entscheidung (analog zu postgres:17 in Artikel 06).
ports: 80:80, 443:443, 443:443/udp Caddy ist der einzige Container in dieser Serie, der Ports am Host veröffentlicht. Das ist Absicht.
./Caddyfile:/etc/caddy/Caddyfile:ro Read-only-Mount auf das Caddyfile, das wir in Sektion 5 angelegt haben. Caddy darf die Datei nicht ändern, du hast die Hoheit.
./data Hier landen die Let's-Encrypt-Zertifikate und der Account-State. Verlierst du dieses Verzeichnis, fordert Caddy beim nächsten Start neue Zertifikate an – kein Datenverlust, aber Let's Encrypt hat Rate-Limits
./config Caddys interne Laufzeit-Konfiguration
./logs Access-Logs, die wir in Artikel 10 für CrowdSec brauchen werden
homelab_net Das gemeinsame Netzwerk aus Artikel 03 – darüber erreicht Caddy später alle Apps per Service-Namen

8. .env

Im .env-Tab:

# E-Mail für Let's Encrypt – Cert-Renewal-Warnungen gehen hierhin
CADDY_EMAIL=admin@deine-domain.de

Eine einzige Variable reicht erstmal. Spätere Apps fügen ggf. eigene .env-Werte hinzu, aber bei Caddy selbst bleibt es bei dieser einen.

Welche E-Mail-Adresse?

Die Mail muss nicht auf derselben Domain liegen, die du absichern willst. Eine generische Admin-Mail oder dein normaler Posteingang reicht völlig – Let's Encrypt nutzt sie ausschließlich, um dich bei fehlgeschlagenen Cert-Renewals zu warnen.

Ohne diese Adresse fliegen Renewal-Probleme im Stillen aus – und irgendwann steht plötzlich nichts mehr unter HTTPS.

9. Update-Verhalten konfigurieren

Bevor du deployst, zwei Schalter im Stack-Editor:

  • Poll for Updates: on aktivieren
  • Auto Update: off lassen

Damit prüft Komodo regelmäßig, ob ein neuer Image-Tag verfügbar ist, und zeigt das in der Stack-Übersicht an – deployt aber nicht automatisch. Gerade beim Reverse Proxy willst du Updates kontrolliert einspielen (kurz die Release-Notes lesen, dann manuell Deploy) und nicht über Nacht überrascht werden, wenn ein Auto-Update mitten in einem Cert-Renewal landet.

Dieselbe Faustregel gilt später für alle Stacks: Poll an, Auto-Update aus.

10. Deploy und erster Test

Im Stack-Overview: Deploy klicken.

Komodo zieht das Image und startet den Container. Beim ersten Start passiert mehr als sonst: Caddy fordert vom Let's-Encrypt-Server ein Zertifikat für test.deine-domain.de an, validiert per HTTP-01 Challenge auf Port 80, bekommt das Zertifikat ausgestellt und legt es in /data/caddy/certificates/.

Logs prüfen (in Komodo: Container caddy → Tab Logs):

Erwartete Schlüsselzeilen:

serving initial configuration
certificate obtained successfully    identifier=test.deine-domain.de

Wenn dort ein Fehler wie no servers are configured to listen on port 80 oder connection refused auftaucht, prüfe in dieser Reihenfolge:

  1. DNS-Eintrag richtig? dig +short test.deine-domain.de zeigt deine VPS-IP?
  2. UFW: 80/tcp und 443/tcp offen? sudo ufw status
  3. Sitzt ein anderer Dienst auf Port 80? sudo ss -tulpn | grep :80

Im Browser:

https://test.deine-domain.de

Erwartung: Du siehst „Caddy läuft. HTTPS ist aktiv." Schloss-Symbol klickbar → Zertifikat ausgestellt von „Let's Encrypt".

Das war's. Du hast jetzt einen produktiv tauglichen Reverse Proxy mit echtem HTTPS – ohne eine einzige Zeile Certbot-Konfiguration.

Hinweis: Den test.deine-domain.de-Block kannst du nach dem ersten erfolgreichen Test wieder aus dem Caddyfile entfernen. Ein einfaches caddy reload danach reicht – Caddy entzieht das Zertifikat nicht aktiv, es läuft einfach aus.

11. Das Muster für alle künftigen App-Artikel

Jede App, die ab Artikel 12 dazukommt, ergänzt nur einen Block im Caddyfile. So wird das aussehen:

# Vaultwarden (Artikel 12) – persönliche App, Authelia kommt davor
vault.deine-domain.de {
    import public
    import auth          # ← kommt in Artikel 09
    reverse_proxy vaultwarden:80
}

# Ghost (Artikel 15) – öffentlicher Blog, kein Auth
blog.deine-domain.de {
    import public
    reverse_proxy ghost:2368
}

# Komodo bleibt VPN-only – KEIN Caddy-Block
# Komodo erreichst du weiterhin nur über http://homelab:9120 im Tailscale-Netz

Drei Sachen sind hier wichtig:

  • reverse_proxy vaultwarden:80 – Caddy spricht den Service-Namen an, nicht eine IP. Genau das hatten wir in Artikel 03 mit dem whoami-Test demonstriert.
  • Kein Authelia-Block für Ghost – ein Blog will gelesen werden, der Login-Bereich wird separat per Caddy-Regel auf VPN beschränkt (zeigt der Ghost-Artikel).
  • Komodo taucht hier nie auf. Admin-Tools haben in Caddy nichts verloren – auch nicht mit Authelia davor. Das war die zentrale Entscheidung aus Artikel 05.

12. Caddyfile ändern: Redeploy in Komodo

Wenn du eine neue Site einträgst (oder eine bestehende änderst), ist der Standard-Weg in dieser Serie der Redeploy über Komodo – konsistent mit allen anderen Stack-Änderungen, die du in dieser Serie machst.

Standard-Workflow:

  1. Caddyfile bearbeiten:

    nano /srv/docker/stacks/caddy/Caddyfile
    
  2. Optional, aber empfohlen: Syntax prüfen, bevor du deployst – verhindert, dass Caddy mit einem kaputten File startet:

    docker exec caddy caddy validate --config /etc/caddy/Caddyfile
    

    Bei Erfolg: Valid configuration. Bei Fehler bekommst du eine konkrete Zeilenangabe → erst korrigieren, dann weiter.

  3. In Komodo: Stack caddy öffnen → Redeploy klicken.

Was passiert dabei?

Komodo führt effektiv docker compose up -d aus. Der Container wird neu erstellt mit dem aktuellen Caddyfile. Caddys Zertifikate liegen im persistenten /data-Volume – es wird also kein neuer Let's-Encrypt-Request ausgelöst, auch bei häufigen Redeploys. Die Downtime ist Sekunden.

Schneller Hot-Reload (optional, für Power-User)

Wenn du oft am Caddyfile schraubst und Container-Restarts vermeiden willst, geht es auch per SSH ohne Komodo:

docker exec caddy caddy validate --config /etc/caddy/Caddyfile
docker exec caddy caddy reload --config /etc/caddy/Caddyfile

Vorteil: Echtes Hot-Reload, laufende Verbindungen bleiben bestehen, noch schneller. Nachteil: Du brichst aus dem Komodo-zentrierten Workflow aus. Für routine-mäßige Caddyfile-Pflege ist der Redeploy einfacher und völlig ausreichend.

13. CrowdSec – jetzt vorbereitet, später aktiviert

Das Image ghcr.io/serfriz/caddy-crowdsec enthält das CrowdSec-Bouncer-Plugin als Teil des Caddy-Binaries. Solange im Caddyfile keine crowdsec-Direktive auftaucht, passiert technisch nichts:

  • Plugin wird nicht initialisiert
  • Keine Verbindungsversuche zu einer nicht-existenten CrowdSec-Instanz
  • Performance identisch zum Stock-Caddy

Prüfen, dass das Plugin wirklich da ist:

docker exec caddy caddy list-modules | grep -i crowdsec

Erwartung:

admin.api.crowdsec
crowdsec
http.handlers.crowdsec

Das Plugin bringt drei Module mit: einen globalen Caddyfile-Block (crowdsec), einen HTTP-Handler (http.handlers.crowdsec) für die einzelnen Routen und eine Admin-API-Erweiterung (admin.api.crowdsec). Solange wir den globalen Block nicht setzen, bleibt alles inaktiv.

Wenn die Zeilen fehlen, hast du versehentlich das falsche Image gezogen.

Was Artikel 10 dann macht (Vorschau, nichts davon jetzt eintragen):

  1. CrowdSec selbst als eigenen Stack deployen (mit Zugriff auf ./logs:/var/log/caddy:ro)
  2. Im CrowdSec-Container einen API-Key für den Bouncer erzeugen
  3. Im Caddyfile globalen Block ergänzen:
    crowdsec {
        api_url http://crowdsec:8080
        api_key {$CROWDSEC_API_KEY}
    }
    
  4. Im (public)-Snippet eine crowdsec-Direktive hinzufügen

Vier Schritte und ein Redeploy – fertig. Kein Image-Wechsel, kein neuer Stack.

Und jetzt?

Caddy steht. Damit hast du den ersten kontrollierten öffentlichen Eingang in dein Setup eingebaut. Jede App, die ab Artikel 12 dazukommt, hängt sich mit einem import public und einer reverse_proxy-Zeile ein – das war's.

Vor den Apps fehlen noch zwei Infrastruktur-Bausteine, je nachdem, was du vorhast:

  • Mail-Versand (Artikel 08) – brauchst du, sobald irgendeine App Benachrichtigungen verschicken soll: Authelia bei der Account-Verifizierung, Ghost für Newsletter, Komodo für Alerts, Uptime Kuma für Downtime-Meldungen.
  • Authelia (Artikel 09) – die Auth-Schicht mit 2FA für deine persönlichen Apps (Vaultwarden, Immich, Paperless). Authelia braucht Mail – also lohnt sich Artikel 08 davor.

Im nächsten Artikel kümmern wir uns deshalb um Mail. Drei Optionen, je nach Anspruch: ganz ohne Mail (Test-Setup), Direkt-Versand pro App, oder ein zentraler SMTP-Relay-Container.

👉 Nächster Artikel: 08. Mail-Versand für Self-Hosting