Claude-code-plugins clerk-deploy-integration
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/clerk-pack/skills/clerk-deploy-integration" ~/.claude/skills/jeremylongshore-claude-code-plugins-clerk-deploy-integration && rm -rf "$T"
manifest:
plugins/saas-packs/clerk-pack/skills/clerk-deploy-integration/SKILL.mdsource content
Clerk Deploy Integration
Overview
Deploy Clerk-authenticated applications to Vercel, Netlify, Railway, and other hosting platforms. Covers environment variable configuration, domain setup, and webhook endpoint configuration.
Prerequisites
- Clerk production instance with
/pk_live_
keyssk_live_ - Production domain configured
- Hosting platform account
Instructions
Step 1: Vercel Deployment
# Add Clerk env vars to Vercel vercel env add NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY production # Paste: pk_live_... vercel env add CLERK_SECRET_KEY production # Paste: sk_live_... vercel env add CLERK_WEBHOOK_SECRET production # Paste: whsec_... # Add for preview deployments too vercel env add NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY preview vercel env add CLERK_SECRET_KEY preview
Configure Clerk Dashboard for Vercel:
- Go to Dashboard > Domains and add your production domain
- Set Home URL:
https://myapp.com - Set Sign-in URL:
https://myapp.com/sign-in - Set Sign-up URL:
https://myapp.com/sign-up - Set After sign-in URL:
https://myapp.com/dashboard
Step 2: Netlify Deployment
# Add env vars via Netlify CLI netlify env:set NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY pk_live_... netlify env:set CLERK_SECRET_KEY sk_live_...
For Netlify Functions (serverless API routes):
// netlify/functions/clerk-auth.ts import { createClerkClient } from '@clerk/backend' const clerk = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY! }) export async function handler(event: any) { const token = event.headers.authorization?.replace('Bearer ', '') if (!token) { return { statusCode: 401, body: JSON.stringify({ error: 'No token' }) } } try { const session = await clerk.sessions.verifySession(token, token) return { statusCode: 200, body: JSON.stringify({ userId: session.userId }), } } catch { return { statusCode: 401, body: JSON.stringify({ error: 'Invalid token' }) } } }
Step 3: Railway Deployment
# Set env vars via Railway CLI railway variables set NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_... railway variables set CLERK_SECRET_KEY=sk_live_... railway variables set CLERK_WEBHOOK_SECRET=whsec_...
Step 4: Docker Deployment
# Dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . # Build-time env vars (public key only) ARG NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY ENV NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=$NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY RUN npm run build FROM node:20-alpine AS runner WORKDIR /app COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/public ./public # Runtime env vars (secret key injected at runtime, not baked into image) # CLERK_SECRET_KEY set via docker run -e or docker-compose EXPOSE 3000 CMD ["node", "server.js"]
# docker-compose.yml services: app: build: context: . args: NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: pk_live_... environment: - CLERK_SECRET_KEY=sk_live_... - CLERK_WEBHOOK_SECRET=whsec_... ports: - "3000:3000"
Step 5: Post-Deployment Verification
#!/bin/bash # scripts/verify-deployment.sh set -euo pipefail DOMAIN="${1:-https://myapp.com}" echo "Checking deployment at $DOMAIN..." # 1. Homepage loads STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$DOMAIN") echo "Homepage: HTTP $STATUS" # 2. Sign-in page accessible STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$DOMAIN/sign-in") echo "Sign-in: HTTP $STATUS" # 3. Health check (if implemented) curl -s "$DOMAIN/api/clerk-health" | python3 -m json.tool 2>/dev/null || echo "No health endpoint" # 4. Webhook endpoint reachable STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$DOMAIN/api/webhooks/clerk") echo "Webhook endpoint: HTTP $STATUS (400/405 expected without valid payload)"
Output
- Platform-specific environment variables configured
- Clerk Dashboard domains and URLs set for production
- Docker multi-stage build with proper secret handling
- Post-deployment verification script
- Webhook endpoint accessible at production URL
Error Handling
| Error | Cause | Solution |
|---|---|---|
| 500 on sign-in page | Missing | Add secret key to platform env vars |
| Webhook signature fails | Wrong endpoint URL | Update URL in Clerk Dashboard > Webhooks |
| CORS error | Domain not in allowed origins | Add production domain in Clerk Dashboard > Domains |
| Redirect loop after deploy | Sign-in URL misconfigured | Check matches route |
| Docker build missing PK | Not passed as build arg | Add |
Examples
Vercel Preview Deployment with Clerk
# Configure Clerk for Vercel preview deployments # Use test keys for preview, live keys for production vercel env add NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY preview # pk_test_... vercel env add CLERK_SECRET_KEY preview # sk_test_... vercel env add NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY production # pk_live_... vercel env add CLERK_SECRET_KEY production # sk_live_...
Resources
Next Steps
Proceed to
clerk-webhooks-events for webhook configuration.