关于 infra-deploy
infra-deploy 是用于部署和管理 Cal.com 基础设施的技能,面向自托管部署与本地开发。它涵盖 GCP Cloud Run、Supabase PostgreSQL、Docker Compose,以及 Pushover Webhook 中继服务。
主要功能
- 01部署到 GCP Cloud Run
- 02配置 Supabase PostgreSQL
- 03通过 Docker Compose 本地运行
- 04部署 Cal.com 到 Pushover 的 Webhook 中继
- 05执行数据库连接检查与迁移
适用场景
- 01在 GCP Cloud Run 部署 Cal.com
- 02使用 Docker Compose 运行本地开发环境
- 03为 Cal.com Webhook 部署 Pushover 中继
- 04连接 Supabase 并运行数据库迁移
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill infra-deploy安装后在 Claude Code 中输入/infra-deploy确认已加载。
附带文件references/evolution-log.md
详细介绍
基础设施部署
将 Cal.com 自托管部署到 GCP Cloud Run,并使用 Supabase PostgreSQL;也可以通过 Docker Compose 在本地运行。
自我演进技能:此技能会在使用过程中不断改进。如果说明有误、参数已变更,或需要采用变通方案,请立即修复此文件,不要拖延。只针对真实、可复现的问题进行更新。
强制预检
步骤 1:检查 GCP 项目配置
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}"
如果为 NOT_SET:在 shell 中导出这些变量(参见 env-setup.md),或运行设置命令。
步骤 2:验证 GCP 身份验证
gcloud auth list --filter="status=ACTIVE" --format="value(account)" 2>/dev/null
步骤 3:检查 Supabase 配置
echo "SUPABASE_PROJECT_REF: ${SUPABASE_PROJECT_REF:-NOT_SET}"
echo "SUPABASE_DB_URL_REF: ${SUPABASE_DB_URL_REF:-NOT_SET}"
步骤 4:验证 Cal.com 密钥
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}"
所有 1Password 引用都必须为 SET。 密钥存储在 Claude Automation 保险库中。
部署目标:GCP Cloud Run
步骤 1:验证 GCP API 是否已启用
gcloud services list --enabled \
--project="$CALCOM_GCP_PROJECT" \
--account="$CALCOM_GCP_ACCOUNT" 2>/dev/null | grep -E "run|artifact|build"
所需 API:Cloud Run、Artifact Registry、Cloud Build。
步骤 2:构建容器
# From the cal.com fork directory
cd ~/fork-tools/cal.com
# Build Docker image
docker build -t calcom-self-hosted .
步骤 3:推送到 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"
步骤 4:部署到 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"
部署目标:Docker Compose(本地开发)
docker-compose.yml 模板
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:
本地 .env 模板
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
部署目标:Webhook 中继(Pushover 通知)
轻量级 Cloud Run 服务,用于将 Cal.com webhook 转发为 Pushover 紧急警报。零依赖(仅使用 Python 标准库)。
步骤 1:验证 Pushover 凭据
echo "PUSHOVER_APP_TOKEN: ${PUSHOVER_APP_TOKEN:+SET}"
echo "PUSHOVER_USER_KEY: ${PUSHOVER_USER_KEY:+SET}"
echo "PUSHOVER_SOUND: ${PUSHOVER_SOUND:-dune}"
所有凭据都必须为 SET。 凭据设置请参见 pushover-setup.md。
步骤 2:将 Webhook 中继部署到 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
记下输出中的服务 URL。将其保存为 WEBHOOK_RELAY_URL,添加到 ~/gh/<org>/<automation-repo>/.env.launchd(守护进程)和 shell 环境中。
步骤 3:验证运行状况
curl -s "$WEBHOOK_RELAY_URL" | python3 -m json.tool
# Expected: {"status": "healthy", "service": "calcom-pushover-webhook"}
步骤 4:注册 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}"
步骤 5:使用模拟预订进行测试
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"}}'
预期结果:设备收到带有 “dune” 声音的 Pushover 紧急警报。
Supabase 数据库管理
检查连接
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
1Password 密钥引用
Claude Automation 保险库中的所有密钥(无需生物识别验证即可访问):
| 密钥 | 1Password 引用 |
|---|---|
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 |
变更后检查清单
- YAML frontmatter 有效(描述中不含冒号)
- 触发关键词为最新
- 路径模式使用 $HOME,而非硬编码路径
- 1Password 引用不依赖具体环境(不含硬编码 UUID)
执行后回顾
此技能执行完成后,请在结束任务前进行回顾:
- 确认文件位置。 — 找到此 SKILL.md 的规范路径,然后再进行编辑。
- 哪些地方失败了? — 修复导致问题的说明。
- 哪些地方比预期更顺利? — 将其列为推荐做法。
- 哪些内容已发生变化? — 修复任何与实际情况不符的脚本、引用或依赖项。
- 记录下来。 — 在演进日志中记录触发原因、修复内容和证据。
不要拖延。下一次调用将继承你留下的一切。