Harthelm 1.3.0
What changed in Harthelm 1.3.0: Valkey, MariaDB, RabbitMQ and S3 object storage as managed services next to PostgreSQL, a managed service's secret as its own variable, in-cluster TLS for managed services.
Released 2026-10-14. API version 0.11.2. A minor release with one database migration, which only adds. Nothing needs to be done before the upgrade, but read Before you upgrade: every PostgreSQL database restarts once, and team quotas now count managed services at their full plan.
helm upgrade harthelm oci://<your registry>/charts/harthelm --version 1.3.0 -n harthelm-system -f my-values.yamlBefore you upgrade
- Every PostgreSQL database restarts once during the upgrade, for a few seconds. Its image is now pinned by tag and digest (PostgreSQL 17.11 and 18.6), so its minor version moves only with a Harthelm release, and each such release restarts the databases once. The services bound to a database no longer restart with it (Fixed).
- The platform database restarts too. The console and the API are unavailable for about 30 seconds while it moves to its pinned image (PostgreSQL 18.6); workspaces and services keep running.
- A team's quota counts a managed service at its full plan, CPU and memory, because its pods request the whole
plan. Before, it counted only the share that workspaces and services request (by default 20 % of the CPU and 50 %
of the memory), so the API could accept a database that Kubernetes then refused. Teams with several managed
services may now reach their quota earlier: running services keep running, but creating, resuming or growing one
can be refused with
quota-exceeded. A cluster admin raises one team's quota on its Settings → Quota, andteams.quotasets the default (Quotas).
New
Four more managed services. Next to PostgreSQL, the catalog offers four more providers, all on by default:
| Provider | In the console | What you get | Versions |
|---|---|---|---|
valkey | Valkey (Redis-compatible) | a cache or job queue; Redis clients read its redis:// URL unchanged | 9.1 |
mariadb | MariaDB | a database with its user, mysql:// URL and a JDBC URL in its details | 12.3, 11.8 (default), 11.4 |
rabbitmq | RabbitMQ | a message broker with its own virtual host and user, amqp:// URL | 4.3 |
s3 | S3 object storage | an S3-compatible store on SeaweedFS with the buckets you list | one SeaweedFS release per Harthelm release |
Each works like PostgreSQL: create it from the Catalog or as a type: managed service in harthelm.yml,
Rotate its secret, and a workspace's Teardown pauses it while its data stays. Each is dumped every night
unless you turn backups off, and each runs on air-gapped installations: its images are in images.txt. Every
instance is one server, without replicas. See Managed services for the
plans and settings.
- Valkey keeps its data as snapshots (
persistence: rdb, the default), writes every change to a log (aof), or keeps it in memory only (none: a restart or a pause empties it, and the console warns).maxmemoryPolicydecides what happens when the memory is full. - MariaDB moves to a newer series in place: change
mariadbVersionfrom 11.4 to 11.8 or 12.3, or from 11.8 to 12.3. It never goes back, so dump it first; the console's confirmation offers Dump now. - RabbitMQ creates quorum queues by default (
defaultQueueType;classicuses less memory). Its nightly backup keeps the topology (virtual host, users, queues, exchanges, bindings, policies), not the messages in the queues. When a later release stops shipping a series, Harthelm moves each broker to the next series by itself after a dump; that release's notes say so. - S3 object storage creates the buckets you list in
buckets(up to 20, defaultdata);publicBucketsmakes some readable without a key, andbucketQuotaMiBcaps each bucket. A bucket you remove from the list keeps its objects. Use path-style requests. Its nightly backup reads only the objects that changed since the last one.
${{ services.<name>.secret }}. A service reads a managed service's secret on its own: the password of PostgreSQL,
MariaDB, Valkey and RabbitMQ, the secret access key of S3. Unlike ${{ secrets.<key> }} it follows a
Rotate without a new Sync: the services that use it restart once the new value works.
web:
env:
AWS_ENDPOINT_URL: ${{ services.files.dsn }}
AWS_ACCESS_KEY_ID: ${{ services.files.details.accessKeyId }}
AWS_SECRET_ACCESS_KEY: ${{ services.files.secret }}In-cluster TLS for Valkey, RabbitMQ and MariaDB. Where in-cluster TLS is on and cert-manager is installed, each
instance gets a certificate of the installation's internal CA. Valkey also listens with TLS on 6380, RabbitMQ on 5671
(AMQPS) and 15671 (its management API over HTTPS), and MariaDB offers TLS on its port 3306. The connection URLs stay
plain, so apps connect as before; an app that wants TLS uses the TLS port and trusts the internal CA
($HART_INTERNAL_CA_FILE in a workspace). The nightly backups then always use TLS. A new instance waits for its
certificate before it starts (at most two minutes), and a renewal, about every 75 days, restarts the server for a
few seconds. S3 has no in-cluster TLS in 1.3.
S3 for browsers. Presigned URLs work through a forward service with
one route per bucket, each without strip, and your dev domain as the endpoint. Keys with a space, +, % or a
non-ASCII character work only on such routes, not behind a path prefix. See
Managed services.
Changed
- No browser-facing routes for managed services in 1.3. Reach RabbitMQ's management UI and S3 from a workspace,
with a port-forward, or through a
forwardservice behind your workspace's sign-in; see Managed services. - Managed services no longer reach the internet. Their pods reach their own team's namespace and DNS; nothing is downloaded at runtime.
- A plan that needs a bigger volume on a storage class that cannot grow volumes is refused up front: the Sync
reports
update-constraintat the plan ("the storage class … cannot grow volumes; choose a plan with at most … or move the data to a new instance"), the API answers 422volume-cannot-grow. Before, the change was accepted and the volume kept its size. - The Rotate dialog names the references that restart with the new secret, such as
${{ services.db.dsn }}and${{ services.db.secret }}.
Fixed
- A database restart no longer restarts the services bound to it. A managed database that restarted (after an upgrade, a node drain) restarted every service that used it, twice. Now they restart only when the connection itself changes: another host, port or user, or an applied Rotate.
- IDE terminals always start bash. The editor's first window opened bash, every later window
sh, without your.bashrcand what it sets up, such as the mirrors and the note on the Git identity.
For operators
The four new providers have one shape of values each, marketplace.builtin.valkey, .mariadb, .rabbitmq and
.s3: enabled, the images pinned by tag and digest, storageClass, scheduling, overrides, and podMonitor for
RabbitMQ and S3. Their volumes are ReadWriteOnce on the class you name, or the default class; the pods run as
security.defaultUid with that number as their primary group and fsGroup, so NFS servers with manage-gids work.
See Managed services.
Images from Docker Hub. The Valkey, MariaDB and RabbitMQ images come from Docker Hub, whose anonymous pulls are
rate-limited per address. A cluster that creates many instances at once, or restarts them all at an upgrade, wants a
login there (global.imagePullSecrets) or a
mirror. images.txt and mirror.sh include every built-in provider's images.
hart admin doctor has four new checks: managed-images (each image's digest resolves), managed-storage (the
classes allow volume expansion), managed-backups (the backup pods reach every enabled service, and every instance
with backups on has a dump of the last 26 hours) and managed-tls (the certificates are issued and renewed).
--capabilities lists managed-valkey, managed-mariadb, managed-rabbitmq and managed-s3.
Permissions. Core manages StatefulSets (the new providers' servers), and it may delete a managed service's pod that is stuck at an older revision and not ready; the admission guard allows that delete for managed-service pods only. The chart grants both.
Backups. The backup pods reach the new services' ports (and their TLS ports). A MariaDB instance is dumped with
the client of its own server image, in a Job that core starts after the nightly run. An S3 snapshot is a list of
objects plus their contents, which the snapshots of an instance share; an instance larger than
backup.managed.s3.maxBytes (100 GiB by
default) is recorded as a failed dump. See Backups and restore.
API 0.11.2. The change rule upgrade-only for a provider's version field (a newer version, a newer major too,
never a lower one), and the 422 volume-cannot-grow of
PATCH /managed-services/{ms}. Provider definitions may mark
details that change while an instance runs with x-hart-volatile: true: a change of their value does not restart
the services that use the instance. The migration adds a warning to backup records (a RabbitMQ dump that found
feature flags not enabled).
Changed values
| Value | Change |
|---|---|
marketplace.builtin.valkey, .mariadb, .rabbitmq, .s3 | New, on by default. enabled: false hides a provider from the catalog; its existing instances keep running. |
marketplace.builtin.postgres.images | The default images are now pinned by tag and digest (17.11 and 18.6). |
database.bundled.smartShutdownTimeout | New, default 15 seconds: how long the bundled database waits for open sessions when it restarts. It keeps the outage of an upgrade short. |
backup.managed.s3.maxBytes | New, default 100 GiB: the largest S3 instance the nightly backup copies; 0 for no limit. |
Harthelm 1.4.0
What changed in Harthelm 1.4.0: browser hosts for RabbitMQ and S3 with single sign-on to RabbitMQ's management UI and public S3 stores, in-cluster TLS for S3, safer S3 backups, the restore runbooks as a release asset, three new doctor checks.
Harthelm 1.2.2
What changed in Harthelm 1.2.2: an email address goes onto a commit only when your sign-in provider verified it.