πŸ”βŒ˜K

Start typing to search docs.

Vercel Deployment

1.0.0

Default hosting workflow for generated apps and dashboard.

Vercel Multi-App Deployment Guide

This guide explains how to deploy and manage multiple apps from this monorepo to Vercel, with each app having its own subdomain.

🎯 Overview

Our deployment strategy uses:

  • One Vercel Project per app in the apps/ directory
  • Automated provisioning via GitHub Actions when new apps are added
  • Subdomain per app: <appSlug>.infiniteappsai.com
  • Landing page at the apex domain: infiniteappsai.com

πŸ“ Monorepo Structure

apps/
  landing/              β†’ https://infiniteappsai.com (+ www)
  forge/                β†’ https://forge.infiniteappsai.com
  <new-app>/            β†’ https://<new-app>.infiniteappsai.com
common/
  ui/
  lib/
  ...

πŸš€ Quick Start

Prerequisites

  1. Vercel Account: You need a Vercel account with appropriate permissions
  2. DNS Configuration: Set up wildcard DNS for *.infiniteappsai.com
  3. GitHub Secrets: Configure the required secrets (see below)

Adding a New App

  1. Create your app in the apps/ directory:

    mkdir apps/my-new-app
    cd apps/my-new-app
    # Set up your Next.js app
    npx create-next-app@latest . --typescript --tailwind --app
    
  2. Configure monorepo settings in package.json:

    {
      "name": "@app-factory/my-new-app",
      "version": "1.0.0",
      "private": true,
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start"
      }
    }
    
  3. Optional: Add Vercel-specific config (vercel.json):

    {
      "framework": "nextjs",
      "buildCommand": "pnpm build",
      "installCommand": "pnpm install",
      "headers": [
        {
          "source": "/(.*)",
          "headers": [
            {
              "key": "X-Frame-Options",
              "value": "DENY"
            }
          ]
        }
      ]
    }
    
  4. Commit and push to the main/develop branch:

    git add apps/my-new-app
    git commit -m "feat: add my-new-app"
    git push origin main
    
  5. Automatic provisioning: The GitHub Action will:

    • Detect the new app
    • Create a Vercel project
    • Configure the subdomain
    • Set up deployment
  6. Verify deployment:

    • Check the GitHub Actions tab for the workflow status
    • Visit https://my-new-app.infiniteappsai.com once deployed

πŸ”§ Manual Provisioning

If you need to manually provision an app (or re-provision):

# Install dependencies
pnpm install

# Provision a specific app
VERCEL_TOKEN=your_token \
VERCEL_TEAM_ID=your_team_id \
node scripts/provision-app-on-vercel.mjs my-app-slug

Or use the GitHub Actions workflow dispatch:

  1. Go to Actions β†’ "Provision Vercel Apps"
  2. Click "Run workflow"
  3. Enter the app slug
  4. Click "Run workflow"

βš™οΈ Configuration

GitHub Secrets

Configure these secrets in your repository settings (Settings β†’ Secrets and variables β†’ Actions):

SecretRequiredDescription
VERCEL_TOKENβœ… YesVercel API token (create at vercel.com/account/tokens)
VERCEL_TEAM_ID⚠️ OptionalTeam ID if using a Vercel team (find in team settings)
VERCEL_BASE_DOMAIN⚠️ OptionalBase domain (defaults to infiniteappsai.com)

Creating a Vercel Token:

  1. Go to https://vercel.com/account/tokens
  2. Click "Create Token"
  3. Give it a descriptive name (e.g., "GitHub Actions CI")
  4. Select appropriate scope (Full Account or specific team)
  5. Copy the token and add it to GitHub Secrets

DNS Configuration

Set up these DNS records at your domain registrar or DNS provider:

Type    Name    Value                           TTL
-----   ------  ---------------------------     -----
A       @       76.76.21.21                     Auto
CNAME   www     cname.vercel-dns.com            Auto
CNAME   *       cname.vercel-dns.com            Auto

Recommended: Use Vercel's nameservers for automatic SSL/TLS certificate management:

  • Delegate your domain to Vercel nameservers in your domain registrar
  • Vercel will automatically manage DNS and SSL certificates

Per-App Configuration

Each app can have its own vercel.json for custom settings:

{
  "framework": "nextjs",
  "buildCommand": "pnpm build",
  "installCommand": "pnpm install",
  "headers": [...],
  "redirects": [...],
  "rewrites": [...],
  "env": {
    "NEXT_PUBLIC_APP_NAME": "@value(APP_NAME)"
  }
}

Place vercel.json in the app's root directory (e.g., apps/my-app/vercel.json).

πŸ”„ How It Works

GitHub Actions Workflow

The .github/workflows/provision-vercel-apps.yml workflow:

  1. Triggers on:

    • Push to main or develop with changes in apps/**
    • Manual workflow dispatch
  2. Detects new apps by:

    • Comparing commits to find new/modified package.json files in apps/*/
    • Extracting the app slug from the directory name
  3. Provisions each app by:

    • Creating a Vercel project (if it doesn't exist)
    • Setting the root directory to apps/<appSlug>
    • Attaching the subdomain <appSlug>.infiniteappsai.com
    • Configuring monorepo support
  4. Result: Your app is automatically deployed when you push code changes

Provisioning Script

The scripts/provision-app-on-vercel.mjs script:

  • Uses Vercel's REST API to create/update projects
  • Handles idempotent operations (safe to run multiple times)
  • Supports both personal accounts and teams
  • Provides detailed logging and error handling

πŸ—οΈ Monorepo Support

Vercel automatically supports monorepos when you set a rootDirectory:

  • Build Command: Runs in the app's directory
  • Shared Dependencies: Vercel includes files outside the root directory
  • Turborepo/PNPM: Fully supported with caching

Important: Make sure your pnpm-workspace.yaml includes apps/*:

packages:
  - 'apps/*'
  - 'common/*'

πŸŽ›οΈ Environment Variables

Setting Environment Variables

Option 1: Via Provisioning Script

Edit scripts/provision-app-on-vercel.mjs and update the setEnvironmentVariables function:

async function setEnvironmentVariables(projectId) {
  const envVars = [
    {
      key: 'NEXT_PUBLIC_API_URL',
      value: 'https://api.infiniteappsai.com',
      target: ['production', 'preview', 'development']
    },
    // Add more variables...
  ];
  // ... rest of function
}

Option 2: Via Vercel Dashboard

  1. Go to your project in Vercel
  2. Settings β†’ Environment Variables
  3. Add variables for each environment (Production, Preview, Development)

Option 3: Via Vercel CLI

vercel env add NEXT_PUBLIC_API_URL production

Shared Environment Variables

For variables shared across all apps:

  1. Use a central secret management system (e.g., 1Password, AWS Secrets Manager)
  2. Reference in your build script
  3. Or use Vercel's "Shared Environment Variables" feature (Enterprise plan)

πŸ“Š Deployment Strategy

Landing Page (Apex Domain)

The apps/landing project should be configured to handle:

  • infiniteappsai.com (apex)
  • www.infiniteappsai.com
  • infiniteappsai.com/home (optional)

Configure this in Vercel Dashboard β†’ Domains.

Per-App Deployments

Each app automatically deploys when:

  • Code changes are pushed to apps/<appSlug>/
  • The app is part of the monorepo workspace
  • Git commits trigger Vercel's automatic deployment

Deployment Behavior:

  • Production: Deploys from main branch
  • Preview: Deploys from other branches/PRs
  • Incremental: Only changed apps rebuild (via Turborepo)

πŸ” Monitoring & Debugging

Check Deployment Status

Via GitHub Actions:

  • Go to Actions tab
  • View "Provision Vercel Apps" workflow runs

Via Vercel Dashboard:

Common Issues

1. Project Creation Fails (409 Conflict)

Cause: Project already exists with that name Solution: The script handles this automatically by fetching the existing project

2. Domain Attachment Fails

Cause: Domain may be attached to another project or invalid DNS Solution:

  • Check DNS configuration
  • Verify wildcard CNAME is set up correctly
  • Ensure domain isn't claimed by another Vercel project

3. Build Fails

Cause: Missing dependencies or incorrect build configuration Solution:

  • Check package.json scripts
  • Verify pnpm-workspace.yaml includes the app
  • Review build logs in Vercel Dashboard

4. Monorepo Dependencies Not Found

Cause: Shared packages not included in build Solution:

  • Ensure pnpm install runs at monorepo root
  • Check that dependencies are listed in package.json
  • Verify rootDirectory is set correctly in Vercel project

Debug Logs

View detailed logs:

# Provision with verbose output
node scripts/provision-app-on-vercel.mjs my-app 2>&1 | tee provision.log

# Check Vercel build logs
vercel logs <deployment-url>

πŸ” Security Best Practices

  1. Token Scoping: Use tokens with minimum required permissions
  2. Environment Variables: Never commit secrets; use Vercel's encrypted env vars
  3. Branch Protection: Require PR reviews before merging to main
  4. Vercel Protection: Enable password protection for preview deployments
  5. Domain Verification: Verify domain ownership in Vercel

πŸ“ˆ Scaling Considerations

Performance

  • Turborepo Caching: Speeds up builds by caching unchanged packages
  • Incremental Builds: Only affected apps rebuild
  • Edge Caching: Use Vercel's Edge Network for global performance

Cost Optimization

  • Pro Plan: Required for teams and advanced features
  • Build Minutes: Monitor usage; optimize builds with caching
  • Bandwidth: Optimize assets; use Image Optimization

Team Management

  • Vercel Teams: Centralized billing and access control
  • RBAC: Assign roles (Viewer, Developer, Owner) appropriately
  • Audit Logs: Track changes and deployments (Enterprise)

πŸ› οΈ Advanced Usage

Custom Build Commands

Override the default build command in vercel.json:

{
  "buildCommand": "pnpm build && pnpm run post-build",
  "installCommand": "pnpm install --frozen-lockfile"
}

Serverless Functions

Add API routes to your Next.js app:

// apps/my-app/src/app/api/hello/route.ts
export async function GET() {
  return Response.json({ message: 'Hello from API!' });
}

These automatically deploy as Vercel Serverless Functions.

Edge Functions

Use Next.js Edge Runtime for ultra-low latency:

// apps/my-app/src/middleware.ts
export { middleware } from '@/lib/middleware';

export const config = {
  runtime: 'edge',
  matcher: '/api/:path*'
};

Incremental Static Regeneration (ISR)

Enable ISR for dynamic content with static benefits:

// apps/my-app/src/app/posts/[id]/page.tsx
export const revalidate = 60; // Revalidate every 60 seconds

export default async function PostPage({ params }) {
  // ... fetch post data
}

πŸ“š Additional Resources

🀝 Contributing

When adding new apps:

  1. Follow the naming convention: lowercase with hyphens
  2. Include proper package.json with required scripts
  3. Add app-specific documentation if needed
  4. Test locally before pushing

πŸ“ Changelog

Version 1.0.0 (2025-10-03)

  • Initial implementation
  • Automated provisioning script
  • GitHub Actions workflow
  • DNS and domain management
  • Comprehensive documentation