Deployment Guide

Get VeilProxy running in production with Docker, Kubernetes, or a direct install. Includes reverse proxy configs and environment variable reference.

Quick Start

The fastest way to run VeilProxy in production:

terminal
git clone https://github.com/Threatlabs-LLC/veil-public.git cd veil-public cp .env.example .env # Edit .env with your API keys and a random secret key docker compose up -d

Open http://localhost:8000 and register your first user.

1. Docker Compose (Recommended)

Prerequisites: Docker and Docker Compose

terminal
# Production docker compose up -d # Development (with hot reload) docker compose -f docker-compose.dev.yml up

With Ollama (Air-Gapped)

If running Ollama on the host machine, VeilProxy in Docker can reach it via host.docker.internal:

.env
VEILCHAT_OLLAMA_BASE_URL=http://host.docker.internal:11434/v1
Linux note: Add --add-host=host.docker.internal:host-gateway to Docker run, or use the host network.

2. Docker Standalone

terminal
docker build -t veilproxy . docker run -d \ --name veilproxy \ -p 8000:8000 \ -v veilproxy-data:/app/data \ -e VEILCHAT_SECRET_KEY=your-random-secret \ -e VEILCHAT_OPENAI_API_KEY=sk-... \ veilproxy

Build without NER (smaller image)

terminal
docker build --build-arg INSTALL_NER=false -t veilproxy:slim .

3. Direct Install (No Docker)

terminal
# Install pip install -e ".[ner]" python -m spacy download en_core_web_md # Configure cp .env.example .env # Edit .env # Run uvicorn backend.main:app --host 0.0.0.0 --port 8000 # Build frontend (optional) cd frontend && npm ci && npm run build && cd .. mv frontend/dist static/

4. Kubernetes

Basic deployment manifest:

apiVersion: apps/v1 kind: Deployment metadata: name: veilproxy spec: replicas: 1 selector: matchLabels: app: veilproxy template: metadata: labels: app: veilproxy spec: containers: - name: veilproxy image: ghcr.io/threatlabs-llc/veil-public:latest ports: - containerPort: 8000 env: - name: VEILCHAT_SECRET_KEY valueFrom: secretKeyRef: name: veilproxy-secrets key: secret-key livenessProbe: httpGet: path: /api/health/live port: 8000 initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: path: /api/health/ready port: 8000 initialDelaySeconds: 15 periodSeconds: 10

Create the secrets:

terminal
kubectl create secret generic veilproxy-secrets \ --from-literal=secret-key=$(openssl rand -base64 32) \ --from-literal=openai-api-key=sk-...

Reverse Proxy Setup

Caddy (Recommended)

Automatic TLS. A Caddyfile is included in the repository:

yourdomain.com { handle /api/* { reverse_proxy veilproxy:8000 } handle /v1/* { reverse_proxy veilproxy:8000 } handle { root * /srv/static try_files {path} /index.html file_server } }

Nginx

server { listen 443 ssl; server_name yourdomain.com; location /api/ { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # SSE streaming support location /api/chat/ { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_buffering off; chunked_transfer_encoding off; } location /v1/ { proxy_pass http://127.0.0.1:8000; proxy_buffering off; } location / { root /var/www/veilproxy/static; try_files $uri /index.html; } }

Database Configuration

SQLite (Default)

No configuration needed. Database created automatically at data/veilchat.db. For production single-instance deployments, SQLite with WAL mode is sufficient for most workloads.

PostgreSQL

.env
VEILCHAT_DATABASE_URL=postgresql+asyncpg://veilchat:password@localhost:5432/veilchat

Recommended when running multiple instances, needing database-level backups/replication, or exceeding ~100 concurrent users.

Environment Variables

Only two variables are needed to get started. Everything else has sensible defaults and can be configured later.

Required

VariableDescription
VEILCHAT_SECRET_KEYJWT signing key — set to a random string (e.g. openssl rand -base64 32)

LLM Provider (at least one)

Configure at least one provider. Users can also add their own keys in the Settings page after login.

VariableDescription
VEILCHAT_OPENAI_API_KEYOpenAI API key (GPT-4o, o3-mini, etc.)
VEILCHAT_ANTHROPIC_API_KEYAnthropic API key (Claude)
VEILCHAT_OLLAMA_BASE_URLOllama endpoint — defaults to http://localhost:11434/v1, no key needed
That's it. Clone, set these 2-3 variables, docker compose up -d. Everything below is optional.

Optional: Google OAuth

Enable "Continue with Google" on the login page. Get credentials at Google Cloud Console → APIs & Services → Credentials.

VariableDescription
VEILCHAT_GOOGLE_CLIENT_IDOAuth client ID
VEILCHAT_GOOGLE_CLIENT_SECRETOAuth client secret

Optional: Email (Password Reset)

Enable password reset emails. Without this, users can still log in — they just can't reset a forgotten password.

VariableDefaultDescription
VEILCHAT_SMTP_HOSTSMTP server (e.g. smtp.gmail.com)
VEILCHAT_SMTP_PORT587SMTP port
VEILCHAT_SMTP_USERSMTP username
VEILCHAT_SMTP_PASSWORDSMTP password (use App Password for Gmail)
VEILCHAT_SMTP_FROM_EMAILFrom address for emails

Optional: Advanced

Defaults work for most deployments. Only change these if you need to.

VariableDefaultDescription
VEILCHAT_DATABASE_URLSQLiteUse postgresql+asyncpg://... for scale
VEILCHAT_REDIS_URLRedis for distributed rate limiting (multi-worker)
VEILCHAT_CORS_ORIGINS["http://localhost:5173"]Allowed origins (set to your domain)
VEILCHAT_APP_BASE_URLhttp://localhost:5173Public URL (for OAuth callbacks, reset links)
VEILCHAT_LICENSE_PUBLIC_KEY_PATHLicense key for paid tiers
VEILCHAT_OPENAI_BASE_URLhttps://api.openai.com/v1Custom endpoint (Azure OpenAI, etc.)
VEILCHAT_ANTHROPIC_BASE_URLhttps://api.anthropic.com/v1Custom Anthropic endpoint

Health Checks

EndpointPurposeExpected
GET /api/healthBasic status{"status": "ok"}
GET /api/health/liveLiveness probeAlways 200
GET /api/health/readyReadiness probe200 if DB healthy

Upgrading

terminal
docker pull ghcr.io/threatlabs-llc/veil-public:latest docker compose down docker compose up -d

Database migrations run automatically on startup. Data is persisted in the Docker volume.

Backup

SQLite

terminal
docker compose down cp data/veilchat.db data/veilchat.db.backup docker compose up -d

PostgreSQL

terminal
pg_dump -h localhost -U veilchat veilchat > backup.sql