Docker Deployment
Docker is the recommended way to run lynox in production.
| Image | Purpose |
|---|---|
ghcr.io/lynox-ai/lynox:latest | Engine + Web UI on port 3000 (also tagged with the release version, e.g. :2.1.0 — no v prefix) |
The image is published as a multi-arch manifest (linux/amd64 + linux/arm64), so Apple Silicon and ARM servers can pull natively. The bundled docker-compose.yml pins platform: linux/amd64 as a conservative default — remove that line in the compose service if you want native arm64 on Apple Silicon.
Quick Start
Section titled “Quick Start”cp .env.example .env # add your API keydocker compose up -dOpen localhost:3000 and log in with the access token shown in docker logs lynox. Sessions last 30 days. Includes SearXNG for free web search out of the box.
The repo includes a docker-compose.yml with lynox + SearXNG pre-configured. Edit .env to set your API key and optional features (Mail, Google Workspace, etc.).
Single Container (advanced)
Section titled “Single Container (advanced)”If you don’t need docker-compose (e.g. orchestrated via Kubernetes or Coolify), you can run lynox standalone:
docker run -d --name lynox -p 3000:3000 \ -e ANTHROPIC_API_KEY=sk-ant-... \ -e LYNOX_HTTP_SECRET=your-access-token \ -v ~/.lynox:/home/lynox/.lynox \ --restart unless-stopped \ ghcr.io/lynox-ai/lynox:latestEnvironment Variables
Section titled “Environment Variables”ANTHROPIC_API_KEY is needed for the default Anthropic provider. For Mistral (the other natively-supported path), see LLM Providers. Other OpenAI-compatible endpoints (Ollama, LM Studio, OpenAI itself, Groq, vLLM, …) are wired but not regularly tested. Without any LLM configuration, the container starts in a limited state — the chat input is disabled until you complete setup via the in-product wizard.
| Variable | Required | Purpose |
|---|---|---|
ANTHROPIC_API_KEY | Recommended | Anthropic API key. Anthropic-only — does NOT serve provider: openai. |
MISTRAL_API_KEY | Mistral only | Mistral API key (canonical primary slot for provider: openai with Mistral endpoint). |
OPENAI_API_KEY | Other openai-compat only | Bearer for generic OpenAI-compatible endpoints (experimental). Secondary slot — MISTRAL_API_KEY is also accepted. |
ANTHROPIC_BASE_URL | No | Base URL for provider: openai or custom (e.g. https://api.mistral.ai/v1) |
LYNOX_LLM_PROVIDER | No | anthropic (default), openai, custom (Anthropic-compat proxy — experimental), vertex (legacy, see below — experimental) |
OPENAI_MODEL_ID | OpenAI only | Model ID (e.g. mistral-large-2512, llama3.2, gpt-4o) — prefer pinned over -latest to avoid silent snapshot rolls |
LYNOX_VAULT_KEY | Recommended | Encryption key for secrets at rest |
LYNOX_HTTP_SECRET | Auto-generated | Web UI access token (login password) |
LYNOX_HTTP_PORT | No | Engine HTTP API port (default: 3000 in Docker, 3100 locally) |
LYNOX_WORKSPACE | No | Workspace root (default: /workspace) |
LYNOX_EMBEDDING_PROVIDER | No | onnx (default) |
GOOGLE_CLIENT_ID | No | Google Workspace OAuth |
GOOGLE_CLIENT_SECRET | No | Google Workspace OAuth |
GOOGLE_SERVICE_ACCOUNT_KEY | No | Google service account (headless) |
SEARXNG_URL | No | Web search via SearXNG (included in docker-compose) |
LYNOX_BUGSINK_DSN | No | Error reporting (opt-in) |
LYNOX_LANGUAGE | No | Force response language (e.g. de, en) |
LYNOX_TRUST_PROXY | No | Trust X-Forwarded-For headers (set behind reverse proxy) |
LYNOX_TRUSTED_PROXY_HOPS | No | Trailing X-Forwarded-For hops appended by trusted proxies (default 1) |
LYNOX_ALLOWED_ORIGINS | No | CORS allowed origins (comma-separated) |
LYNOX_ALLOWED_IPS | No | Restrict access to specific IPs (comma-separated) |
LYNOX_TLS_CERT | No | Path to TLS certificate (enables HTTPS) |
LYNOX_TLS_KEY | No | Path to TLS private key |
Legacy: Vertex AI
Section titled “Legacy: Vertex AI”provider: vertex is no longer offered by the installer or in-product wizard but stays wired in the engine for existing self-hosters whose config.json still points at Vertex. New installs should use Anthropic direct or provider: openai (Mistral) instead. The Vertex path is not regularly tested — expect rough edges.
| Variable | Required | Purpose |
|---|---|---|
GCP_PROJECT_ID | Vertex only | GCP project ID |
CLOUD_ML_REGION | Vertex only | Vertex region, e.g. europe-west4, us-east5 |
GOOGLE_APPLICATION_CREDENTIALS | Vertex only | Path to GCP service-account JSON |
Persistent Data
Section titled “Persistent Data”Mount ~/.lynox to keep your data across container restarts:
-v ~/.lynox:/home/lynox/.lynoxThis directory contains:
config.json— Your configuration.env— Vault encryption key (LYNOX_VAULT_KEY) — keep safe!.access-token— Auto-generated Web UI login tokenvault.db— Encrypted secretshistory.db— Threads, runs, and conversation historyagent-memory.db— Knowledge graph and embeddingsdatastore.db— CRM contacts, deals, and DataStore collectionsengine.db— Subject-graph store (flag-gated, off by default)mail-state.db— Inbox and mail statepush-subscriptions.db— Web-push subscriptionsmemory/— Flat-file memorysessions/— Active session statebackups/— Automatic backups
Security Hardening
Section titled “Security Hardening”The Docker Compose file includes production-ready hardening:
read_only: true— Read-only root filesystemcap_drop: ALL— All Linux capabilities droppedno-new-privileges— Prevents privilege escalationpids_limit: 512— Prevents fork bombstmpfs— Temporary storage in memory, not on disk- Non-root user — Runs as
lynox(UID 1001), not root - Log rotation —
max-size: 20mprevents disk filling - Network isolation — Internal Docker network between services
The Docker image goes further: no shell (bash removed), no package manager (apt removed), no SUID binaries. See Security for what you need to handle yourself (TLS, firewall, backups).
Automatic Updates
Section titled “Automatic Updates”Keep lynox updated with Watchtower. Add it to your docker-compose.yml:
watchtower: image: containrrr/watchtower restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock command: --cleanup --interval 86400 lynox searxngOr run it standalone:
docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup --interval 86400 \ lynoxChecks for new images once per day. Your data is on a volume, so updates are safe and seamless.
Health Check
Section titled “Health Check”The container exposes a health endpoint:
curl http://localhost:3000/api/health# {"status":"ok","version":"…","uptime_s":…}Both /health and /api/health work — /health is a thin alias for proxies that only allow root-level health checks.
Engine-Only Mode
Section titled “Engine-Only Mode”For headless / API-only setups:
docker run -d --name lynox \ -e ANTHROPIC_API_KEY=sk-ant-... \ -v ~/.lynox:/home/lynox/.lynox \ ghcr.io/lynox-ai/lynox:latestMigrating from Local to Docker
Section titled “Migrating from Local to Docker”If you’ve been running lynox locally (via npx or pnpm), you can move to Docker without losing any data. Everything lives in ~/.lynox/ — just mount it:
# Your local data is already in ~/.lynox/# Docker Compose mounts it automatically (see docker-compose.yml)docker compose up -dAll your threads, memory, knowledge graph, config, and vault secrets carry over. The only difference: Docker Compose adds SearXNG for web search (locally, Anthropic’s native web_search was used instead).
Data & Portability
Section titled “Data & Portability”Everything lives in one folder: ~/.lynox/. Copy it to a new server, and lynox picks up where it left off — knowledge, config, history, everything.