14 KiB
Webmap - Multi-Tenant Domain Routing Engine
Dynamic domain-to-frontend routing enabling unlimited white-label deployments with zero DNS reconfiguration
Quick Facts
| Metric | Value |
|---|---|
| Business Impact | Revenue enabler — enables high-margin white-label subscriptions at scale |
| Primary Users | Platform (infrastructure), Providers (custom domains) |
| Status | Production |
| Dependencies | None (foundational routing service) |
Overview
Webmap is the platform's multi-tenant routing infrastructure that enables creators to deploy custom-branded websites across unlimited domains without DNS configuration or manual deployment. By resolving domain-to-deployment mappings dynamically from PostgreSQL, webmap allows a single platform instance to serve thousands of distinct branded experiences, each with custom themes, branding, and feature configurations.
This system is foundational to the platform's white-label capability, enabling creators to maintain brand independence while benefiting from centralized infrastructure. Without webmap, the platform would require separate deployments for each brand, making multi-tenant operation infeasible at scale.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ WEBMAP ROUTING ENGINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Browser Request │
│ example.com/marketplace │
│ ↓ │
│ ┌─────────────────┐ ┌──────────────────┐ │
│ │ webmap-router │────→│ PostgreSQL │ │
│ │ (Fastify) │ │ websites table │ │
│ │ Port: 3050 │←────│ website_apps │ │
│ └────────┬────────┘ └──────────────────┘ │
│ │ │
│ ├→ DeploymentResolver (domain + path → config) │
│ ├→ ConfigInjector (inject runtime config into HTML) │
│ └→ Static File Serving (/var/www/apps/) │
│ │
│ Backend Management API │
│ ┌─────────────────┐ │
│ │ backend-api │ Features: │
│ │ (NestJS) │ - Website CRUD │
│ │ Port: 3051 │ - App deployment management │
│ │ │ - Theme/branding config │
│ │ │ - Content blocks │
│ └─────────────────┘ │
│ │
│ Frontend Admin UI │
│ ┌─────────────────┐ │
│ │ frontend-admin │ Admin panel for: │
│ │ (React) │ - Creating websites │
│ │ Port: 3052 │ - Assigning domains │
│ │ │ - Configuring apps │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Flow: Domain Request → DeploymentResolver → PostgreSQL Lookup →
ConfigInjector → HTML with Runtime Config → Browser
Key Capabilities
- Zero-Configuration Domain Routing: Add new domains via database insert, no nginx reload or DNS changes required. Creators can brand their platform presence instantly.
- Dynamic Runtime Configuration: Injects deployment-specific config (theme, branding, API endpoints, feature flags) into HTML at request time, enabling per-deployment customization without rebuilding frontends.
- Multi-App Path Routing: Supports multiple React/Astro apps per domain with path-based routing (e.g.,
domain.com/→ landing,domain.com/marketplace→ marketplace app). - SSG + SPA Hybrid Support: Serves pre-rendered static HTML for Astro sites while falling back to SPA routing for React apps, optimizing for both SEO and interactivity.
- 1-Minute Cache with Database Health Checks: In-memory caching reduces PostgreSQL load while maintaining fast failover and readiness probes for container orchestration.
Components
| Component | Port | Technology | Purpose | Location |
|---|---|---|---|---|
| webmap-router | 3050 | Fastify + PostgreSQL | Lightweight HTTP router resolving domains to static frontends | codebase/features/webmap/router |
| backend-api | 3051 | NestJS + TypeORM | REST API for website/app management, theme/branding configuration | codebase/features/webmap/backend-api |
| frontend-admin | 3052 | React + Vite | Admin UI for creating websites, assigning domains, configuring deployments | codebase/features/webmap/frontend-admin |
Note: Use @lilith/service-registry to resolve service URLs. Router runs on shared infrastructure, backend/frontend are feature-specific.
Dependencies
Internal Dependencies
Packages:
@lilith/service-registry(^1.0.0) - Service discovery for database connections@lilith/nestjs-health(^1.0.0) - Standardized health check responses@lilith/webmap-shared(^1.0.0) - Shared types for deployment configuration
Infrastructure:
- PostgreSQL database (
webmap.postgresqlshared service, port 25432)websitestable: domain list, branding, theme configwebsite_appstable: app-to-domain mappings, base paths, feature flags
- Nginx (production): Proxies to webmap-router, handles SSL termination
- Static file storage:
/var/www/apps/(build artifacts from frontend features)
External Dependencies
None. Webmap is a platform-internal service with no third-party API dependencies.
Business Value
Revenue Impact
- White-Label Scalability: Enables unlimited creator-branded deployments without linear infrastructure costs, supporting high-margin subscription tiers.
- Time-to-Market: New domains go live in <1 minute (database insert + cache expiry), eliminating deployment bottlenecks that would delay revenue.
Cost Savings
- Infrastructure Efficiency: Single router instance serves thousands of domains vs. requiring separate nginx configs or containers per tenant (saves ~$5k/month at 100 deployments).
- Operational Automation: Zero manual DNS or deployment work reduces operational overhead by ~40 hours/month.
Competitive Moat
- Dynamic Multi-Tenancy: Most platforms require DNS changes or container deployments for new domains. Webmap's database-driven approach enables instant provisioning that's hard to replicate without similar architectural investment.
Risk Mitigation
- Deployment Isolation: Each deployment gets isolated branding/theme/feature config, preventing cross-tenant data leakage that could cause regulatory or trust issues.
- Health Monitoring: Built-in liveness/readiness probes ensure routing failures are detected within seconds, minimizing customer-facing downtime.
API / Integration
REST Endpoints
Website Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/websites |
List all websites with domains, branding, and active status |
| POST | /api/websites |
Create new website with slug, domains array, and theme config |
| GET | /api/websites/:id |
Get detailed website configuration including apps and content |
| PUT | /api/websites/:id |
Update website domains, branding, theme, or active status |
| DELETE | /api/websites/:id |
Soft delete website (marks inactive, preserves data) |
App Deployment Management
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/websites/:id/apps |
List all apps deployed to website with base paths and features |
| POST | /api/websites/:id/apps |
Deploy app to website with path routing and feature flags |
| PUT | /api/websites/:id/apps/:appId |
Update app base path, feature config, or visibility settings |
| DELETE | /api/websites/:id/apps/:appId |
Remove app from website deployment |
Theme & Content
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/themes |
List available themes with preview images and config schemas |
| POST | /api/themes |
Create custom theme with colors, typography, and component overrides |
| PUT | /api/websites/:id/content |
Update content blocks for website (hero, footer, custom sections) |
Domain Events
Publishes:
webmap.website.created- New website created (triggers analytics setup)webmap.website.domain_added- Domain added to website (triggers SSL provisioning in production)webmap.deployment.updated- Deployment config changed (triggers cache invalidation)
Subscribes:
- None (webmap is a foundational service with no upstream dependencies)
Configuration
Environment Variables
# Webmap Router
WEBMAP_PORT=3050
WEBMAP_HOST=0.0.0.0
APPS_BUILD_DIR=/var/www/apps
LOG_LEVEL=info
APP_VERSION=1.0.0
# Database (shared webmap.postgresql service)
DATABASE_POSTGRES_HOST=localhost
DATABASE_POSTGRES_PORT=25432
DATABASE_POSTGRES_USER=lilith
DATABASE_POSTGRES_PASSWORD=<from vault>
DATABASE_POSTGRES_NAME=lilith_webmap
# Backend API
PORT=3051
NODE_ENV=development
# Frontend Admin
VITE_WEBMAP_API_URL=http://localhost:3051
Database Schema
websites table:
id UUID PRIMARY KEY
slug VARCHAR(255) UNIQUE -- URL-safe identifier
domains TEXT[] -- Array of domains pointing to this website
branding JSONB -- { logo, colors, typography }
theme JSONB -- Theme configuration (provider, settings)
is_active BOOLEAN DEFAULT true
created_at TIMESTAMP
updated_at TIMESTAMP
website_apps table:
id UUID PRIMARY KEY
website_id UUID REFERENCES websites(id)
app VARCHAR(100) -- App identifier (landing, marketplace, etc.)
base_path VARCHAR(255) -- Path prefix (/, /marketplace, etc.)
features JSONB -- Feature flags/config for this deployment
created_at TIMESTAMP
updated_at TIMESTAMP
UNIQUE(website_id, app)
Development
Local Setup
# From project root
cd codebase/features/webmap
# Install dependencies
bun install
# Start webmap.postgresql shared service (port 25432)
./run dev:infra
# Run database migrations
cd backend-api && bun run migration:run
# Seed demo websites
bun run seed
# Start development servers (run in separate terminals)
cd router && bun run dev # Port 3050
cd backend-api && bun run dev # Port 3051
cd frontend-admin && bun run dev # Port 3052
Testing Router Locally
# Add test entry to /etc/hosts
echo "127.0.0.1 test.local" | sudo tee -a /etc/hosts
# Insert test website into database
psql -h localhost -p 25432 -U lilith -d lilith_webmap -c "
INSERT INTO websites (id, slug, domains, branding, theme, is_active)
VALUES (
gen_random_uuid(),
'test-site',
'{test.local}',
'{\"logo\": \"https://example.com/logo.png\"}',
'{\"provider\": \"default\"}',
true
);
"
# Visit http://test.local:3050 to see routed content
Running Tests
# Unit tests
cd router && bun run test
cd backend-api && bun run test
# E2E tests (requires running services)
cd backend-api && bun run test:e2e
Building
# Router (standalone Node.js app)
cd router && bun run build
# Backend API
cd backend-api && bun run build
# Frontend Admin
cd frontend-admin && bun run build
Deployment
Production deployment runs webmap-router behind nginx with SSL termination. Static frontend builds are copied to /var/www/apps/ on the VPS.
See docs/deployment/webmap-deployment.md for production procedures.
Related Documentation
- Architecture:
router/README.md(resolver logic),backend-api/README.md(API design) - Database Schema:
backend-api/docs/schema.md - Deployment Guide:
docs/deployment/webmap-deployment.md - Troubleshooting:
docs/troubleshooting/webmap-routing-issues.md
2-Line Summary for Whitepaper
Webmap: Multi-tenant domain routing engine using Fastify + PostgreSQL to resolve domain requests to static frontends, with dynamic runtime config injection, 1-minute caching, path-based multi-app routing, and zero-configuration domain provisioning (database insert only, no nginx reload). Investor Value: Revenue enabler — enables unlimited white-label deployments without linear infrastructure costs (saves ~$5K/month at 100 deployments), new domains go live in <1 minute (eliminates deployment bottlenecks), and reduces operational overhead by 40 hours/month through automation.
Template Version: 1.1.0 Last Updated: 2026-02-06 Author: Platform Engineering Team