# Baikal Server (Docker) CalDAV/CardDAV-Server ([sabre/baikal](https://sabre.io/baikal/)) per Docker Compose, mit vorgeschaltetem [Caddy](https://caddyserver.com/) als TLS-Reverse-Proxy. ## Aufbau - **baikal** — `ckulka/baikal:nginx`, liefert Baikal auf Port 80 (intern) - **caddy** — eigenes Image (`caddy:2-alpine` + `openssl`), terminiert TLS auf Port 443 und leitet an `baikal` weiter. HTTP (Port 80) wird permanent auf HTTPS umgeleitet. Alle persistenten Daten liegen im Projektverzeichnis unter `./daten`: ``` daten/ config/ Baikal-Konfiguration (Setup, Admin-Login, DB-Settings) data/ Baikal-Nutzdaten (Kalender, Adressbuecher, SQLite-DB) caddy_certs/ Selbstsigniertes TLS-Zertifikat (nur Fallback-Modus, s.u.) caddy_data/ Let's-Encrypt-Zertifikatscache (nur Let's-Encrypt-Modus) caddy_config/ Caddy Runtime-Config-Autosave ``` `daten/` ist damit der einzige Ordner, den man fuer Backups sichern bzw. bei einem Umzug/Redeploy 1:1 mitnehmen muss. ## TLS-Zertifikat (Let's Encrypt oder 100 Jahre selbstsigniert, automatisch) Der Caddy-Container hat einen eigenen Entrypoint (`caddy/entrypoint.sh`), der das `Caddyfile` bei JEDEM Start dynamisch erzeugt — abhaengig davon, ob in `.env` eine Domain + Email fuer Let's Encrypt hinterlegt sind: ### Modus 1 — Let's Encrypt (echtes Zertifikat) Werden **beide** Variablen `DOMAIN` und `LETSENCRYPT_EMAIL` in `.env` ausgefuellt, fordert Caddy automatisch ein echtes, oeffentlich vertrauenswuerdiges Let's-Encrypt-Zertifikat fuer `DOMAIN` an und erneuert es danach von selbst (Caddys eingebautes automatisches HTTPS). Voraussetzungen: - `DOMAIN` zeigt per DNS (A/AAAA-Record) auf diesen Host. - Port `80` UND `443` sind aus dem Internet erreichbar (HTTP-01 Challenge). ```bash cp .env.example .env # .env bearbeiten: # DOMAIN=baikal.meine-domain.de # LETSENCRYPT_EMAIL=ich@meine-domain.de ``` ### Modus 2 — Fallback: selbstsigniertes 100-Jahres-Zertifikat Bleibt `DOMAIN` oder `LETSENCRYPT_EMAIL` leer (Default, z.B. bei reiner LAN/IP-Nutzung ohne oeffentliche Erreichbarkeit), nutzt der Entrypoint automatisch ein selbstsigniertes Zertifikat: - **Noch keins vorhanden** unter `daten/caddy_certs/baikal.crt` + `baikal.key` -> es wird automatisch per `openssl` neu erzeugt, gueltig fuer **36500 Tage (100 Jahre)**. - **Bereits vorhanden** -> wird unveraendert weiterverwendet (kein Ueberschreiben bei jedem Neustart). Da es sich um ein selbstsigniertes Zertifikat handelt, werden CalDAV/CardDAV- Clients (Browser, Thunderbird, DAVx5, iOS/macOS Kalender-App, ...) beim ersten Verbinden eine Zertifikatswarnung anzeigen. Das Zertifikat muss dort einmalig als vertrauenswuerdig akzeptiert bzw. importiert werden. Bei Modus 1 (Let's Encrypt) entfaellt diese Warnung, da das Zertifikat echt ist. ### Hostname/CN des selbstsignierten Zertifikats anpassen Nur relevant fuer Modus 2. Der Common Name (CN) und SAN-Eintrag werden ueber die Umgebungsvariable `CADDY_CERT_CN` gesteuert (Default: `baikal.local`). Eigene Domain/IP setzen, bevor der Container zum ersten Mal hochfaehrt (das Zertifikat wird nur EINMAL erzeugt — danach `daten/caddy_certs` loeschen und neu starten, falls sich der Hostname aendert): ```bash cp .env.example .env # .env bearbeiten: CADDY_CERT_CN=baikal.meine-domain.de ``` ## Start ```bash docker compose up -d --build ``` Danach ist der Setup-Wizard erreichbar unter: ``` https:///admin/ ``` Dort einmalig Admin-Zugang, Zeitzone und Datenbank (Standard: SQLite, kein externer DB-Server noetig) einrichten. ## CalDAV/CardDAV-URLs (nach Setup) - CalDAV: `https:///dav.php/calendars//` - CardDAV: `https:///dav.php/addressbooks//` ## Neustart / Update ```bash docker compose pull docker compose up -d --build ``` Alle Nutzdaten bleiben in `./daten` erhalten, solange dieser Ordner nicht geloescht wird. ## Zertifikat erneuern / Hostname aendern ```bash docker compose down rm -rf daten/caddy_certs docker compose up -d --build ``` Beim naechsten Start wird automatisch ein neues 100-Jahres-Zertifikat mit dem aktuellen `CADDY_CERT_CN` erzeugt (nur relevant im Fallback-Modus 2, siehe oben — bei aktivem Let's Encrypt kuemmert sich Caddy selbst um Erneuerung).