Move site configuration under settings, model analytics and licensing as resources, and isolate scheduler runs under the internal API. BREAKING CHANGE: site email, branding, analytics, licensing, WebDAV verification, and scheduler endpoint paths have changed. Refs #451
4.9 KiB
Vercel Deployment
ZPan supports Vercel as a first-class deploy target using Vercel Functions (Node.js runtime) + Turso as the database and an external S3-compatible bucket for storage.
Edge runtime is not supported.
@aws-sdk/client-s3requires Node.js APIs (streams, crypto) that are unavailable in the Edge runtime. All Vercel Functions for ZPan run on thenodejs22.xruntime.
Prerequisites
| Tool | Purpose |
|---|---|
| Vercel account | Hosts the application |
| Turso database | libSQL-compatible remote database |
| S3-compatible storage | File storage (Cloudflare R2 recommended — free egress) |
vercel CLI |
Local development and linking |
Required Secrets
Set these in your fork's GitHub repository under Settings → Secrets and variables → Actions:
| Secret | Description |
|---|---|
VERCEL_TOKEN |
Vercel API token. Create at vercel.com/account/tokens |
VERCEL_ORG_ID |
Your Vercel team/org ID. Found in vercel link output or team settings |
VERCEL_PROJECT_ID |
Project ID after first vercel link. Found in .vercel/project.json |
TURSO_DATABASE_URL |
Turso database URL, e.g. libsql://your-db.turso.io |
BETTER_AUTH_URL |
Your Vercel deployment URL, e.g. https://your-app.vercel.app |
Optional Secrets
| Secret | Description |
|---|---|
TURSO_AUTH_TOKEN |
Turso auth token. Create with turso db tokens create your-db. Required for remote Turso URLs; can be omitted for file:// local databases. |
BETTER_AUTH_SECRET |
Signing secret for auth sessions. If not provided, the workflow generates one on first deploy and persists it in your Vercel project env. Back it up from the Vercel dashboard before rotating. To bring your own: openssl rand -base64 32. |
TRUSTED_ORIGINS |
Comma-separated list of additional trusted origins. |
Quick Start (Fork + Deploy)
-
Fork the
saltbo/zpanrepository. -
Create a Turso database:
turso db create zpan-db turso db tokens create zpan-db -
Link your Vercel project locally (first time only):
cp deploy/vercel/vercel.json vercel.json pnpm exec vercel link # Note the VERCEL_ORG_ID and VERCEL_PROJECT_ID from .vercel/project.json -
Add the required secrets to your fork (see table above).
BETTER_AUTH_SECRETis optional — the workflow auto-generates one on first deploy and stores it in your Vercel project env. -
Push to
main— thedeploy-vercel.ymlworkflow runs automatically and deploys to production.
Local Development
Install the Vercel CLI and run:
pnpm add --global vercel
cp deploy/vercel/vercel.json vercel.json
# Using a local libSQL file (no Turso token needed)
TURSO_DATABASE_URL=file:./zpan.db \
BETTER_AUTH_SECRET=$(openssl rand -base64 32) \
vercel dev
The app will be available at http://localhost:3000.
Build Output
pnpm build:vercel produces:
| Path | Contents |
|---|---|
dist/ |
React SPA static assets |
api/entry-vercel.js |
Hono API compiled as a Vercel Function (ESM) |
vercel.json routes:
/api/*and/health→ Vercel Function- All other paths →
dist/index.html(SPA)
Entitlement Refresh (License Cert)
ZPan refreshes its entitlement certificate every 6 hours. On Vercel there is no persistent process, so you need to trigger a refresh via an external scheduler.
Setup
-
Generate a secret:
openssl rand -hex 32 -
Add the env var in your Vercel project settings (Project → Settings → Environment Variables):
Variable Value REFRESH_CRON_SECRETThe random string from step 1 CRON_SECRETThe same value; Vercel sends it as the scheduler Bearer token -
Schedule the call using Vercel Cron Jobs. Add a
cronsentry to yourvercel.json:{ "crons": [ { "path": "/api/internal/licensing/refresh-runs", "schedule": "0 */6 * * *" }, { "path": "/api/internal/traffic-sync-runs", "schedule": "*/10 * * * *" } ] }
Send Authorization: Bearer <REFRESH_CRON_SECRET> with every scheduler request. If REFRESH_CRON_SECRET is not set, the endpoint returns 401 for all requests.
Pricing Notes
- Hobby (free) — suitable for personal and non-commercial use. 100 GB-hours of function compute per month.
- Pro ($20/mo) — required for commercial use per Vercel's fair-use policy. Includes team features, higher limits, and SLA.
- Turso — free tier includes 500 databases and 9 GB of total storage.
- Cloudflare R2 — recommended S3-compatible storage. Free egress (no bandwidth charges between Vercel and R2 if using the same region is not required — R2 has zero egress fees globally).