Cal.com self-hosted deployment to GCP Cloud Run with Supabase PostgreSQL. Docker Compose for local dev. TRIGGERS - deploy calcom, cloud run, self-hosted, docker compose, supabase, gcp deploy, infrastructure, cal.com hosting.
From calcom-commandernpx claudepluginhub terrylica/cc-skills --plugin calcom-commanderThis skill is limited to using the following tools:
references/evolution-log.mdGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Optimizes cloud costs on AWS, Azure, GCP via rightsizing, tagging strategies, reserved instances, spot usage, and spending analysis. Use for expense reduction and governance.
Deploy Cal.com self-hosted to GCP Cloud Run with Supabase PostgreSQL, or run locally via Docker Compose.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
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.
gcloud auth list --filter="status=ACTIVE" --format="value(account)" 2>/dev/null
echo "SUPABASE_PROJECT_REF: ${SUPABASE_PROJECT_REF:-NOT_SET}"
echo "SUPABASE_DB_URL_REF: ${SUPABASE_DB_URL_REF:-NOT_SET}"
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.
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.
# From the cal.com fork directory
cd ~/fork-tools/cal.com
# Build Docker image
docker build -t calcom-self-hosted .
# 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"
# 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"
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:
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
Lightweight Cloud Run service bridging Cal.com webhooks to Pushover emergency alerts. Zero dependencies (Python stdlib only).
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.
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.
curl -s "$WEBHOOK_RELAY_URL" | python3 -m json.tool
# Expected: {"status": "healthy", "service": "calcom-pushover-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}"
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.
DATABASE_URL=$(op read "$SUPABASE_DB_URL_REF")
psql "$DATABASE_URL" -c "SELECT version();"
cd ~/fork-tools/cal.com
DATABASE_URL=$(op read "$SUPABASE_DB_URL_REF") npx prisma migrate deploy
All secrets in Claude Automation vault (biometric-free access):
| Secret | 1Password Reference |
|---|---|
NEXTAUTH_SECRET | op://Claude Automation/<item-id>/NEXTAUTH_SECRET |
CALENDSO_ENCRYPTION_KEY | op://Claude Automation/<item-id>/CALENDSO_ENCRYPTION_KEY |
CRON_API_KEY | op://Claude Automation/<item-id>/CRON_API_KEY |
DATABASE_URL | op://Claude Automation/<item-id>/DATABASE_URL |
DATABASE_DIRECT_URL | op://Claude Automation/<item-id>/DATABASE_DIRECT_URL |
After this skill completes, reflect before closing the task:
Do NOT defer. The next invocation inherits whatever you leave behind.