- Infrastructure Deployment
- Deploy Cal.com self-hosted to GCP Cloud Run with Supabase PostgreSQL, or run locally via Docker Compose.
- Mandatory Preflight
- Step 1: Check GCP Project Configuration
- echo
- "CALCOM_GCP_PROJECT:
- ${CALCOM_GCP_PROJECT
- :-
- NOT_SET}
- "
- echo
- "CALCOM_GCP_ACCOUNT:
- ${CALCOM_GCP_ACCOUNT
- :-
- NOT_SET}
- "
- echo
- "CALCOM_GCP_REGION:
- ${CALCOM_GCP_REGION
- :-
- us-central1}
- "
- If NOT_SET
- These must be configured in
.mise.local.toml
. Run the setup command.
Step 2: Verify GCP Authentication
gcloud auth list
--filter
=
"status=ACTIVE"
--format
=
"value(account)"
2
/dev/null Step 3: Check Supabase Configuration echo "SUPABASE_PROJECT_REF: ${SUPABASE_PROJECT_REF :- NOT_SET} " echo "SUPABASE_DB_URL_REF: ${SUPABASE_DB_URL_REF :- NOT_SET} " Step 4: Verify Cal.com Secrets echo "CALCOM_NEXTAUTH_SECRET_REF: ${CALCOM_NEXTAUTH_SECRET_REF :- NOT_SET} " echo "CALCOM_ENCRYPTION_KEY_REF: ${CALCOM_ENCRYPTION_KEY_REF :- NOT_SET} " echo "CALCOM_CRON_API_KEY_REF: ${CALCOM_CRON_API_KEY_REF :- NOT_SET} " All 1Password references must be SET. Secrets are stored in Claude Automation vault. Deploy Target: GCP Cloud Run Step 1: Verify GCP APIs Enabled gcloud services list --enabled \ --project = " $CALCOM_GCP_PROJECT " \ --account = " $CALCOM_GCP_ACCOUNT " 2
/dev/null | grep -E "run|artifact|build" Required APIs: Cloud Run, Artifact Registry, Cloud Build. Step 2: Build Container
From the cal.com fork directory
cd ~/fork-tools/cal.com
Build Docker image
docker build -t calcom-self-hosted . Step 3: Push to Artifact Registry
Tag for Artifact Registry
docker tag calcom-self-hosted \ " ${CALCOM_GCP_REGION} -docker.pkg.dev/ ${CALCOM_GCP_PROJECT} /calcom/calcom:latest"
Push
docker push \ " ${CALCOM_GCP_REGION} -docker.pkg.dev/ ${CALCOM_GCP_PROJECT} /calcom/calcom:latest" Step 4: Deploy to Cloud Run
Resolve secrets from 1Password
NEXTAUTH_SECRET
$( op read " $CALCOM_NEXTAUTH_SECRET_REF " ) ENCRYPTION_KEY = $( op read " $CALCOM_ENCRYPTION_KEY_REF " ) CRON_API_KEY = $( op read " $CALCOM_CRON_API_KEY_REF " ) DATABASE_URL = $( op read " $SUPABASE_DB_URL_REF " ) gcloud run deploy calcom \ --image = " ${CALCOM_GCP_REGION} -docker.pkg.dev/ ${CALCOM_GCP_PROJECT} /calcom/calcom:latest" \ --region = " $CALCOM_GCP_REGION " \ --project = " $CALCOM_GCP_PROJECT " \ --account = " $CALCOM_GCP_ACCOUNT " \ --platform = managed \ --allow-unauthenticated \ --port = 3000 \ --memory = 512Mi \ --cpu = 1 \ --min-instances = 0 \ --max-instances = 2 \ --set-env-vars = "DATABASE_URL= ${DATABASE_URL} " \ --set-env-vars = "NEXTAUTH_SECRET= ${NEXTAUTH_SECRET} " \ --set-env-vars = "CALENDSO_ENCRYPTION_KEY= ${ENCRYPTION_KEY} " \ --set-env-vars = "CRON_API_KEY= ${CRON_API_KEY} " \ --set-env-vars = "NEXT_PUBLIC_WEBAPP_URL=https://calcom- ${CALCOM_GCP_PROJECT} .run.app" \ --set-env-vars = "NEXT_PUBLIC_API_V2_URL=https://calcom- ${CALCOM_GCP_PROJECT} .run.app/api/v2" Deploy Target: Docker Compose (Local Dev) docker-compose.yml Template version : "3.9" services : calcom : image : calcom/cal.com : latest restart : unless - stopped ports : - "3000:3000" env_file : - .env depends_on : database : condition : service_healthy database : image : postgres : 15 restart : unless - stopped volumes : - calcom - db : /var/lib/postgresql/data environment : POSTGRES_USER : calcom POSTGRES_PASSWORD : calcom POSTGRES_DB : calcom healthcheck : test : [ "CMD-SHELL" , "pg_isready -U calcom" ] interval : 10s timeout : 5s retries : 5 volumes : calcom-db : Local .env Template DATABASE_URL = postgresql://calcom:calcom@database:5432/calcom NEXTAUTH_SECRET = < generate-with-openssl
CALENDSO_ENCRYPTION_KEY
< generate-with-openssl
CRON_API_KEY
< generate-with-openssl
NEXT_PUBLIC_WEBAPP_URL
http://localhost:3000 NEXT_PUBLIC_API_V2_URL = http://localhost:3000/api/v2 Deploy Target: Webhook Relay (Pushover Notifications) Lightweight Cloud Run service bridging Cal.com webhooks to Pushover emergency alerts. Zero dependencies (Python stdlib only). Step 1: Verify Pushover Credentials echo "PUSHOVER_APP_TOKEN: ${PUSHOVER_APP_TOKEN :+ SET} " echo "PUSHOVER_USER_KEY: ${PUSHOVER_USER_KEY :+ SET} " echo "PUSHOVER_SOUND: ${PUSHOVER_SOUND :- dune} " All must be SET. See pushover-setup.md for credential setup. Step 2: Deploy Webhook Relay to Cloud Run RELAY_SOURCE = " $HOME /.claude/plugins/marketplaces/cc-skills/plugins/calcom-commander/scripts/webhook-relay" gcloud run deploy calcom-pushover-webhook \ --source " $RELAY_SOURCE " \ --project = " $CALCOM_GCP_PROJECT " \ --account = " $CALCOM_GCP_ACCOUNT " \ --region = " $CALCOM_GCP_REGION " \ --platform managed \ --allow-unauthenticated \ --set-env-vars = "PUSHOVER_TOKEN= $PUSHOVER_APP_TOKEN ,PUSHOVER_USER= $PUSHOVER_USER_KEY ,PUSHOVER_SOUND= ${PUSHOVER_SOUND :- dune} " \ --memory = 128Mi \ --cpu = 1 \ --min-instances = 0 \ --max-instances = 1 \ --timeout = 30 \ --quiet Note the Service URL from the output. Store in .mise.local.toml as WEBHOOK_RELAY_URL . Step 3: Verify Health curl -s " $WEBHOOK_RELAY_URL " | python3 -m json.tool
Expected:
Step 4: Register Cal.com Webhook
CALCOM_API_KEY
=
$(
op
item get
"
$CALCOM_OP_UUID
"
--vault
"Claude Automation"
--fields
password
--reveal
)
curl
-s
-X
POST
"https://api.cal.com/v1/webhooks?apiKey=
$CALCOM_API_KEY
"
\
-H
"Content-Type: application/json"
\
-d
"{
\"
subscriberUrl
\"
:
\"
$WEBHOOK_RELAY_URL
\"
,
\"
eventTriggers
\"
:[
\"
BOOKING_CREATED
\"
,
\"
BOOKING_RESCHEDULED
\"
,
\"
BOOKING_CANCELLED
\"
],
\"
active
\"
:true}"
Step 5: Test with Simulated Booking
curl
-s
-X
POST
"
$WEBHOOK_RELAY_URL
"
\
-H
"Content-Type: application/json"
\
-d
'{"triggerEvent":"BOOKING_CREATED","payload":{"title":"Test Meeting","attendees":[{"name":"Test User"}],"startTime":"2026-01-01T10:00:00Z","endTime":"2026-01-01T10:30:00Z"}}'
Expected: Pushover emergency alert with "dune" sound on your device.
Supabase Database Management
Check Connection
DATABASE_URL
=
$(
op
read
"
$SUPABASE_DB_URL_REF
"
)
psql
"
$DATABASE_URL
"
-c
"SELECT version();"
Run Migrations
cd
~/fork-tools/cal.com
DATABASE_URL
=
$(
op
read
"
$SUPABASE_DB_URL_REF
"
)
npx prisma migrate deploy
1Password Secret References
All secrets in Claude Automation vault (biometric-free access):
Secret
1Password Reference
NEXTAUTH_SECRET
op://Claude Automation/