Skip to content
Deployments

Deploy Cal.com with the calcom-scheduling template

Deployment

Deploy Cal.com with the calcom-scheduling template

Stand up Cal.com, an open-source scheduling and booking platform, on a single Quake AI instance using the validated OpenTofu template calcom-scheduling. You apply the template, serve it over HTTPS through Caddy, set the public app URL, build the app from source, sign up the first account, connect a calendar, set your availability, create an event type, share the resulting booking page, and confirm a test booking.

Cal.com keeps your scheduling data on infrastructure you own. You run it yourself; this is a self-hosted tool you operate, not a managed multi-tenant service.

InviteeFloating IPUbuntu instanceCaddyreverse proxyCal.comapp (built from source)PostgreSQL proxies 443 to 3000users, event types, bookingsHTTPS
Click to zoom
What you'll build: a Cal.com host built from source on a single instance with a bundled PostgreSQL, served over HTTPS through a Caddy reverse proxy

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on shared vCPU.

Starting template$65.80/mo

Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

Cal.com scheduling host

s1a.large · 8 shared vCPU, 8 GiB RAM, 0.5 Gbps

Clones Cal.com's source tree and builds the app image locally alongside a bundled PostgreSQL, because the published Docker Hub image bakes its public URL in at build time.

Building the Cal.com Next.js monorepo from source needs real CPU and disk; 8 vCPU and 8 GiB RAM is the floor while building. Size down after the first successful build if you want to save cost.

$66.00/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

s1a.large

8 shared vCPU, 8 GiB RAM, 0.5 Gbps

$66.00

Compute + RAM rate basis

8 vCPU + 8 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (60 GiB)

60 GiB at $0.08/GiB/mo

$4.80

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the calcom-scheduling template directory from the template reference page.
  • A domain you can point at the instance.

Step 1: Apply the template#

Copy the template's example variables file and set key_name:

bash
cp terraform.tfvars.example terraform.tfvars
HCL
key_name = "YOUR_KEY_NAME"

Initialize, preview, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, a router, a security group, a block volume mounted at /var/lib/docker, an instance, and a floating IP. On first boot, cloud-init installs Docker Engine, clones Cal.com's source to /opt/calcom/src, generates NEXTAUTH_SECRET, CALENDSO_ENCRYPTION_KEY, and the PostgreSQL password into /opt/calcom/.env, and starts only database. The app image isn't built yet: NEXT_PUBLIC_WEBAPP_URL has to be correct before the build starts, since it's compiled into the app rather than read at startup.

Read the outputs and record floating_ip:

bash
tofu output

Step 2: Point a domain at the host and serve HTTPS with Caddy#

  1. Create a DNS A record for your domain (for example cal.example.com) pointing at YOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until it resolves:
bash
dig +short cal.example.com
  1. SSH to the instance and create /opt/calcom/Caddyfile:
cal.example.com {
  reverse_proxy 127.0.0.1:3000
}
  1. Add Caddy to /opt/calcom/docker-compose.yml:
YAML
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/calcom/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
volumes:
  caddy_data:

For background on certificates, see How to issue and auto-renew a TLS certificate with Let's Encrypt.

Step 3: Set the app URL and build Cal.com#

Edit /opt/calcom/.env, uncomment, and set:

NEXT_PUBLIC_WEBAPP_URL=https://cal.example.com
NEXTAUTH_URL=https://cal.example.com

Build the app image, then start the full stack:

bash
cd /opt/calcom
sudo docker compose build calcom
sudo docker compose up -d

The build compiles the entire Next.js monorepo, so expect it to take a while. The calcom container runs its database migrations automatically once it starts.

Step 4: Sign up the first account#

Open https://cal.example.com. The setup wizard walks you through creating the first account on first visit.

Step 5: Connect a calendar and set your availability#

  1. From the dashboard, go to Settings > My Account > Calendars, and connect a calendar provider (for example Google Calendar or a CalDAV-compatible calendar).
  2. Go to Availability, and adjust your working hours and time zone, or accept the default schedule.

Step 6: Create an event type and share it#

  1. Go to Event Types > New, name it (for example 30 Minute Meeting), and set its duration.
  2. Save it, then copy the booking link Cal.com generates for that event type.
  3. Open the link in a private browser window (as an invitee would) and book a slot to confirm the flow works end to end.

What you built#

  • Applied the calcom-scheduling template to provision a network, security group, data volume, instance, and floating IP, with PostgreSQL started automatically by cloud-init
  • Served Cal.com over HTTPS by pointing a domain at the floating IP and routing it through a Caddy reverse proxy
  • Built the app from source with the correct public URL compiled in, then started it
  • Signed up the first account
  • Connected a calendar and set your availability
  • Created an event type and confirmed a test booking

Scope of this deployment#

This template runs a single-VM Cal.com host, not a managed multi-tenant scheduling service. The instance is CPU-only and runs in one region, and it bundles PostgreSQL as a container on the same host. You operate the instance, Docker, the build, Cal.com, the database, and the data volume yourself: back them up, patch them, and rebuild when you upgrade to a newer release.

Next steps#

Clean up#

When you no longer need the deployment, destroy everything the template created:

bash
tofu destroy

Then remove the DNS A record you created in step 2. Because Cal.com, its build cache, and its database all live on the instance and its attached volume, tofu destroy removes them along with the infrastructure.

Before this
Was this page helpful?