Railway

Deploy Cal.com — Open Source Calendly Alternative

Self-hosted scheduling with Postgres — no per-seat booking fees

Deploy Cal.com — Open Source Calendly Alternative

Just deployed

/var/lib/postgresql/data

Deploy and Host Cal.com on Railway

Cal.com is the leading open-source scheduling platform — a self-hosted alternative to Calendly and Acuity. Share a booking link, let people pick a slot, and sync it to Google, Outlook, or CalDAV automatically. Unlimited event types, unlimited bookings, no per-seat fees, and your customers' calendar data stays on infrastructure you own. This template deploys Cal.com with a managed PostgreSQL database, pre-wired and persistent.


What This Template Deploys

ServicePurpose
Cal.comThe Next.js scheduling app, booking pages, and admin on port 3000
PostgreSQLUsers, event types, bookings, and encrypted calendar credentials

Both services run on Railway's private network with credentials injected automatically. Railway handles SSL and domain provisioning, and Prisma runs the database migrations on first boot.


About Hosting Cal.com

Cal.com is a Next.js application, and that creates one specific pitfall on any container platform that catches most self-hosters: NEXT_PUBLIC_WEBAPP_URL is compiled into the app at build time, not read at runtime. Any variable prefixed NEXT_PUBLIC_ is baked into the client bundle when the image is built, so setting it afterward as an environment variable does nothing — booking links, OAuth redirect URIs, and confirmation-email links all point at localhost and break. This template supplies that URL at build time so your links resolve to your real domain from the first boot.

Two secrets must be generated once and then never changed:

  • NEXTAUTH_SECRET signs user sessions — openssl rand -base64 32
  • CALENDSO_ENCRYPTION_KEY encrypts every stored calendar credential (Google and Microsoft OAuth tokens). It is 24 bytes, not 32 — openssl rand -base64 24. Change it and every connected calendar is permanently corrupted and must be reconnected by hand.

Cal.com also needs DATABASE_DIRECT_URL alongside DATABASE_URL; Prisma uses the direct connection to run migrations. Both are wired to the Railway Postgres service here.

The database is not just app data — it holds OAuth tokens granting read/write access to your users' real calendars. Treat it as sensitive and back it up regularly.

Typical cost: ~$5–15/month on Railway for a small instance with Postgres. Cal.com's own cloud starts at $12/user/month for team features, so self-hosting removes per-seat billing entirely.


How It Compares

Cal.com (self-hosted)CalendlyAcuityCal.com Cloud
Cost modelFlat ~$5–15/mo infraPer user/monthPer user/monthFrom $12/user/mo
Event typesUnlimitedLimited on freePer planUnlimited
Data ownershipFullVendorVendorCal-hosted
Calendar syncGoogle, Outlook, CalDAVGoogle, OutlookGoogle, OutlookSame
Custom brandingFullHigher tiersHigher tiersTeam plans
Self-hostableYesNoNoNo

Calendly and Acuity are more polished out of the box. Cal.com wins on unlimited event types at a flat cost, full branding control, and keeping your customers' calendar credentials on your own infrastructure.


Deploy in Under 5 Minutes

  1. Click Deploy on Railway — Cal.com and PostgreSQL build automatically (the Next.js build takes a few minutes)
  2. Confirm NEXT_PUBLIC_WEBAPP_URL is set to your Railway domain as a build argument, and NEXTAUTH_URL matches it
  3. Confirm NEXTAUTH_SECRET and the 24-byte CALENDSO_ENCRYPTION_KEY are set — and save both externally
  4. Open your Railway domain; Cal.com redirects to the /auth/setup wizard
  5. Create your admin account, set your availability, and share your first booking link

Configure the EMAIL_SERVER_* variables so booking confirmations and reminders send.


Common Use Cases

  • Calendly replacement — share booking links with unlimited event types and no per-seat fees
  • Team scheduling — round-robin and collective event types route bookings across a team
  • Client-facing booking pages — branded scheduling for consultants, coaches, and agencies on your own domain
  • Support and office hours — recurring availability windows with buffer times and booking limits
  • Embedded scheduling — drop Cal.com booking widgets into your own site or app

Configuration

VariableRequiredDescription
NEXT_PUBLIC_WEBAPP_URLRequired (build arg)Your Railway domain — compiled into the app at build time, not runtime
NEXTAUTH_URLRequiredSame as your public URL — used for authentication callbacks
NEXTAUTH_SECRETRequiredSession signing key — openssl rand -base64 32, keep stable
CALENDSO_ENCRYPTION_KEYRequiredCredential encryption — openssl rand -base64 24 (24 bytes). Never change it
DATABASE_URLAuto-injectedPostgreSQL connection string via Railway reference variable
DATABASE_DIRECT_URLAuto-injectedDirect connection for Prisma migrations — same as DATABASE_URL
NEXT_PUBLIC_LICENSE_CONSENTPre-setagree — acknowledges the AGPLv3 self-host terms
CALCOM_TELEMETRY_DISABLEDOptionalSet 1 to disable telemetry
EMAIL_FROMRequiredSender address for booking emails
EMAIL_SERVER_HOSTRequiredSMTP hostname
EMAIL_SERVER_PORTRequiredSMTP port, e.g. 587
EMAIL_SERVER_USERRequiredSMTP username
EMAIL_SERVER_PASSWORDRequiredSMTP password

NEXT_PUBLIC_WEBAPP_URL must be a build argument. It is compiled into the client bundle, so setting it only at runtime leaves booking and OAuth links pointing at localhost. This is the single most common broken self-hosted Cal.com deployment.

CALENDSO_ENCRYPTION_KEY is 24 bytes and permanent. It encrypts stored calendar credentials. Changing it corrupts every connected calendar. Generate it once, back it up externally, and never rotate it.


Dependencies for Cal.com Hosting

  • Railway account — Hobby plan (~$5–15/month) covers both services
  • An SMTP provider for booking confirmations and reminders
  • Optional: Google Cloud OAuth credentials for Google Calendar sync
  • Optional: Microsoft Azure app credentials for Outlook sync

Deployment Dependencies

Implementation Details

The template runs the official calcom/cal.com image on port 3000 against a managed Railway PostgreSQL service. Because NEXT_PUBLIC_WEBAPP_URL is a Next.js public variable, it is provided as a build argument so the correct domain is compiled into the client bundle rather than defaulting to localhost — the failure that breaks booking links, OAuth redirects, and email URLs on naive deployments.

Both DATABASE_URL and DATABASE_DIRECT_URL point at the Postgres service; Prisma uses the direct URL to apply migrations, which run automatically on startup when schema changes are present. NEXTAUTH_SECRET and the 24-byte CALENDSO_ENCRYPTION_KEY are generated at deploy time and must persist unchanged, since the encryption key protects stored OAuth tokens for connected calendars.

All application data lives in PostgreSQL, including the encrypted calendar credentials. That database is both your bookings and a set of tokens with read/write access to real calendars, so it should be backed up on a schedule and treated as sensitive.


Frequently Asked Questions

My booking links point at localhost — why? NEXT_PUBLIC_WEBAPP_URL was set at runtime instead of build time. It's compiled into the app, so it must be a build argument set to your real domain. This template handles that; if you fork it, preserve the build-arg setup.

Why is CALENDSO_ENCRYPTION_KEY only 24 bytes? Cal.com's credential encryption expects a 24-byte key — generate it with openssl rand -base64 24, not 32. Using the wrong length or changing it later permanently corrupts every stored calendar credential.

Do my calendar connections survive a redeploy? Yes, provided CALENDSO_ENCRYPTION_KEY stays constant. The OAuth tokens are encrypted with it and stored in Postgres; the key must not change or they become unreadable.

Why does it need DATABASE_DIRECT_URL? Prisma uses a direct database connection to run migrations, separate from the pooled connection the app uses. Both are wired to the same Railway Postgres here.

Is the self-hosted version free? Yes. Cal.com's community edition is AGPLv3 with no per-seat fees. Some enterprise features require a license, but core scheduling and calendar sync are fully open.

How do I enable Google Calendar sync? Create a Google Cloud project, enable the Calendar and People APIs, configure the OAuth consent screen, and add credentials with your Railway domain as the redirect URI. Then set the Google client ID and secret in Cal.com.

Do I need SMTP? Yes, for booking confirmations, reminders, and password resets. Configure the EMAIL_SERVER_* variables with your provider before going live.


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 get open-source scheduling with the build-time pitfall already solved — Cal.com and PostgreSQL pre-wired over a private network, the webapp URL compiled correctly, encryption keys generated, automatic HTTPS, and Prisma migrations run for you. Unlimited event types, no per-seat billing, and your customers' calendar credentials on infrastructure you own.


Template Content

More templates in this category

View Template
Rocky Linux
[Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀

codestorm
29
View Template
Foundry Virtual Tabletop
A Self-Hosted & Modern Roleplaying Platform

Lucas
71
View Template
Letta Code Remote
Run a Letta Code agent 24/7. No inbound ports, just deploy.

Letta
51