Installer¶
The Jarvis Installer is a static React SPA that generates a Docker Compose stack for initial deployment. It runs entirely in the browser without a backend and produces a downloadable docker-compose.yml configured for the services you select.
Quick Reference¶
| Source | jarvis-installer/ |
| Framework | React (static SPA) |
| Output | Downloadable docker-compose.yml |
| Use case | Compose file generation without installing the admin binary |
Infrastructure Images¶
The installer generates compose files with fixed infrastructure images. These images are not tagged with JARVIS_IMAGE_TAG or release tracks — infra images are pinned independently of the Jarvis service release cycle.
| Service | Image | Notes |
|---|---|---|
| PostgreSQL | pgvector/pgvector:pg16 |
Required — see below |
PostgreSQL: pgvector Required¶
The installer uses pgvector/pgvector:pg16 rather than stock postgres:16 or postgres:16-alpine. Stock postgres does not ship the vector extension. Command-center's alembic migration e9f0a1b2c3d4 (add_embedding_and_pinned_to_memories) runs CREATE EXTENSION IF NOT EXISTS vector and will abort with:
if the postgres image does not include pgvector. pgvector/pgvector:pg16 is the official drop-in for postgres:16.
Do not swap the postgres image
Replacing pgvector/pgvector:pg16 with postgres:16 or postgres:16-alpine in installer-generated compose files causes jarvis-command-center to fail at startup.
Whisper GPU Backend¶
Since jarvis-installer#8, WizardState.whisperBackend (cpu | cuda | vulkan | rocm, default cpu) lets you pick Whisper's GPU backend independently of the LLM's auto-detected gpuType. Previously Whisper's image variant just followed the LLM's GPU type, and AMD/Vulkan boxes were hardcoded to CPU.
| Backend | Image suffix | Device passthrough |
|---|---|---|
cpu (default) |
none | none |
cuda |
-cuda |
NVIDIA deploy block |
vulkan |
-vulkan |
/dev/dri + render group |
rocm |
-rocm |
/dev/dri + /dev/kfd |
Default cpu keeps Whisper off the GPU — base.en is fast enough on CPU, leaving the GPU free for the LLM.
Both generators implement this via a whisper-scoped image lookup + a whisper-aware GPU config helper:
compose-export-generator.ts(downloadable file) — since #8.compose-generator.ts(interactive preview) — since jarvis-installer#10, for full parity with the export path and the admin sync generator.
Since jarvis-installer#9, the Configuration step surfaces a whisperBackend selector (CPU default / NVIDIA CUDA / AMD Vulkan / AMD ROCm) next to the Whisper model picker, dispatching SET_WHISPER_BACKEND. Default cpu means zero behavior change for existing installs — this is opt-in GPU-accelerated speech-to-text.
Generated Secrets¶
The installer mints a fresh, random secret for every sensitive credential in SECRET_KEYS (src/lib/secret-generator.ts) rather than shipping fixed defaults — this includes database passwords, ADMIN_API_KEY, and GRAFANA_ADMIN_PASSWORD (the Grafana container's GF_SECURITY_ADMIN_PASSWORD). Earlier installer versions hardcoded the Grafana admin password to the literal jarvis; it's now generated per-install like the other secrets and baked into the exported compose file.
Compose Export: Consistent Strong Secrets + Production Mode¶
Since jarvis-installer#12, the downloadable compose-export-generator.ts path resolves every secret once via a memoized resolveSecret() and reuses that same value everywhere it's referenced: a wizard-provided value wins, otherwise a strong random secret is generated. This fixes a mismatch where the export's SecretsMap fell back to the literal "changeme" while the generic per-service env loop fell back to "" for the same secret ref — producing different values for what should be one shared secret (e.g. AUTH_SECRET_KEY) and silently breaking fleet-wide JWT validation on a partial-wizard export. "changeme" is also on jarvis-auth's boot-time secret guard blocklist (see jarvis-auth: secret guard), so a prod export using it was a latent boot-breaker.
The export also now emits JARVIS_ENV: "production" on every service, opting a fresh install into that boot-time secret enforcement. This is safe by construction — the export always bakes strong, consistent secrets, so the guard has nothing to trip on.
MQTT Broker Lock (Fresh Installs)¶
Since jarvis-installer#18 (P0.4), compose-export-generator.ts defaults the exported broker to MQTT_ALLOW_ANON=false — Mosquitto starts authenticated-only from first boot. The installer only ever produces fresh installs, which never need the anonymous-broker transition window: command-center reads MQTT_PASSWORD from its own env, and every node fetches broker credentials over authenticated HTTP before it opens an MQTT connection (see Command Center: MQTT Broker Auth).
This is parity with the admin generator's fresh-install behavior (see Admin: MQTT Broker Lock) — the installer SPA has no upgrade path, so it always takes the locked default and never needs the admin generator's pre-existing-.env carve-out.
Service Registry¶
Service definitions live in public/service-registry.json. Each entry defines the Docker image, configurable ports, required environment variables, and named volumes. Two generators consume this file:
compose-generator.ts— powers the interactive UI selection listcompose-export-generator.ts— produces the static compose file for download
Both generators treat infrastructure images (postgres, Redis, etc.) as fixed — JARVIS_IMAGE_TAG and release-track overrides are not applied to them.
Command-Center Admin Key Wiring¶
Since jarvis-installer#20, the jarvis-admin service entry in service-registry.json declares COMMAND_CENTER_ADMIN_KEY (required, secretRef: ADMIN_API_KEY), so a compose file generated by the installer gives the admin dashboard the key it needs to authenticate to command-center's admin API (Request Traces, node detail). Previously this var was never emitted here, so commandCenterAdminKey defaulted to '' in any admin container started from an installer-generated compose, and command-center returned 401 once the traces router started requiring admin auth. The key shares the same ADMIN_API_KEY secret already generated for the admin service — no new secret is introduced. This is the installer-side twin of the same fix in the admin repo's own generator.
Supervised llm-proxy Launch (serve.sh)¶
Since jarvis-installer#21, the exported llm-proxy service's command is ["bash", "scripts/serve.sh"] (the supervised launcher the image ships, added in jarvis-llm-proxy-api#21) instead of a raw unsupervised dual-uvicorn shell command. serve.sh runs the API server in the foreground and supervises the model service, respawning it with backoff on a native crash (e.g. a llama.cpp segfault) — previously a crashed model service was never restarted and the API 503'd every request indefinitely while the container itself still looked healthy (the 2026-07-02 outage class, roadmap#59). Only compose-export-generator.ts emitted the old pattern — compose-generator.ts (interactive preview) relies on the image's own CMD for llm-proxy and was unaffected. This is the installer-side twin of the same fix in jarvis-admin's own generator (see Admin: Supervised llm-proxy Launch).
Named Volumes¶
The exported docker-compose.yml includes a top-level volumes: block declaring the two app-level named volumes. Without this declaration Docker Compose rejects the file at startup with invalid compose project.
| Volume | Used by service |
|---|---|
whisper-voice-profiles |
jarvis-whisper-api |
command-center-prompt-providers |
jarvis-command-center |
Infrastructure services (postgres, Redis, Mosquitto) use bind mounts rather than named volumes and are not listed here.
Both compose-generator.ts (interactive preview) and compose-export-generator.ts (download) apply the same top-level volume declarations.
vs. Admin Wizard¶
Both the installer SPA and the jarvis-admin setup wizard generate Docker Compose stacks, but serve different use cases:
| Installer SPA | Admin Setup Wizard | |
|---|---|---|
| Requires install | No — runs in any browser | Yes — admin binary (~7 MB) |
| Executes compose | No — download only | Yes — pulls images and starts services |
| Ongoing management | No | Yes — dashboard, model downloads, settings |
| Good for | Scripted deploys, air-gapped prep | Interactive first-time setup |
For most installs, use the admin wizard via curl … | sh or npx @alexberardi/jarvis-admin — it handles the full install lifecycle interactively. Use the installer SPA when you need a compose file without running the admin binary first.