> ## Content Index
> Fetch the complete content index at: https://sakis.tech/llms.txt
> Use this file to discover other available public pages before exploring further.

# Radicale Docker: Kalender und Kontakte ohne Google
- URL: https://sakis.tech/radicale-docker-kalender-kontakte-ohne-google/
- Published: 2026-10-03T12:35:06.000Z
- Updated: 2026-10-03T12:35:06.000Z
- Description: Termine und Kontakte raus aus Google, rein in einen einzigen Container: Radicale per Docker Compose starten, Benutzer anlegen, Google-Export hochladen, Android und Thunderbird verbinden. Ohne Datenbank, mit Backup.
- Author: Sakis
- Tags: homelab, docker

„Works out-of-the-box, no complicated setup or configuration required." So beschreibt sich Radicale selbst, in einer Zeile auf GitHub. Ich lese so etwas inzwischen mit hochgezogener Augenbraue, weil es meistens heißt: Es läuft, bis du dich anmelden willst. Bei Radicale stimmt der Satz zur Hälfte. Der Container läuft nach einem Befehl. Aber ohne eine Benutzerdatei lässt er niemanden hinein, seit Version 3.5.0 absichtlich. Genau diese Datei ist der eine Handgriff, den die Zeile verschweigt, und um den geht es hier.

Das Ziel: Deine Termine und Kontakte liegen am Ende nicht mehr bei Google, sondern als kleine Textdateien auf deinem Server. Handy und PC holen sie sich dort ab, über zwei offene Protokolle, die jedes Gerät seit Jahren spricht.

**Kurz gesagt:** Du exportierst Kalender und Kontakte bei Google, startest Radicale als einen Docker-Container, legst einen Benutzer an, lädst die Dateien im Browser hoch und verbindest Android (DAVx⁵) und Thunderbird. Dauer: rund 45 Minuten, der Export bei Google eingerechnet. Stufe: Standard (Docker und Kommandozeile im Groben bekannt). Stand: Radicale 3.8.1, geprüft am 03-10-2026.

![Schaubild mit drei Schritten: bei Google exportieren, Radicale starten, Geräte verbinden](https://sakis.tech/content/images/2026/10/grafik-2.png)

Der ganze Weg auf einen Blick: exportieren, Radicale starten, Geräte verbinden

## Was Radicale ist und was es bewusst nicht kann

Radicale ist ein CalDAV- und CardDAV-Server. Beide Begriffe tauchen gleich ständig auf, deshalb einmal in Ruhe:

**CalDAV und CardDAV?** Zwei offene Protokolle, über die Kalender-Apps Termine (CalDAV) und Adressbücher Kontakte (CardDAV) mit einem Server abgleichen. Dein Handy, Thunderbird und Apple-Geräte sprechen sie von Haus aus. Der Server ist das Postfach, die Apps holen ab und legen ein; welche App das tut, ist dem Server egal.

Was Radicale von Nextcloud unterscheidet, ist der Umfang. [Nextcloud](https://sakis.tech/nextcloud-docker-compose-installieren/) bringt Kalender und Kontakte als Teil einer ganzen Büro-Suite mit, samt Datenbank, PHP und Web-Oberfläche zum Termine-Eintragen. Radicale ist ein einziger Python-Prozess, der Termine als Textdateien in Ordner legt. Keine Datenbank, nichts zu warten. Dafür fehlt die Web-Oberfläche zum Arbeiten: Im Browser verwaltest du nur die Kalender selbst (anlegen, hochladen, löschen), die Termine trägst du in Thunderbird oder auf dem Handy ein. Für mich ist das kein Nachteil, sondern der Punkt: Die Apps, die ich sowieso benutze, bleiben die Apps. Der Server ist nur noch das Postfach dahinter.

Die aktuelle Version 3.8.1 ist vom 24-09-2026, und die Docker-Images baut das Projekt selbst, für amd64 und ARM. Das war nicht immer so; lange gab es nur Images aus der Community. Dass jetzt ein offizielles mit festen Versions-Tags da ist, macht die Sache für diese Anleitung deutlich einfacher.

## Was du brauchst

- Einen Linux-Server im Heimnetz mit Docker und Docker Compose. Wie die Compose-Datei grundsätzlich funktioniert, steht in der [Docker-Compose-Anleitung für Einsteiger](https://sakis.tech/docker-compose-grundlagen-fuer-einsteiger/).
- Ein Google-Konto, dessen Kalender und Kontakte umziehen sollen.
- Ein Android-Handy (für DAVx⁵) und/oder einen PC mit Thunderbird. iPhone und Mac können CalDAV und CardDAV ohne Zusatz-App, das zeige ich hier aber nicht.

Prüfen, ob Docker da ist:

**So liest du diese Anleitung:** Alles, was du selbst tun sollst, steht in einem farbigen Kasten. **\[ per klick \]** heißt: Das erledigst du mit der Maus in einer Web-Oberfläche, hier Google Kalender, Google Kontakte, die Radicale-Oberfläche oder die Apps DAVx⁵ und Thunderbird. **\[ über die shell \]** heißt: Den Befehl kopieren, ins Terminal einfügen, Enter. Stehen beide Kästen direkt untereinander, führen sie zum selben Ergebnis. Du gehst EINEN davon, nicht beide.

```bash
docker --version
docker compose version
```

Zwei Versionsnummern, und es kann losgehen. Kommt stattdessen „command not found", fehlt Docker; die Einsteiger-Anleitung oben beginnt mit der Installation.

Diese Werte benutze ich im ganzen Beitrag. Ersetze sie durch deine:

- IP-Adresse des Servers: `192.168.178.40`
- Ordner für Radicale: `~/radicale`
- Radicale-Benutzer: `sakis`
- Port: `5232`, Adresse im Browser also `http://192.168.178.40:5232`

## Schritt 1: Kalender und Kontakte bei Google exportieren

Google gibt beides in offenen Formaten heraus: Kalender als ICS-Datei, Kontakte als vCard. Das sind dieselben Formate, die Radicale später hochlädt, es gibt also nichts umzuwandeln.

**Kalender:** Im Browser **calendar.google.com** öffnen, oben rechts das Zahnrad, **Einstellungen**. Links **Importieren & Exportieren**, dann **Exportieren**. Google lädt eine ZIP-Datei herunter, darin eine ICS-Datei pro Kalender.

**Kontakte:** **contacts.google.com** öffnen, alle Kontakte auswählen (Kästchen vor einem Kontakt, dann **Alle**), oben rechts das Dreipunkt-Menü **Weitere Aktionen**, **Exportieren**. Als Format **vCard** wählen, nicht Google CSV, dann **Exportieren**. Du bekommst eine Datei `contacts.vcf`.

Die ZIP-Datei packst du aus. Am Ende liegen auf deinem PC eine oder mehrere `.ics`\-Dateien und eine `.vcf`\-Datei. Das ist die Erfolgskontrolle für diesen Schritt, und nebenbei dein erstes Backup außerhalb von Google. Lösch bei Google noch nichts. Erst, wenn alles am Ende synchron läuft.

## Schritt 2: Ordner, Compose-Datei und Konfiguration anlegen

Alles Weitere passiert auf dem Server. Per SSH anmelden, dann einen Ordner anlegen und hineinwechseln:

```bash
mkdir -p ~/radicale/config
cd ~/radicale
```

Jetzt die Compose-Datei. Editor öffnen, Inhalt einfügen, mit `Strg+O` und Enter speichern, mit `Strg+X` schließen:

```bash
nano compose.yaml
```

```yaml
services:
  radicale:
    image: ghcr.io/kozea/radicale:3.8.1
    container_name: radicale
    restart: unless-stopped
    ports:
      - "5232:5232"
    volumes:
      - ./config:/etc/radicale:ro
      - radicale-data:/var/lib/radicale

volumes:
  radicale-data:
```

Was die Zeilen tun, und wo ich vom offiziellen Beispiel abweiche:

- **image**: das offizielle Image aus der GitHub-Registry, auf die Version 3.8.1 festgenagelt. Das Projekt empfiehlt den Tag `stable`; ich nehme lieber die Nummer, dann entscheidest du, wann ein Update kommt, nicht der nächste `pull`.
- **./config:/etc/radicale:ro**: Der Ordner `config` neben der Compose-Datei landet im Container dort, wo Radicale seine Konfiguration und die Benutzerdatei sucht. Das `:ro` heißt nur lesen; der Container kann die Dateien nicht ändern, muss er auch nicht.
- **radicale-data:/var/lib/radicale**: Hier liegen die Kalender und Kontakte. Das ist ein von Docker verwaltetes Volume, kein Ordner neben der Compose-Datei. Der Grund ist nüchtern: Radicale läuft im Container als Benutzer mit der ID 1000\. Ein Ordner, den Docker beim Start selbst anlegt, gehört root, und dann bricht Radicale mit „Permission denied" ab; in den Issues des Projekts taucht genau das wiederholt auf (dazu unten mehr). Ein Docker-Volume übernimmt die Rechte aus dem Image, und das Problem taucht gar nicht erst auf.

Dann die Konfigurationsdatei. Sie heißt `config`, ohne Endung, und liegt im Ordner `config`:

```bash
nano config/config
```

```ini
[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = autodetect

[storage]
filesystem_folder = /var/lib/radicale/collections
```

Der Abschnitt `[auth]` ist der, den die GitHub-Zeile verschweigt. Ohne ihn steht Radicale auf `denyall` und lehnt jede Anmeldung ab. Mit `htpasswd` prüft es Benutzername und Passwort gegen eine Datei, die wir im nächsten Schritt anlegen. Der Abschnitt `[storage]` ist der Standardwert und steht nur da, damit du siehst, wohin die Daten gehen: in das Volume von eben. Den Netzwerk-Teil (auf welcher Adresse Radicale lauscht) setzt das Docker-Image selbst, deshalb fehlt hier ein Abschnitt `[server]`, den du in anderen Anleitungen siehst.

## Schritt 3: Den Benutzer anlegen

Die Benutzerdatei ist das Format des Apache-Webservers: eine Zeile pro Benutzer, Name, Doppelpunkt, verschlüsseltes Passwort. Das Werkzeug dafür heißt `htpasswd` und steckt auf Debian und Ubuntu im Paket `apache2-utils`:

```bash
sudo apt install apache2-utils
htpasswd -B -c config/users sakis
```

Das `-B` wählt bcrypt als Verfahren, das die Radicale-Doku empfiehlt; das `-c` legt die Datei neu an und gehört nur zum ersten Benutzer. Für einen zweiten lässt du es weg, sonst überschreibst du den ersten. Das Passwort fragt der Befehl zweimal ab, es erscheint beim Tippen nichts. Das ist dann auch das Passwort, das du später in DAVx⁵ und Thunderbird einträgst, also eines, das du dir merken kannst, oder eines aus dem Passwort-Manager.

Kontrolle:

```bash
cat config/users
```

```text
sakis:$2y$05$7hJx3f1Z6uQw2kL9…
```

Eine Zeile, der Name vorne, dahinter ein Hash, der mit `$2y$` beginnt. Das Passwort selbst steht nirgends im Klartext.

## Schritt 4: Radicale starten

```bash
docker compose up -d
docker compose ps
```

```text
NAME       IMAGE                          COMMAND                  SERVICE    CREATED        STATUS                  PORTS
radicale   ghcr.io/kozea/radicale:3.8.1   "/app/bin/python /ap…"   radicale   1 second ago   Up Less than a second   0.0.0.0:5232->5232/tcp, [::]:5232->5232/tcp
```

Das Image ist 36 MB groß, der Pull dauert Sekunden. Steht da `Up`, läuft der Server. Steht da `Exited`, zeigt `docker compose logs` den Grund, und die Stelle „Wo es klemmt" unten kennt die üblichen. Und dann der Moment, den ich bei jedem neuen Dienst mag: die Adresse im Browser öffnen, `http://192.168.178.40:5232`. Eine schlichte Anmeldeseite, Benutzername, Passwort, Sign in. Nach der Anmeldung siehst du die Verwaltung deiner Kalender, die im Moment noch leer ist.

Wie die Teile jetzt zusammenhängen:

Handy / Thunderbird→ CalDAV, CardDAV, Port 5232 →Radicale→ Textdateien →Volume radicale-data

## Schritt 5: Kalender und Kontakte hochladen

Hier kommen die Dateien aus Schritt 1 ins Spiel. Radicales Web-Oberfläche kann seit Version 3.2.2 fertige ICS- und vCard-Dateien einlesen und daraus einen Kalender beziehungsweise ein Adressbuch machen.

Im Browser auf `http://192.168.178.40:5232` angemeldet: auf **Upload an addressbook or calendar** klicken, die erste `.ics`\-Datei auswählen, hochladen. Für jeden weiteren Google-Kalender wiederholen, zum Schluss die `contacts.vcf`. Jede Datei wird ein eigener Eintrag in der Liste.

Fehlt dir ein leerer Kalender, etwa für die Familie: **Create a new addressbook or calendar**, Typ wählen, Titel vergeben. Über **Edit** gibst du jedem Eintrag Titel und Farbe.

Erfolgskontrolle: Die Liste zeigt für jede hochgeladene Datei einen Eintrag mit einer Adresse der Form `/sakis/<lange-nummer>/`. Die Nummer vergibt Radicale, der Titel aus dem Edit-Dialog ist das, was die Geräte später anzeigen. Dass alle Kalender unter `/sakis/` hängen, ist kein Zufall: Die Standard-Rechteregel `owner_only` gibt jedem Benutzer genau seinen eigenen Ordner, und nur dort finden die Apps Kalender automatisch.

## Schritt 6: Handy und PC verbinden

Jetzt der Teil, an dem die Umzugskartons leer werden. Zuerst Android, mit DAVx⁵, der App, die Android CalDAV und CardDAV beibringt (im Play Store kostet sie ein paar Euro, bei F-Droid ist sie kostenlos, es ist dieselbe App).

In DAVx⁵ ein neues Konto hinzufügen und die Anmeldung **mit URL und Benutzername** wählen. Als Basis-URL `http://192.168.178.40:5232` eintragen, darunter `sakis` und das Passwort aus Schritt 3\. DAVx⁵ fragt diese Adresse nach CalDAV und CardDAV ab und legt das Konto an. Danach erscheinen die Reiter **CardDAV** und **CalDAV**; in jedem die Kalender und Adressbücher anhaken, die synchronisiert werden sollen, dann den Abgleich anstoßen.

Erfolgskontrolle: Die Kalender-App auf dem Handy zeigt die Termine, die Kontakte-App die Namen, jeweils unter dem neuen Konto. Das ist der Augenblick, in dem der Umzug sichtbar wird. Kurz freuen ist erlaubt.

Dann Thunderbird. Die Radicale-Doku beschreibt es in zwei Sätzen: einen neuen Kalender im Netzwerk anlegen, Benutzername und die Adresse des Servers eingeben, nach dem Passwort listet Thunderbird die vorhandenen Kalender auf.

**Kalender:** In Thunderbird **Datei → Neu → Kalender**, **Im Netzwerk**. Benutzername `sakis`, Adresse `http://192.168.178.40:5232`, auf **Kalender suchen**. Thunderbird fragt das Passwort ab und zeigt alle Kalender aus Schritt 5; die gewünschten anhaken und abonnieren.

**Kontakte:** Das Adressbuch öffnen, **Neues Adressbuch → CardDAV-Adressbuch hinzufügen**, Benutzername und dieselbe Adresse, **Weiter**. Nach dem Passwort erscheint das Adressbuch aus der vCard-Datei; auswählen, fertig.

Ab jetzt landet ein Termin, den du in Thunderbird einträgst, beim nächsten Abgleich auf dem Handy, und umgekehrt. Google ist aus der Kette raus.

## Was am Ende eingestellt ist

- **Benutzer und Rechte.** Ein Benutzer, der nur seine eigenen Kalender sieht. Für Partnerin oder Kinder je ein eigener Eintrag mit `htpasswd -B config/users name` (ohne `-c`!) und danach `docker compose restart`. Einen gemeinsamen Familienkalender löst Radicale über Freigaben in der Rechte-Datei; das ist ein Thema für einen eigenen Beitrag.
- **Verschlüsselung.** Radicale spricht hier reines HTTP. Im eigenen Heimnetz ist das vertretbar, von außen nicht: Benutzername und Passwort gingen im Klartext durch das Internet. Port 5232 bleibt im Router zu. Wer unterwegs synchronisieren will, nimmt den Weg über ein [VPN ins Heimnetz](https://sakis.tech/wg-easy-docker-compose/) oder stellt einen [Reverse Proxy mit Zertifikat](https://sakis.tech/nginx-proxy-manager-installieren/) davor und trägt dann dessen HTTPS-Adresse in DAVx⁵ ein.
- **Updates.** Die Version steht in der Compose-Datei. Ein Update heißt: neue Nummer eintragen, `docker compose pull`, `docker compose up -d`. Vorher das Backup von eben. Die Release-Seite auf GitHub sagt, was sich geändert hat; bei 3.8.1 waren es Fehlerbehebungen beim Teilen von Kalendern.
- **Google.** Wenn Handy und Thunderbird ein paar Tage sauber laufen: in den Android-Einstellungen beim Google-Konto die Synchronisation für Kalender und Kontakte abschalten, damit nichts mehr doppelt landet. Die Daten bei Google löschen musst du nicht; sie veralten einfach.

**Speicherort und Backup.** Die Daten liegen im Docker-Volume `radicale-data`, als Textdateien, ein Termin pro Datei. Für ein Backup reicht ein Archiv dieses Volumes, nach dem Muster aus der Docker-Doku:

```bash
docker run --rm -v radicale-data:/data -v "$PWD":/backup alpine tar czf /backup/radicale-$(date +%F).tgz -C /data .
```

Das legt eine Datei wie `radicale-2026-10-03.tgz` in den aktuellen Ordner. Die gehört auf eine zweite Platte, so wie die Dateien aus Schritt 1\. Ja, ich weiß, ich sag das jedes Mal.

## Wo es klemmt

**„Permission denied: '/var/lib/radicale/collections'" und der Container stirbt.** Der häufigste Treffer in den Issues des Projekts (#1813, #2163), und fast immer ein Ordner, der root gehört, während Radicale als Benutzer 1000 läuft. Mit dem Docker-Volume aus Schritt 2 passiert das nicht. Wer trotzdem lieber einen Ordner neben der Compose-Datei will, legt ihn vorher an und gibt ihn dem richtigen Benutzer: `mkdir data && sudo chown 1000:1000 data`, dann `./data:/var/lib/radicale` in die Compose-Datei. In Issue #2163 beschreibt der Melder noch die Falle dahinter: Wer das Problem mit `user: "0:0"` wegdrückt, startet Radicale als root, und die Daten landen womöglich im Container statt im Volume. Nach dem nächsten Neubau sind sie weg.

**Anmeldung schlägt fehl, obwohl Passwort stimmt.** Dann liest Radicale deine `config` nicht. Prüfen: `docker compose exec radicale cat /etc/radicale/config` muss deine Datei zeigen. Zeigt es „No such file", liegt sie im falschen Ordner oder heißt `config.ini`. Radicale fällt dann still auf `denyall` zurück und lehnt alles ab.

**DAVx⁵ oder Thunderbird finden keine Kalender.** Die Doku sagt es selbst: Viele Clients können keine Kalender anlegen, nur vorhandene finden. Erst in der Web-Oberfläche hochladen oder anlegen (Schritt 5), dann das Konto im Client einrichten. Und die Adresse ohne Pfad eintragen, `http://192.168.178.40:5232`, nicht die lange Adresse eines einzelnen Kalenders; die Suche nach den Kalendern macht der Client.

**Der Google-Export ist eine ZIP-Datei.** Radicale nimmt nur `.ics` und `.vcf`. Erst auspacken, dann jede Datei einzeln hochladen.

Ist Radicale die Lösung für alle? Nein. Wer Termine lieber im Browser pflegt oder Nextcloud ohnehin laufen hat, ist dort richtig. Wer nur will, dass Handy und PC denselben Kalender sehen und die Daten zu Hause liegen, bekommt mit Radicale das kleinste Ding, das diesen Job macht: ein Container, zwei Textdateien, keine Datenbank. Dass es die Hälfte seiner Werbezeile einlöst, ist mehr, als viele schaffen.

Welche Google-Dienste hängen bei dir noch am Handy, und welcher wäre der nächste, der gehen darf? Schreib's in die Kommentare.

Wenn der Kalender umgezogen ist, sind die Fotos meistens der nächste Karton: [Raus aus Google Fotos](https://sakis.tech/raus-aus-google-fotos-so-ziehst-du-deine-bilder-zu-immich-um/) zeigt den Weg zu Immich.

sakis@homelab:\~$ echo "bleib neugierig — und mach backups" 

## Quellen

- [Radicale: Dokumentation v3 (Docker, Authentifizierung, Clients)](https://radicale.org/v3.html?ref=sakis.tech)
- [Radicale 3.8.1: Release Notes](https://github.com/Kozea/Radicale/releases/tag/v3.8.1?ref=sakis.tech)
- [Radicale: offizielle compose.yaml](https://github.com/Kozea/Radicale/blob/master/compose.yaml?ref=sakis.tech)
- [Radicale: Dockerfile (Benutzer-ID 1000, htpasswd im Image)](https://github.com/Kozea/Radicale/blob/master/Dockerfile?ref=sakis.tech)
- [Radicale: Changelog (Upload-Dialog seit 3.2.2, denyall seit 3.5.0)](https://github.com/Kozea/Radicale/blob/master/CHANGELOG.md?ref=sakis.tech)
- [Radicale Issue #2163: Permission denied im Container](https://github.com/Kozea/Radicale/issues/2163?ref=sakis.tech)
- [Radicale Issue #1813: Permission denied creating collection-cache](https://github.com/Kozea/Radicale/issues/1813?ref=sakis.tech)
- [DAVx⁵: Accounts and Collections](https://manual.davx5.com/accounts%5Fcollections.html?ref=sakis.tech)
- [Google: Kalender exportieren](https://support.google.com/calendar/answer/37111?hl=de&ref=sakis.tech)
- [Google: Kontakte exportieren](https://support.google.com/contacts/answer/7199294?hl=de&ref=sakis.tech)
- [Docker: Volumes (Backup eines Volumes)](https://docs.docker.com/engine/storage/volumes/?ref=sakis.tech)