{
    "kind": 30023,
    "id": "a1f1bd174cfaae44ca0cc27883091b6a7610cb5fe19e4d4815796e9465d15972",
    "pubkey": "c1baf4f74cd829963828b1da8d73e52cc94caa6d8dc944f7ca450a75c4b3311f",
    "created_at": 1791891899,
    "tags": [
        [
            "title",
            "Cal.com selbst hosten 2026: Was nach dem Wechsel zu Closed Source noch geht und welche Alternativen tragen"
        ],
        [
            "d",
            "cal-com-selbst-hosten-2026"
        ],
        [
            "summary",
            "Cal.com ist seit April 2026 Closed Source. Was Cal.diy noch kann, warum es kein aktuelles Image gibt und welche selbst gehosteten Alternativen tragen."
        ],
        [
            "published_at",
            "1791891899"
        ]
    ],
    "content": "\nCal.com l\u00e4sst sich im Oktober 2026 nur noch eingeschr\u00e4nkt selbst hosten. Der Hersteller hat den Produktionscode im April 2026 geschlossen. Offen geblieben ist ein abgespeckter Ableger namens Cal.diy, f\u00fcr den es kein aktuelles fertiges Image gibt und von dessen Produktivbetrieb der Hersteller selbst abr\u00e4t. F\u00fcr eine Terminbuchung ohne Abo und ohne Daten bei Dritten kommen vor allem Tymeslot, Calnode und Easy!Appointments infrage. Welches davon passt, h\u00e4ngt an einer Frage: eine Instanz je Person oder Betrieb, oder eine Instanz f\u00fcr viele.\n\nStand aller Angaben: 13.10.2026. Grundlage sind GitHub- und Docker-Hub-API, eine Durchsicht des Quellcodes und ein lokaler Test von Calnode. Die \u00fcbrigen Kandidaten wurden nicht live installiert.\n\n## Cal.com ist seit April 2026 Closed Source, offen ist nur noch Cal.diy\n\nAm 14.04.2026 k\u00fcndigte Cal.com die Umstellung auf geschlossenen Quellcode an. Als Grund nennt der Beitrag Sicherheitsrisiken durch KI-gest\u00fctzte Schwachstellensuche [1]. Einen Tag sp\u00e4ter wurde das Repository `calcom/cal.com` in `calcom/cal.diy` umbenannt. Der Umstellungs-Commit l\u00f6schte rund 412.000 Zeilen in 4.080 Dateien [2][3]. Wer heute `github.com/calcom/cal.com` aufruft, landet bei Cal.diy.\n\nSeitdem gelten zwei Lizenzen nebeneinander. Auf dem Zweig `main` steht Cal.diy vollst\u00e4ndig unter MIT, keine Funktion braucht mehr einen Lizenzschl\u00fcssel [4]. Die letzte ver\u00f6ffentlichte Version ist aber v6.2.0 vom 01.03.2026. Sie steht unter AGPLv3, ihre `ee`-Ordner (Teams, Organisationen, Workflows, SSO und weitere) unter einer kommerziellen Lizenz, die den Produktivbetrieb ohne Enterprise-Abo untersagt [5]. MIT bekommt also nur, wer selbst aus `main` baut. Einen neuen Versionstag gab es seit der Umstellung nicht.\n\nREADME und Dokumentation empfehlen Cal.diy \u201estrictly \u2026 for personal, non-production use\u201c und verweisen f\u00fcr kommerziellen Einsatz auf Cal.com. Cal.com \u00fcbernimmt nach eigener Aussage keine Gew\u00e4hr f\u00fcr die Sicherheit des offenen Projekts [6]. Eine Lizenzbedingung ist das nicht: Der MIT-Text erlaubt Nutzung, Ver\u00e4nderung und Verkauf, solange Copyright- und Lizenzhinweis erhalten bleiben [4]. Gepflegt wird Cal.diy laut Hersteller von ehemaligen Praktikanten [2]. Auf `main` landeten im April 39 Commits, im September 14, im Oktober bis zum 13. keiner.\n\n## Anleitungen mit fertigem Cal.com-Image beschreiben den Stand vom M\u00e4rz 2026\n\nWer einer \u00e4lteren Anleitung folgt und `calcom/cal.com` von Docker Hub zieht, bekommt v6.2.0 vom 02.03.2026, also den AGPL-Stand mit kommerziellem EE-Teil (5,1 Millionen Abrufe). Das Nachfolge-Image `calcom/cal.diy`, auf das README und Doku verweisen, hatte am 13.10.2026 null Tags und null Abrufe [7]. Das fr\u00fchere Repository `calcom/docker` ist seit dem 29.10.2025 archiviert [8].\n\nLaut Issue #28995, offen seit dem 24.04.2026, ist der Fehler im Bau-Ablauf behoben; es fehlt ein neuer Tag, den niemand mit den n\u00f6tigen Rechten setzt. Die letzten acht Release-L\u00e4ufe (12. bis 26.09.2026) schlugen fehl [9]. Ein Nutzer dokumentierte am 30.09.2026 den Bau aus dem Quellcode: rund 36 Minuten, in der Spitze etwa 6,5 GB Arbeitsspeicher auf einer VM mit 2 vCPU und 8 GB [9]. Zum Betrieb nennt die Doku PostgreSQL ab Version 13, dazu Redis, und \u201eIdeally, 2 vCPUs and 2-4GB RAM\u201c [6].\n\n## Cal.diy hat keine Teams, Organisationen, Workflows und Routing Forms mehr\n\nDie Funktionen wurden aus Cal.diy entfernt, nicht nur gesperrt. Laut Hersteller fehlen Organisationen und Teams mit Team-Buchung, Round-Robin und rollenbasierten Rechten, au\u00dferdem Routing Forms, Workflows, Instant Booking, Cal.ai Phone, Attribute und Segmente, SAML/SSO, Insights, API v1, Booking Audit und Impersonation [2]. Die Doku-Tabelle nennt zus\u00e4tzlich Managed Event Types, SCIM und Videoaufzeichnungen [6].\n\nErhalten bleiben unabh\u00e4ngige Einzelkonten mit eigenen Buchungsseiten unter `/<benutzername>/<termin>`. Die offene Registrierung l\u00e4sst sich abschalten, Markenfarbe und Theme sind je Konto einstellbar, und auf eigener Domain darf jedes Konto den Hinweis \u201ePowered by\u201c ausblenden. Ein eigenes Logo je Konto wurde im Code nicht gefunden [10].\n\nEine Anfrage an Dritte bleibt auch auf `main`: Ohne Profilbild l\u00e4dt Cal.diy einen Platzhalter von `eu.ui-avatars.com`, mit dem Namen des Kontos in der Adresse. Eine Variable zum Abschalten wurde nicht gefunden [10]. Telemetrie, Sentry und weitere Dienste sind auf `main` ohne gesetzte Schl\u00fcssel inaktiv. F\u00fcr v6.2.0, das einzige fertige Image, ist das nicht gepr\u00fcft.\n\n\u201eCal.diy\u201c und \u201eCal\u201c sind eingetragene Marken von Cal.com, Inc. Eine ver\u00f6ffentlichte Markenrichtlinie wurde nicht gefunden. Der angezeigte Name einer Instanz l\u00e4sst sich \u00fcber `NEXT_PUBLIC_APP_NAME` \u00e4ndern [10].\n\n## Tymeslot, Calnode und Easy!Appointments bringen Buchungsseite, Kalenderabgleich und Absage durch den Gast mit\n\n| | Tymeslot | Calnode | Easy!Appointments |\n|---|---|---|---|\n| Lizenz | AGPL-3.0, Name gesch\u00fctzt | Apache-2.0, Name gesch\u00fctzt, CLA | GPL-3.0 |\n| Datenbank | PostgreSQL, im Container eingebaut oder extern | SQLite, optional Litestream | MySQL |\n| Mehrere Anbieter in einer Instanz | ja, je Nutzer eigene Seite, Farben, Einbett-Domains | nein, eine Instanz je Arbeitsbereich | ja, aber ein Firmenname, Logo und Farbe je Instanz |\n| Einbettung | inline, Popup, schwebender Knopf; an erlaubte Domains gebunden | Web Component im Shadow DOM, kein iframe | kein Widget im Kern, iframe per `X-Frame-Options: SAMEORIGIN` gesperrt |\n| Kalender | Google, Outlook, iCloud, CalDAV | Google, Microsoft 365, CalDAV | Google, CalDAV |\n| Absage und Umbuchung durch Gast | ja, signierte Links ohne Anmeldung | ja, signierte Links | ja |\n| Mailversand | SMTP, Postmark, SendGrid, Mailgun, AhaSend | SMTP oder Resend-API | SMTP |\n| Stand | v1.23.0 vom 08.10.2026, seit 08/2025 | v0.10.1 vom 29.09.2026, seit 06/2026 | 1.6.0 vom 27.05.2026, seit 2014 |\n\nQuellen der Tabelle: [11][12][13].\n\nTymeslot ist in Elixir geschrieben und l\u00e4uft als ein Container mit eingebautem PostgreSQL, laut Doku ab \u201e500MB RAM minimum (1GB recommended)\u201c. Oberfl\u00e4che, Buchungsseite und Mails gibt es auf Deutsch. Ohne gesetzte Schl\u00fcssel fand die Code-Durchsicht keinen Aufruf externer Dienste. Von rund 5.000 Commits stammen fast alle von einer Person, und `TRADEMARK.md` schlie\u00dft aus, ein eigenes Angebot unter dem Namen Tymeslot zu betreiben. Eine Falle bei der Einrichtung: Die Vorgabe `EMAIL_ADAPTER=test` verwirft alle Mails [11].\n\nCalnode ist in Go geschrieben, speichert in SQLite und trennt Kunden \u00fcber je eine eigene Instanz (\u201einstance-per-tenant\u201c). Mehrere Domains in einer Instanz stehen erst auf der Roadmap. Die Buchungsseiten sind maschinell ins Deutsche \u00fcbersetzt, die Verwaltung gibt es nur auf Englisch. Calnode ist das j\u00fcngste Projekt im Vergleich; 559 Commits stammen von einer Person [12].\n\nEasy!Appointments ist das \u00e4lteste, in PHP geschrieben, mit offiziellem Image (134.877 Abrufe). Es kennt mehrere Anbieter mit eigenen Leistungen, aber nur einen Markenauftritt je Instanz, passt also zu einem Betrieb mit mehreren Mitarbeitenden. Fremde Webseiten k\u00f6nnen die Buchung ohne Code-\u00c4nderung nicht einbetten; wie das vorhandene WordPress-Plugin das l\u00f6st, ist nicht gepr\u00fcft. Die Admin-Seite \u201eAbout\u201c l\u00e4dt serverseitig einen Feed von easyappointments.org, und acht von zehn mitgelieferten Themes laden Google Fonts [13].\n\n## Rallly, alf.io, LibreBooking und Thunderbird Appointment taugen nicht als Ersatz f\u00fcr Cal.com\n\nRallly stimmt Termine per Gruppenumfrage ab, alf.io verkauft Tickets, LibreBooking bucht R\u00e4ume und Ger\u00e4te. Thunderbird Appointment (MPL-2.0) hat Buchungsseiten je Nutzer, aber kein fertiges Image, braucht f\u00fcnf Container mit PostgreSQL, Redis und Celery, und eine Einbettung wurde im Frontend nicht gefunden. Die Termin-Funktion von Nextcloud Calendar setzt eine Nextcloud voraus, G\u00e4ste k\u00f6nnen dort nicht selbst absagen. calit gleicht nur mit Google ab, DayOtter nennt sich selbst \u201enot yet battle-tested\u201c [14].\n\n## F\u00fcr eine Person oder einen Betrieb reicht eine eigene Instanz, f\u00fcr viele Kunden braucht es Mehrmandanten\n\nMehrmandanten hei\u00dft: eine Instanz f\u00fcr viele Kunden. Wer sie betreibt, h\u00e4lt die Termine und Kundendaten aller Beteiligten auf einem Server. Eine Instanz je Person oder Betrieb trennt diese Daten von vornherein und kostet je Kunde einen Container, was nur bei geringem Speicherbedarf g\u00fcnstig bleibt.\n\n| Lage | Passende L\u00f6sung | Grund |\n|---|---|---|\n| Eine Person, eigene Webseite, kleiner Server | Calnode | SQLite, gemessen 85 MB Arbeitsspeicher, Einbettung ohne iframe |\n| Ein Betrieb, mehrere Mitarbeitende, ein Markenauftritt | Easy!Appointments | mehrere Anbieter, ein Branding; Buchung als eigene Seite statt eingebettet |\n| Ein Dienstleister richtet vielen Selbstst\u00e4ndigen je eine Seite in einer Instanz ein | Tymeslot | Theme und Einbett-Domains je Nutzer; Angebot darf nicht Tymeslot hei\u00dfen |\n| Bisherige Cal.com-Instanz nur mit Einzelkonten | Cal.diy aus `main` selbst bauen oder wechseln | MIT, aber kein Image und Herstellerempfehlung gegen Produktivbetrieb |\n| Bisherige Cal.com-Instanz mit Teams oder Workflows | der gehostete Dienst von Cal.com; v6.2.0 nur mit Enterprise-Abo | diese Funktionen gibt es in Cal.diy nicht mehr; ob das Abo f\u00fcr v6.2.0 noch verkauft wird, ist nicht gepr\u00fcft |\n| Nextcloud ist schon vorhanden | Termin-Funktion von Nextcloud Calendar | kein zus\u00e4tzlicher Dienst; G\u00e4ste sagen per Kontakt ab |\n\n## Calnode braucht im Test 85 MB Arbeitsspeicher und l\u00e4dt auf der Buchungsseite nichts von Dritten\n\nGetestet wurde Calnode v0.10.1 am 13.10.2026 lokal in Docker, der Netzverkehr wurde mit den Chrome DevTools mitgeschnitten. Das Image ist 64 MB gro\u00df. Im Leerlauf belegte der Container 11 MB Arbeitsspeicher, nach Einrichtung und mehreren Seitenaufrufen 85 MB. Zum Vergleich die Herstellerangaben, nicht gemessen: Tymeslot nennt 500 MB als Minimum, Cal.diy 2 bis 4 GB.\n\nDie Buchungsseite `/book/<slug>` lud nur eigenes CSS, die eigene Schnittstelle f\u00fcr freie Zeiten und das Favicon, keine einzige Anfrage ging an Dritte. Die Verwaltung unter `/admin` lud als einzige Fremdquelle Google Fonts (Poppins). Eingebettet wird \u00fcber `embed.js` als Web Component im Shadow DOM (`<calnode-booking slug=\"\u2026\">` oder als Popup-Knopf). Die Buchungsseite selbst verbietet Rahmen per `frame-ancestors 'none'`, ein iframe funktioniert also nicht.\n\nNicht getestet wurden in diesem Durchlauf der CalDAV-Abgleich, der Mailversand und eine echte Buchung. Die Werte stammen aus einem einzelnen Durchlauf auf einem Rechner.\n\nOffenlegung: Die Terminbuchung dieser Webseite l\u00e4uft seit dem 13.10.2026 auf einer eigenen Calnode-Instanz unter [termine.stevennoack.de](https://termine.stevennoack.de/book/gespraech). Dort gingen Best\u00e4tigung und Absage einer Testbuchung \u00fcber die Resend-API zu.\n\n## CalDAV mit App-Passwort erspart die OAuth-Pr\u00fcfung von Google\n\nF\u00fcr den Google-Kalender braucht jede selbst gehostete Instanz eine eigene OAuth-App. Kalenderereignisse zu lesen gilt bei Google als \u201esensitive scope\u201c, die Freigabe verlangt eine Pr\u00fcfung mit Begr\u00fcndung je Berechtigung und ein Demo-Video [15]. Eine ungepr\u00fcfte App zeigt Nutzern einen Warnbildschirm und ist auf 100 neue Nutzer begrenzt [16]. Im Status \u201eTesting\u201c verfallen die Refresh-Token nach sieben Tagen [17].\n\nCalDAV mit einem App-Passwort kommt ohne OAuth aus. Alle drei empfohlenen Alternativen unterst\u00fctzen es. Ob iCloud und Nextcloud die CalDAV-Abfrage f\u00fcr freie und belegte Zeiten (RFC 4791, Abschnitt 7.10) beantworten, ist nicht gepr\u00fcft; Easy!Appointments liest stattdessen die Ereignisse im Zeitraum [13][18].\n\n## Manche Hoster sperren ausgehendes SMTP, dann geht Mail nur \u00fcber eine HTTPS-Schnittstelle\n\nOhne Mail gibt es keine Buchungsbest\u00e4tigung. Manche Hoster blockieren ausgehendes SMTP ganz oder auf einzelnen Ports. Auf Hetzner-Cloud-Servern waren in zwei Praxisf\u00e4llen (29.08. und 13.10.2026) ausgehend die Ports 25 und 465 gesperrt. Der E-Mail-Versand von Cloudflare nimmt SMTP auf `smtp.mx.cloudflare.net` \u00fcber Port 465 an; diese Kombination stellt keine Mail zu. Eine offizielle Aussage von Hetzner dazu wurde nicht gepr\u00fcft.\n\nDie Calnode-Doku beschreibt das Muster allgemein: Railway sperrt SMTP unterhalb des Pro-Tarifs, indem es die Pakete verwirft. Im Container sieht das zuerst wie ein H\u00e4nger aus, dann wie ein falsches Passwort, auf den Ports 25, 465, 587 und 2525 gleich [12]. Keine SMTP-Einstellung hilft dagegen, wohl aber Versand \u00fcber eine HTTPS-Schnittstelle auf Port 443: Calnode und Cal.diy k\u00f6nnen Mails \u00fcber die API von Resend schicken [10][12]. Teils hilft ein Ausweich-Port; Resend \u00fcber Port 2465 kam am 29.08.2026 von einem Hetzner-Server an. Easy!Appointments kennt nur SMTP. Ob die Tymeslot-Adapter f\u00fcr Postmark, SendGrid, Mailgun und AhaSend \u00fcber HTTPS senden, ist nicht gepr\u00fcft.\n\n## Offene Fragen: Admin-Verwaltung von Cal.diy, Build-Variablen und ungepr\u00fcfte Drittanfragen\n\nOb Cal.diy eine Benutzerverwaltung f\u00fcr Admins hat, ist widerspr\u00fcchlich. Die Doku-Tabelle sagt \u201eAdmin Panel \u274c\u201c, im Code auf `main` sind die Seiten vorhanden. Laut Issue #30013 vom 19.08.2026 sieht der Admin in v6.2.0 nicht einmal, wer sich registriert hat; behoben ist das nur auf `main` [19].\n\nOb `NEXT_PUBLIC_WEBAPP_URL` beim Bau feststeht, ist ebenfalls widerspr\u00fcchlich: Die Docker-Doku verlangt daf\u00fcr ein eigenes Image, Code und README ersetzen den Wert beim Start, zwei offene Issues melden trotzdem Umleitungen auf `localhost` [10][20].\n\nNicht gepr\u00fcft sind die Drittanfragen von v6.2.0, m\u00f6gliche weitere Hosts in Hintergrundjobs von Tymeslot und Calnode und der Speicherbedarf von Easy!Appointments. Zu Release-Pl\u00e4nen f\u00fcr Cal.diy haben die Maintainer in den Issues #28995 und #30013 nicht geantwortet [9][19].\n\n## Quellen\n\nAlle Abrufe am 13.10.2026.\n\n\u2022 [1] Cal.com Blog, Bailey Pumfleet, 14.04.2026: https://cal.com/blog/cal-com-goes-closed-source-why\n\u2022 [2] Cal.com Blog, Keith Williams, 15.04.2026: https://cal.com/blog/cal-diy-open-source-to-closed-source\n\u2022 [3] Umstellungs-Commit, Pull Request #28903: https://github.com/calcom/cal.diy/pull/28903\n\u2022 [4] Lizenz auf `main`: https://github.com/calcom/cal.diy/blob/main/LICENSE\n\u2022 [5] Lizenz v6.2.0: https://github.com/calcom/cal.diy/blob/v6.2.0/LICENSE und https://github.com/calcom/cal.diy/blob/v6.2.0/packages/features/ee/LICENSE\n\u2022 [6] Cal.diy-Dokumentation und README: https://www.cal.diy/ und https://github.com/calcom/cal.diy/blob/main/README.md\n\u2022 [7] Docker Hub, Tags von calcom/cal.diy: https://hub.docker.com/v2/repositories/calcom/cal.diy/tags\n\u2022 [8] Archiviertes Repository: https://github.com/calcom/docker\n\u2022 [9] Issue #28995 \u201eDocker Image Missing\u201c: https://github.com/calcom/cal.diy/issues/28995\n\u2022 [10] Cal.diy-Quellcode und Umgebungsvorlage: https://github.com/calcom/cal.diy/blob/main/.env.example\n\u2022 [11] Tymeslot: https://github.com/Tymeslot/tymeslot und https://hub.docker.com/r/luka1thb/tymeslot\n\u2022 [12] Calnode, README und DEPLOY.md: https://github.com/Calnode/calnode\n\u2022 [13] Easy!Appointments: https://github.com/alextselegidis/easyappointments und https://hub.docker.com/r/alextselegidis/easyappointments\n\u2022 [14] Rallly https://github.com/lukevella/rallly, alf.io https://github.com/alfio-event/alf.io, LibreBooking https://github.com/LibreBooking/librebooking, Thunderbird Appointment https://github.com/thunderbird/appointment, Nextcloud Calendar https://docs.nextcloud.com/server/latest/user_manual/en/groupware/calendar.html, calit https://github.com/asm0dey/calit, DayOtter https://github.com/Dayotter/dayotter\n\u2022 [15] Google, Pr\u00fcfung sensibler Berechtigungen: https://developers.google.com/identity/protocols/oauth2/production-readiness/sensitive-scope-verification\n\u2022 [16] Google, ungepr\u00fcfte Apps: https://support.google.com/cloud/answer/7454865\n\u2022 [17] Google, OAuth 2.0: https://developers.google.com/identity/protocols/oauth2\n\u2022 [18] RFC 4791, Abschnitt 7.10: https://www.rfc-editor.org/rfc/rfc4791.html\n\u2022 [19] Issue #30013: https://github.com/calcom/cal.diy/issues/30013\n\u2022 [20] Issues #28172 und #28712: https://github.com/calcom/cal.diy/issues/28172 und https://github.com/calcom/cal.diy/issues/28712\n\nDie Messwerte zu Calnode und die Befunde zum Mailversand auf Hetzner stammen aus Praxistests vom 29.08. und 13.10.2026, die nicht gesondert ver\u00f6ffentlicht sind.",
    "sig": "67db2dd5a4a49a35d3fb8e19cbd298120f3658c06fe63eb3a7fb1362ed616adb43818eb348e5f393308ff520f24e4cd4d9fe1ca27b2a041c6e09bb907df04474"
}
