Skip to main content

Overview

Cal.com is an open-source scheduling platform, a Calendly alternative: public booking pages, event types, availability, calendar connections, teams and webhooks. This template deploys the Cal.com app (UI, booking pages and /api/* on port 3000), a small caller that drives Cal.com’s scheduled jobs, and a bundled PostgreSQL, single-instance by default and highly available behind one flag. Cal.com runs in exactly one location of your GVC and installs private: you create the admin account over a port-forward, then publish.
This template deploys into an existing GVC that you already have — it does not create or manage a GVC. The location you set must already be one of that GVC’s locations; if it is not, Cal.com starts nothing in the GVC.

What Gets Created

Your application keys and database credentials are not created by the template — see Prerequisites.

Prerequisites

Two secrets must exist before installing, and the GVC should have one location (see the last step). The values never pass through Helm values.
1

Create the application keys secret

A dictionary secret with four keys. encryptionKey must be exactly 32 characters:
Set calcom.auth.secretName to this name. Back the keys up outside Control Plane and never replace encryptionKey: it encrypts every connected calendar and app credential.
2

Create the database credentials secret

The bundled PostgreSQL initializes with these values and Cal.com connects with them:
Set postgres.config.credentialsSecretName to this name (postgresHA.config.credentialsSecretName in highly available mode). Secret names are org-wide, so give each release its own secrets. The three values are part of Cal.com’s connection URL, so use letters, digits, - and _ only.
3

Use a GVC with one location

Cal.com runs only in the location named by location, which must already be a location of your GVC. The bundled PostgreSQL starts in every location of the GVC, so a GVC with a single location keeps one Cal.com against one database.
Create both secrets before installing. Installing without one reports success, but the deployment never becomes ready and cpln logs stays empty; status.versions[].message from the command below names the missing secret:
A secret created after install is not picked up on its own. For the database credentials, run cpln workload force-redeployment on RELEASE_NAME-postgres (RELEASE_NAME-postgres-ha in highly available mode) and RELEASE_NAME-calcom; for the application keys, on RELEASE_NAME-calcom and RELEASE_NAME-calcom-cron. See Troubleshooting.
Optional features need their own setup first: an SMTP relay (see Email) and a backup bucket (see Backing Up).

Installation

Once your two secrets exist, install from the marketplace registry, pointing the keys at them and location at a location of your GVC:
Other ways to install and manage the template:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Location

Use a bare location name such as aws-us-east-1. A link form (//location/aws-us-east-1), a list, or a comma-separated value is refused at render time.

Application

Scheduled Jobs

Cal.com runs no scheduler of its own. Keep the caller on unless you call the endpoints yourself: without it queued email, calendar sync and credential refresh never run while Cal.com still reports healthy.

Email

Turn email on before inviting anyone. For an authenticated relay, create the dictionary and set email.auth.secretName:

Access

A firewall change takes time to propagate after the upgrade reports success, and it restarts Cal.com: at calcom.replicas: 1 that is a short outage, so set replicas: 2 for zero-downtime changes.

Database

Highly available mode runs three Patroni replicas, three etcd members, and an HAProxy leader endpoint. Enable exactly one of postgres and postgresHA:
The postgres.backup and postgresHA.backup blocks pass straight through to the underlying templates — see Backing Up.

Connecting

Verify the install through a tunnel:

First Run

Whoever completes /auth/setup first becomes the instance admin, so the install starts private:
  1. Install with publicAccess.enabled: false (the default).
  2. Run cpln port-forward RELEASE_NAME-calcom 3000:3000 --gvc GVC_NAME and open http://localhost:3000/auth/setup. Use http://localhost:3000 exactly: while private, Cal.com issues its session cookie for that origin.
  3. Create your admin account (the license step can be skipped), then finish the onboarding: Cal.com redirects every page until it is done.
  4. Set publicAccess.enabled: true and run cpln helm upgrade with your install values. The firewall change takes time to propagate and restarts Cal.com.

Webhooks

Add webhooks under Settings, Developer, Webhooks. Cal.com delivers to public URLs and to *.cpln.local workload URLs in the GVC, for example http://RECEIVER_WORKLOAD.GVC_NAME.cpln.local:8080/path. Each delivery carries an X-Cal-Signature-256 header: the HMAC-SHA256 of the request body, keyed with the webhook’s secret.

Calendar and Video Integrations

Google Calendar, Outlook Calendar and Zoom need your own OAuth app. An admin enters its keys at /settings/admin/apps: open the app, edit its keys, save, then switch the app on. The keys are stored in the database, not in a secret. Register the matching callback with the provider, using the public URL of your instance:
If you set calcom.appUrl, the callback host is that domain. Users then connect the app from their own settings.

Teams and Licensed Features

The template runs the official image without a Cal.com license key. Teams work; Workflows, Organizations and other licensed features stay locked. The separate v2 API service is not included.

Operations

Backing Up

Database backups are off by default. Enable postgres.backup.enabled: true (or postgresHA.backup.enabled: true) and choose a provider of aws, gcp, or minio; the bucket, cloud account, and IAM setup are described in Backing Up for the single-instance database and Backing Up for highly available mode, and the backup blocks of values.yaml use the same keys.

Restoring a Backup

Restore steps belong to the underlying database templates: Restoring a Backup and Restoring a Backup.

Rotating a Secret

Rotating a referenced secret does not restart Cal.com. After changing a value, redeploy the app, and also RELEASE_NAME-calcom-cron when you changed cronSecret. Never replace encryptionKey.

Scaling and Availability

calcom.replicas is a real knob: the app tier is stateless, and with two or more replicas the UI stays up through a rolling restart or a firewall change. For database availability, set postgresHA.enabled: true and postgres.enabled: false at install.

Troubleshooting

Symptom: cpln helm install reported success, cpln logs returns nothing, and cpln workload get-deployments RELEASE_NAME-calcom --gvc GVC_NAME -o yaml names a secret under status.versions[].message, beginning The secret SECRET_NAME no longer exists even if it never existed.Cause: A prerequisite secret does not exist: the application keys or the database credentials.Fix: Create it (see Prerequisites), then run cpln workload force-redeployment with --gvc GVC_NAME on each workload that reads it: for the database credentials RELEASE_NAME-postgres (RELEASE_NAME-postgres-ha in HA mode) and RELEASE_NAME-calcom; for the application keys RELEASE_NAME-calcom and RELEASE_NAME-calcom-cron. The deployment does not retry on its own.
Symptom: The deployment message reads This workload location is deactivated because maxScale is set to 0.Cause: location is not one of the GVC’s locations. The default is aws-us-east-1.Fix: Set location to a location your GVC already has, and run cpln helm upgrade with your install values.
Symptom: The log shows [calcom] FATAL: PostgreSQL at ... did not answer and the app retries.Cause: PostgreSQL did not answer within 240 seconds of the app’s start.Fix: Check the database workload (RELEASE_NAME-postgres, or RELEASE_NAME-postgres-ha-proxy in HA mode) and its credentials secret.
Symptom: The app does not become ready and its log shows P1000: Authentication failed against database server.Cause: The password in the credentials secret no longer matches the one PostgreSQL initialized with.Fix: Restore the original password in the secret and run cpln workload force-redeployment RELEASE_NAME-calcom --gvc GVC_NAME.
Symptom: cpln helm install fails with a message beginning calcom:, such as calcom: enable exactly one backing store.Cause: A value is missing or invalid: a link-form or list location, calcom.auth.secretName or the database credentials secret name left empty, cron.enabled with internalAccess.type: none, calcom.appUrl without a scheme, email enabled without email.host or email.fromAddress, both or neither of postgres.enabled and postgresHA.enabled, a database internalAccess of none, or a database workload-list that omits RELEASE_NAME-calcom.Fix: Correct the value the message names and reinstall. With workload-list, include //gvc/GVC_NAME/workload/RELEASE_NAME-calcom.

Important Notes

  • Install into a GVC with one location and set location to it; the bundled PostgreSQL starts in every GVC location, and the app logs a warning naming the extra locations.
  • Never replace encryptionKey: it encrypts every connected calendar and app credential.
  • After rotating a key or creating a late prerequisite secret, run cpln workload force-redeployment; neither is picked up on its own.
  • Any firewall change restarts Cal.com; use calcom.replicas: 2 to avoid downtime.
  • Turn email on before inviting anyone: without SMTP, booking confirmations, invites and password resets are not sent.
  • Signup cannot be disabled by an environment variable; use the disable-signup feature flag under Settings, Admin, Features.

External References

Cal.com

Product site

Self-hosting with Docker

Upstream self-hosting guide

Environment Variables

Every setting the server reads at v6.2.0

Cal.com on GitHub

Source code and releases