Use Valkey instead of Redis

Redis 7.4+ is RSALv2/SSPL and 8.0+ adds AGPLv3. None of the three works
for a closed-source commercial cloud service, and SSPL section 13
specifically targets offering the software's functionality as a service,
which is what a control plane does. Valkey is BSD-3-Clause, under the
Linux Foundation, forked from Redis 7.2.4.

Deciding this now rather than after step 3 of PLAN.md stands up real
infrastructure makes it free: Valkey speaks the same RESP protocol, so
`ioredis` is untouched and only names change. `REDIS_URL` becomes
`VALKEY_URL`, the exported client becomes `valkey`, and `/health`
reports a `valkey` field.

Two things deliberately do not change, documented in place so they are
not "fixed" later: the `redis://` URL scheme, which names the wire
protocol and is what every client actually parses (none understands
`valkey://`), and `ioredis` itself, which is a RESP client whose name
refers to the protocol's origin and not to the server we run.

docker-compose.yml is new, pinning valkey/valkey:8-alpine alongside
pgvector/pgvector:pg17 - the plain postgres image lacks the extension
`frame_embeddings` needs. It makes the Valkey choice concrete rather
than a note someone has to remember.
This commit is contained in:
2026-10-03 10:10:28 +00:00
parent 349c4073cd
commit ab093f3136
5 changed files with 69 additions and 11 deletions
+3 -3
View File
@@ -3,7 +3,7 @@ import { cors } from "@elysiajs/cors";
import { swagger } from "@elysiajs/swagger";
import { sql } from "drizzle-orm";
import { db } from "./db";
import { redis } from "./queue";
import { valkey } from "./queue";
import { authRoutes } from "./routes/auth";
import { farmRoutes } from "./routes/farms";
import { printerRoutes } from "./routes/printers";
@@ -15,8 +15,8 @@ const app = new Elysia()
.use(swagger({ path: "/docs" }))
.get("/health", async () => {
const rows = await db.execute<{ ok: number }>(sql`select 1 as ok`);
const redisPing = await redis.ping();
return { status: "ok", db: rows[0]?.ok === 1, redis: redisPing === "PONG" };
const valkeyPing = await valkey.ping();
return { status: "ok", db: rows[0]?.ok === 1, valkey: valkeyPing === "PONG" };
})
.use(authRoutes)
.use(farmRoutes)