Clean-room Helm charts for the QuenchWorks catalog. Every chart deploys a hardened, 0-CVE image from the images factory, pins it strictly by sha256 digest, ships as a cosign-signed OCI artifact on GHCR, and is listed on ArtifactHub as a verified publisher with a Values schema.
230+ charts. No paywall, no account, no vendor lock. Browse them all at quench-works.com/charts.
helm install cache oci://ghcr.io/quenchworks/charts/redisThat's the whole install. The image it deploys is already signed and pinned to a digest, so you don't have to track image security yourself.
Three guarantees, baked into every chart:
- Digest-pinned, always. Charts resolve images by
repository@sha256:..., never by tag. A tag-only reference is refused on purpose, so a chart physically can't ship an unpinned image. - One hardened baseline. Every chart inherits the same pod and container security context from the
quench-commonlibrary chart: nonroot, read-only root filesystem, no privilege escalation, all capabilities dropped, seccompRuntimeDefault. Fix it once, fix it everywhere. - Verifiable provenance. Charts are cosign keyless-signed, and the images they point at are signed and SBOM-carrying. You can check it all yourself.
Five families of manifest that were near-identical in every chart render from the
quench-common library rather than from a
copy in each chart: ServiceAccount, RBAC (Role/RoleBinding, optionally
cluster-scoped), PodDisruptionBudget, HorizontalPodAutoscaler and NetworkPolicy.
Fix one, fix the catalog.
Which families moved was decided by measurement, not taste — grouping all 138 charts
by rendered shape: serviceaccount.yaml 117/132 identical, poddisruptionbudget.yaml
105/123, rbac.yaml 104/123, hpa.yaml 20/23. The NetworkPolicy is shared but
parameterised, because 128 charts produced 91 distinct shapes — every app allows
different ports. service.yaml deliberately stays per-chart: 98 distinct shapes from
128 charts, since the port list is the application's identity and a helper would need
as much configuration as the manifest it replaced.
Every chart that serves HTTP has an Ingress, disabled by default:
ingress:
enabled: true
className: nginx
hosts:
- host: app.example.com # a host with no `paths` gets one "/" Prefix path
tls:
- hosts: [app.example.com]
secretName: app-tlsThe backend port is resolved from whichever service shape the chart uses, so a host is usually all you need. Enabling it with no host, or where no HTTP port can be resolved, fails the template with an explanation instead of installing something that routes nowhere.
Charts that do not speak HTTP — PostgreSQL, Redis, Kafka, MariaDB, etcd — have no
ingress knob at all. An Ingress is an HTTP router and cannot front them; expose
those with service.type=LoadBalancer or your controller's TCP passthrough. A flag
that silently did nothing would be worse than no flag.
Five umbrella stacks (observability, logging, tracing, lgtm, identity) have an
ingress of their own. They have no Service, so it fronts a subchart Service — the stack's primary UI by default (Grafana, or Keycloak for
identity-stack) — and ingress.serviceName / ingress.servicePort point it at any
other component. You can equally leave it off and enable the subchart's own ingress,
e.g. grafana.ingress.enabled=true. The other stacks have no stack-level
ingress; use their subcharts' own.
Alongside those, every chart exposes commonLabels, commonAnnotations and
podLabels (all safe to change on a live release), plus partOf, fullnameOverride,
image.registry and imagePullSecrets. selectorLabels exists too, but it feeds
spec.selector, which Kubernetes treats as immutable — set it before the first
install or every later helm upgrade fails with field is immutable.
| Category | Charts |
|---|---|
| Relational | postgresql · mariadb · mysql · cockroachdb |
| Document | couchdb · ferretdb · documentdb · postgres-documentdb · mongodb |
| Wide-column | cassandra · scylladb |
| Key-value / cache | valkey · redis · memcached · dragonfly |
| Search / vector | opensearch · solr · meilisearch · qdrant · elasticsearch |
| Time series | influxdb · victoriametrics |
| Analytical | clickhouse |
| Graph | neo4j |
| Messaging / streaming | kafka · nats · rabbitmq · pulsar |
| Coordination | etcd · zookeeper · temporal |
| Observability | prometheus · grafana · loki · tempo · otel-collector · vector · fluent-bit |
| Gateways / proxies | nginx · caddy · traefik · haproxy |
| Object storage | garage · rustfs · seaweedfs |
| Secrets / identity | openbao · keycloak |
| Registry · Git · CI/IaC | harbor · gitea · atlantis |
A stack installs several charts wired together: fixed service names, shared credentials, and the connection settings already filled in. One stack per namespace. Browse them at quench-works.com/stacks.
| Stack | What it installs |
|---|---|
observability-stack |
Prometheus, Grafana, Alertmanager, kube-state-metrics, node-exporter |
logging-stack |
Loki, Grafana, Vector |
tracing-stack |
Tempo, Grafana, an OpenTelemetry Collector gateway |
lgtm-stack |
Loki, Grafana, Tempo, VictoriaMetrics, collectors |
identity-stack |
Keycloak, PostgreSQL, oauth2-proxy |
secrets-stack |
OpenBao signing in through Keycloak |
cache-stack |
Valkey with metrics, Prometheus, Grafana |
postgres-ha-stack |
3-node Patroni PostgreSQL, PgBouncer, metrics |
streaming-stack |
Kafka, Karapace, AKHQ |
ml-stack |
JupyterHub, MLflow, Label Studio |
llm-stack |
Ollama, LiteLLM, Qdrant |
lakehouse-stack |
Trino, Nessie, SeaweedFS (Apache Iceberg) |
gitops-stack |
Argo CD, Rollouts, Workflows, Events |
sigstore-stack |
Fulcio, Rekor v2, Timestamp Authority |
backup-stack |
Velero with its AWS plugin, SeaweedFS |
ingress-stack |
ingress-nginx, cert-manager, a cluster CA issuer |
dns-stack |
PowerDNS Authoritative, external-dns, a zone Job |
supply-chain-stack |
Kyverno admitting only signed QuenchWorks images, trivy-operator |
cosign verify ghcr.io/quenchworks/charts/postgresql@sha256:DIGEST \
--certificate-identity-regexp 'https://github.com/quenchworks/.+' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comGitHub shows this single repo README on every chart's package page; it can't render a per-chart README for OCI artifacts. Each chart's own docs (values, examples, security notes) live on ArtifactHub and ship inside the chart itself:
helm show readme oci://ghcr.io/quenchworks/charts/<chart>quench/<app>/ one app chart per directory, e.g. quench/postgresql
.github/workflows/ release (lint, install, package, push) and digest repin
The shared quench-common library chart lives in its own repo, quenchworks/common, published at oci://ghcr.io/quenchworks/charts/quench-common. App charts depend on it and pull it at build time, so it isn't vendored here.
The image factory builds and signs an image, then fires an image-published dispatch to this repo. on-digest.yml repins the chart's values.yaml to the new digest and commits. That push triggers release-<app>.yml, which lints, templates, installs into a kind cluster and runs a real client roundtrip as a gate, then packages and pushes the cosign-signed OCI chart and publishes the ArtifactHub metadata.
Charts here are written from each application's own upstream documentation. They are not copied or adapted from any other vendor's charts. See CONTRIBUTING.
Most of the catalog is OSI-clean. Four charts wrap source-available datastores and carry a loud license banner in their README, NOTES, and on the website, because these are not OSI-approved open source. Each names the clean alternative we recommend instead:
| Chart | License | Clean alternative |
|---|---|---|
mongodb |
SSPL-1.0 | ferretdb + documentdb (MongoDB-wire compatible, truly open) |
elasticsearch |
SSPL-1.0 | opensearch (Apache-2.0 drop-in fork) |
cockroachdb |
BUSL-1.1 | postgresql for single-region SQL (BUSL converts to Apache after 3 years) |
dragonfly |
BUSL-1.1 | valkey (BSD-3-Clause, Redis-compatible) |
MIT for the chart templates and tooling. Each deployed application carries its own upstream license.
