bulwark: new chart page, index, sidebar, stalwart cross-reference, and four rules it bought
The chart page leads with the two things that are not visible from outside and
that govern everything else: Bulwark is a pure CLIENT, so with the mail server
gone the release is Ready and green and nothing in it can tell; and the VOLUME
BEATS THE CHART for every value, silently, because the application resolves
"admin override > env var > default" and its admin dashboard may write any key.
Upstream documents the second only for the server URL, which is what makes it a
trap rather than a footnote.
Also on the page, each measured against the source at tag 1.12.0 rather than
taken from the documentation: the real way out of an OIDC lockout (remove the
override in the dashboard - a helm upgrade with OAUTH_ONLY=false goes through the
same precedence chain and can do nothing), the three-part price of
adminConfigReadOnly, the redirect URI that carries the UI language across 27
locales, the two-part backup statement (the volume alone is not a backup, and it
may hold the OAuth secret in cleartext), why rotation needs no restart and which
mount detail that depends on, and what the probes do and do not carry.
Charts: new row, and the counter is now measured against */Chart.yaml instead of
carried forward - it had drifted. The table also still lists convertx, for which
there is no chart directory in the repository; flagged in a note rather than
deleted, because removing it is a decision about that chart and not a
documentation fix.
Lessons learned, four entries, all of them transferable beyond this chart:
a recovery instruction that ran through the fault it was meant to repair; a
read-only switch whose write barrier also blocked the one-time bootstrap write
that creates the admin password; a probe method the platform does not offer at
all (an HTTP probe is always GET); and a 0400 secret file that only works
because the kubelet silently widens it.
keycloak: new chart page, index, sidebar, and three rules it bought
The chart page carries the values table, the vault fields, the first-install
checklist with the permanent administrator as a mandatory step, the
minor-upgrade procedure, and the traps - of which two are the point of the
page: hostname-admin is not an access control, and a shared database merges two
clusters.
Chart index counter: 30 directories / 29 installable. That follows the index
TABLE, which already lists convertx - its page landed before its PR, and
convertx/ does not exist on origin/main yet. So the number is one ahead of the
repository on purpose, as it was before this change.
Renovate: the counter-case to garage, measured rather than assumed - four tag
shapes on quay.io/keycloak/keycloak and plain docker versioning already excludes
the three unwanted ones, so that block carries no versioningTemplate. Written
down because an unnecessary constraint is not free: it reads as load-bearing to
the next person and has to stay correct as upstream's tagging changes. Plus a
section on the automerge decision: switching it off for minor and major was
proposed and declined, so the upgrade procedure is documented instead of
prevented, with the obligation that puts on whoever reviews an app-version PR.
Chart style guide section 11: a chart defaulting to more than one replica ships
a PodDisruptionBudget, and it is rendered only while the computed replica count
is >= 2 - minAvailable 1 with a single replica blocks every drain forever with a
message that names the PDB rather than the replica count.
CI/CD: the trusted-registry list for AVD-KSV-0125 is a separate file from the
ignore file on purpose, so a new registry is an entry there rather than a
suppression. quay.io joined it with this chart.
Lessons learned, two entries and three lines in the recurring shape:
- "The application that rewrites its own installation at start" - three correct
requirements that cannot start a pod together, and why the obvious repair
(an empty volume over the directory) breaks the command meant to fill it.
- "The upgrade procedure the automerge did not know about" - the general form,
which applies to any clustered application whose versions must not be mixed:
a constraint living in documentation is invisible to the machinery that
performs upgrades, and the better the pipeline, the less likely anybody is
standing in the path to notice.
garage: new chart page, index row, sidebar entry, two lessons
The page carries the values table, the first-install checklist for both paths
(self-configuring with --single-node, and the manual layout sequence) and a
traps section: the metadata gap in a volume backup, metadata_fsync being off
upstream, the two-snapshot restore window, the non-idempotency of
layout apply and why single-node mode does not have it, replication factor 1
applying to the metadata, the scratch image that rules out exec probes for
good, and why the RPC secret has to be an environment variable.
Two Lessons-Learned entries, both in their general form rather than as garage
notes: "the snapshot that was not a restore point" repeats at every embedded
database on a volume with snapshots, and "a permission check that assumes it
owns the filesystem" at every application offering a *_secret_file with a
0o077 mode test.
Chart index count 28 -> 29 directories.
stalwart: new chart page, index, sidebar and four lessons
The chart page carries the full values reference, the eight-step first
install (eight, not seven: the bootstrap wizard appears only when
config.json is ABSENT, and the chart always renders one, so a first
install goes through recovery mode) and a Traps section.
Four entries on Lessons-Learned, because none of them is specific to mail:
- The source address every NodePort quietly replaces. externalTrafficPolicy
Cluster masquerades the client address onto the node IP, and every
application that evaluates the client address meets this - bans, rate
limits, geo rules, audit logs. Includes the three traps of the PROXY
header remedy and the reason the trusted set and the probe set have to be
disjoint in Kubernetes.
- The rate limit that counted a node instead of a client. A per-IP limit in
an application is a per-node limit for probes; the arithmetic that picks
the probe intervals, and why a tcpSocket probe is the wrong escape.
- The hardening that stopped the container from starting. setcap +ep makes
the binary capability-dumb, so drop: [ALL] fails the execve itself. The
lesson is that a deviation has to be documented with its mechanism, or the
next hardening pass removes it as unused.
- The missing file that opened a database nobody meant to use. An absent
config.json opens an ephemeral in-memory store with green probes; an
unparsable one aborts. The lenient path is the one a broken mount takes.
Also on the fail-open: it covers the TASKS as well as the listeners, with
all ten enabled by default, and the error is logged after the listeners are
already bound.
convertx: new chart page, index row, sidebar entry, two lessons
The chart page follows outline.md: prerequisites, installation walkthrough,
the required 1Password field, the complete values reference and the operating
notes. No version rows, as on every chart page.
The notes it carries are the ones that cannot be read off the values:
- the chart bypasses the image entrypoint, which is what keeps the hardening
baseline intact on an image that carries no USER - together with the
obligation that creates, namely re-reading the upstream entrypoint at every
app-version bump
- uid 1000 rather than the repo's 20000, because the image owns /home/convertx
with it and the uid owns data on a PersistentVolume
- what has to be writable and why: /home/convertx is HOME, and LibreOffice is
invoked without -env:UserInstallation, so its profile can only go there
- the probes use /healthcheck; "/" is never a 200
- whoever opens the page first becomes the administrator, and
accountRegistration does not gate that
- the ingress annotation is the only upload ceiling, because the application
enforces none
- WEBROOT, PUID/PGID/UMASK and PORT do not belong in the env block
Two entries in Lessons learned, both preventive rather than post-mortem, in
the shape the valkey entries already use:
- the probe that would have passed on a redirect and meant something else a
week later - a 3xx makes an httpGet pass, so a redirecting path hides the
question instead of answering it, and the answer has to hold for every
state the application can be in
- the entrypoint we skipped, and the obligation that created - an override
forks the entrypoint silently, and a fork with no diff is a fork nobody
reviews, so the warning belongs at the line the next change will touch
Also corrected in CI-CD: the per-chart publish workflow count, which read 24
and was already one behind before this chart made it 26.
valkey: chart page, index row, sidebar entry, two lessons
The new valkey chart (helm-charts #53, issue #46): one instance per
application instead of the shared cluster-redis, whose separation rested
on a single ACL file in a single 1Password field.
The page carries what an operator cannot read off the templates: that the
1Password field auth-conf holds a finished "requirepass <password>" line
rather than a password, that uid 999 / gid 1000 are the image's own user
and why fsGroup has to match them, that maxmemory is derived from the
computed memory limit and a value above it aborts the render, and that
persistence and the eviction policy are a pair rather than two switches.
Also what the install-test does not cover: one variant per chart, and
fsGroup itself is unproven on k3d's node-directory volumes.
Two Lessons-Learned entries, both from this chart's review rather than
from an outage, because both generalize: a CLI that prints an error and
exits 0 (valkey-cli without -e, so the natural ping probe cannot fail),
and a secret whose FORMAT is load-bearing - a present-but-malformed field
yields a running server with its protection off.
sure: chart page for the new we-promise Sure chart
Adds the chart page following the outline reference (same sections, same
table shapes, the complete values reference), a row in the chart index and
the sidebar entry, and pulls the two publish-workflow counts up by one
where the new chart changes them.
One page per chart - prerequisites, installation walkthrough, the required
1Password fields, the complete values reference and the chart's operating
traps - plus the long form of the workflow, the forge and its measured
differences, the pipelines, versioning, Renovate, the chart style guide, the
procedure for a new chart, local development, and the incidents each rule was
bought with.
Chart pages quote versions as snapshots; Chart.yaml stays authoritative,
because Renovate moves app versions continuously and never edits the wiki.