Guides

Private instance deployment

Deploy OpsDash for a client on their own server. The client owns the data, the infrastructure, and the subscription — you charge for integration, configuration, and ongoing support on terms you define.

Why clients pay for this model

  • Data sovereignty: CRM, projects, and financial data lives on their server — not in a vendor's cloud
  • Zero per-user fees: After the initial engagement, no recurring software license fees to a vendor
  • Integration: Configured specifically for their business — custom fields, deal stages, team structure
  • The pitch: “I will deploy a private instance of OpsDash on your own DigitalOcean/AWS. You own the data. No per-user fees. Forever.”

What you deliver

DeliverableDescription
Deployed instanceRunning OpsDash on the client's own server or cloud account
Domain + SSLTheir own subdomain (e.g. ops.theirclientname.com)
Supabase projectDedicated Supabase project under their account
ConfigurationCustom fields, deal stages, branding, module settings via opsdash.config.ts
Seed dataDemo data removed, org set up for their team
Admin setupClient's email set as Platform Admin + Org Owner
HandoffWalk client through onboarding, invite team members, set up 2FA

Option 1 — DigitalOcean / Hetzner (Docker)

Best for: clients who want the lowest ongoing hosting cost (small VPS + managed database).

# On the server
git clone <your-repo-url> /opt/opsdash
cd /opt/opsdash

# Create production env file
cp ".env copy.example" .env
# Fill in Supabase Cloud credentials, app URL, Stripe keys, etc.

# Build and start
docker-compose up -d --build

Put Nginx or Caddy in front for SSL and domain routing. Get SSL with Certbot:

certbot --nginx -d ops.clientname.com

Nginx reverse proxy:

server {
    listen 443 ssl;
    server_name ops.clientname.com;

    ssl_certificate     /etc/letsencrypt/live/ops.clientname.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ops.clientname.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Option 2 — Vercel + Supabase Cloud

Best for: clients comfortable with managed hosting.

  1. Create a Supabase project in the client's account → run all migrations → copy env vars
  2. Fork or clone the repository to the client's GitHub
  3. Import the repo into Vercel → set environment variables
  4. Set NEXT_PUBLIC_APP_URL to the Vercel deployment URL or custom domain
  5. Set up Stripe webhook endpoint pointing to the Vercel URL
  6. Configure auth redirect URLs in Supabase → Authentication → URL Configuration

Post-deployment checklist

  1. Run all migrations: supabase db push or apply via Supabase Dashboard
  2. Set PLATFORM_ADMIN_EMAILS to your email + client's email
  3. Create the client's account → verify they are Org Owner
  4. Configure opsdash.config.ts: branding, modules, feature overrides
  5. Remove demo seed data: truncate the demo tables or use the Admin panel to delete the demo org
  6. Set up cron jobs — configure your scheduler to hit the cron endpoints with CRON_SECRET
  7. Test Stripe checkout end-to-end with a test card
  8. Walk the client through onboarding — invite their team

Client handoff

What to document for the client:

  • Admin URL (/admin) and their credentials
  • How to invite team members (Settings → Team)
  • How to add custom fields (Settings → Custom Fields)
  • How to configure deal stages (Settings → Deal Stages)
  • Contact for support (you) and how you handle updates