Skip to content

magnusfroste/domain-proxy-saas

Repository files navigation

🚀 DomainProxy SaaS Starter

Separate repository - Complete example SaaS app that demonstrates DomainProxy integration.

Works with DomainProxy Cloud - Get custom domains for your SaaS without infrastructure headaches.

What This Demonstrates

  • User authentication — Simple login system
  • Multi-tenant architecture — Each user can create multiple custom domains
  • DomainProxy integration — Automatic subdomain registration via API
  • Host-based routing — Detect custom domains and render tenant-specific content

Quick Start

Use with DomainProxy Cloud (Recommended)

# 1. Get your API key from https://proxy.froste.eu/admin

# 2. Clone and configure
cd saas-demo/saas
cp .env.example .env
# Edit .env with your API key (DOMAINPROXY_API_KEY)

# 3. Install and run
npm install
npm start

# 4. Open http://localhost:3001/login

Option 2: Use with Self-Hosted DomainProxy

# 1. First, deploy DomainProxy (see main README)
# 2. Get your API key from your instance's /admin

# 3. Configure
cp .env.example .env
# Set DOMAINPROXY_URL to your instance
# Set DOMAINPROXY_API_KEY to your key

# 4. Run
npm install
npm start

Option 3: VPS Demo Mode

If you're having issues with platforms like EasyPanel or Railway (where Traefik blocks forwarded headers), deploy directly on a VPS for testing:

# 1. Deploy to VPS (see deployment guide below)

# 2. Set ENABLE_VPS_DEMO=true in .env
# This bypasses host header detection and shows a demo tenant page

# 3. Access your VPS IP/domain directly
# The app will show a demo page instead of requiring custom domains

Deployment Guide

Variable Description Default
PORT Server port 3001
DOMAINPROXY_URL DomainProxy API URL https://proxy.froste.eu
DOMAINPROXY_API_KEY Your API key -
SAAS_URL Public URL of this SaaS http://localhost:3001
DEMO_EMAIL Demo login email demo@example.com
DEMO_PASSWORD Demo login password demo123
SESSION_SECRET Session encryption key -
ENABLE_VPS_DEMO Enable VPS demo mode (bypasses host header checks) false

How It Works

1. User Creates a Custom Domain

When a user creates a domain in the dashboard, the SaaS:

  1. Calls POST /api/v1/create-tenant to register the base domain
  2. Calls POST /api/v1/register-subdomain to set up the proxy
  3. Saves the tenant info to the local database
// From server.js
await domainProxyClient.createTenant(base_domain);
await domainProxyClient.registerSubdomain(subdomain, base_domain, config.saasUrl);

2. User Sets Up DNS

The user adds a CNAME record pointing their subdomain to DomainProxy:

app.customer.com  CNAME  proxy.froste.eu

3. Visitor Accesses Custom Domain

When someone visits https://app.customer.com:

  1. DNS resolves to DomainProxy
  2. DomainProxy provisions TLS certificate (first visit)
  3. DomainProxy proxies request to your SaaS
  4. Your SaaS detects the custom domain via X-Forwarded-Host header
  5. Your SaaS renders tenant-specific content
// Host detection middleware
const host = req.headers['x-forwarded-host'] || req.headers.host;
const subdomain = host.split('.')[0];
const baseDomain = host.split('.').slice(1).join('.');

// Look up tenant and render their page
const tenant = await db.get('SELECT * FROM tenants WHERE subdomain = ? AND base_domain = ?', [subdomain, baseDomain]);

Project Structure

saas/
├── server.js        # Main application
├── .env.example     # Environment template
├── package.json     # Dependencies
├── Dockerfile       # Container config
├── data/            # SQLite database (auto-created)
└── public/          # Static files

Docker Deployment

# Build
docker build -t saas-starter .

# Run
docker run -d \
  -p 3001:3001 \
  -e DOMAINPROXY_URL=https://proxy.froste.eu \
  -e DOMAINPROXY_API_KEY=your_key \
  -e SAAS_URL=https://your-saas.com \
  -v saas_data:/app/data \
  saas-starter

Customization Ideas

This starter is intentionally simple. Here are some ways to extend it:

  • Add real authentication — Replace plain-text passwords with bcrypt
  • Add a database — Swap SQLite for PostgreSQL/MySQL
  • Add a frontend framework — React, Vue, or Svelte
  • Add more tenant customization — Logo, theme, custom CSS
  • Add billing — Stripe integration for paid plans
  • Add analytics — Track visits per tenant

API Client

The starter includes a simple DomainProxy API client:

const domainProxyClient = {
  async createTenant(baseDomain) { ... },
  async registerSubdomain(subdomain, baseDomain, targetUrl) { ... },
  async deleteProxy(subdomain, baseDomain) { ... },
  async verifyDomain(domain) { ... }
};

Copy this pattern into your own application!

License

MIT — use this however you want.


Need help? Check out the main DomainProxy documentation.

About

The **DomainProxy SaaS Starter Kit** offers a complete blueprint for building SaaS applications with effortless domain management. It leverages DomainProxy integration to allow users to manage custom domains without dealing with complex infrastructure. The app includes a user authentication system and supports multi-tenant architecture, offering...

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors