Deployment Guide
Product: v0.19.0 · Contract: OpenAPI · Spec ops: Ingestion cancel & fairness
Deployment Guide
Section titled “Deployment Guide”Deploying EdgeQuake to Production
This guide covers deploying EdgeQuake in production environments, from single-server setups to containerized deployments with PostgreSQL.
⚡ Quickstart — One Command (~30 seconds)
Section titled “⚡ Quickstart — One Command (~30 seconds)”Fastest path: no Rust toolchain, no Node.js, no
cargo build.
Prebuilt multi-arch images (amd64 + arm64) are pulled from GitHub Container Registry.
# Clone repo (or just download the compose file)git clone https://github.com/raphaelmansuy/edgequake.gitcd edgequake
# Pull images and start all servicesmake stackWithout make:
docker compose -f docker-compose.quickstart.yml up -dAccess:
| Service | URL |
|---|---|
| 🌐 Web UI | http://localhost:3000 |
| 🔗 API | http://localhost:8080 |
| 📚 Swagger | http://localhost:8080/swagger-ui |
| 🏥 Health | http://localhost:8080/health |
Stop:
make stack-downUse OpenAI instead of Ollama:
EDGEQUAKE_LLM_PROVIDER=openai OPENAI_API_KEY=sk-... make stackPin to a specific version:
EDGEQUAKE_VERSION=0.19.0 make stackProduction auth (auth is on by default; quickstart uses EDGEQUAKE_DEV_MODE=true for open API):
EDGEQUAKE_VERSION=0.19.0 \EDGEQUAKE_DEV_MODE=false \EDGEQUAKE_AUTH_ENABLED=true \EDGEQUAKE_BOOTSTRAP_ADMIN_PASSWORD='ChangeMe123!' \ docker compose -f docker-compose.quickstart.yml up -dFor full documentation see: Docker Quickstart Guide
Deployment Options
Section titled “Deployment Options”| Option | Complexity | Cold Start | Best For |
|---|---|---|---|
make stack (GHCR images) |
⭐ Lowest | ~30 s | Local dev, demos, quick evaluation |
make docker-prebuilt (GHCR) |
Low | ~45 s | Staging / production with pinned version |
make docker-up (build from src) |
Medium | 5–15 min | Custom builds, self-hosted |
| Binary + PostgreSQL | Low | N/A | Bare metal / VMs |
| Kubernetes | High | N/A | Scale, HA, enterprise |
Prerequisites
Section titled “Prerequisites”Required
Section titled “Required”- PostgreSQL 16+ (recommended: PG18 via GHCR image) with extensions:
pgvector0.8.3 (vector similarity search)age1.6.0 (PG16) or 1.7.0 (PG17/PG18) — Apache AGE for graph storage
- LLM provider access (OpenAI API key or Ollama running)
See Release & CD for the triple-track pin matrix.
Recommended
Section titled “Recommended”- 4+ CPU cores
- 8GB+ RAM (16GB for large corpora)
- SSD storage
- Docker (for containerized deployments)
Option 1: Binary Deployment
Section titled “Option 1: Binary Deployment”Step 1: Build Release Binary
Section titled “Step 1: Build Release Binary”cd edgequakecargo build --releaseThe binary is at target/release/edgequake (~15MB).
Step 2: Set Up PostgreSQL
Section titled “Step 2: Set Up PostgreSQL”Install PostgreSQL 16+ and extensions (pins match GHCR postgres image):
# macOS with Homebrew (example: PG17)brew install postgresql@17brew services start postgresql@17
# Build pgvector 0.8.3git clone --branch v0.8.3 https://github.com/pgvector/pgvector.gitcd pgvector && make && make install
# Build Apache AGE (pick branch for your PG major)# PG16 → RELEASE_1.6.0 PG17/PG18 → RELEASE_1.7.0git clone --branch RELEASE_1.7.0 https://github.com/apache/age.gitcd age && make && make installStep 3: Create Database
Section titled “Step 3: Create Database”-- Connect as superuserpsql -U postgres
-- Create user and databaseCREATE USER edgequake WITH PASSWORD 'your_secure_password';CREATE DATABASE edgequake OWNER edgequake;
-- Connect to database\c edgequake
-- Enable extensionsCREATE EXTENSION IF NOT EXISTS vector;CREATE EXTENSION IF NOT EXISTS age;LOAD 'age';SET search_path = ag_catalog, "$user", public;SELECT create_graph('edgequake_graph');Step 4: Configure and Run
Section titled “Step 4: Configure and Run”# Set environment variablesexport DATABASE_URL="postgresql://edgequake:your_secure_password@localhost:5432/edgequake"export OPENAI_API_KEY="sk-your-key" # Or use Ollamaexport RUST_LOG="edgequake=info,tower_http=info"
# Run the server./target/release/edgequakeStep 5: Systemd Service (Linux)
Section titled “Step 5: Systemd Service (Linux)”Create /etc/systemd/system/edgequake.service:
[Unit]Description=EdgeQuake RAG ServerAfter=network.target postgresql.serviceRequires=postgresql.service
[Service]Type=simpleUser=edgequakeGroup=edgequakeWorkingDirectory=/opt/edgequakeExecStart=/opt/edgequake/edgequakeRestart=on-failureRestartSec=5Environment=DATABASE_URL=postgresql://edgequake:password@localhost:5432/edgequakeEnvironment=OPENAI_API_KEY=sk-your-keyEnvironment=RUST_LOG=edgequake=info,tower_http=infoEnvironment=HOST=0.0.0.0Environment=PORT=8080
[Install]WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reloadsudo systemctl enable edgequakesudo systemctl start edgequakeOption 2: Docker Compose (Recommended)
Section titled “Option 2: Docker Compose (Recommended)”Step 1: Create Environment File
Section titled “Step 1: Create Environment File”Create .env in project root (see .env.example for full reference):
# Database (quickstart default: edgequake_secret)POSTGRES_PASSWORD=your_secure_password_here
# LLM Provider (choose one)OPENAI_API_KEY=sk-your-key# OR for Ollama:EDGEQUAKE_LLM_PROVIDER=ollamaOLLAMA_HOST=http://host.docker.internal:11434OLLAMA_MODEL=gemma4:latestOLLAMA_EMBEDDING_MODEL=embeddinggemma:latest
# Server (optional)EDGEQUAKE_PORT=8080FRONTEND_PORT=3000EDGEQUAKE_VERSION=0.19.0
# Auth (production — auth is ON by default; quickstart sets EDGEQUAKE_DEV_MODE=true)EDGEQUAKE_DEV_MODE=falseEDGEQUAKE_AUTH_ENABLED=trueEDGEQUAKE_BOOTSTRAP_ADMIN_USERNAME=adminEDGEQUAKE_BOOTSTRAP_ADMIN_PASSWORD=ChangeMe123!JWT_SECRET=your-256-bit-secret-here
# Multi-replica (SPEC-057 — required when EDGEQUAKE_REPLICAS>1)# EDGEQUAKE_REPLICAS=2# EDGEQUAKE_TASK_DELIVERY=bridged# EDGEQUAKE_TASK_LEASE_TTL_SECS=120Step 2: Start Services
Section titled “Step 2: Start Services”cd edgequake/dockerdocker compose up -dArchitecture
Section titled “Architecture”┌─────────────────────────────────────────────────────────────────┐│ DOCKER COMPOSE STACK │├─────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────┐ ┌─────────────────┐ ││ │ edgequake │ ──────▶ │ postgres │ ││ │ (API Server) │ │ (pgvector+AGE)│ ││ │ :8080 │ │ :5432 │ ││ └─────────────────┘ └─────────────────┘ ││ │ ││ ▼ ││ ┌─────────────────┐ ││ │ External LLM │ ││ │ (OpenAI/Ollama)│ ││ └─────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Step 3: Verify Deployment
Section titled “Step 3: Verify Deployment”# Check service healthdocker compose ps
# Test health endpointcurl http://localhost:8080/health
# View logsdocker compose logs -f edgequakeStep 4: Add Frontend (Optional)
Section titled “Step 4: Add Frontend (Optional)”For the full stack with frontend, create docker-compose.full.yml:
services: edgequake: # ... (from docker-compose.yml)
postgres: # ... (from docker-compose.yml)
frontend: build: context: ../edgequake_webui dockerfile: Dockerfile container_name: edgequake-frontend ports: - "3000:3000" environment: - NEXT_PUBLIC_API_URL=http://edgequake:8080 depends_on: - edgequake networks: - edgequake-networkOption 3: Kubernetes
Section titled “Option 3: Kubernetes”Helm Chart (Coming Soon)
Section titled “Helm Chart (Coming Soon)”For Kubernetes deployments, a Helm chart is in development. For now, use the following manifests as a starting point:
Namespace
Section titled “Namespace”apiVersion: v1kind: Namespacemetadata: name: edgequakeConfigMap
Section titled “ConfigMap”apiVersion: v1kind: ConfigMapmetadata: name: edgequake-config namespace: edgequakedata: RUST_LOG: "edgequake=info,tower_http=info" HOST: "0.0.0.0" PORT: "8080"Secret
Section titled “Secret”apiVersion: v1kind: Secretmetadata: name: edgequake-secrets namespace: edgequaketype: OpaquestringData: DATABASE_URL: "postgresql://edgequake:password@postgres:5432/edgequake" OPENAI_API_KEY: "sk-your-key"Deployment
Section titled “Deployment”apiVersion: apps/v1kind: Deploymentmetadata: name: edgequake namespace: edgequakespec: replicas: 2 selector: matchLabels: app: edgequake template: metadata: labels: app: edgequake spec: containers: - name: edgequake image: ghcr.io/raphaelmansuy/edgequake:0.19.0 ports: - containerPort: 8080 envFrom: - configMapRef: name: edgequake-config - secretRef: name: edgequake-secrets resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "2000m" memory: "2Gi" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 30 readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 10Service
Section titled “Service”apiVersion: v1kind: Servicemetadata: name: edgequake namespace: edgequakespec: selector: app: edgequake ports: - port: 8080 targetPort: 8080 type: ClusterIPEnvironment Variables Reference
Section titled “Environment Variables Reference”| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
For PostgreSQL | None | PostgreSQL connection string |
OPENAI_API_KEY |
For OpenAI | None | OpenAI API key |
OLLAMA_HOST |
For Ollama | http://localhost:11434 |
Ollama server URL |
OLLAMA_MODEL |
For Ollama | gemma4:latest |
Ollama model for LLM |
OLLAMA_EMBEDDING_MODEL |
For Ollama | embeddinggemma:latest |
Ollama model for embeddings |
HOST |
No | 0.0.0.0 |
Server bind address |
PORT |
No | 8080 |
Server port |
RUST_LOG |
No | edgequake=debug |
Log level |
WORKER_THREADS |
No | CPU count | Background worker count |
EDGEQUAKE_DEV_MODE |
No | false (product) |
Open API without login (quickstart: true) |
EDGEQUAKE_AUTH_ENABLED |
No | true |
Require JWT/API key on protected routes |
EDGEQUAKE_BOOTSTRAP_ADMIN_USERNAME |
When auth on | admin |
First-run admin username |
EDGEQUAKE_BOOTSTRAP_ADMIN_PASSWORD |
When auth on | — | First-run admin password (required on fresh DB) |
JWT_SECRET |
When auth on | — | JWT signing secret (256-bit recommended) |
EDGEQUAKE_REPLICAS |
No | 1 |
Intended API/worker process count |
EDGEQUAKE_TASK_DELIVERY |
No | local |
local | bridged | notify_only (required non-local when replicas > 1) |
EDGEQUAKE_TASK_LEASE_TTL_SECS |
No | 120 |
Task claim lease TTL (min 30; heartbeat every 60s) |
See Ingestion cancel & fairness for multi-replica delivery, lease, and restart semantics.
Auth Bootstrap (SPEC-027)
Section titled “Auth Bootstrap (SPEC-027)”Auth is enabled by default in v0.19.0. On a fresh PostgreSQL database, set bootstrap credentials before first boot:
EDGEQUAKE_AUTH_ENABLED=trueEDGEQUAKE_BOOTSTRAP_ADMIN_USERNAME=adminEDGEQUAKE_BOOTSTRAP_ADMIN_PASSWORD='ChangeMe123!'JWT_SECRET='your-256-bit-secret-here'Quickstart compose (docker-compose.quickstart.yml) defaults to EDGEQUAKE_DEV_MODE=true and EDGEQUAKE_AUTH_ENABLED=false for frictionless demos. Never use EDGEQUAKE_DEV_MODE=true in production.
Upgrades from pre-v0.15 installs: legacy KV auth:user:* records are imported automatically on startup.
Multi-Replica & Task Delivery (SPEC-057)
Section titled “Multi-Replica & Task Delivery (SPEC-057)”When running more than one API/worker process against shared PostgreSQL:
| Variable | Default | Notes |
|---|---|---|
EDGEQUAKE_REPLICAS |
1 |
Set to intended replica count |
EDGEQUAKE_TASK_DELIVERY |
local |
Must be bridged or notify_only when replicas > 1 |
EDGEQUAKE_TASK_LEASE_TTL_SECS |
120 |
Claim lease TTL; workers refresh every 60s |
Boot fails if EDGEQUAKE_REPLICAS>1 and delivery is local. Correctness is always claim_next + lease — bridged/notify_only are wake modes only; never process from a channel payload without claim.
Storage Modes
Section titled “Storage Modes”EdgeQuake automatically selects storage based on DATABASE_URL:
┌─────────────────────────────────────────────────────────────────┐│ STORAGE MODE SELECTION │├─────────────────────────────────────────────────────────────────┤│ ││ DATABASE_URL set? ││ │ ││ ├── YES ─────▶ PostgreSQL Mode ││ │ • Persistent storage ││ │ • pgvector for embeddings ││ │ • Apache AGE for graph ││ │ • Full multi-tenant support ││ │ ││ └── NO ──────▶ ❌ Error: DATABASE_URL required ││ • Server exits with code 1 ││ • Set DATABASE_URL to proceed ││ • In-memory mode removed in v0.4.0 ││ │└─────────────────────────────────────────────────────────────────┘Health Checks
Section titled “Health Checks”EdgeQuake provides health endpoints for monitoring:
| Endpoint | Purpose | Response |
|---|---|---|
GET /health |
Basic health | status, version, storage_mode, components, llm_provider_name, capabilities |
GET /ready |
Readiness check | Storage + LLM status |
GET /live |
Liveness check | Process alive |
Docker Healthcheck
Section titled “Docker Healthcheck”HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1Kubernetes Probes
Section titled “Kubernetes Probes”livenessProbe: httpGet: path: /live port: 8080 initialDelaySeconds: 10 periodSeconds: 30
readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10Reverse Proxy Configuration
Section titled “Reverse Proxy Configuration”upstream edgequake { server localhost:8080; keepalive 32;}
server { listen 443 ssl http2; server_name rag.yourdomain.com;
ssl_certificate /etc/ssl/certs/your-cert.pem; ssl_certificate_key /etc/ssl/private/your-key.pem;
location / { proxy_pass http://edgequake; 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;
# SSE support for streaming proxy_buffering off; proxy_cache off; proxy_read_timeout 86400; }}rag.yourdomain.com { reverse_proxy localhost:8080 { header_up X-Real-IP {remote_host} flush_interval -1 }}Security Checklist
Section titled “Security Checklist”- Use strong PostgreSQL password (not
edgequake_secret) - Set
EDGEQUAKE_DEV_MODE=falseand configure auth bootstrap credentials - Keep
OPENAI_API_KEYandJWT_SECRETin secrets manager - Enable TLS termination at reverse proxy
- Set up firewall rules (only expose 443)
- Use non-root user in Docker
- Enable audit logging
- Set up backup for PostgreSQL
- Monitor rate limits on LLM providers
- Set
EDGEQUAKE_TASK_DELIVERY=bridged(ornotify_only) whenEDGEQUAKE_REPLICAS>1
See Also
Section titled “See Also”- Configuration Reference - Detailed configuration options
- Monitoring Guide - Observability setup
- Quick Start - Development setup
- Architecture Overview - System design