From af6710d849b25984d2e7989f120ba13ea47b55cd Mon Sep 17 00:00:00 2001 From: Luxit Date: Thu, 27 Aug 2026 17:34:01 +0200 Subject: [PATCH] Sync the self-hosting stack --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 398e6a2..8000c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,52 @@ one of them changed. An entry says which artefact and which version, so `web 0.1 Every version published to a channel appears here. Nothing is written from memory afterwards: a build cannot be published without its entry. +## 2026-08-27 — Redis can survive losing a node `api 0.94.0` + +**Nothing to do on Docker Compose.** Every setting below is optional and absent by default, and an +unchanged stack behaves exactly as it did. This release is for deployments that run more than one +copy of the api. + +**A Redis that fails over is now something you can point at.** `REDIS_URL` names one server, and +there is nowhere in a URL to put what Redis Sentinel needs: the sentinels themselves, and the name +of the primary they are watching. So there are two new settings, and setting them switches the +shape — see `.env.example`: + +``` +REDIS_SENTINELS=a:26379,b:26379,c:26379 +REDIS_SENTINEL_NAME=jarvis +``` + +Set one without the other and the api **refuses to start and says why**, rather than starting and +waiting forever for a primary nobody has heard of. `REDIS_PASSWORD` and `REDIS_SENTINEL_PASSWORD` +are there too, because the sentinels' password is frequently not the data node's. Redis **Cluster** +is deliberately not supported: the realtime adapter and the inter-pod bus both publish across what +would be different shards. + +What a failover costs, measured rather than estimated: commands issued while the primary is gone +queue and land on the new one, so a failover is a pause and not an error storm. **Messages published +during it are lost** — Redis pub/sub has no buffer and no redelivery, and nothing on the client side +can change that. In practice that is a few seconds in which something happening on one api replica +may not reach another. Nothing is corrupted by it: what must survive is in Postgres for exactly this +reason. + +**Losing Redis now appears in the log.** Nothing was listening for connection errors on those +sockets, which meant a Redis blip printed dozens of stack traces per container, none of which said +what had broken or that it had come back. It is now one line when a connection drops and one when it +returns, naming which connection and how long it took. + +**For Kubernetes: the secrets can now be minted by the cluster.** Generating them exactly once used +to depend on every container sharing one filesystem, which no longer exists once there are several +pods — so it was a manual step that silently corrupted the vault if you got it wrong. There is now a +Job that mints them once, using the API server's refusal to create something twice as the +guarantee. It can create a Secret and cannot read one back. See `deploy/kubernetes/`. + +**Also in `deploy/kubernetes/`, which has now been applied to a real cluster rather than only +validated:** manifests for a Sentinel-backed Redis, replicas that are spread across nodes instead of +being allowed to share one, and two faults that stopped every pod in the directory from starting +under the `restricted` Pod Security Standard. If you have been working from those files, take the +new ones. + ## 2026-08-27 — The console container listens on 8080 and runs unprivileged `web 0.120.0` **Check your port mapping before you pull.** The web container used to listen on **80** and now