Sync the self-hosting stack

This commit is contained in:
2026-10-21 12:12:12 +02:00
parent e210b4db11
commit 6a2b67364b
13 changed files with 263 additions and 134 deletions
+11 -13
View File
@@ -2,9 +2,9 @@
#
# ─── WHAT THIS REPLACES ───────────────────────────────────────────────────────────────────────
#
# On Compose, `init-secrets.cjs` runs as a one-shot writing into a volume every container shares,
# and its guarantee that a key is generated exactly once is `openSync(path, "wx")` — two writers
# race, the kernel picks one. There is no shared filesystem across pods, so the exclusion moves to
# On Compose, `jarvis init-secrets` runs as a one-shot writing into a volume every container shares,
# and its guarantee that a key is generated exactly once is creating a file that must not exist yet
# (`O_EXCL`) — two writers race, the kernel picks one. There is no shared filesystem across pods, so the exclusion moves to
# the one thing every pod does share: the API server. Creating a Secret that already exists is a
# 409, decided by one serialized writer. Same guarantee, same strength.
#
@@ -50,7 +50,7 @@ rules:
# `create` AND NOTHING ELSE. No `get`, no `list`, no `update`.
#
# Deliberate, and worth the paragraph: this identity cannot read any Secret in the namespace,
# including the one it just wrote. That is why the script does not look before it writes — the
# including the one it just wrote. That is why the command does not look before it writes — the
# 409 is the check, and it is a stronger one than a read-then-write could be, because a read and
# a write are two operations and something else can happen between them.
#
@@ -122,18 +122,16 @@ spec:
type: RuntimeDefault
containers:
- name: mint
# The api image, because the script ships in it and a first deployment should pull one
# The api image, because the command ships in it and a first deployment should pull one
# image rather than three. By digest like every other image here — the same one you put
# in 03-migrate-job.yaml and 04-api.yaml.
image: git.luxit.be/luxit/jarvis-api@sha256:REPLACE_ME
command: ["node", "/app/apps/api/mint-k8s-secret.cjs"]
env:
# Node verifies the API server's certificate against the cluster CA. Without this the
# request would fail — which is the correct failure. Do not reach for
# NODE_TLS_REJECT_UNAUTHORIZED: a bearer token good enough to write Secrets is a bearer
# token worth stealing, and an unverified TLS session is where that happens.
- name: NODE_EXTRA_CA_CERTS
value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# Exec form: `jarvis` is a bash script that execs the API, and a `/bin/sh -c` (dash) in between
# would drop the image's dotted logging variables. It verifies the API server's certificate
# against the service account's own ca.crt, and trusts nothing else for it — so no variable
# names the CA (Node's NODE_EXTRA_CA_CERTS went with the TypeScript image). A bearer token good
# enough to write Secrets is a bearer token worth stealing: never turn that check off.
command: ["jarvis", "mint-k8s-secret"]
resources:
requests:
cpu: 50m