docs(docker): document SQLite single-replica HA limits (#10817)

Merged — validated together with a batch of related RaviTharuma PRs in one combined worktree (typecheck:core clean, complexity/file-size/changelog gates green, focused tests passing). Thanks for the contribution!
This commit is contained in:
Ravi Tharuma
2026-08-20 16:48:10 +02:00
committed by GitHub
parent 56b9d00335
commit 7c6bf32186
3 changed files with 38 additions and 0 deletions

View File

@@ -0,0 +1 @@
- **docs(docker):** document default SQLite as single-replica / HA-unsupported, including Recreate and HEALTHCHECK session blast radius ([#10350](https://github.com/diegosouzapw/OmniRoute/issues/10350))

View File

@@ -22,6 +22,7 @@ lastUpdated: 2026-06-28
- [Docker Compose with Caddy (HTTPS)](#docker-compose-with-caddy-https-auto-tls)
- [Cloudflare Quick Tunnel](#cloudflare-quick-tunnel)
- [Image Tags](#image-tags)
- [Availability: default SQLite is single-replica](#availability-default-sqlite-is-single-replica)
- [Important Notes](#important-notes)
---
@@ -465,6 +466,28 @@ docker compose up -d
A release-branch build can never move `latest`; only an eligible stable semantic version may promote the stable pointer. The `next` images retain the release image inspection and blocking CRITICAL-vulnerability gate.
## Availability: default SQLite is single-replica
Stock Docker / Kubernetes OmniRoute is **one Node process + one SQLite writer**. High availability is **not supported** on that topology.
| Constraint | Consequence |
| --- | --- |
| Single writer | Do **not** run multiple replicas against the same SQLite file. That corrupts the DB. |
| Recreate / restart / HEALTHCHECK kill | **Full outage** of in-flight SSE, dashboard sessions, and in-memory state. Every connected client drops. |
| Same event loop as `/healthz` | A busy catalog or compression tick can delay probes; a short timeout then restarts the **only** replica. |
**Probe matrix** (see also [Kubernetes probe recommendations](../ops/MONITORING_GUIDE.md#kubernetes-probe-recommendations)):
| Probe | Target | Do not use |
| --- | --- | --- |
| Liveness | TCP on `PORT` (default `20128`), or soft HTTP `/healthz` | `/api/monitoring/health` |
| Readiness | HTTP `GET /healthz` | Tight timeouts that treat event-loop busy as dead |
| Deep / humans | `/api/monitoring/health` | Automated kubelet liveness |
**Upgrades:** expect every session to drop. Drain clients if you can; there is no rolling update on default SQLite. Compose `restart: unless-stopped` plus Docker `HEALTHCHECK` will also replace the only process when the container is Unhealthy — same blast radius.
External Postgres / multi-writer HA is **not** a documented stock path. If you need HA, keep a single replica or run a topology the project has tested and documented separately.
## Important Notes
- **SQLite WAL Mode:** `docker stop` should be allowed to finish so OmniRoute can checkpoint the latest changes back into `storage.sqlite`. The bundled Compose files already set a 40s stop grace period. If you run the image directly, keep `--stop-timeout 40`.

View File

@@ -80,3 +80,17 @@ Implementation:
- `bin/cli/runtime/index.mjs` — startup orchestrator (`warmUpRuntimes()`)
- `scripts/postinstall.mjs` — npm post-install hook (non-fatal warm-up)
- `src/lib/db/core.ts``ensureDbInitialized()` / `getDriverInfo()` exports
## Single-writer topology (HA unsupported)
The driver fallback chain above still runs in **one process**. Default SQLite
OmniRoute is a **single writer**:
- Do not attach two OmniRoute replicas to the same `storage.sqlite` file.
- A container restart, Recreate deploy, OOM kill, or HEALTHCHECK restart drops
every in-flight SSE session. There is no session drain on the stock path.
- Orchestrator liveness that treats a slow `/healthz` as dead will kill the only
replica. Prefer TCP liveness + HTTP `/healthz` readiness. See
[Docker Guide — availability](../guides/DOCKER_GUIDE.md#availability-default-sqlite-is-single-replica)
and [Kubernetes probe recommendations](./MONITORING_GUIDE.md#kubernetes-probe-recommendations).