docs: Dokumentation auf Feature-Stand von master aktualisiert
This commit is contained in:
12
README.md
12
README.md
@@ -10,9 +10,17 @@ Ein einfacher Daemon, der automatisch einen Geburtstagskalender für jede Mailco
|
||||
|
||||
## Kurzübersicht
|
||||
|
||||
- Liest Geburtstage aus allen CardDAV-Adressbüchern jeder Mailbox
|
||||
- Liest Geburtstage und Jahrestage aus allen CardDAV-Adressbüchern jeder Mailbox
|
||||
- Erstellt und synchronisiert automatisch einen Geburtstagskalender pro Benutzer
|
||||
- Synchronisation alle **15 Minuten**
|
||||
- Konfigurierbarer Kalendername (`CALENDAR_NAME`) und Kalenderfarbe (`CALENDAR_COLOR`)
|
||||
- Optionale Benachrichtigungen (VALARM) zur konfigurierbaren Uhrzeit
|
||||
- Konfigurierbares Sync-Intervall (`SYNC_INTERVAL`) und Event-Horizont (`EVENT_YEARS`)
|
||||
- Mailboxen einzeln ausschließbar via `MAILBOX_EXCLUDE`
|
||||
- Automatische App-Passwort-Verwaltung (persistent im State-File)
|
||||
- Integrierter Cleanup-Befehl bei doppelten Kalendern nach Umbenennung
|
||||
- Startup-Connectivity-Check, Graceful Shutdown und Docker-Healthcheck
|
||||
- Hairpin-NAT-Lösung via `MAILCOW_RESOLVE_HOST` für Docker-Netze
|
||||
- Strukturiertes Logging mit konfigurierbarem Log-Level
|
||||
- Läuft als Docker-Container direkt im Mailcow-Stack
|
||||
|
||||
## Schnellstart
|
||||
|
||||
@@ -12,7 +12,9 @@ Willkommen in der Dokumentation des **Mailcow Birthday Daemon** 🎂
|
||||
## Kurzübersicht
|
||||
|
||||
- Automatischer Geburtstagskalender für jede Mailcow-Mailbox
|
||||
- Liest Geburtstage aus allen CardDAV-Adressbüchern
|
||||
- Liest Geburtstage und Jahrestage aus allen CardDAV-Adressbüchern
|
||||
- Optionale Benachrichtigungen (VALARM) zur konfigurierbaren Uhrzeit
|
||||
- Konfigurierbares Sync-Intervall, Event-Horizont und Kalenderfarbe
|
||||
- Mailboxen einzeln ausschließbar, strukturiertes Logging mit Log-Level
|
||||
- Docker-Healthcheck, Graceful Shutdown und Startup-Connectivity-Check
|
||||
- Läuft als Docker-Container im Mailcow-Stack via `docker-compose.override.yml`
|
||||
- Synchronisation alle 15 Minuten, vollständig automatisch
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
Der Mailcow Birthday Daemon synchronisiert automatisch Geburtstagskalender für jede aktive Mailbox. Der gesamte Prozess läuft ohne Benutzereingriff ab.
|
||||
|
||||
## Startup-Connectivity-Check
|
||||
|
||||
Beim Start prüft der Daemon aktiv, ob die Mailcow-API und SOGo erreichbar sind, bevor die erste Synchronisation beginnt. Die Prüfung nutzt exponentielles Backoff (2 s → 4 s → … → max 30 s) und wiederholt sich, bis beide Dienste antworten. Im Log wird klar angegeben, welcher Dienst noch nicht bereit ist. Ein Shutdown-Signal bricht den Check sofort ab.
|
||||
|
||||
## App-Passwörter
|
||||
|
||||
- Über die Mailcow-API wird für jeden aktiven Benutzer ein App-Passwort mit Zugriff auf CardDAV und CalDAV erzeugt.
|
||||
@@ -12,10 +16,20 @@ Der Mailcow Birthday Daemon synchronisiert automatisch Geburtstagskalender für
|
||||
## Kontakte und Geburtstage
|
||||
|
||||
- Alle Kontakte aus sämtlichen Adressbüchern werden abgerufen und die Geburtstagsinformationen je Benutzer extrahiert.
|
||||
- Zusätzlich zu Geburtstagen werden auch Jahrestage (`ANNIVERSARY`-Feld nach vCard 4.0 / RFC 6350) ausgelesen. Dieses Feld wird von allen gängigen Clients unterstützt (Android, iOS, Thunderbird).
|
||||
- Geburtstags-Events erhalten das Präfix 🎂, Jahrestags-Events das Präfix 💍 – so sind beide Typen im Kalender sofort unterscheidbar.
|
||||
- Die daraus resultierenden Kalendereinträge werden im Voraus berechnet.
|
||||
- Aktuell fest eingestellt: 1 Jahr in der Vergangenheit, 10 Jahre in der Zukunft.
|
||||
|
||||
> **Hinweis zu Jahrestagen:** Die SOGo-Weboberfläche bietet kein Feld zum Anzeigen oder Bearbeiten von Jahrestagen. Das `ANNIVERSARY`-Feld muss über einen externen Client (z. B. Thunderbird, Android- oder iOS-Kontakte-App) gepflegt und per CardDAV synchronisiert werden. Das SOGo-CardDAV-Backend speichert und liefert das Feld korrekt – es fehlt lediglich die Unterstützung in der Web-UI.
|
||||
- Aktuell standardmäßig: 1 Jahr in der Vergangenheit, 10 Jahre in der Zukunft (konfigurierbar über `EVENT_YEARS`).
|
||||
- Selbstverständlich pro Mailbox isoliert – ein Benutzer sieht nur die Geburtstage seiner eigenen Kontakte.
|
||||
|
||||
## Mailbox-Filter
|
||||
|
||||
Standardmäßig erhalten alle aktiven Mailboxen einen Geburtstagskalender. Über die Umgebungsvariable `MAILBOX_EXCLUDE` können einzelne Mailboxen von der Synchronisation ausgeschlossen werden (z. B. Service-Accounts oder Shared Mailboxen). Ausgeschlossene Mailboxen werden beim Sync-Zyklus übersprungen. Bereits vorhandene Kalender in diesen Mailboxen werden dabei nicht automatisch entfernt – dafür kann der `cleanup`-Befehl verwendet werden (siehe [Troubleshooting](troubleshooting.md#doppelte-kalender-nach-umbenennung-von-calendar_name)).
|
||||
|
||||
Die Variable kann jederzeit – auch bei bestehenden Installationen – per Update hinzugefügt oder geändert werden.
|
||||
|
||||
## Kalendersynchronisation
|
||||
|
||||
- Die berechneten Ereignisse werden in einen Kalender synchronisiert, dessen Name über `CALENDAR_NAME` konfigurierbar ist (Standard: „Birthdays"). Der Anzeigename kann vom Benutzer in SOGo zusätzlich umbenannt werden.
|
||||
@@ -23,6 +37,13 @@ Der Mailcow Birthday Daemon synchronisiert automatisch Geburtstagskalender für
|
||||
|
||||
> **Wichtig (betrifft nur Updates von vor v0.2.0):** Damit die Umbenennung korrekt erkannt wird, muss der Daemon **mindestens einmal** mit dem neuen Code (ab v0.2.0) und dem **alten** Kalendernamen gelaufen sein, damit der Name im State-File gespeichert wird. Erst danach `CALENDAR_NAME` ändern und erneut starten. Wird der Name geändert, bevor der State aktualisiert wurde, kann der alte Kalender nicht automatisch entfernt werden. In diesem Fall kann der integrierte Cleanup-Befehl verwendet werden (siehe [Troubleshooting](troubleshooting.md#doppelte-kalender-nach-umbenennung-von-calendar_name)).
|
||||
|
||||
## Kalenderfarbe
|
||||
|
||||
- Der Daemon setzt automatisch die CalDAV-Property `calendar-color` (Apple-Namespace) auf dem Geburtstagskalender. Dadurch hebt sich der Kalender im Client farblich sofort ab.
|
||||
- Die Farbe ist über `CALENDAR_COLOR` konfigurierbar (Standard: `#D01818`). Das Format ist `#RRGGBB`.
|
||||
- Hat ein Benutzer die Farbe seines Kalenders manuell geändert (z. B. in SOGo oder einem anderen Client), wird diese Anpassung respektiert und nicht überschrieben.
|
||||
- Bei einer Änderung von `CALENDAR_COLOR` werden alle Kalender aktualisiert, deren Farbe nicht manuell angepasst wurde.
|
||||
|
||||
## Benachrichtigungen
|
||||
|
||||
- Wenn `NOTIFICATION_ENABLED=true` gesetzt ist, erhält jedes Geburtstags-Event einen **VALARM** (iCal-Alarm). Kalender-Clients (SOGo, iOS, Android, Thunderbird) zeigen dann zur konfigurierten Uhrzeit eine Benachrichtigung an. Das Event bleibt weiterhin ein Ganztags-Event.
|
||||
@@ -31,4 +52,21 @@ Der Mailcow Birthday Daemon synchronisiert automatisch Geburtstagskalender für
|
||||
|
||||
## Synchronisationsintervall
|
||||
|
||||
Der Synchronisationszyklus läuft alle **15 Minuten** automatisch.
|
||||
Der Synchronisationszyklus läuft standardmäßig alle **15 Minuten** automatisch. Das Intervall kann über die Umgebungsvariable `SYNC_INTERVAL` angepasst werden (z. B. `SYNC_INTERVAL=30m`). Details zu den möglichen Werten finden sich in der [Umgebungsvariablen-Tabelle](schnellstart.md#umgebungsvariablen).
|
||||
|
||||
## Graceful Shutdown
|
||||
|
||||
Der Daemon reagiert auf `SIGTERM` und `SIGINT` (z. B. durch `docker stop`) und beendet sich sauber:
|
||||
|
||||
1. Der aktuelle Synchronisationszyklus wird noch vollständig abgeschlossen.
|
||||
2. Ungespeicherte App-Passwörter werden in die Zustandsdatei geschrieben.
|
||||
3. Erst danach beendet sich der Prozess.
|
||||
|
||||
Dadurch wird sichergestellt, dass das State-File konsistent bleibt und keine Daten verloren gehen. Auch der Startup-Connectivity-Check wird bei einem Shutdown-Signal sofort abgebrochen.
|
||||
|
||||
## Healthcheck
|
||||
|
||||
- Das Dockerfile enthält eine `HEALTHCHECK`-Anweisung, die den eingebauten Subcommand `healthcheck` nutzt – es werden keine externen Tools wie `curl` oder `wget` benötigt und kein Port wird geöffnet.
|
||||
- Nach jedem Sync-Lauf schreibt der Daemon eine kleine Statusdatei (`health.json`) neben das State-File. Der `healthcheck`-Subcommand liest diese Datei und prüft, ob der letzte Sync aktuell und fehlerfrei war.
|
||||
- Docker zeigt den Status in `docker ps` als `(healthy)` oder `(unhealthy)` an.
|
||||
- Der Healthcheck meldet **unhealthy**, wenn der letzte Sync-Lauf fehlgeschlagen ist oder länger als das konfigurierte Sync-Intervall plus 5 Minuten Toleranz zurückliegt. Während der Startphase (bevor der erste Sync abgeschlossen ist) gilt der Daemon als healthy.
|
||||
|
||||
@@ -24,9 +24,14 @@ services:
|
||||
- MAILCOW_BASE=https://mail.example.com
|
||||
- MAILCOW_APIKEY=DEIN-APIKEY-HIER
|
||||
- CALENDAR_NAME=Birthdays
|
||||
# - CALENDAR_COLOR=#D01818
|
||||
# - MAILCOW_RESOLVE_HOST=nginx-mailcow
|
||||
# - NOTIFICATION_ENABLED=true
|
||||
# - NOTIFICATION_TIME=08:00
|
||||
# - SYNC_INTERVAL=15m
|
||||
# - EVENT_YEARS=10
|
||||
# - MAILBOX_EXCLUDE=user1@example.com,user2@example.com
|
||||
# - LOG_LEVEL=info
|
||||
volumes:
|
||||
- birthdaydaemon:/data
|
||||
|
||||
@@ -49,7 +54,7 @@ cd /opt/mailcow-dockerized
|
||||
docker compose pull birthdaydaemon && docker compose up -d --no-deps birthdaydaemon
|
||||
```
|
||||
|
||||
> **Hinweis:** Nach dem Start wartet der Daemon zunächst **15 Sekunden**, bevor die erste Synchronisation beginnt. Diese Verzögerung stellt sicher, dass abhängige Dienste (z. B. Nginx, SOGo) vollständig bereit sind.
|
||||
> **Hinweis:** Nach dem Start prüft der Daemon aktiv die Erreichbarkeit der Mailcow-API und SOGo, bevor die erste Synchronisation beginnt. Die Prüfung wiederholt sich mit steigendem Intervall (2 s → 4 s → … → max 30 s), bis beide Dienste antworten. Im Log wird klar angezeigt, welcher Dienst noch nicht bereit ist.
|
||||
|
||||
## Umgebungsvariablen
|
||||
|
||||
@@ -59,9 +64,14 @@ docker compose pull birthdaydaemon && docker compose up -d --no-deps birthdaydae
|
||||
| `MAILCOW_APIKEY` | **Ja** | – | API-Key mit Lese-/Schreibzugriff aus dem Mailcow-Admin-Panel |
|
||||
| `MAILCOW_RESOLVE_HOST` | Nein | – | Interner Hostname für TCP-Verbindungen (z. B. `nginx-mailcow`). Löst Hairpin-NAT-Probleme in Docker-Netzen. TLS nutzt weiterhin den Hostnamen aus `MAILCOW_BASE`. |
|
||||
| `CALENDAR_NAME` | Nein | `Birthdays` | Name des Geburtstagskalenders, der in jeder Mailbox erstellt wird |
|
||||
| `CALENDAR_COLOR` | Nein | `#D01818` | Farbe des Geburtstagskalenders im Hex-Format (z. B. `#FF6600`). Wird nur gesetzt, wenn der Benutzer die Farbe nicht manuell geändert hat. |
|
||||
| `NOTIFICATION_ENABLED` | Nein | `false` | Aktiviert Kalender-Benachrichtigungen (VALARM) für Geburtstags-Events (`true`/`false`) |
|
||||
| `NOTIFICATION_TIME` | Nein | `08:00` | Uhrzeit der Benachrichtigung im Format `HH:MM` (nur wirksam wenn `NOTIFICATION_ENABLED=true`) |
|
||||
| `STATEFILE` | Nein | `state.json` (im Container: `/data/state.json`) | Pfad zur Zustandsdatei, in der App-Passwörter und der aktuelle Kalendername gespeichert werden |
|
||||
| `SYNC_INTERVAL` | Nein | `15m` | Intervall zwischen den Synchronisationsläufen im Go-Duration-Format (z. B. `10m`, `30m`, `1h`). Mindestwert: `1m`. |
|
||||
| `EVENT_YEARS` | Nein | `10` | Anzahl der Jahre, für die Geburtstags-Events im Voraus erzeugt werden. Gültige Werte: `1`–`30`. Kleinere Werte können die Performance in Kalender-Clients verbessern. |
|
||||
| `MAILBOX_EXCLUDE` | Nein | – | Kommagetrennte Liste von Mailadressen, die von der Synchronisation ausgeschlossen werden (z. B. `admin@example.com,noreply@example.com`). Standardmäßig erhalten alle aktiven Mailboxen einen Geburtstagskalender. |
|
||||
| `LOG_LEVEL` | Nein | `info` | Log-Verbosity: `debug`, `info`, `warn` oder `error`. Im `debug`-Modus werden einzelne Kalendereinträge (hinzugefügt/entfernt) und Kontaktdetails geloggt. |
|
||||
|
||||
## API-Key erstellen
|
||||
|
||||
@@ -78,7 +88,7 @@ cd /opt/mailcow-dockerized
|
||||
docker compose logs -f birthdaydaemon
|
||||
```
|
||||
|
||||
Nach dem Start synchronisiert der Daemon automatisch alle 15 Minuten die Geburtstagskalender für jede Mailbox.
|
||||
Nach dem Start synchronisiert der Daemon automatisch alle 15 Minuten (konfigurierbar über `SYNC_INTERVAL`) die Geburtstagskalender für jede Mailbox.
|
||||
|
||||
> **Hinweis für bestehende Installationen:** Falls der Daemon die Mailcow-API wegen Hairpin-NAT nicht erreichen kann, muss lediglich `MAILCOW_RESOLVE_HOST=nginx-mailcow` als Umgebungsvariable ergänzt werden. Details siehe [Installationsabschnitt](#installation).
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
## Container startet, aber keine Kalender werden erstellt
|
||||
|
||||
1. Logs prüfen: `docker compose logs -f birthdaydaemon`
|
||||
2. Sicherstellen, dass der API-Key **Lese- und Schreibzugriff** hat (nicht nur Lesezugriff).
|
||||
3. Prüfen, ob die Mailbox aktiv ist – inaktive Mailboxen werden übersprungen.
|
||||
2. Für detaillierte Ausgaben `LOG_LEVEL=debug` als Umgebungsvariable setzen – damit werden einzelne Kontakte und Kalendereinträge sichtbar.
|
||||
3. Sicherstellen, dass der API-Key **Lese- und Schreibzugriff** hat (nicht nur Lesezugriff).
|
||||
4. Prüfen, ob die Mailbox aktiv ist – inaktive Mailboxen werden übersprungen.
|
||||
|
||||
## Verbindungsfehler / Timeout
|
||||
|
||||
@@ -33,12 +34,12 @@ docker compose exec birthdaydaemon /mailcow-birthday-daemon cleanup Birthdays
|
||||
**Beispielausgabe:**
|
||||
|
||||
```
|
||||
2026/03/28 23:46:22 INFO starting calendar cleanup calendarName=Birthdays
|
||||
2026/03/28 23:46:22 INFO using internal resolve host for connections resolveHost=nginx-mailcow
|
||||
2026/03/28 23:46:22 INFO removed old birthday calendar user=user1@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:23 INFO removed old birthday calendar user=user2@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:23 INFO removed old birthday calendar user=user3@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:24 INFO cleanup finished processed=5 skipped=0
|
||||
2026/03/28 23:46:22 [INFO] starting calendar cleanup calendarName=Birthdays
|
||||
2026/03/28 23:46:22 [INFO] using internal resolve host for connections resolveHost=nginx-mailcow
|
||||
2026/03/28 23:46:22 [INFO] removed old birthday calendar user=user1@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:23 [INFO] removed old birthday calendar user=user2@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:23 [INFO] removed old birthday calendar user=user3@example.com calendar=Birthdays
|
||||
2026/03/28 23:46:24 [INFO] cleanup finished processed=5 skipped=0
|
||||
```
|
||||
|
||||
> **Hinweis:** Der Daemon muss vorher mindestens einmal gelaufen sein, damit App-Passwörter im State-File vorhanden sind. Benutzer ohne gespeichertes Passwort werden übersprungen.
|
||||
@@ -46,3 +47,10 @@ docker compose exec birthdaydaemon /mailcow-birthday-daemon cleanup Birthdays
|
||||
## Kalender erscheint nicht in SOGo
|
||||
|
||||
SOGo zeigt neue Kalender manchmal erst nach einem Neuladen der Seite (Strg+Shift+R) oder nach dem nächsten Login an. Der Kalender wird unter dem Namen erstellt, der in `CALENDAR_NAME` konfiguriert ist (Standard: `Birthdays`).
|
||||
|
||||
## Healthcheck meldet `unhealthy`
|
||||
|
||||
1. Logs prüfen: `docker compose logs -f birthdaydaemon`
|
||||
2. Status manuell abfragen: `docker compose exec birthdaydaemon /mailcow-birthday-daemon healthcheck`
|
||||
3. Der Healthcheck meldet `unhealthy`, wenn der letzte Sync-Lauf fehlgeschlagen ist oder länger als 20 Minuten zurückliegt.
|
||||
4. Falls der Container gerade erst gestartet wurde, kann es bis zu 2 Minuten dauern, bis der erste Sync abgeschlossen und der Status `healthy` ist.
|
||||
|
||||
Reference in New Issue
Block a user