github dunglas/mercure v0.23.4

latest releases: v0.23.5, caddy/v0.23.5
6 hours ago

This patch release tightens the Helm chart's defaults for high-availability and multi-tenant Mercure deployments. New opt-in NetworkPolicy and CiliumNetworkPolicy templates keep tenants and infrastructure cleanly separated, readOnlyRootFilesystem: true plus rootless runs work without changing your securityContext, and the chart now lands in line with the restricted PodSecurity Standard out of the box. Also caps the topic-selector cache to 100k entries by default to bound memory usage on busy hubs, and fixes the broken Docker image release that held back v0.23.3 (so this is the v0.23 line you actually want to upgrade to).

✨ New Features

  • Helm: Add opt-in NetworkPolicy and CiliumNetworkPolicy templates. Restrict ingress/egress per-tenant without templating policies outside the chart. The Cilium variant supports FQDN-pinned egress and L7 rules. Disabled by default; enable via networkPolicy.enabled / ciliumNetworkPolicy.enabled and supply rule lists by @dunglas in #1229
  • Helm: Support readOnlyRootFilesystem: true out of the box. /config and /tmp now mount as emptyDir unconditionally. With the default BoltDB transport, set persistence.enabled: true so /data is a writable PVC. Other transports work without persistence as long as no Caddy module writes under /data (see the known-issues note above for rate_limit). Also fixes bolt.NewBoltTransport to MkdirAll the parent directory so a fresh empty /data does not crash the hub on first write by @dunglas in #1226
  • Helm: Tighten secure-by-default settings. serviceAccount.automount: false (Mercure does not call the K8s API), enableServiceLinks: false on the hub Pod (no neighbour-Service env leak in shared namespaces), podSecurityContext.seccompProfile.type: RuntimeDefault, and a fully hardened helm test pod so helm test works on PSS-restricted clusters by @dunglas in #1231
  • Helm: Pass through HTTPRoute rule timeouts. Supply timeouts: blocks per rule when you need to bound a specific path (for instance, cap publish POSTs so a slow publisher cannot hold a gateway connection open). The chart's auto-default rule keeps timeouts.request: 0s so SSE subscribers are not cut by the gateway by @dunglas in #1223
  • Helm: Expose HPA customMetrics and behavior. Append Pods/Object/External metrics to spec.metrics and configure scaling behavior (for instance, scaleDown policies tuned for SSE workloads) by @dunglas in #1217
  • Helm: Seed replicas at minReplicas on fresh install with HPA. Avoids the 30 to 90 second under-provisioning window where Kubernetes defaulted spec.replicas: 1 before the HPA caught up by @dunglas in 8ea6a35
  • Docker: Re-apply cap_net_bind_service and ship a transport-aware HEALTHCHECK. Lets docker run --user 1000 bind 80/443 without losing the file capability the upstream caddy:2-alpine binary ships with. The new HEALTHCHECK hits /mercure/health/ready on the admin API instead of the deprecated /healthz by @dunglas in #1222. (Note: the setcap line is removed in v0.23.5 because modern container runtimes set ip_unprivileged_port_start=0, and the file capability conflicted with restrictive K8s securityContexts — see the known-issues note above.)
  • Examples: Harden the chat demo chart and refresh dependencies. Moves to python:3.13-slim + gunicorn (replacing the unmaintained tiangolo/meinheld-gunicorn), bumps Flask to 3.0, PyJWT to 2.10, and uritemplate to 4.1, ships a NetworkPolicy template, runs the pod non-root on a read-only rootfs, and adds an HTTPRoute alongside the Ingress by @dunglas in #1227, #1228

🐛 Bug Fixes

  • Cache: Cap the default topic-selector cache to 100k entries. The previous default (2.56M) could reach ~256MB at ~100B per entry on busy hubs, putting Go's runtime in a gcBgMarkWorker thrashing loop near GOMEMLIMIT. Resize per workload via topic_selector_cache in the Caddyfile (set to -1 to disable entirely) by @dunglas in 8b24ffd
  • CI: Restore the multi-arch Docker image build. v0.23.3's release failed at RUN setcap because the linux/arm64 image build was not getting QEMU registered on the amd64 runner. Heads-up: v0.23.3 is an orphan tag; upgrade directly from v0.23.2 to v0.23.4 by @dunglas in #1232

📖 Documentation

  • Helm: Correct the rootless deployment example. Binding 80/443 from a securityContext with allowPrivilegeEscalation: false requires the binary to bind on an unprivileged port (or on a runtime with ip_unprivileged_port_start=0, which is the default on containerd 1.5+ and Docker 20.10+). Recommend service.targetPort: 8080 as a portable workaround by @dunglas in #1230

The hardening defaults in this release matter most for HA and multi-tenant Mercure deployments, where pod-to-pod isolation, a restricted PodSecurity profile, and conservative cache bounds are not optional. Mercure Cloud tenants already run with every default in this release applied for them, because we manage the cluster on their behalf, alongside the production transports (Redis, Kafka, Pulsar, Postgres) and an SLA-backed managed offering. Mercure Enterprise brings the same hardening on-premise plus the HA transports and priority support. Contact contact@mercure.rocks for the managed cloud offering, on-premise licenses, custom development, consulting, and training.

Full Changelog: v0.23.2...v0.23.4

Don't miss a new mercure release

NewReleases is sending notifications on new releases.