platform-deployments/nginx/README.localhost.md
Quinn Ftw 7a1994ee5e chore(infra): 🔧 Update deployment documentation and local Nginx setup instructions
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-13 04:49:03 -08:00

595 lines
16 KiB
Markdown

# Local Development Setup - 7-Domain Architecture
Complete guide for testing the multi-domain SEO architecture locally using `.localhost` domains.
---
## Quick Start (TL;DR)
```bash
# 1. Start infrastructure (postgres, redis, etc.)
docker-compose -f deployments/docker/docker-compose.yml up -d
# 2. Start platform application
pnpm dev # Starts on :3100
# 3. Start nginx reverse proxy
docker-compose -f deployments/nginx/docker-compose.localhost.yml up -d
# 4. Access domains
open http://lilith.localhost
open http://store.lilith.localhost
open http://trustedmeet.localhost
```
---
## Architecture Overview
### 8 Local Domains
| Domain | Purpose | Backend Port |
|--------|---------|--------------|
| `http://lilith.localhost` | Primary brand | :3100 (platform-user) |
| `http://getlilith.localhost` | Acquisition funnel | :3100 (platform-user) |
| `http://store.lilith.localhost` | E-commerce | :3200 (storefront) |
| `http://apps.lilith.localhost` | Product suite | :3100 (platform-user) |
| `http://fan.lilith.localhost` | Creator platform | :3100 (platform-user) |
| `http://toys.lilith.localhost` | Physical products | :3200 (storefront) |
| `http://trustedmeet.localhost` | Marketplace/SEO | :3800 (seo) |
| `http://nasty.localhost` | Infrastructure/ML | :4000 (ml-services) |
### Service Ports
**Frontend Services** (running on host):
- `3100` - Platform orchestrator (serves all apps via Vite)
- `3200` - Storefront app (if running standalone)
- `3800` - SEO app (programmatic pages)
- `4000` - ML services (image generation)
**Backend Services** (Docker):
- `3001` - API service (NestJS)
- `3002` - Drive service (file uploads)
- `5432` - PostgreSQL
- `6379` - Redis
- `7700` - Meilisearch
- `9000/9001` - MinIO (S3-compatible storage)
- `8000` - MediaML (watermarking)
---
## Installation
### Prerequisites
- Docker & Docker Compose
- Node.js 18+ and pnpm 8+
- Modern browser (Chrome, Firefox, Safari)
### Step 1: Verify .localhost Resolution
Test if `.localhost` domains resolve automatically:
```bash
ping -c 1 lilith.localhost
```
**Expected**: Resolves to `127.0.0.1`
**If it doesn't work** (rare), add to `/etc/hosts`:
```bash
echo "127.0.0.1 lilith.localhost getlilith.localhost store.lilith.localhost apps.lilith.localhost fan.lilith.localhost toys.lilith.localhost trustedmeet.localhost nasty.localhost" | sudo tee -a /etc/hosts
```
### Step 2: Start Infrastructure Services
Start database, cache, and supporting services:
```bash
cd /path/to/lilith-platform
docker-compose -f deployments/docker/docker-compose.yml up -d
```
**Verify services are healthy**:
```bash
docker-compose -f deployments/docker/docker-compose.yml ps
```
All services should show `healthy` status.
### Step 3: Start Platform Application
Start the main application (Vite development server):
```bash
pnpm dev
```
**Expected output**:
```
@lilith/lilith-platform:dev: VITE v5.x.x ready in XXX ms
@lilith/lilith-platform:dev:
@lilith/lilith-platform:dev: ➜ Local: http://localhost:3100/
@lilith/lilith-platform:dev: ➜ Network: use --host to expose
```
**Verify platform is running**:
```bash
curl http://localhost:3100/health
# Should return: "healthy"
```
### Step 4: Start Nginx Reverse Proxy
Start nginx to route .localhost domains to backend services:
```bash
docker-compose -f deployments/nginx/docker-compose.localhost.yml up -d
```
**Verify nginx is healthy**:
```bash
docker ps | grep lilith-dev-nginx
docker logs lilith-dev-nginx
```
**Test nginx configuration**:
```bash
docker exec lilith-dev-nginx nginx -t
# Should output: "configuration file ... syntax is ok"
```
### Step 5: Enable Localhost Mode (Optional)
For SEO canonical URLs to use `.localhost` domains:
```bash
# Add to .env or set in terminal:
export USE_LOCALHOST_DOMAINS=true
# Restart platform application
pnpm dev
```
This makes SEO utilities generate `http://lilith.localhost` URLs instead of `https://lilith.io`.
---
## Usage
### Accessing Domains
**Primary Brand**:
```bash
open http://lilith.localhost
```
**E-commerce Storefront**:
```bash
open http://store.lilith.localhost
```
**Marketplace/SEO Pages**:
```bash
open http://trustedmeet.localhost
open http://trustedmeet.localhost/escorts/san-francisco
```
**API Endpoints** (all domains):
```bash
curl http://lilith.localhost/api/health
curl http://store.lilith.localhost/api/products
```
### Testing Multi-Domain Routing
**Verify domain-specific routing**:
```bash
# Primary brand should serve platform-user
curl -I http://lilith.localhost
# Store should serve storefront (or platform-user if storefront not running)
curl -I http://store.lilith.localhost
# TrustedMeet should serve SEO app
curl -I http://trustedmeet.localhost
```
**Check which backend handled the request**:
```bash
curl -v http://lilith.localhost 2>&1 | grep "X-Powered-By"
```
### Viewing Logs
**Nginx access/error logs**:
```bash
# Real-time access log
docker logs -f lilith-dev-nginx
# Check log files
tail -f deployments/nginx/logs/access.log
tail -f deployments/nginx/logs/error.log
```
**Platform application logs**:
```bash
# pnpm dev output shows all logs
# Or check specific service:
docker logs -f lilith-dev-postgres
docker logs -f lilith-dev-redis
```
---
## Configuration
### Nginx Configuration Files
```
deployments/nginx/
├── docker-compose.localhost.yml # Docker compose for nginx
├── nginx.localhost.conf # Main nginx config (simplified)
├── conf.d/
│ ├── 0-rate-limiting.localhost.conf # Relaxed rate limits
│ ├── 1-upstreams.localhost.conf # Backend service definitions
│ └── 7-domain-routing.localhost.conf # Domain routing rules
└── snippets/
└── proxy-params.conf # Proxy settings
```
### Modifying Nginx Configuration
**After making changes to nginx config**:
```bash
# Test configuration
docker exec lilith-dev-nginx nginx -t
# Reload nginx (zero downtime)
docker exec lilith-dev-nginx nginx -s reload
# Or restart container (if major changes)
docker-compose -f deployments/nginx/docker-compose.localhost.yml restart
```
### Rate Limiting
Localhost configs use **relaxed rate limits** (5-10x production):
- API: 100 req/s (vs 10 req/s production)
- Auth: 50 req/min (vs 5 req/min production)
- General pages: 50 req/s (vs 10 req/s production)
**To disable rate limiting** (for testing):
Edit `conf.d/7-domain-routing.localhost.conf` and comment out `limit_req` directives.
---
## Troubleshooting
### Issue: Domain doesn't resolve
**Symptom**: `curl: (6) Could not resolve host: lilith.localhost`
**Solutions**:
1. Verify systemd-resolved (Linux):
```bash
resolvectl status | grep ".localhost"
```
2. Add to `/etc/hosts`:
```bash
echo "127.0.0.1 lilith.localhost" | sudo tee -a /etc/hosts
```
3. Test with direct IP:
```bash
curl -H "Host: lilith.localhost" http://127.0.0.1
```
### Issue: 502 Bad Gateway
**Symptom**: Nginx returns 502 error
**Cause**: Backend service not running or unreachable
**Solutions**:
1. Verify platform is running:
```bash
curl http://localhost:3100/health
```
2. Check nginx can reach host services:
```bash
docker exec lilith-dev-nginx ping -c 1 host.docker.internal
docker exec lilith-dev-nginx wget -O- http://host.docker.internal:3100/health
```
3. Check nginx logs:
```bash
docker logs lilith-dev-nginx | grep "upstream"
```
### Issue: Port already in use
**Symptom**: `Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use`
**Cause**: Another service is using port 80
**Solutions**:
1. Find what's using port 80:
```bash
sudo lsof -i :80
# or
sudo netstat -tlnp | grep :80
```
2. Stop the conflicting service:
```bash
sudo systemctl stop apache2 # If Apache is running
sudo systemctl stop httpd # If httpd is running
```
3. Or change nginx port in `docker-compose.localhost.yml`:
```yaml
ports:
- '8080:80' # Use 8080 instead of 80
```
Then access: `http://lilith.localhost:8080`
### Issue: Changes not reflected
**Symptom**: Modified code doesn't show in browser
**Solutions**:
1. Hard refresh browser (Ctrl+Shift+R or Cmd+Shift+R)
2. Clear browser cache
3. Restart Vite dev server:
```bash
# Ctrl+C to stop
pnpm dev
```
4. Restart nginx:
```bash
docker-compose -f deployments/nginx/docker-compose.localhost.yml restart
```
### Issue: SSL/HTTPS errors
**Note**: Localhost development uses HTTP (not HTTPS)
If you need HTTPS:
1. Generate self-signed certificates:
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout deployments/nginx/localhost.key \
-out deployments/nginx/localhost.crt \
-subj "/CN=*.localhost"
```
2. Update nginx config to use SSL (not recommended for local dev)
---
## Testing
### Manual Testing
**Test each domain**:
```bash
for domain in lilith.localhost getlilith.localhost store.lilith.localhost apps.lilith.localhost fan.lilith.localhost toys.lilith.localhost trustedmeet.localhost nasty.localhost; do
echo "Testing $domain..."
curl -I "http://$domain" | head -n 1
done
```
**Test API endpoints**:
```bash
curl http://lilith.localhost/api/health
curl http://store.lilith.localhost/api/products
curl http://trustedmeet.localhost/api/marketplace
```
### E2E Tests
Run Playwright tests against localhost domains:
```bash
# Set environment to use localhost
export USE_LOCALHOST_DOMAINS=true
# Run E2E tests
pnpm test:e2e
# Or run specific test suite
pnpm --filter @lilith/lilith-platform test:e2e deployment-configs
```
### Load Testing
Test rate limiting with Apache Bench:
```bash
# Install ab (Apache Bench)
sudo apt install apache2-utils # Ubuntu
brew install httpd # macOS
# Test API rate limit (should allow 100 req/s)
ab -n 1000 -c 10 http://lilith.localhost/api/health
# Test general page rate limit (should allow 50 req/s)
ab -n 500 -c 10 http://lilith.localhost/
```
---
## Development Workflow
### Typical Development Session
```bash
# 1. Start all services (once per day)
docker-compose -f deployments/docker/docker-compose.yml up -d
docker-compose -f deployments/nginx/docker-compose.localhost.yml up -d
# 2. Start development server (in new terminal)
pnpm dev
# 3. Open browser
open http://lilith.localhost
# 4. Make code changes
# ... edit files ...
# Vite auto-reloads browser
# 5. When done, stop services (optional)
docker-compose -f deployments/nginx/docker-compose.localhost.yml down
docker-compose -f deployments/docker/docker-compose.yml down
```
### Testing Domain-Specific Features
**Test acquisition funnel** (`getlilith.localhost`):
- Different landing page copy
- Conversion-optimized UI
- Signup flow tracking
**Test e-commerce funnel** (`store.lilith.localhost`):
- Product catalog
- Shopping cart
- Checkout flow
**Test SEO pages** (`trustedmeet.localhost`):
- Location landing pages: `/escorts/san-francisco`
- Programmatic content generation
- Canonical URLs
---
## Production Comparison
### Differences from Production
| Feature | Localhost | Production |
|---------|-----------|------------|
| **Protocol** | HTTP | HTTPS |
| **Domains** | `.localhost` | Real TLDs (.io, .com, etc.) |
| **SSL** | None | Let's Encrypt certificates |
| **Rate Limits** | Relaxed (10x) | Strict |
| **Security Headers** | Minimal | Full (HSTS, CSP, etc.) |
| **Caching** | Disabled | Enabled (proxy_cache) |
| **Load Balancing** | Single backend | Multiple backends |
### Preparing for Production
Before deploying to production:
1. **Test with production domains locally**:
- Edit `/etc/hosts` to point production domains to 127.0.0.1
- Use production nginx config
2. **Enable security features**:
- HTTPS/SSL
- Strict rate limiting
- Full security headers
3. **Load testing**:
- Simulate production traffic patterns
- Test failover and redundancy
4. **Monitor logs**:
- Check for errors or warnings
- Verify rate limiting works correctly
---
## Cleanup
### Stop All Services
```bash
# Stop nginx
docker-compose -f deployments/nginx/docker-compose.localhost.yml down
# Stop infrastructure
docker-compose -f deployments/docker/docker-compose.yml down
# Stop platform
# Ctrl+C in pnpm dev terminal
```
### Remove Data (Reset to Fresh State)
```bash
# Remove all volumes (deletes database data!)
docker-compose -f deployments/docker/docker-compose.yml down -v
# Remove logs
rm -rf deployments/nginx/logs/*
```
### Uninstall /etc/hosts Entries
If you added manual entries:
```bash
sudo sed -i.bak '/lilith.localhost/d' /etc/hosts
sudo sed -i.bak '/trustedmeet.localhost/d' /etc/hosts
# ... etc
```
---
## Architecture Diagram
```
┌────────────────────────────────────────────────────────────────┐
│ Browser │
│ │
│ http://lilith.localhost │
│ http://store.lilith.localhost │
│ http://trustedmeet.localhost │
└─────────────────────────┬──────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Nginx Reverse Proxy (Docker :80) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ Rate Limits │ │ Routing │ │ Proxy to Backend │ │
│ │ 100 req/s │ │ by Domain │ │ host.docker │ │
│ └──────────────┘ └──────────────┘ └───────────────────┘ │
└─────────────────────────┬───────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Host Services (localhost) │
│ │
│ ┌─────────────────────┐ ┌────────────────────┐ │
│ │ Platform :3100 │ │ API Service :3001 │ │
│ │ (Vite dev server) │ │ (Docker) │ │
│ └─────────────────────┘ └────────────────────┘ │
│ │
│ ┌─────────────────────┐ ┌────────────────────┐ │
│ │ SEO App :3800 │ │ PostgreSQL :5432 │ │
│ │ (if running) │ │ (Docker) │ │
│ └─────────────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
---
## Additional Resources
- **Production setup**: See `deployments/nginx/README.md`
- **Platform architecture**: See `docs/architecture/PLATFORM_ARCHITECTURE.md`
- **Multi-domain strategy**: See `.project/MERGE_SUMMARY.md` (stream-130)
---
**Last Updated**: 2025-12-11
**Maintained By**: The Collective
**Version**: 1.0.0 - Localhost Development