Self-Hosting Guide

Deploy your own ShipKit instance on Vercel + Supabase.

Prerequisites

  • Node.js 20+
  • Vercel CLI (npm i -g vercel)
  • Supabase account (free tier works)
  • Stripe account (for billing)
  • Google AI API key (optional — for AI screenshot analysis)

Step 1: Clone and Install

git clone https://github.com/your-org/shipkit.git

cd shipkit

npm install

Step 2: Supabase Setup

  1. Create a new project at supabase.com
  2. Run all 13 migrations in order via SQL Editor:
supabase/migrations/001initialschema.sql

supabase/migrations/002addscheduling.sql

supabase/migrations/003addai_analysis.sql

supabase/migrations/004addusage_functions.sql

supabase/migrations/005v3features.sql

supabase/migrations/006v4features.sql

supabase/migrations/007v4translation_feedback.sql

supabase/migrations/008changelogseo.sql

supabase/migrations/009statuspage_og.sql

supabase/migrations/010emailnotifications.sql

supabase/migrations/011apikeys.sql

supabase/migrations/012_webhooks.sql

supabase/migrations/013sitedocs.sql

  1. Enable Email auth in Authentication settings
  2. (Optional) Configure GitHub OAuth provider for repo connections
Migration 001 automatically creates screenshots and diffs storage buckets. If they don't appear, create them manually in Supabase Dashboard > Storage (both private).

Step 3: Stripe Setup

  1. Create 2 products with monthly prices:
  • Pro — $19/month
  • Team — $49/month
  1. Note the Price IDs (e.g., price_xxx)
  2. Note your Secret Key, Publishable Key, and Webhook Secret

Step 4: Google AI Setup (Optional)

  1. Go to aistudio.google.com/apikey
  2. Create an API key (free tier is generous)
  3. This enables: AI-powered visual change analysis on screenshots
  4. All other features work without it

Step 5: Environment Variables

Set these in the Vercel dashboard (Settings > Environment Variables):

Required (8)

VariableDescription
NEXTPUBLICSUPABASE_URLSupabase project URL
NEXTPUBLICSUPABASEANONKEYSupabase anonymous key
SUPABASESERVICEROLE_KEYSupabase service role key
STRIPESECRETKEYStripe secret key
NEXTPUBLICSTRIPEPUBLISHABLEKEYStripe publishable key
STRIPEWEBHOOKSECRETStripe webhook signature secret
STRIPEPRICEPROStripe Price ID for Pro plan
STRIPEPRICETEAMStripe Price ID for Team plan

Optional

VariableDescription
GEMINIAPIKEYGoogle AI key (enables AI screenshot analysis)
CRON_SECRETBearer token for cron auth
NEXTPUBLICAPP_URLProduction URL (defaults to Vercel URL)
Tip: Vercel env vars can have invisible whitespace. Always delete and re-add vars rather than editing in place.

Step 6: Deploy

vercel login

vercel --prod

Step 7: Verify

curl https://YOUR-DOMAIN/api/health

Expected response:

{

"status": "ok",

"version": "5.7.0",

"env": {

"ready": true,

"configured": 8,

"missing": 0,

"ai_enabled": true,

"billing_enabled": true

}

}

Step 8: Post-Deploy Configuration

  1. Stripe webhook: Set URL to https://YOUR-DOMAIN/api/stripe/webhook
  • Events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted
  1. Test the signup flow
  2. Test a demo capture from the landing page
  3. Test AI doc generation (requires GEMINIAPIKEY)

Cron Jobs

Configured automatically via vercel.json:

PathScheduleDescription
/api/cron/capture-scheduledDaily 6 AM UTCProcess scheduled screenshot captures
/api/cron/daily-tasksDaily midnight UTCUsage reset, doc updates, status checks

Screenshot Capture on Vercel

The capture engine uses @sparticuz/chromium (serverless-optimized, ~50MB), automatically detected via process.env.VERCEL. No extra configuration needed.

If captures fail with size errors, upgrade to Vercel Pro (250MB function limit).

Platform Connections

To enable publishing to external platforms, users configure in their dashboard:

PlatformToken Source
Notionnotion.so/my-integrations
Confluenceid.atlassian.com/manage-profile/security/api-tokens
GitBookGitBook settings page

Pre-Deploy Checklist

npm test              # 325 unit tests must pass

npm run build # 0 TypeScript errors

Troubleshooting

Storage buckets missing

Create screenshots and diffs buckets manually in Supabase Dashboard > Storage. Both should be private.

Environment variable issues

Delete the variable and re-add it. Do not edit in place — Vercel's UI can introduce invisible whitespace.

Capture timeouts

The capture and demo capture routes have maxDuration: 60 set in vercel.json. If pages take longer to load, increase the delay via waitdelayms in the screenshot config.