Deployment Guide
Deploy Kosuke Template to production in 60-90 minutes. This guide covers forking the repository, setting up all services, and configuring your production environment.
Prerequisites
Required Accounts
Create accounts with these services (all have free tiers):
| Service | Purpose | Free Tier | Sign Up |
|---|---|---|---|
| GitHub | Source code hosting | Yes | github.com |
| Vercel | Application hosting | Yes (Hobby) | vercel.com |
| Neon | PostgreSQL database | Yes (3 GB) | Via Vercel integration |
| Fly.io | Microservice hosting | Yes (3 VMs) | fly.io |
| Stripe | Billing & subscriptions | Test mode | stripe.com |
| Clerk | Authentication | Yes (10k MAUs) | clerk.com |
| Resend | Email delivery | Yes (100/day) | resend.com |
| Sentry | Error monitoring | Yes (5k events) | sentry.io |
Environments Overview
Kosuke Template uses a three-tier environment strategy for safe, controlled deployments:
Environment Architecture
| Environment | Branch Tracking | Deploy Trigger | Database | Use Case |
|---|---|---|---|---|
| Production | None | Git tag v*.*.* (GHA) | Production Neon DB | Live users, real payments |
| Staging | main | Auto on push | Staging Neon DB | Integration testing, QA |
| Preview | PR branches | Auto on PR | Inherits staging DB | Feature testing in isolation |
Key Features
Production:
- Manual deployment via GitHub Actions tag (
v1.0.0,v2.1.3) - Production Stripe credentials (live mode)
- Production Clerk instance
- Production Neon database
- Webhook URLs use production domain
Staging:
- Auto-deploys on pushes to main
- Test Stripe credentials (test mode)
- Development Clerk instance
- Staging Neon database with preview branch support
- Webhook URLs use staging domain (
staging-template.kosuke.ai) - Full sign-up, billing, and authentication testing
Preview:
- Auto-deploys on pull requests
- Inherits staging database (read/write to shared staging DB)
- Test Stripe and Clerk credentials
- ⚠️ Note: Webhooks target staging, not preview URLs
- Use staging environment to test sign-up and billing flows
Webhook Behavior
| Service | Production | Staging | Preview |
|---|---|---|---|
| Clerk | https://yourdomain.com/api/clerk/webhook | https://your-project-name-staging.vercel.app/api/clerk/webhook | Not available |
| Stripe | https://yourdomain.com/api/billing/webhook | https://your-project-name-staging.vercel.app/api/billing/webhook | Not available |
Preview deployments are great for UI/UX testing, but always test sign-up and billing flows on staging where webhooks are active.
Step 1: Fork Repository
Fork to Your Account
- Visit github.com/filopedraz/kosuke-template
- Click Fork button (top-right)
- Configure fork:
- Owner: Your GitHub account
- Repository name:
your-project-name(kebab-case) - Copy main branch only: ✅ Checked
- Click Create fork
Good Names: my-saas, startup-mvp, customer-portal
Avoid: My App, MyApp123, my_app
Step 2: Create Vercel Project
Import Repository
- Go to vercel.com/new
- Sign in with GitHub
- Click Import Git Repository
- Select your forked repository
- Click Import
Configure Production Environment
- Project Name: Same as repository name
- Framework Preset: Next.js (auto-detected)
- Root Directory:
./(default) - Build Settings: Leave defaults
Click Deploy and wait for build (will fail - expected!).
Set Up Blob Storage
- In Vercel project, go to Storage tab
- Click Create Blob
- Name:
your-project-name-prod-blob - Region: Same as your Neon production database
- Select Production environment only
- Click Create
Vercel automatically adds BLOB_READ_WRITE_TOKEN to production environment.
Set Up Staging Environment
In Vercel project Settings:
- Click Environments
- Click Add Environment
- Configure:
- Name:
staging - Git branch:
main - Auto-deploy on push: Yes
- Name:
- Click Create
Create staging blob storage:
- Go to Storage tab
- Click Create Blob
- Name:
your-project-name-staging-blob - Region: Same as your Neon staging database
- Select Preview environment only (staging inherits from preview)
- Click Create
Staging environment inherits all preview environment variables (Neon staging DB, Blob storage) automatically.
Step 3: Set Up Neon Database
Create Production Database
- In Vercel project, go to Storage tab
- Click Create Database
- Select Neon
- Choose:
- Create new Neon account (sign up with GitHub), OR
- Link existing account (if you have one)
- Create database:
- Region: Choose closest to users
- Name:
your-project-name-prod - Environments: Production only
- Create Database Branch for Deployment: No
- Click Create
Create Staging Database
- In Vercel project, go to Storage tab
- Click Create Database
- Select Neon
- Create database:
- Region: Same as production (or closest to development users)
- Name:
your-project-name-staging - Environments: Preview only (staging inherits)
- Create Database Branch for Deployment: Yes (enables preview branches for PRs)
- Click Create
Automatic Configuration
Vercel adds environment variables automatically:
POSTGRES_URL(Production environment) - Production Neon pooled connectionPOSTGRES_URL(Preview environment) - Staging Neon pooled connection
Preview Branches
Neon automatically creates isolated database branches for pull requests when configured:
- PR opened → Database branch created
- Run migrations on preview branch automatically
- PR closed → Branch deleted
- No impact on staging data
Configure Automated Branch Cleanup (Optional)
The template includes GitHub Actions automation to clean up preview branches when PRs are closed:
- Go to Neon Dashboard → Settings
- Navigate to API Keys section
- Create new API key: Click Create API key
- Copy the key
- Add to GitHub Secrets (Settings → Secrets and variables → Actions):
- Name:
NEON_API_KEY - Secret: [paste your Neon API key]
- Name:
NEON_PROJECT_ID - Secret: [find in Neon Dashboard → Project Settings]
- Name:
The cleanup script (.github/scripts/cleanup-neon-branch.mjs) automatically runs when PRs close.
Step 4: Configure Stripe Billing
Staging: Create Test Products
Start in Stripe test mode for staging environment:
- Dashboard: dashboard.stripe.com/dashboard
- Click your organization name (top-left) → Switch to a sandbox
Product 1: Pro Plan
- Go to Products → Create Product
- Configure:
- Name:
Pro Plan - Description:
Professional subscription with advanced features - Recursion:
Recurring - Amount:
$20.00 USD per month - Billing Interval:
Monthly
- Name:
- Click Save product
- Under Pricing, open the recurring price Stripe created
- Copy the Price ID:
price_abc123...
Product 2: Business Plan
- Click Create Product again
- Configure:
- Name:
Business Plan - Description:
Business subscription with premium features and priority support - Recursion:
Recurring - Price:
$200.00 USD per month - Billing Interval:
Monthly
- Name:
- Click Save product
- Under Pricing, open the recurring price
- Copy the Price ID:
price_xyz789...
Staging: Create Test API Credentials & Webhook
- Go to Developers → API keys
- Copy the Publishable key (test mode):
pk_test_... - Click Reveal test key and copy the Secret key:
sk_test_...
Set Up Test Webhook:
- Go to Webhooks → Add Endpoint
- Configure:
- Endpoint URL:
https://your-project-name-staging.vercel.app/api/billing/webhook - Events:
- ✅
customer.subscription.created - ✅
customer.subscription.updated - ✅
customer.subscription.deleted - ✅
invoice.paid - ✅
invoice.payment_failed - ✅
subscription_schedule.completed - ✅
subscription_schedule.canceled
- ✅
- Endpoint URL:
- Copy Signing Secret
Update staging environment variables in Vercel (select Preview environment):
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PRO_PRICE_ID=price_...
STRIPE_BUSINESS_PRICE_ID=price_abc123...
STRIPE_WEBHOOK_SECRET=whsec_xyz789...
STRIPE_SUCCESS_URL=https://your-project-name-staging.vercel.app/settings/billing
STRIPE_CANCEL_URL=https://your-project-name-staging.vercel.app/settings/billing
Production: Create Live Products
When ready for production:
- Go to dashboard.stripe.com
- Disable test mode (top-left, switch out of sandbox)
- Activate your Stripe account (complete verification)
- Go to Products → Create Product
- Create same products with same pricing:
- Pro Plan: $20.00 USD per month
- Business Plan: $200.00 USD per month
- Copy both Price IDs (will start with
price_in live mode)
Production: Create Live API Credentials & Webhook
- Go to Developers → API keys (live mode)
- Copy the Publishable key (live mode):
pk_live_... - Click Reveal live key and copy the Secret key:
sk_live_...
Set Up Production Webhook:
- Go to Webhooks → Add Endpoint
- Configure:
- Endpoint URL:
https://yourdomain.com/api/billing/webhook - Events: Same as staging (all 7 events)
- Endpoint URL:
- Copy Signing Secret
Update production environment variables in Vercel (select Production environment):
STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_SECRET_KEY=sk_live_...
STRIPE_PRO_PRICE_ID=price_prod_...
STRIPE_BUSINESS_PRICE_ID=price_prod_...
STRIPE_WEBHOOK_SECRET=whsec_prod_...
STRIPE_SUCCESS_URL=https://yourdomain.com/settings/billing
STRIPE_CANCEL_URL=https://yourdomain.com/settings/billing
Step 5: Configure Clerk Authentication
Create Single Application
- Go to dashboard.clerk.com
- Sign up with GitHub
- Click Add application
- Configure:
- Application name:
Your Project - Framework: Next.js
- Application name:
- Click Create application
Enable Organizations
- Go to Settings → Organizations
- Toggle Enable Organizations to ON
- Configure:
- Organization naming: ✅ Allow custom names
- Default roles: admin, member (recommended)
- Allow Personal Accounts: ON
- Sessions Claims __session:
{
"publicMetadata": "{{user.public_metadata}}"
} - Enable Organization Slugs: ON
- Click Save
Staging: Development Environment
By default, Clerk creates a Development environment. Get your development credentials:
- In your Clerk app dashboard, ensure Development is selected (top dropdown)
- Go to API Keys
- Copy the Publishable key:
pk_test_... - Click Reveal secret key and copy Secret key:
sk_test_...
Set Up Development Webhook:
- Go to Webhooks → Add Endpoint
- Configure:
- Endpoint URL:
https://your-project-name-staging.vercel.app/api/clerk/webhook - Subscribe to events:
- ✅ User:
user.created,user.updated,user.deleted - ✅ Organization:
organization.created,organization.updated,organization.deleted - ✅ Membership:
organizationMembership.created,organizationMembership.updated,organizationMembership.deleted
- ✅ User:
- Endpoint URL:
- Copy Signing Secret (starts with
whsec_)
Update staging environment variables in Vercel (select Preview environment):
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_WEBHOOK_SECRET=whsec_...
# URLs (same for both environments)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding
Production: Production Environment
When ready for production:
- In your Clerk app dashboard, click the environment dropdown (top-left)
- Click + Create environment
- Configure:
- Name:
Production - Type: Production
- Name:
- Click Create
Configure Production Domain:
- Go to Settings → Domains (Production environment)
- Add your production domain:
yourdomain.com - Configure DNS as instructed by Clerk
Get Production Credentials:
- Ensure Production environment is selected (top dropdown)
- Go to API Keys
- Copy the Publishable key:
pk_live_... - Click Reveal secret key and copy Secret key:
sk_live_...
Set Up Production Webhook:
- Go to Webhooks → Add Endpoint
- Configure:
- Endpoint URL:
https://yourdomain.com/api/clerk/webhook - Subscribe to events: Same as staging (all 9 events)
- Endpoint URL:
- Copy Signing Secret
Update production environment variables in Vercel (select Production environment):
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_live_...
CLERK_SECRET_KEY=sk_live_...
CLERK_WEBHOOK_SECRET=whsec_prod_...
# URLs (same for both environments)
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding
Step 6: Configure Resend Email
Create Account & API Key
- Go to resend.com
- Sign up with email
- Verify email address
- Go to API Keys → Create API Key
- Configure:
- Name:
your-project-api - Permission: Full access
- Name:
- Copy API key (starts with
re_)
Email Configuration (Shared)
Same API key and from-email used for both staging and production:
RESEND_API_KEY=re_... # Shared - one key for both environments
RESEND_FROM_EMAIL=noreply@yourdomain.com # Same for staging & production
RESEND_FROM_NAME=Your Project Name
Add to Vercel - select both Production and Preview environments (staging inherits from preview):
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL=noreply@yourdomain.com
RESEND_FROM_NAME=Your Project Name
Step 7: Configure Sentry Monitoring
Create Account & Project
- Go to sentry.io
- Sign up with GitHub
- Click Create Project
- Configure:
- Platform: Next.js
- Project name: your-project-name
- Team: Default team
- Click Create Project
Get DSN
Copy your DSN:
NEXT_PUBLIC_SENTRY_DSN=https://hash@region.ingest.sentry.io/project-id
Find it in: Settings → Projects → [Your Project] → Client Keys (DSN)
Configuration
The template includes Sentry configuration with:
- Error tracking enabled
- Performance monitoring (10% sample rate)
- Session replay (10% normal, 100% on errors)
- Automatic source map upload
The same Sentry project is used across all environments (production, staging, preview). Errors are tagged with environment to distinguish them.
Adjust sample rates in sentry.*.config.ts if needed.
Add to Vercel environment variables - select both Production and Preview:
NEXT_PUBLIC_SENTRY_DSN=https://hash@region.ingest.sentry.io/project-id
Step 8: Deploy Engine Microservice (Fly.io)
The template includes a Python FastAPI microservice that runs on Fly.io. This service provides additional backend functionality and can be extended with custom business logic.
Install Fly CLI
macOS:
curl -L https://fly.io/install.sh | sh
Windows (PowerShell):
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
Linux:
curl -L https://fly.io/install.sh | sh
Verify installation:
fly version
Create Fly.io Account
- Sign up at fly.io
- Log in via CLI:
fly auth login
Deploy Engine Service
- Navigate to engine directory:
cd engine
- Launch application:
fly launch
-
Configure deployment:
- App name:
your-project-engine(or use auto-generated) - Region: Choose closest to users (same as Neon database)
- PostgreSQL: No (we use Neon)
- Redis: No (unless needed)
- Deploy now: No (set secrets first)
- App name:
-
Copy your app URL:
https://your-project-engine.fly.dev
Set Environment Variables
Set secrets for the engine service via CLI:
# Sentry monitoring (use same DSN as main app)
fly secrets set SENTRY_DSN=https://hash@region.ingest.sentry.io/project-id
# Frontend URL for CORS configuration
fly secrets set FRONTEND_URL=https://your-project-name.vercel.app
# API secret key for authentication (generate with: openssl rand -base64 32)
fly secrets set API_SECRET_KEY=<random-secure-token>
Generate secure API key:
openssl rand -base64 32
Alternative: Set via Fly.io Dashboard:
You can also manage secrets through the web UI:
- Go to fly.io/dashboard
- Select your app → Secrets
- Click Add Secret for each variable
- Enter Name and Value
- Click Set Secret
CLI secrets automatically trigger a deployment. Dashboard secrets require manual deployment via fly deploy or the UI.
Deploy
fly deploy
Wait for deployment to complete (~2-3 minutes).
Verify Deployment
Test health endpoint:
curl https://your-project-engine.fly.dev/health
Expected response:
{
"status": "healthy",
"service": "engine-service",
"timestamp": "2025-10-14T10:00:00.000000"
}
Visit API docs: https://your-project-engine.fly.dev/docs
Fly.io Configuration
The engine is configured to:
- Auto-scale: Scales to 0 when idle (free tier friendly)
- Auto-start: Starts on first request (2-3s cold start)
- Health checks: Monitors
/healthendpoint every 30s - HTTPS: Forced HTTPS with automatic certificates
- Region: Deploys to your selected region
Cost: Free tier includes 3 shared-cpu VMs with 256MB RAM each.
Step 9: Configure GitHub Actions Secrets
The template includes GitHub Actions for automated PR reviews and controlled production deployment. Configure repository secrets to enable these features.
Navigate to GitHub Secrets
- Go to your forked repository on GitHub
- Click Settings → Secrets and variables → Actions
- Click New repository secret
Required Secrets
1. Anthropic API Key (Claude AI)
Enables AI-powered PR reviews and issue assistance via Claude.
Get API Key:
- Go to console.anthropic.com
- Sign up or log in
- Navigate to API Keys
- Click Create Key
- Copy the key (starts with
sk-ant-)
Add to GitHub:
- Name:
ANTHROPIC_API_KEY - Secret:
sk-ant-api03-...
Usage:
- Mention
@claudein pull requests for code reviews - Mention
@claudein issues for assistance - Automated PR analysis and suggestions
2. Fly.io API Token (Microservice Deployment)
Enables automatic deployment of the engine microservice on pull requests and pushes.
Get API Token:
fly auth token
Or via dashboard:
- Go to fly.io/user/personal_access_tokens
- Click Create token
- Name:
github-actions-deploy - Copy the token
Add to GitHub:
- Name:
FLY_API_TOKEN - Secret:
fo1_...
Usage:
- Automatic engine deployment on main branch pushes
- Preview deployments for pull requests
3. Vercel Deployment Tokens (Production Deployment)
Enables controlled production deployment via GitHub Actions when tags are created.
Get Tokens:
- Go to vercel.com/account/tokens
- Click Create Token
- Name:
github-actions-prod-deploy - Expiration: No expiration (or your preference)
- Copy the token
Add to GitHub:
- Name:
VERCEL_TOKEN - Secret: [paste your Vercel token]
Also add:
-
Name:
VERCEL_ORG_ID -
Secret: [Find in Vercel Settings → Account → ID]
-
Name:
VERCEL_PROJECT_ID -
Secret: [Find in Vercel Project Settings → Project ID]
Usage:
- Automatic production deployment when tag
v*.*.*is pushed - Example: Create tag
git tag v1.0.0 && git push origin v1.0.0
4. OpenAI API Key (Optional)
Optional: Enables additional AI-powered code review features.
Get API Key:
- Go to platform.openai.com/api-keys
- Sign up or log in
- Click Create new secret key
- Name:
github-actions-pr-review - Copy the key (starts with
sk-)
Add to GitHub:
- Name:
OPENAI_API_KEY - Secret:
sk-...
Usage:
- Enhanced PR review with Codex analysis
- Code quality suggestions
- Security vulnerability detection
Verify Configuration
After adding secrets:
- Go to Actions tab in your repository
- Secrets should be available to workflows
- Test by creating a pull request or tag
- Check Actions logs for successful API connections
Step 10: Add Environment Variables
Navigate to Vercel
- Go to Vercel dashboard → Your project
- Click Settings → Environment Variables
Add All Variables
For each variable, click Add New and:
- Enter Key and Value
- Select appropriate environment(s)
- Click Save
Environment Variable Reference
Three-tier deployment with different credentials:
- Preview: Auto-deploys on pull requests using dynamic
$VERCEL_URL. Uses staging database/credentials (webhooks can't be dynamic per PR). - Staging: Auto-deploys main branch to fixed domain. Inherits database & most credentials from Preview.
- Production: Manual tag-triggered deployments (
git tag v*.*.*). Separate database, live credentials, and production webhook secrets.
Variables that differ per environment:
| Variable | Preview | Staging | Production |
|---|---|---|---|
NEXT_PUBLIC_APP_URL | https://$VERCEL_URL | https://your-staging-domain.vercel.app | https://yourdomain.com |
STRIPE_SUCCESS_URL | Staging domain | Staging domain | Prod domain |
STRIPE_CANCEL_URL | Staging domain | Staging domain | Prod domain |
STRIPE_WEBHOOK_SECRET | we_... (staging) | we_... (staging) | whsec_... (prod) |
STRIPE_SECRET_KEY | sk_test_... | sk_test_... | sk_live_... |
STRIPE_PUBLISHABLE_KEY | pk_test_... | pk_test_... | pk_live_... |
CLERK_SECRET_KEY | sk_test_... | sk_test_... | sk_live_... |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | pk_test_... | pk_test_... | pk_live_... |
CLERK_WEBHOOK_SECRET | Dev webhook | Dev webhook | Prod webhook |
NODE_ENV | (not set) | (not set) | production |
CRON_SECRET | (not set) | (not set) | Random token |
POSTGRES_URL | Staging DB | Staging DB | Prod DB |
BLOB_READ_WRITE_TOKEN | Staging blob | Staging blob | Prod blob |
Shared across all environments (identical):
RESEND_API_KEY,RESEND_FROM_EMAIL,RESEND_FROM_NAME(one API key, same email)NEXT_PUBLIC_SENTRY_DSN(one project, environment-tagged)ENGINE_BASE_URL(same microservice)- All
NEXT_PUBLIC_CLERK_SIGN_*URLs (/sign-in,/sign-up,/onboarding) STRIPE_PRO_PRICE_ID,STRIPE_BUSINESS_PRICE_ID(same prices in test/live mode)
Key Facts:
- ✅ Preview & Staging use identical credentials (except
NEXT_PUBLIC_APP_URL) - ✅ Only Production has live credentials for Stripe/Clerk
- ✅ Database and blob storage auto-configured by Vercel per environment
Redeploy
Trigger new staging deployment:
git commit --allow-empty -m "Configure environment variables"
git push origin main
Trigger new production deployment:
git tag v1.0.0
git push origin v1.0.0
Or in Vercel: Deployments → ⋯ → Redeploy (production only).
Verify Deployment
Staging:
- ✅ Deployment status: Ready
- Visit:
https://your-staging-domain.vercel.app - Test sign-in/sign-up
- Verify no errors in console
Production:
- ✅ Deployment status: Ready
- Visit:
https://yourdomain.com - Test sign-in/sign-up with real payment test cards
- Verify no errors in Sentry
🎉 Your staging and production environments are now live!
Deployment Workflow
Staging Deployment
Push to main for automatic staging deployment:
git commit -m "Feature: add new feature"
git push origin main
# → Automatically deploys to staging environment
Production Deployment
Create a git tag to trigger production deployment via GitHub Actions:
git tag v1.0.0
git push origin v1.0.0
# → GitHub Actions automatically deploys to production
The workflow will:
- Update version files (package.json, pyproject.toml, .version)
- Build and push Docker images
- Create GitHub Release with release notes
- Deploy to Vercel production
Check Actions tab to verify deployment succeeded.