Skip to content

Cal.com scheduling

Template

Cal.com scheduling

This pattern composes Compute, Network, and Block Storage into a self-hosted scheduling and booking platform, on infrastructure you control.

What this template does#

Provisions a single instance running Cal.com, an open-source scheduling and booking platform (a self-hosted alternative to Calendly). You configure availability, event types, and calendar sync, and share booking links, on infrastructure you own:

  • Compute instance that clones Cal.com's source and builds the app image locally, alongside a bundled PostgreSQL (8 vCPU and 8 GiB RAM, sized for the Next.js build rather than the running app)
  • Private network, subnet, router, port, and security group; a floating IP for public access
  • A block volume mounted at /var/lib/docker, so the cloned source tree, the Next.js build cache, and the PostgreSQL data all live on a volume you can grow
  • cloud-init installs Docker Engine, clones the pinned v6.2.0 release tag, and brings up PostgreSQL; the app image is not built until you finish configuration

NEXTAUTH_SECRET, CALENDSO_ENCRYPTION_KEY, and the PostgreSQL password are generated on first boot and written to /opt/calcom/.env; no credential ships with this template.

Why this template builds from source instead of pulling an image#

Cal.com's published calcom/cal.com Docker Hub image compiles NEXT_PUBLIC_WEBAPP_URL into the Next.js bundle at build time. Cal.com's own documentation lists it as a build-time-only variable, alongside NEXT_PUBLIC_LICENSE_CONSENT and NEXT_PUBLIC_TELEMETRY_KEY: there is no supported runtime override, so pointing the prebuilt image at your own domain doesn't work. This template clones Cal.com's source instead and builds the app locally with your domain baked in correctly the first time.

That build needs real CPU and disk. The default s1a.large flavor (8 vCPU, 8 GiB RAM) and 30 GiB volume cover it; you can size the flavor down after the first successful build, and size it back up for any future rebuild.

Parameters#

ParameterDescriptionDefault
key_nameSSH keypair name (must already exist)No default
flavor_nameInstance size (the Next.js build from source needs 8 vCPU / 8 GiB)s1a.large
image_nameOperating system imageUbuntu-24.04
app_nameDisplay name prefix for resourcescalcom
volume_sizeBlock volume size in GiB, mounted at /var/lib/docker30
external_networkExternal network for floating IP allocationPublicStatic
private_cidrCIDR for the private subnet10.56.0.0/24
app_allowed_cidrCIDR allowed to reach Cal.com on port 300010.56.0.0/24

Finish setup after apply#

cloud-init starts PostgreSQL and writes the generated secrets to /opt/calcom/.env. Complete the setup over SSH:

  1. Point a domain's DNS A record at the floating IP and put a reverse proxy (Caddy or Nginx) in front for HTTPS on 443.
  2. Edit /opt/calcom/.env: uncomment and set NEXT_PUBLIC_WEBAPP_URL and NEXTAUTH_URL to your public HTTPS address.
  3. Build and start Cal.com:
bash
cd /opt/calcom
sudo docker compose build calcom
sudo docker compose up -d calcom

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

  1. Open the site URL. The first visit walks you through creating the first admin account.

Access and security#

Cal.com listens on port 3000 over plain HTTP. The security group restricts 3000 to app_allowed_cidr, which defaults to the private network only. Because Cal.com needs a public URL for OAuth calendar-sync callbacks and booking-page links, the normal access path is a domain with HTTPS on 443 behind a reverse proxy. Ports 80 and 443 stay open for that proxy; they carry no traffic until you add one.

When to use this pattern#

Run scheduling and booking pages for a person or a team on a host you operate, rather than a managed multi-tenant service. This template bundles PostgreSQL as a container on the same host, which suits a single-team deployment. To run the database separately, point DATABASE_URL and DATABASE_DIRECT_URL in /opt/calcom/.env at a self-managed PostgreSQL instance, remove the bundled database service from the compose file, and rebuild.

Estimated cost#

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.

Template source#

7 files. Download the zip or expand to copy any file.Download calcom-scheduling.zip
Show source (7 files)
main.tfHCL
data "openstack_images_image_v2" "os" {
  name        = var.image_name
  most_recent = true
}

data "openstack_networking_network_v2" "external" {
  name = var.external_network
}

resource "openstack_networking_network_v2" "private" {
  name           = "${var.app_name}-net"
  admin_state_up = true
}

resource "openstack_networking_subnet_v2" "private" {
  name            = "${var.app_name}-subnet"
  network_id      = openstack_networking_network_v2.private.id
  cidr            = var.private_cidr
  ip_version      = 4
  dns_nameservers = ["1.1.1.1", "8.8.8.8"]
}

resource "openstack_networking_router_v2" "main" {
  name                = "${var.app_name}-router"
  external_network_id = data.openstack_networking_network_v2.external.id
}

resource "openstack_networking_router_interface_v2" "private" {
  router_id = openstack_networking_router_v2.main.id
  subnet_id = openstack_networking_subnet_v2.private.id
}

resource "openstack_networking_secgroup_v2" "calcom" {
  name        = "${var.app_name}-sg"
  description = "SSH and HTTP/HTTPS for a reverse proxy; app port 3000 restricted"
}

resource "openstack_networking_secgroup_rule_v2" "ssh" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 22
  port_range_max    = 22
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.calcom.id
}

# 80 and 443 carry Cal.com once it is served over a domain with automatic TLS
# through a reverse proxy (Caddy or Nginx). Required for production use:
# NEXT_PUBLIC_WEBAPP_URL and NEXTAUTH_URL both need a real public HTTPS
# address for OAuth callbacks and calendar-sync redirects to work.
resource "openstack_networking_secgroup_rule_v2" "http" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 80
  port_range_max    = 80
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.calcom.id
}

resource "openstack_networking_secgroup_rule_v2" "https" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 443
  port_range_max    = 443
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.calcom.id
}

# Raw app HTTP on 3000 is restricted to app_allowed_cidr (the private network
# by default). Use it for setup over an SSH tunnel or a scoped workstation IP;
# put a reverse proxy on 443 in front for routine access.
resource "openstack_networking_secgroup_rule_v2" "app" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 3000
  port_range_max    = 3000
  remote_ip_prefix  = var.app_allowed_cidr
  security_group_id = openstack_networking_secgroup_v2.calcom.id
}

resource "openstack_networking_port_v2" "calcom" {
  name               = "${var.app_name}-port"
  network_id         = openstack_networking_network_v2.private.id
  security_group_ids = [openstack_networking_secgroup_v2.calcom.id]

  fixed_ip {
    subnet_id = openstack_networking_subnet_v2.private.id
  }

  depends_on = [openstack_networking_router_interface_v2.private]
}

resource "openstack_blockstorage_volume_v3" "data" {
  name = "${var.app_name}-data"
  size = var.volume_size
}

resource "openstack_compute_instance_v2" "calcom" {
  name        = var.app_name
  flavor_name = var.flavor_name
  key_pair    = var.key_name

  user_data = templatefile("${path.module}/cloud-init/calcom.yaml.tftpl", {
    app_name = var.app_name
  })

  block_device {
    uuid                  = data.openstack_images_image_v2.os.id
    source_type           = "image"
    destination_type      = "volume"
    volume_size           = 30
    boot_index            = 0
    delete_on_termination = true
  }

  network {
    port = openstack_networking_port_v2.calcom.id
  }
}

resource "openstack_compute_volume_attach_v2" "data" {
  instance_id = openstack_compute_instance_v2.calcom.id
  volume_id   = openstack_blockstorage_volume_v3.data.id
}

resource "openstack_networking_floatingip_v2" "calcom" {
  pool = var.external_network
}

resource "openstack_networking_floatingip_associate_v2" "calcom" {
  floating_ip = openstack_networking_floatingip_v2.calcom.address
  port_id     = openstack_networking_port_v2.calcom.id
}
variables.tfHCL
variable "key_name" {
  description = "SSH keypair name (must already exist in your project)"
  type        = string
}

variable "flavor_name" {
  description = "Instance size. Cal.com's published Docker image bakes NEXT_PUBLIC_WEBAPP_URL in at build time, so this template builds the Next.js app from source on first start rather than pulling a prebuilt image. That build needs real CPU and disk, more than a typical single-app ops tool. The default s1a.large (8 vCPU / 8 GiB) covers the build; size down after the first successful build if you want to save cost, since the running app itself is comparable to Unleash or Cal.com's other Postgres-backed peers."
  type        = string
  default     = "s1a.large"
}

variable "image_name" {
  description = "Operating system image. Ubuntu 24.04 is the recommended base."
  type        = string
  default     = "Ubuntu-24.04"
}

variable "app_name" {
  description = "Display name prefix for compute and network resources"
  type        = string
  default     = "calcom"
}

variable "volume_size" {
  description = "Block volume size in GiB, mounted at /var/lib/docker so the cloned source tree, the Next.js build output, the Docker build cache, and the PostgreSQL data all live on a volume you can grow rather than on the boot disk. Larger than the other ops-tools templates because a Next.js monorepo build produces a lot of intermediate output."
  type        = number
  default     = 30
}

variable "external_network" {
  description = "Shared external network for router gateway and floating IPs; defaults to PublicStatic (persisted FIP / production pattern). Override with PublicEphemeral for ephemeral demos."
  type        = string
  default     = "PublicStatic"
}

variable "private_cidr" {
  description = "CIDR for the private tenant network the instance lives in"
  type        = string
  default     = "10.56.0.0/24"
}

variable "app_allowed_cidr" {
  description = "CIDR allowed to reach Cal.com on port 3000. Defaults to the private network only, so the app is not exposed to the public internet on its raw port. Put a reverse proxy on 443 in front for HTTPS once you point a domain at the instance. To reach port 3000 directly from your workstation during setup, set this to YOUR_IP/32."
  type        = string
  default     = "10.56.0.0/24"
}
outputs.tfHCL
output "instance_id" {
  description = "ID of the compute instance running Cal.com"
  value       = openstack_compute_instance_v2.calcom.id
}

output "floating_ip" {
  description = "Public floating IP address of the Cal.com host"
  value       = openstack_networking_floatingip_v2.calcom.address
}

output "private_ip" {
  description = "Private IP address of the instance"
  value       = openstack_compute_instance_v2.calcom.access_ip_v4
}

output "app_url" {
  description = "Cal.com app URL on port 3000. Reachable from app_allowed_cidr (the private network by default). cloud-init starts only PostgreSQL; the Cal.com app image is not built until you set NEXT_PUBLIC_WEBAPP_URL and NEXTAUTH_URL in /opt/calcom/.env and run the build yourself, because that value is compiled into the Next.js bundle rather than read at runtime."
  value       = "http://${openstack_networking_floatingip_v2.calcom.address}:3000"
}
versions.tfHCL
terraform {
  required_version = ">= 1.6.0"

  required_providers {
    openstack = {
      source  = "terraform-provider-openstack/openstack"
      version = "~> 2.0"
    }
  }
}

provider "openstack" {}
terraform.tfvars.exampleHCL
# Required: SSH keypair must already exist in your project
key_name = "YOUR_KEY_NAME"

# Recommended: restrict the app port (3000) to your workstation IP for setup.
# Leave unset to keep 3000 reachable only from the private network and tunnel
# over SSH. For production use, put a reverse proxy in front on 443.
# app_allowed_cidr = "203.0.113.10/32"

# flavor_name = "s1a.large"
# image_name = "Ubuntu-24.04"
# app_name = "calcom"
# volume_size = 30
# external_network = "PublicStatic"
# private_cidr = "10.56.0.0/24"
cloud-init/calcom.yaml.tftpl
#cloud-config
package_update: true
packages:
  - ca-certificates
  - curl
  - git
write_files:
  - path: /opt/calcom/docker-compose.yml
    permissions: "0644"
    content: |
      # Cal.com scheduling for ${app_name}. Cal.com's published Docker Hub
      # image bakes NEXT_PUBLIC_WEBAPP_URL in at build time, with no runtime
      # override, so this compose file builds the app from the source tree
      # cloud-init clones to ./src instead of pulling a prebuilt image.
      # cloud-init starts only the database; build and start the calcom
      # service yourself after you finish configuring /opt/calcom/.env.
      services:
        database:
          image: postgres:16-alpine
          restart: unless-stopped
          env_file:
            - /opt/calcom/.env
          volumes:
            - calcom_pg:/var/lib/postgresql/data
        calcom:
          build:
            context: /opt/calcom/src
            dockerfile: Dockerfile
            args:
              NEXT_PUBLIC_WEBAPP_URL: $${NEXT_PUBLIC_WEBAPP_URL}
              NEXTAUTH_SECRET: $${NEXTAUTH_SECRET}
              CALENDSO_ENCRYPTION_KEY: $${CALENDSO_ENCRYPTION_KEY}
              DATABASE_URL: $${DATABASE_URL}
              CALCOM_TELEMETRY_DISABLED: $${CALCOM_TELEMETRY_DISABLED}
          restart: unless-stopped
          ports:
            - "3000:3000"
          env_file:
            - /opt/calcom/.env
          depends_on:
            - database
      volumes:
        calcom_pg:
runcmd:
  - |
    set -e
    # The data volume attaches as /dev/sdb on this platform (not /dev/vdb).
    # Mount it at /var/lib/docker before Docker is installed so the cloned
    # source tree, the Next.js build cache, and the PostgreSQL data all live
    # on the resizable volume rather than the boot disk.
    DEV=/dev/sdb
    for i in $(seq 1 30); do [ -b "$DEV" ] && break; sleep 5; done
    if ! blkid "$DEV" >/dev/null 2>&1; then mkfs.ext4 -F -L calcomdata "$DEV"; fi
    mkdir -p /var/lib/docker
    mount "$DEV" /var/lib/docker
    grep -q "$DEV" /etc/fstab || echo "$DEV /var/lib/docker ext4 defaults,nofail 0 2" >> /etc/fstab
    # Install Docker Engine plus the compose plugin from Docker's convenience
    # script.
    curl -fsSL https://get.docker.com | sh
    mkdir -p /opt/calcom
    cd /opt/calcom
    # Cal.com's published calcom/cal.com Docker Hub image bakes
    # NEXT_PUBLIC_WEBAPP_URL in at build time; there is no runtime override.
    # Building from source is the only way to point the app at your own
    # domain, so this template clones the pinned release tag instead of
    # pulling the prebuilt image.
    git clone --branch v6.2.0 --depth 1 https://github.com/calcom/cal.com.git src
    # Generate the app secrets and the bundled database password on first
    # boot. None of these ship with this template.
    NEXTAUTH_SECRET=$(openssl rand -base64 32)
    ENCRYPTION_KEY=$(openssl rand -base64 24)
    PGPASS=$(openssl rand -hex 24)
    umask 077
    {
      echo "POSTGRES_USER=calcom"
      echo "POSTGRES_PASSWORD=$PGPASS"
      echo "POSTGRES_DB=calcom"
      echo "DATABASE_URL=postgresql://calcom:$PGPASS@database:5432/calcom"
      echo "DATABASE_DIRECT_URL=postgresql://calcom:$PGPASS@database:5432/calcom"
      echo "NEXTAUTH_SECRET=$NEXTAUTH_SECRET"
      echo "CALENDSO_ENCRYPTION_KEY=$ENCRYPTION_KEY"
      echo "CALCOM_TELEMETRY_DISABLED=1"
      echo "# NEXT_PUBLIC_WEBAPP_URL and NEXTAUTH_URL are compiled into the"
      echo "# Next.js bundle when the calcom image is built, not read at"
      echo "# runtime. Set both to your public HTTPS address, then run:"
      echo "#   cd /opt/calcom && docker compose build calcom && docker compose up -d calcom"
      echo "# NEXT_PUBLIC_WEBAPP_URL=https://cal.example.com"
      echo "# NEXTAUTH_URL=https://cal.example.com"
    } > .env
    chmod 600 .env
    # Bring up PostgreSQL only. The Cal.com app image is not built until you
    # finish configuring .env and build it yourself, since
    # NEXT_PUBLIC_WEBAPP_URL cannot change after the image is built.
    docker compose up -d database
README.mdMarkdown
# Cal.com scheduling

Single compute instance running [Cal.com](https://cal.com), a self-hosted scheduling and booking platform (a self-hosted alternative to Calendly) on infrastructure you control. After apply, cloud-init clones Cal.com's source and starts the bundled PostgreSQL; you set the public app URL and build the app yourself.


**Network class:** production — `external_network` defaults to `PublicStatic` for persisted floating IPs and multi-tier stacks; override with `PublicEphemeral` for ephemeral demos.

The instance provisions a private network, a floating IP, and a block volume mounted at `/var/lib/docker` so the cloned source tree, the Next.js build cache, and the PostgreSQL data all live on a resizable volume.

## Where this fits

Cal.com centralizes availability, event types, and bookings for a person or a team, with calendar sync and workflow automation, on infrastructure you own rather than on a third-party SaaS.

## A build-from-source template, not a pulled image

Cal.com's published `calcom/cal.com` Docker Hub image compiles `NEXT_PUBLIC_WEBAPP_URL` into the Next.js bundle at build time. Cal.com's own documentation lists it, alongside `NEXT_PUBLIC_LICENSE_CONSENT` and `NEXT_PUBLIC_TELEMETRY_KEY`, as a build-time-only variable: changing it after the image is built requires building your own image. There is no supported runtime override.

Because of that constraint, this template does not pull the prebuilt image. cloud-init clones the pinned `v6.2.0` release tag to `/opt/calcom/src` and the compose file builds the `calcom` service from that source tree, passing `NEXT_PUBLIC_WEBAPP_URL`, `NEXTAUTH_SECRET`, `CALENDSO_ENCRYPTION_KEY`, and `DATABASE_URL` in as Docker build arguments read from `/opt/calcom/.env`. This is why the app doesn't start automatically on first boot: cloud-init doesn't know your public domain yet, and building with the wrong URL means rebuilding from scratch to fix it.

## Resource floor: sized for the build step

Building Cal.com's Next.js monorepo needs real CPU and disk during the build step. The default `s1a.large` flavor (8 vCPU, 8 GiB RAM) and 30 GiB data volume cover that build. Once the app is running, you can size the flavor down if you want to save cost; you'll need the larger flavor again for any future rebuild (a version upgrade, for example).

## Prerequisites

- OpenTofu >= 1.6.0 or Terraform >= 1.6.0
- Quake AI account with OpenStack credentials
- An existing SSH keypair in your project (the value of `key_name` must match that keypair)
- A domain you can point at the instance (Cal.com needs a stable public URL for OAuth calendar-sync callbacks and booking-page links)

## Usage

1. Clone or copy this template directory
2. Copy `terraform.tfvars.example` to `terraform.tfvars` and fill in your values
3. Source your OpenStack credentials: `source openrc.sh`
4. Initialize: `tofu init`
5. Preview: `tofu plan`
6. Apply: `tofu apply`

After apply, cloud-init installs Docker, 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`. No credential ships with this template.

## Finish setup after apply

Cal.com needs its public URL before you build the app image, so cloud-init holds the build until you finish configuration:

1. Point a domain's DNS A record at `floating_ip` and put a reverse proxy (Caddy or Nginx) in front for HTTPS on 443.
2. Edit `/opt/calcom/.env`: uncomment and set `NEXT_PUBLIC_WEBAPP_URL` and `NEXTAUTH_URL` to your public HTTPS address.
3. Build and start Cal.com:

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

The build compiles the entire Next.js monorepo; expect it to take a while on first run. Once it completes and the container starts, Cal.com runs its database migrations automatically.

4. Open the site URL. The first visit walks you through creating the first admin account.

## Access and security

Cal.com listens on port 3000 over plain HTTP. The security group restricts 3000 to `app_allowed_cidr`, which defaults to the private network only. Ports 80 and 443 stay open for a reverse proxy you add for production use; they carry no traffic until you add one.

## Datastores

This template bundles PostgreSQL as a container on the same instance, which suits a single-team deployment. To run it as a separate service, point `DATABASE_URL` and `DATABASE_DIRECT_URL` in `/opt/calcom/.env` at a [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres) instance, remove the bundled `database` service from the compose file, and rebuild.

## Variables

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `key_name` | string | yes | n/a | SSH keypair name (must already exist in your project) |
| `flavor_name` | string | no | `s1a.large` | Instance size (the Next.js build from source needs 8 vCPU / 8 GiB) |
| `image_name` | string | no | `Ubuntu-24.04` | Operating system image |
| `app_name` | string | no | `calcom` | Display name prefix for resources |
| `volume_size` | number | no | `30` | Block volume size in GiB, mounted at `/var/lib/docker` |
| `external_network` | string | no | `PublicStatic` | Persisted FIP / production default; override with `PublicEphemeral` for demos |
| `private_cidr` | string | no | `10.56.0.0/24` | CIDR for the private subnet |
| `app_allowed_cidr` | string | no | `10.56.0.0/24` | CIDR allowed to reach Cal.com on port 3000 |

## Outputs

| Name | Description |
| --- | --- |
| `floating_ip` | Public floating IP assigned to the instance |
| `private_ip` | Private IP address of the instance |
| `app_url` | Cal.com app URL on port 3000 |
| `instance_id` | Compute instance ID |

## Scope

This is a single-VM Cal.com host that you operate, not a managed multi-tenant scheduling service. It is CPU-only, runs in one region, bundles PostgreSQL as a container on the same host, and builds the app from source because of the published image's build-time URL constraint. 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.

## Documentation

See also: [self-managed PostgreSQL](/resources/iac-templates/self-managed-postgres), [Infisical secrets management](/resources/iac-templates/infisical-secrets)
Resources, parameters, and variables
Provisions
Parameterized by
Variables
  • key_namerequired
  • flavor_name="s1a.large"
  • image_name="Ubuntu-24.04"
  • app_name="calcom"
  • volume_size=30
  • external_network="PublicStatic"
  • private_cidr="10.56.0.0/24"
  • app_allowed_cidr="10.56.0.0/24"

Customize this pattern#

See also#

Usage Guidelines

The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.

For the full policy, see Usage Guidelines.

Was this page helpful?