Cal.com auf dem Synology NAS installieren: Terminbuchung als Calendly-Alternative
Cal.com läuft als selbstgehostete Terminbuchungsplattform auf dem Synology NAS – DSGVO-konform, ohne SaaS-Abo. Anleitung mit Compose-Stack (PostgreSQL, Redis), korrekten Secrets und Nginx Proxy Manager.

Wer als Berater, Dienstleister oder kleines Unternehmen Kundentermine online buchbar machen will, landet schnell bei Calendly – einem US-amerikanischen SaaS-Dienst, der monatliche Kosten verursacht und Buchungsdaten auf fremden Servern speichert. Ähnlich wie bei der Zeiterfassung mit Kimai gibt es auch hier eine vollwertige Open-Source-Alternative, die sich auf dem eigenen Synology NAS betreiben lässt: Cal.com ist mit über 30.000 GitHub-Stars die meistgenutzte selbstgehostete Terminbuchungsplattform und bietet öffentliche Buchungsseiten, CalDAV-Integration, E-Mail-Bestätigung und Teamkalender – alles unter der eigenen Domain, DSGVO-konform, ohne Fremdzugriff.
Voraussetzungen
- Synology NAS mit DSM 7.2 und installiertem Container Manager (x86_64-Modell empfohlen, z. B. DS923+, DS720+)
- Mindestens 4 GB RAM auf dem NAS (Cal.com-Image 1,52 GB + PostgreSQL + Redis)
- Ca. 3–5 GB freier Speicherplatz auf
/volume1 - Eigene Domain oder Synology DDNS (
xxx.synology.me) mit gültigem SSL-Zertifikat - Nginx Proxy Manager bereits als Container installiert – Anleitung: Nginx Proxy Manager auf der Synology mit Container Manager einrichten
- SSH-Zugang zum NAS (Anleitung: SSH auf dem Synology NAS aktivieren und verbinden)
- SMTP-Zugangsdaten eines E-Mail-Anbieters für Buchungsbestätigungen (z. B. Strato, IONOS, Gmail)
Schritt 1: Ordnerstruktur anlegen
Erstelle die benötigten Verzeichnisse über die Synology File Station oder per SSH. Cal.com benötigt einen Ordner für die PostgreSQL-Datenbankdateien und einen für Redis. Alle App-Daten liegen nach der Synology-Konvention unter /volume1/docker/calcom/. Weitere Details zu Ordnerberechtigungen findest du in der Grund-Anleitung Docker-Ordner und Berechtigungen auf dem Synology NAS.
Per SSH auf dem NAS:
mkdir -p /volume1/docker/calcom/postgres /volume1/docker/calcom/redis
Die Ordner müssen vor dem Stack-Start existieren, damit Docker die Volumes mit korrekten Berechtigungen anlegen kann.
Verifizieren: In der File Station sollte die Struktur sichtbar sein. Per SSH:
ls /volume1/docker/calcom/
# Erwartete Ausgabe: postgres redis
Schritt 2: Secrets auf der Synology-Shell erzeugen
Cal.com benötigt zwei kryptografische Schlüssel, die du vor dem Deployment generieren musst. Das ist der häufigste Fehlerquell beim Cal.com-Setup: NEXTAUTH_SECRET muss exakt 32 Bytes Base64-kodiert sein – nicht 24. Die offizielle cal.diy-Dokumentation und das Troubleshooting bestätigen dies ausdrücklich.
Melde dich per SSH an der Synology an und führe folgende Befehle aus:
# NEXTAUTH_SECRET (32 Bytes – PFLICHT, nicht kürzer!)
openssl rand -base64 32
# CALENDSO_ENCRYPTION_KEY (24 Bytes für AES-256-kompatible Verschlüsselung)
openssl rand -base64 24
Kopiere beide Ausgaben sofort in einen Texteditor. Wichtig: keinen Zeilenumbruch am Ende übernehmen. Diese Werte trägst du im nächsten Schritt in die compose.yaml ein.
Verifizieren: Die Ausgabe von openssl rand -base64 32 ergibt eine Base64-Zeichenkette von ca. 44 Zeichen. Die Ausgabe von openssl rand -base64 24 ergibt ca. 32 Zeichen. Sind beide Werte vorhanden und nicht leer, kannst du fortfahren.
Schritt 3: compose.yaml erstellen
Das Cal.com-Deployment besteht aus drei Diensten: PostgreSQL 15 als Datenspeicher, Redis als Job-Queue für API-Aufgaben und E-Mail-Reminder sowie der eigentlichen Cal.com-Webapp. Der PostgreSQL-Container wartet mit einem Healthcheck, bevor Cal.com startet – das verhindert Startfehler bei langsamer Datenbankinitialisierung.
Erstelle die Datei /volume1/docker/calcom/compose.yaml mit folgendem Inhalt. Ersetze alle Platzhalter durch deine tatsächlichen Werte:
services:
database:
image: postgres:15
container_name: calcom-db
restart: unless-stopped
volumes:
- /volume1/docker/calcom/postgres:/var/lib/postgresql/data
environment:
POSTGRES_USER: calcom
POSTGRES_PASSWORD: "SicheresDBPasswort123!"
POSTGRES_DB: calcom
networks:
- calcom-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U calcom -d calcom"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: calcom-redis
restart: unless-stopped
volumes:
- /volume1/docker/calcom/redis:/data
networks:
- calcom-net
calcom:
image: calcom/cal.com:v6.2.0
container_name: calcom
restart: unless-stopped
ports:
- "3000:3000"
depends_on:
database:
condition: service_healthy
environment:
DATABASE_URL: "postgresql://calcom:SicheresDBPasswort123!@database:5432/calcom"
NEXTAUTH_SECRET: "HIER_DEIN_32-BYTE-SECRET_EINTRAGEN"
NEXTAUTH_URL: "https://cal.deinedomain.de"
NEXT_PUBLIC_WEBAPP_URL: "https://cal.deinedomain.de"
CALENDSO_ENCRYPTION_KEY: "HIER_DEIN_24-BYTE-KEY_EINTRAGEN"
NODE_ENV: production
TZ: Europe/Berlin
REDIS_URL: "redis://redis:6379"
EMAIL_FROM: "noreply@deinedomain.de"
EMAIL_SERVER_HOST: "smtp.deinprovider.de"
EMAIL_SERVER_PORT: "587"
EMAIL_SERVER_USER: "user@deinedomain.de"
EMAIL_SERVER_PASSWORD: "SmtpPasswort"
networks:
- calcom-net
networks:
calcom-net:
driver: bridge
Wichtige Umgebungsvariablen im Überblick
| Variable | Pflicht | Wert / Hinweis |
|---|---|---|
NEXT_PUBLIC_WEBAPP_URL | Ja | Deine HTTPS-Domain, kein trailing Slash – Build-Zeit-Variable |
NEXTAUTH_URL | Ja | Identisch mit WEBAPP_URL, kein trailing Slash |
NEXTAUTH_SECRET | Ja | openssl rand -base64 32 – exakt 32 Bytes |
CALENDSO_ENCRYPTION_KEY | Ja | openssl rand -base64 24 – exakt 24 Bytes |
DATABASE_URL | Ja | Muss POSTGRES_USER/-PASSWORD/-DB widerspiegeln |
REDIS_URL | Ja | Pflicht für Job-Queue und E-Mail-Reminder |
NODE_ENV | Ja | Immer production |
| SMTP-Variablen | Empfohlen | Ohne SMTP keine E-Mail-Bestätigungen |
Verifizieren: Überprüfe die Datei auf Syntaxfehler. Per SSH:
cat /volume1/docker/calcom/compose.yaml
Alle Platzhalter müssen durch echte Werte ersetzt sein. NEXTAUTH_URL und NEXT_PUBLIC_WEBAPP_URL müssen identisch und mit https:// beginnen.
Schritt 4: Stack im Container Manager starten
Öffne den Container Manager in DSM 7.2 und wechsle zum Bereich „Projekt". Klicke auf „Erstellen" und wähle als Quelle „Compose-Datei hochladen". Lade deine compose.yaml hoch oder füge den Inhalt direkt im Editor ein. Vergib als Projektname calcom. Eine detaillierte Schritt-für-Schritt-Erklärung des Compose-Projektmodus findest du unter Container Manager: Docker-Compose-Projekt anlegen, starten und aktualisieren.
Das Cal.com-Image ist ca. 1,52 GB groß – der erste Download kann je nach Verbindungsgeschwindigkeit 5–15 Minuten dauern. Nach dem Download startet PostgreSQL zuerst, der Healthcheck wird geprüft, dann startet Cal.com. Der initiale Container-Start inklusive Prisma-Datenbankmigrationen benötigt weitere 2–5 Minuten. Nicht abbrechen – das ist normales Verhalten.
Verifizieren: Im Container Manager sollten alle drei Container (calcom-db, calcom-redis, calcom) den Status „Wird ausgeführt" anzeigen. Überprüfe die Logs des calcom-Containers auf Fehler:
docker logs calcom --tail 30
Erwartete Ausgabe: keine ERROR-Zeilen, stattdessen eine Meldung wie Ready on http://0.0.0.0:3000. Der Aufruf von http://NAS-IP:3000 im Browser sollte eine Weiterleitung auf den Setup-Wizard zeigen.
Schritt 5: Reverse Proxy im Nginx Proxy Manager einrichten
Cal.com soll über deine eigene Domain per HTTPS erreichbar sein, nicht über die NAS-IP mit Port 3000. Cal.com nutzt WebSockets für Echtzeit-Features – ohne die entsprechenden Header entstehen 502/504-Fehler bei bestimmten Aktionen.
Melde dich im Nginx Proxy Manager an und lege einen neuen „Proxy Host" an:
- Domain Name:
cal.deinedomain.de - Forward Hostname / IP: IP-Adresse des Synology NAS im lokalen Netz
- Forward Port:
3000 - Websockets Support: aktivieren
- SSL: Let's-Encrypt-Zertifikat ausstellen oder vorhandenes Zertifikat wählen
Wechsle zum Tab „Advanced" und füge folgende Custom Nginx Configuration ein:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Verifizieren: Rufe https://cal.deinedomain.de im Browser auf. Du solltest eine HTTPS-Verbindung (Schloss-Symbol) sehen und zur Cal.com-Startseite oder dem Setup-Wizard weitergeleitet werden. Erscheint ein 502-Fehler, überprüfe Forward-IP/-Port und ob der calcom-Container läuft.
Schritt 6: Setup-Wizard und Admin-Account anlegen
Der Cal.com-Setup-Wizard erscheint nur beim allerersten Start, solange die Benutzertabelle leer ist. Danach ist /setup nicht mehr zugänglich. Rufe https://cal.deinedomain.de auf – du wirst automatisch zum Wizard weitergeleitet.
Im Wizard legst du fest:
- Name und E-Mail-Adresse des Admin-Accounts
- Passwort (stark wählen, wird gehashed in PostgreSQL gespeichert)
- Username – dieser erscheint in der öffentlichen Buchungs-URL:
https://cal.deinedomain.de/dein-username
Nach dem Wizard wirst du zum Dashboard weitergeleitet. Dort konfigurierst du Verfügbarkeiten, Event-Typen und das Erscheinungsbild der Buchungsseite.
Verifizieren: Nach dem Wizard wirst du automatisch eingeloggt und siehst das Cal.com-Dashboard. Navigiere zu https://cal.deinedomain.de/dein-username – dort sollte deine öffentliche Buchungsseite erscheinen. Klickt ein Besucher auf einen freien Zeitslot, erscheint das Buchungsformular.
Schritt 7: Kalender verbinden und Test-Buchung durchführen
Damit Cal.com weiß, wann du wirklich verfügbar bist, muss ein Kalender verbunden werden. Cal.com unterstützt CalDAV (für Synology Calendar, Apple Calendar) und Google Calendar per OAuth.
CalDAV-Anbindung (Synology Calendar, Apple Calendar)
Navigiere im Cal.com-Dashboard zu Einstellungen > Verbundene Kalender. Wähle „CalDAV" und trage die Verbindungsdaten deines CalDAV-Servers ein. Die CalDAV-Callback-URL lautet:
https://cal.deinedomain.de/api/integrations/caldavcalendar/callback
Wichtig: Der CALENDSO_ENCRYPTION_KEY muss korrekt gesetzt sein, da Cal.com die CalDAV-Zugangsdaten verschlüsselt in der Datenbank speichert. Ein falscher oder zu kurzer Key führt zu stillen Verbindungsfehlern.
Google Calendar (optional)
Für Google Calendar benötigst du OAuth2-Credentials aus der Google Cloud Console (Client ID + Secret). Diese trägst du als Umgebungsvariable GOOGLE_API_CREDENTIALS in der compose.yaml ein und startest den Stack neu. Ohne diese Keys ist der Google-Calendar-Verbinden-Button in Cal.com ausgegraut.
Test-Buchung durchführen
Öffne deine öffentliche Buchungsseite (https://cal.deinedomain.de/dein-username) in einem privaten Browser-Fenster oder einem anderen Gerät. Wähle einen freien Zeitslot und fülle das Buchungsformular aus. Du solltest eine Bestätigungs-E-Mail erhalten (sofern SMTP konfiguriert) und den Termin im verbundenen Kalender sehen.
Verifizieren: Die Test-Buchung erscheint im Cal.com-Dashboard unter „Buchungen". Prüfe den Posteingang der angegebenen Adresse auf die Bestätigungs-E-Mail. Im Log (docker logs calcom --tail 20) sollte kein ERROR erscheinen.
Eckdaten auf einen Blick
| Eigenschaft | Wert |
|---|---|
| Docker-Image | calcom/cal.com:v6.2.0 (Verified Publisher, AMD64 + ARM64) |
| Image-Größe | ca. 1,52 GB |
| PostgreSQL | postgres:15 (empfohlene stabile LTS-Version) |
| Redis | redis:7-alpine |
| Webapp-Port | 3000 (intern, per Reverse Proxy auf HTTPS) |
| Datenbankdaten | /volume1/docker/calcom/postgres |
| Redis-Persistenz | /volume1/docker/calcom/redis |
| Lizenz | MIT / AGPL (Open Source) |
| Setup-Dauer | ca. 45 Minuten |
Troubleshooting / Typische Fehler
- Login-Redirect auf
localhost:3000:NEXT_PUBLIC_WEBAPP_URLoderNEXTAUTH_URLsind nicht gesetzt oder auflocalhostbelassen. DaNEXT_PUBLIC_WEBAPP_URLeine Build-Zeit-Variable ist, muss nach einer Änderung der Stack vollständig neu gestartet werden. Beide Variablen auf die HTTPS-Domain setzen, kein trailing Slash. - CLIENT_FETCH_ERROR beim Login: Der Cal.com-Container kann seinen eigenen Hostnamen intern nicht auflösen. Lösung: In der
compose.yamlbeimcalcom-Serviceextra_hostseintragen:cal.deinedomain.de:host-gateway– oder sicherstellen, dass der interne DNS die Domain auflöst. - NEXTAUTH_SECRET zu kurz oder Standardplatzhalter: Cal.com verweigert den Start oder Logins schlagen fehl. Immer
openssl rand -base64 32auf der Synology-Shell ausführen und den Wert ohne Zeilenumbruch eintragen. 24 Bytes sind nicht ausreichend. - CALENDSO_ENCRYPTION_KEY – falsche Länge: Führt zu Verschlüsselungsfehlern bei CalDAV- oder OAuth-Tokens. Muss exakt 24-Byte-Base64 sein:
openssl rand -base64 24. - 502 Bad Gateway oder WebSocket-Fehler: Nginx Proxy Manager leitet keine WebSocket-Verbindungen weiter. Lösung: „Websockets Support" im NPM-Proxy-Host aktivieren und
Upgrade/Connection-Header in der Advanced-Konfiguration setzen. - PostgreSQL-Container startet nicht: Der Ordner
/volume1/docker/calcom/postgreshat falsche Berechtigungen (z. B. als root angelegt). Ordner löschen, neu mit korrekten Rechten erstellen oder per File Station anlegen. - E-Mail-Reminder werden nicht versandt: Ohne Redis-Container schlagen Job-Queue-Aufgaben still fehl. Sicherstellen, dass
REDIS_URL=redis://redis:6379gesetzt ist und der Redis-Container läuft. - Erster Start dauert sehr lange: 5–15 Minuten für den Image-Download und 2–5 Minuten für den initialen Start mit Prisma-Migrationen sind normal – nicht abbrechen.
- Prisma Studio (Port 5555) versehentlich erreichbar: Gibt ungeschützten Vollzugriff auf die PostgreSQL-Datenbank. Den Studio-Service nicht in die
compose.yamlaufnehmen und Port 5555 in der DSM-Firewall sperren.
Häufige Fragen
Kann ich Cal.com ohne eigene Domain betreiben?
Für den produktiven Einsatz nein. NEXT_PUBLIC_WEBAPP_URL und NEXTAUTH_URL müssen auf eine erreichbare HTTPS-URL zeigen. Mit einer reinen IP-Adresse funktionieren OAuth-Callbacks und E-Mail-Bestätigungslinks nicht korrekt. Als kostenlose Alternative bietet Synology DDNS die Adresse xxx.synology.me mit automatischem Let's-Encrypt-Zertifikat an.
Wie aktualisiere ich Cal.com auf eine neue Version?
Passe in der compose.yaml den Image-Tag an (z. B. von v6.2.0 auf v6.3.0), erstelle vorher ein Backup des PostgreSQL-Volumes und starte dann den Stack im Container Manager neu. Prisma-Datenbankmigrationen laufen automatisch beim Container-Start. Für Synology-Backups empfiehlt sich DSM Hyper Backup auf das Volume /volume1/docker/calcom/postgres.
Wie verbinde ich Google Calendar?
Navigiere im Cal.com-Dashboard zu Einstellungen > Integrationen > Google Calendar. Voraussetzung: Du musst in der Google Cloud Console ein OAuth2-Projekt anlegen und Client ID sowie Client Secret als Umgebungsvariable GOOGLE_API_CREDENTIALS in der compose.yaml setzen. Ohne diese Credentials ist der Verbinden-Button ausgegraut.
Unterstützt Cal.com mehrere Benutzer und Teams?
Ja. Cal.com unterstützt mehrere Nutzerkonten, Teams und verschiedene Event-Typen: 1:1-Termine, Gruppenveranstaltungen und rotierende Teamzuweisung. Der erste Benutzer nach dem Setup-Wizard wird automatisch Admin und kann weitere Konten einladen.
Was passiert mit meinen Buchungsdaten bei einem Update?
Alle Buchungen, Nutzerkonten und Kalender-Verbindungen liegen in der PostgreSQL-Datenbank unter /volume1/docker/calcom/postgres. Vor jedem Update dieses Volume sichern. Prisma führt beim Container-Start automatisch alle neuen Datenbankmigrationen durch – Datenverlust tritt dabei nicht auf, sofern das Backup vorhanden ist.
Wie lautet die CalDAV-URL für Synology Calendar?
Die CalDAV-Callback-URL lautet: https://cal.deinedomain.de/api/integrations/caldavcalendar/callback. Der CALENDSO_ENCRYPTION_KEY muss korrekt gesetzt sein, da Zugangsdaten verschlüsselt gespeichert werden.
Fazit
Cal.com ist die überzeugendste Open-Source-Alternative zu Calendly für KMU, Berater und Dienstleister, die Buchungsdaten lieber auf dem eigenen NAS behalten. Mit dem Drei-Container-Stack aus PostgreSQL, Redis und der Cal.com-Webapp ist die Installation auf dem Synology NAS in unter einer Stunde erledigt – vorausgesetzt, die Pflicht-Secrets werden korrekt erzeugt und die Domain-Variablen stimmen exakt überein. Der einmalige Mehraufwand gegenüber einem SaaS-Dienst zahlt sich durch volle Datenkontrolle, DSGVO-Konformität und null monatliche Kosten aus. Wer neben der Terminbuchung auch die Arbeitszeiten seiner Mitarbeiter erfassen will, findet mit Kimai auf dem Synology NAS eine ebenso leistungsstarke Self-Hosting-Lösung.
Weiterführende Anleitungen und Quellen
- Nginx Proxy Manager auf der Synology mit Container Manager einrichten: Reverse Proxy und SSL Schritt für Schritt
- Kimai auf dem Synology NAS installieren: professionelle Zeiterfassung für KMU
- Container Manager: Docker-Compose-Projekt anlegen, starten und aktualisieren
- SSH auf dem Synology NAS aktivieren und verbinden
- Docker-Ordner und Berechtigungen auf dem Synology NAS
Offizielle Quellen: Cal.diy – Docker Self-Hosting Dokumentation | calcom/cal.com auf Docker Hub (Verified Publisher)