
Deploy Cal.com - Open Source Scheduling, With a Working Encryption Key
Open-source Calendly alternative, with a working encryption key
Just deployed
/var/lib/postgresql/data
Cal.com
Just deployed
Deploy and Host Cal.com on Railway
Cal.com is the open-source scheduling platform - a self-hosted alternative to
Calendly with booking pages, availability rules, calendar sync, and team
scheduling. This template runs the official calcom/cal.com image against a
pinned Postgres database.
About Hosting Cal.com
Cal.com stores its data in Postgres and encrypts sensitive fields - OAuth
tokens for connected calendars, CalDAV credentials, two-factor secrets - with
a symmetric key read from CALENDSO_ENCRYPTION_KEY. That key has to be
exactly 32 bytes: Cal.com's crypto.ts decodes it with Buffer.from(key, "latin1"), one byte per character, so any length other than 32 characters
throws RangeError: Invalid key length the first time the app tries to
encrypt something.
This template generates that key as a clean 32-character string. The
catalog's most-installed Cal.com template does not: its CALENDSO_ENCRYPTION_KEY
carries a stray leading quote and a trailing = left over from copying a
.env line into a template variable, making it 34 characters. The deployment
itself succeeds - Postgres connects, the app boots, the health check passes -
because nothing touches the encryption key until a user actually connects a
calendar or turns on two-factor authentication. At that point it throws.
Confirmed on this template by registering an admin account and enabling
two-factor authentication through Cal.com's own API: it returned a working
TOTP secret and QR code. The same request against the malformed 34-character
key is exactly the failure mode reported in
calcom/cal.diy#8017, "Can't
set 2FA because of Invalid key length."
Why Deploy Cal.com on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Cal.com on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Specific to this template:
- The encryption key is generated correctly - 32 characters, no stray quotes or padding, so calendar connections and two-factor auth work on the first deploy instead of failing silently until someone tries them.
- Postgres is pinned to
ghcr.io/railwayapp-templates/postgres-ssl:18with a persistent volume, and the Cal.com image is pinned tov6.2.0- the current release - instead of trackinglatest. NEXTAUTH_URLis set explicitly to the deployment's public domain, so NextAuth doesn't have to infer it from request headers behind Railway's proxy.
Common Use Cases
- A self-hosted booking page for consultations, interviews, or client calls, without sending scheduling data through a third-party SaaS.
- Team scheduling with round-robin and collective availability, run on infrastructure a company controls.
- A Calendly replacement for organizations that need calendar sync (Google, CalDAV) and two-factor login to actually work, which is exactly the code path this template's fix addresses.
Dependencies for Cal.com Hosting
- Postgres 18 for application data
Deployment Dependencies
Implementation Details
Nothing required to fill in. NEXTAUTH_SECRET and CALENDSO_ENCRYPTION_KEY
are generated per deployment; NEXTAUTH_URL and NEXT_PUBLIC_WEBAPP_URL are
wired to the Railway-assigned public domain.
GOOGLE_API_CREDENTIALS is optional - leave it blank to skip Google
Calendar/Meet integration, or paste a Google service account JSON credential
to enable it. NEXT_PUBLIC_WEBSITE_TERMS_URL and
NEXT_PUBLIC_WEBSITE_PRIVACY_POLICY_URL are optional links shown in the
Cal.com footer.
Verified on this template: admin account creation via /api/auth/setup,
session login via NextAuth credentials, and two-factor setup via
/api/auth/two-factor/totp/setup all completed successfully against the
generated encryption key.
Template Content
