Developer Guide
Production Deployment & POPIA Guide
Docker Compose production, Nginx reverse proxy, SSL, and SA POPIA compliance.
This guide covers deploying KHOLO into production environments using Docker Compose, configuring reverse proxies with SSL, and implementing South African POPIA (Protection of Personal Information Act) compliance.
1. Production Architecture Overview
In production, the entire stack runs within isolated Docker containers behind an Nginx or Caddy reverse proxy:
Production Container Topologydocker-compose.prod.yml
Reverse Proxy
Nginx / Caddy
Port 80/443 with Let's Encrypt SSL. Routes API and Web traffic.
Frontend Web
Next.js 15 (Port 3000)
Order Control Centre, Pick Slips, Catalog, and Customer Portal.
API Gateway
Fastify (Port 3001)
Webhook receiver, AI extraction, and Background Task Queue worker.
Data Tier
Postgres + Redis 7
Vector Database database and Background Task Queue queue broker with persistent volumes.
2. Server Requirements & Prerequisites
- Hardware Recommendation:
- Minimum: 2 vCPU, 4GB RAM, 40GB SSD.
- Recommended: 4 vCPU, 8GB RAM, 80GB NVMe SSD (handles 5,000+ orders/day with real-time audio transcription).
- Operating System: Ubuntu 22.04 LTS or 24.04 LTS.
- Dependencies: Docker Engine $\ge 24.0$ and Docker Compose V2.
3. Deployment Steps
Step 1: Clone Repository & Configure Production Environment
git clone https://github.com/MojaHorse/KHOLO.git /opt/kholo
cd /opt/kholo
# Copy and edit production environment variables
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.envEnsure production values are set in apps/api/.env:
NODE_ENV=production
DATABASE_URL="postgresql://kholo_user:SECURE_PASSWORD@db:5432/kholo_prod?schema=public"
REDIS_HOST=redis
REDIS_PORT=6379
PORT=3001
# Meta WhatsApp Credentials
META_WHATSAPP_PHONE_NUMBER_ID="1092837465"
META_WHATSAPP_ACCESS_TOKEN="EAAxxxxxxx"
META_APP_SECRET="your_meta_app_secret"
WHATSAPP_VERIFY_TOKEN="your_strong_verify_token"
# Primary AI Provider
PRIMARY_AI_PROVIDER="gemini"
GEMINI_API_KEY="your_production_gemini_key"
OPENAI_API_KEY="your_production_openai_key"
# CORS Allowed Origins
ALLOWED_ORIGINS="https://app.yourdomain.co.za,https://admin.yourdomain.co.za"Step 2: Build and Start Containers
docker compose -f docker-compose.prod.yml up -d --buildStep 3: Run Database Migrations in the Container
docker compose -f docker-compose.prod.yml exec api npx prisma migrate deploy4. Nginx Reverse Proxy & SSL Configuration
Create an Nginx configuration file at /etc/nginx/sites-available/kholo.conf:
# API & Webhooks
server {
server_name api.yourdomain.co.za;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 25M; # Allows WhatsApp voice notes and catalog CSVs
}
}
# Web Control Centre
server {
server_name app.yourdomain.co.za;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable SSL using Certbot:
sudo certbot --nginx -d api.yourdomain.co.za -d app.yourdomain.co.za5. Security & Access Control Architecture
1. Role-Based Access Control (RBAC):
ADMIN: Platform super-administrators with fleet management, tenant creation, and billing management.MANAGER: Distributor administrators with catalog editing, credit hold release, pricing changes, and API key management.CLERK: Order desk operators with order review, SKU resolution, and pick slip printing permissions.
2. Dual Authentication Model:
- Clerk Terminal Access: Clerks log in using a 4-digit PIN (
pinHashverified with bcrypt) for fast, friction-free switching on shared warehouse dispatch tablets. - Manager & Admin Access: Authenticated via Supabase JWT with mandatory session expiry.
3. HTTP Hardening:
- Helmet: Strict Content Security Policy (
CSP), HSTS, and X-Content-Type-Options headers. - Rate Limiting: Configured at 100 requests per minute per IP address with burst protection.
- HMAC Signatures: Every incoming Meta webhook is verified against
META_APP_SECRET.
6. South African POPIA & Data Protection Compliance
Under the South African Protection of Personal Information Act (POPIA):
- Lawful Processing: Customer phone numbers are collected solely for wholesale order fulfillment and delivery notifications.
- Log Sanitization: Plaintext customer phone numbers and payment details are masked in standard application logs.
- Immutable Audit Trails: The
AuditLogtable permanently records:- Who reviewed and approved an order (
userIdorclerkId). - What SKU corrections or alias changes were made (
beforeStateandafterStateJSON). - Exact timestamps for ERP creation and delivery slips.
- Who reviewed and approved an order (
- Data Retention: Audio recordings of voice notes can be set to auto-purge after 30 days while retaining transcribed text for tax auditing.