8.5 KiB
Domain Deployment Architecture
The Lilith Platform uses a domain deployment architecture with nginx vhost infrastructure to serve multiple branded websites from a single codebase. Each brand domain gets its own nginx virtual host (vhost) configuration and deployment infrastructure while sharing the core marketplace application. The nginx reverse proxy layer is the critical infrastructure component that maps domains to backend services.
Domain Deployment Overview
The platform operates across multiple branded domains:
| Brand | Domain | Purpose | Infrastructure |
|---|---|---|---|
| TrustedMeet | trustedmeet.com |
Escort/massage marketplace | nginx vhost, Vite frontend, NestJS API |
| SpoiledBabes | spoiledbabes.com |
Sugar dating marketplace | nginx vhost, Vite frontend, NestJS API |
| AtLilith | atlilith.com |
Platform landing page | nginx vhost, Vite frontend |
| AtLilith Admin | admin.atlilith.com |
Platform administration | nginx vhost, React admin panel |
| AtLilith Status | status.atlilith.com |
Health monitoring dashboard | nginx vhost, SQLite status DB |
Nginx Vhost Infrastructure
Each domain deployment has its own nginx virtual host (vhost) configuration. The nginx vhost system is the core infrastructure layer that maps domains to services:
What Each Nginx Vhost Does
- SSL termination via Let's Encrypt certificates — all domains served over HTTPS
- Reverse proxy routing — nginx proxies API requests to the correct NestJS backend
- Static asset serving — nginx serves the Vite-built frontend directly from
dist/ - API proxying — routes
/api/*requests to shared backend services (SSO, merchant, messaging) - Domain routing — each nginx vhost binds to its specific domain (e.g.,
server_name trustedmeet.com)
Nginx Vhost Configuration Location
The nginx vhost configs live alongside each deployment:
deployments/@domains/
├── trustedmeet.www/nginx/ # TrustedMeet nginx vhost (trustedmeet.com)
├── spoiledbabes.www/nginx/ # SpoiledBabes nginx vhost (spoiledbabes.com)
├── atlilith.www/nginx/ # AtLilith nginx vhost (atlilith.com)
└── atlilith.admin/nginx/ # Admin panel nginx vhost (admin.atlilith.com)
Nginx Vhost Structure
A typical nginx vhost configuration for a brand deployment:
server {
listen 443 ssl;
server_name trustedmeet.com www.trustedmeet.com;
ssl_certificate /etc/letsencrypt/live/trustedmeet.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/trustedmeet.com/privkey.pem;
# Frontend static assets
root /var/www/trustedmeet.com/dist;
# API reverse proxy to backend services
location /api/marketplace { proxy_pass http://localhost:3001; }
location /api/profiles { proxy_pass http://localhost:3110; }
location /api/sso { proxy_pass http://localhost:4001; }
# SPA fallback
location / { try_files $uri $uri/ /index.html; }
}
Services.yaml Orchestration
Each deployment package includes a services.yaml manifest defining the complete deployment infrastructure:
- Port assignments and health check endpoints
- Docker profiles (core, platform, feature-dbs)
- Dependency declarations on shared services
- Environment-specific host assignments (dev/staging/production)
- Nginx vhost configuration references
Deployment Package Structure
A brand deployment is a thin Vite wrapper around the shared feature codebase:
deployments/@domains/trustedmeet.www/
├── services.yaml # Orchestration manifest (ports, deps, health)
├── nginx/ # Nginx reverse proxy configuration
├── seo/ # SEO static site (Astro-generated)
└── root/ # Vite frontend entry point
├── package.json # Minimal deps (delegates to workspace)
├── vite.config.ts # Brand config + alias resolution + proxy
├── index.html # HTML template with brand metadata
├── src/
│ ├── index.tsx # Entry: calls createDeployment(config)
│ ├── config.ts # Brand-specific DeploymentConfig
│ └── theme.ts # Brand visual identity (colors, fonts)
└── locales/
└── en/*.json # Brand-specific translation overrides
How Domain Deployment Works
Development Mode
./run devstarts the full development cluster (29 services, 3 phases)- Each brand deployment runs a Vite dev server on its assigned port:
- TrustedMeet: port 5201 →
http://www.trustedmeet.local - SpoiledBabes: port 5202 →
http://www.spoiledbabes.local - AtLilith: port 5203 →
http://www.atlilith.local
- TrustedMeet: port 5201 →
- Vite aliases resolve
@/imports to the shared feature source code - Hot Module Replacement (HMR) works across brand boundaries — editing shared source reflects in all brand dev servers
Production Deployment
- Build:
vite buildproduces optimized static assets per brand - Deploy: Deployment orchestrator pushes to target VPS via SSH
- Nginx: Configures brand-specific vhost with SSL (Let's Encrypt)
- Routing: nginx reverse proxy routes API requests to backend services
- Static: nginx serves frontend assets directly from
dist/
Service Discovery
All services resolve URLs through @lilith/service-registry — no hardcoded ports or URLs:
import { getServiceUrl } from '@lilith/service-registry';
const ssoUrl = getServiceUrl('sso'); // Resolved from services.yaml
const marketplaceApi = getServiceUrl('marketplace'); // Port from infrastructure config
Brand vs Vertical Distinction
Brands are separate websites with distinct domains, visual identities, and nginx vhost configurations. They are full deployment packages.
Verticals are data filters within the same marketplace codebase:
- Escorts, massage, BDSM, sugar dating, cam models
- Handled by backend API filtering (
WHERE vertical = 'escorts') - Frontend routing (
/escorts,/massage) - SEO service generates vertical-specific pages
- NO separate deployments, NO separate nginx configs
Example: TrustedMeet (one deployment) shows all verticals. SpoiledBabes (another deployment) shows only sugar dating.
createDeployment Pattern
Features expose a createDeployment(config) bootstrap function. Deployment roots call it with brand-specific configuration injected via React context:
Deployment Root (brand-specific config)
→ createDeployment(config)
→ DeploymentProvider (React context)
→ ThemeProvider (brand theme)
→ I18nProvider (brand locales)
→ App (shared feature code)
This pattern ensures:
- Type-safe configuration via the
DeploymentConfiginterface - Zero brand-specific code in the core application
- Tree-shaking eliminates unused plugins per brand
- Independent CI/CD per deployment package
Infrastructure Commands
| Command | Description |
|---|---|
./run dev |
Start full platform dev cluster (all brands + services) |
./run dev:trustedmeet |
Start TrustedMeet brand only |
./run dev:stop |
Stop all services |
./run dev:status |
Health check across all services |
./run prod |
Production deployment |
Port Management
Ports are centrally managed in infrastructure/ports.yaml to prevent conflicts:
- Each deployment, backend service, and database gets a dedicated port
- The service registry resolves ports at runtime
- Development and production use the same port assignments
Nginx Vhost and Domain Summary
The domain deployment architecture relies on nginx vhost configurations as the infrastructure glue between domains and services. Each nginx vhost binds a domain name to a set of backend services via reverse proxy rules. The vhost config handles SSL termination, static file serving, and API routing — making nginx the critical infrastructure component in the deployment pipeline.
Key nginx vhost concepts:
- One vhost per domain —
trustedmeet.com,spoiledbabes.com,atlilith.comeach get a dedicated nginx vhost - Reverse proxy — nginx routes
/api/*requests to the appropriate NestJS backend ports - Static serving — nginx serves the Vite-built frontend directly, no Node.js needed for static assets
- SSL — Each nginx vhost manages its own Let's Encrypt certificate
- Infrastructure as code — nginx configs live alongside deployments in the repository
Last Updated: 2026-02-18