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
- Create a new project at supabase.com
- 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
- Enable Email auth in Authentication settings
- (Optional) Configure GitHub OAuth provider for repo connections
Migration 001 automatically createsscreenshotsanddiffsstorage buckets. If they don't appear, create them manually in Supabase Dashboard > Storage (both private).
Step 3: Stripe Setup
- Create 2 products with monthly prices:
- Pro — $19/month
- Team — $49/month
- Note the Price IDs (e.g.,
price_xxx) - Note your Secret Key, Publishable Key, and Webhook Secret
Step 4: Google AI Setup (Optional)
- Go to aistudio.google.com/apikey
- Create an API key (free tier is generous)
- This enables: AI-powered visual change analysis on screenshots
- All other features work without it
Step 5: Environment Variables
Set these in the Vercel dashboard (Settings > Environment Variables):
Required (8)
| Variable | Description |
|---|---|
NEXTPUBLICSUPABASE_URL | Supabase project URL |
NEXTPUBLICSUPABASEANONKEY | Supabase anonymous key |
SUPABASESERVICEROLE_KEY | Supabase service role key |
STRIPESECRETKEY | Stripe secret key |
NEXTPUBLICSTRIPEPUBLISHABLEKEY | Stripe publishable key |
STRIPEWEBHOOKSECRET | Stripe webhook signature secret |
STRIPEPRICEPRO | Stripe Price ID for Pro plan |
STRIPEPRICETEAM | Stripe Price ID for Team plan |
Optional
| Variable | Description |
|---|---|
GEMINIAPIKEY | Google AI key (enables AI screenshot analysis) |
CRON_SECRET | Bearer token for cron auth |
NEXTPUBLICAPP_URL | Production 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
- Stripe webhook: Set URL to
https://YOUR-DOMAIN/api/stripe/webhook
- Events:
checkout.session.completed,customer.subscription.updated,customer.subscription.deleted
- Test the signup flow
- Test a demo capture from the landing page
- Test AI doc generation (requires
GEMINIAPIKEY)
Cron Jobs
Configured automatically via vercel.json:
| Path | Schedule | Description |
|---|---|---|
/api/cron/capture-scheduled | Daily 6 AM UTC | Process scheduled screenshot captures |
/api/cron/daily-tasks | Daily midnight UTC | Usage 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:
| Platform | Token Source |
|---|---|
| Notion | notion.so/my-integrations |
| Confluence | id.atlassian.com/manage-profile/security/api-tokens |
| GitBook | GitBook 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.