blumeops/containers/valkey/container.py
Erich Blume fabca04771 Mirror valkey 8.1 locally for paperless and immich (#346)
## 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: #346
2026-05-01 17:40:03 -07:00

47 lines
1.3 KiB
Python

"""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,
)