From fabca0477188b3e4713b27c71f11a7022e8a3add Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Fri, 1 May 2026 17:40:03 -0700 Subject: [PATCH] Mirror valkey 8.1 locally for paperless and immich (#346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add native Dagger build of valkey 8.1.6-r0 on Alpine 3.22 at `containers/valkey/` - Swap paperless redis sidecar and immich-valkey from `docker.io/valkey/valkey:8.1-alpine` to `registry.ops.eblu.me/blumeops/valkey:v8.1.6-r0-946fa75` - Resolves the DR-2026-04 TODO in paperless kustomization about multi-arch redis ## Why Move toward fully locally-built containers for supply chain control. Paperless and immich both pulled the same upstream tag — one mirror serves both. Authentik's nix-built Redis stays separate (different image entirely). ## Risk Low. Both sidecars are stateless caches: - paperless redis: no volumeMount (in-pod localhost, pure memory) - immich-valkey: `emptyDir` (cache only) Pod restart rebuilds the cache. Smoke-tested locally (PING/SET/GET roundtrip on `valkey 8.1.6` with `--bind 0.0.0.0 --protected-mode no`). ## Test plan - [ ] After merge: `mise run container-build-and-release valkey` to rebuild with main SHA - [ ] Update kustomizations to the `[main]` SHA tag (C0 follow-up) - [ ] `argocd app sync paperless` and `argocd app sync immich` - [ ] Verify pods come up healthy (paperless OCR queue functional, immich job queue functional) - [ ] `mise run services-check` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://forge.eblu.me/eblume/blumeops/pulls/346 --- argocd/manifests/immich/kustomization.yaml | 3 +- argocd/manifests/paperless/kustomization.yaml | 7 +-- containers/valkey/container.py | 47 +++++++++++++++++++ docs/changelog.d/valkey-mirror.infra.md | 1 + service-versions.yaml | 12 +++++ 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 containers/valkey/container.py create mode 100644 docs/changelog.d/valkey-mirror.infra.md diff --git a/argocd/manifests/immich/kustomization.yaml b/argocd/manifests/immich/kustomization.yaml index c7c54e1..399a975 100644 --- a/argocd/manifests/immich/kustomization.yaml +++ b/argocd/manifests/immich/kustomization.yaml @@ -19,4 +19,5 @@ images: - name: ghcr.io/immich-app/immich-machine-learning newTag: v2.6.3 - name: docker.io/valkey/valkey - newTag: "8.1-alpine" + newName: registry.ops.eblu.me/blumeops/valkey + newTag: v8.1.6-r0-946fa75 diff --git a/argocd/manifests/paperless/kustomization.yaml b/argocd/manifests/paperless/kustomization.yaml index 3e65578..4e1f658 100644 --- a/argocd/manifests/paperless/kustomization.yaml +++ b/argocd/manifests/paperless/kustomization.yaml @@ -14,9 +14,6 @@ resources: images: - name: registry.ops.eblu.me/blumeops/paperless newTag: v2.20.13-07f52e9 - # TODO(DR-2026-04): authentik-redis is amd64-only (nix-built on ringtail). - # Was running under QEMU emulation before. Switched to upstream valkey - # during DR recovery. Build a multi-arch blumeops/redis or keep upstream. - name: docker.io/library/redis - newName: docker.io/valkey/valkey - newTag: "8.1-alpine" + newName: registry.ops.eblu.me/blumeops/valkey + newTag: v8.1.6-r0-946fa75 diff --git a/containers/valkey/container.py b/containers/valkey/container.py new file mode 100644 index 0000000..5d150e7 --- /dev/null +++ b/containers/valkey/container.py @@ -0,0 +1,47 @@ +"""Valkey — native Dagger build. + +Alpine 3.22 base with the `valkey` apk package (8.1.x — Redis-compatible). +Mirrors `docker.io/valkey/valkey:8.1-alpine`, used by paperless and immich +as a cache/queue sidecar. +""" + +import dagger +from dagger import dag + +from blumeops.containers import oci_labels + +# Alpine 3.22 ships valkey 8.1.6-r0. Alpine 3.23 jumps to 9.0 — hold on 3.22 +# to keep this a 1:1 swap for the upstream `valkey:8.1-alpine` image. +VERSION = "8.1.6-r0" + +ALPINE_BASE = "alpine:3.22" + + +async def build(src: dagger.Directory) -> dagger.Container: + ctr = ( + dag.container() + .from_(ALPINE_BASE) + .with_exec(["apk", "add", "--no-cache", f"valkey={VERSION}"]) + .with_exec(["mkdir", "-p", "/data"]) + .with_exec(["chown", "valkey:valkey", "/data"]) + .with_workdir("/data") + .with_exposed_port(6379) + .with_user("valkey") + .with_default_args( + args=[ + "valkey-server", + "--bind", + "0.0.0.0", + "--protected-mode", + "no", + "--dir", + "/data", + ] + ) + ) + return oci_labels( + ctr, + title="Valkey", + description="Valkey high-performance key/value datastore (Redis-compatible)", + version=VERSION, + ) diff --git a/docs/changelog.d/valkey-mirror.infra.md b/docs/changelog.d/valkey-mirror.infra.md new file mode 100644 index 0000000..06f8d98 --- /dev/null +++ b/docs/changelog.d/valkey-mirror.infra.md @@ -0,0 +1 @@ +Mirror Valkey 8.1 locally as `registry.ops.eblu.me/blumeops/valkey`. Replaces direct pulls of `docker.io/valkey/valkey:8.1-alpine` for paperless and immich sidecars. Built via native Dagger pipeline on Alpine 3.22. Stateless swap — no data migration. Authentik's nix-built Redis remains separate. diff --git a/service-versions.yaml b/service-versions.yaml index 42f9c77..76c0655 100644 --- a/service-versions.yaml +++ b/service-versions.yaml @@ -125,6 +125,18 @@ services: upstream-source: https://github.com/immich-app/immich/releases notes: Kustomize manifests with upstream images + - name: valkey + type: argocd + last-reviewed: 2026-05-01 + current-version: "8.1.6-r0" + upstream-source: https://pkgs.alpinelinux.org/package/v3.22/community/aarch64/valkey + notes: >- + Shared Alpine-built valkey image, used as a sidecar/cache by paperless + (sidecar) and immich (separate Deployment). Mirrors the upstream + docker.io/valkey/valkey:8.1-alpine. Pinned to Alpine 3.22 for valkey 8.1.x; + Alpine 3.23 jumps to 9.0. Distinct from authentik-redis (nix-built Redis + 8.x) which has its own entry. + - name: external-secrets type: argocd last-reviewed: 2026-03-25