Skip to content
Dekglas
Marolum documentation

Upgrades and versioning

What a release is, how to verify one, the support window, and the upgrade and rollback procedure.

Upgrades and versioning

What a version is

A Marolum version is MAJOR.MINOR.PATCH, optionally with a prerelease suffix such as -rc.1. Version syntax does not establish supported availability; only the matching supported.json record does. The version field has no leading v or build metadata; website directories add v as their path prefix. The mutable, multi-architecture latest tag is a convenience alias that Dekglas moves by hand. It may point at an earlier version than the newest one published, or at an evaluation candidate. It is not a support status; check that version's tester.json or supported.json. Public dev and branch-named tags are not offered. The frozen v0.20.2 documentation predates the latest alias decision; this current guide describes it.

Pin the digest. A version tag is immutable on Docker Hub; the digest identifies the exact image bytes. Tester availability does not establish a supported release. The release packet names the accepted version, source, image digest and documentation revision.

What a release publishes

Each release has an immutable directory at https://www.dekglas.com/downloads/marolum/v<version>/. No later release replaces its bytes:

  • release.json binds the version, source revision, Docker Hub image index and platform digests, matching CLI, verification metadata and the documentation revision.
  • publication.json inventories the immutable published files by SHA-256. Image composition and verification references are embedded in release.json.
  • marolum-cli-<version>.tgz and SHA256SUMS let you fetch and verify the CLI without a GitHub account or repository access.
  • Release-specific documentation and compatibility preserve the instructions and limits reviewed with those artifacts while the current website documentation evolves.

Use the exact version in your release or tester packet. A missing download is unavailable; never substitute a moving tag, guessed version or unrelated CLI. The same immutable artifact record can first be offered for testing and later accepted for supported use. Acceptance and announcement are separate decisions and do not rebuild the artifacts.

The composition record

Every release record embeds a machine-derived account of what the image is made of: the source commit; the image index and per-platform digests, the pinned base image, and the Node.js version; the resolved version of every production dependency, including the embedded SQLite version; SBOM and provenance references; and verifiedAgainst: only the surfaces this release was actually tested against (Pulumi CLI versions, deployment schema versions, object store targets, browsers).

No field is hand-authored, and verifiedAgainst is a test record, not a compatibility promise. A surface that is listed was exercised; that is all it claims.

Verify what you pull

Published digests are keylessly signed with the applicable tester or supported-release workflow's GitHub OIDC identity. Verify before you run:

cosign verify \
  --certificate-identity-regexp '^https://github\.com/dekglas/application/\.github/workflows/(publish-tester-candidate|promote-public-release)\.yml@refs/heads/master$' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  'docker.io/dekglas/marolum@sha256:<digest>'

Only the release workflow identity named by the versioned verification metadata is trusted. A tester packet must identify its tester-publication signer; do not treat an arbitrary GitHub workflow or a signature alone as supported-release acceptance.

The image is built once in a private candidate boundary and promoted by copying the exact reviewed digest; it is never rebuilt for publication. The candidate build scans both architectures and rejects fixed high or critical findings before promotion.

Support window

Only the newest release explicitly accepted for supported use is supported. A tester record alone does not provide support status. There are no maintenance lines and no backports: a fix, including a security fix, ships as a new release at the head of the line, and upgrading is the supported way to receive it. A prerelease is superseded by any later release.

Compatibility

Surface Contract
Image One edition-neutral, multi-architecture (linux/amd64, linux/arm64) OCI image per release
Browser API Versioned under /api/v1; UI-internal routes carry no compatibility promise
Ingestion API /api/v1/ingestion/…, bearer-token only; stable within a major version
Health and diagnostics /api/v1/health, /api/v1/readiness, /api/v1/storage-health, /api/v1/observation-polling, /api/v1/object-store-traffic; fields may be added within a major
Backend configuration schemaVersion: 1; unknown fields rejected atomically
Export document marolum-operation-history-export, schema version 10
Database schema Migrated forward at startup, transactionally; an older image refuses a newer schema

Supported automation surfaces (the ingestion API, the health probes, and the documented diagnostics) change incompatibly only in a new major version, after a release whose notes named the deprecation. Everything else under /api/v1 serves the shipped console and may change in any release without notice; automation built against it is unsupported.

Release notes

Every release's notes enumerate capability additions, changes, and removals; every schema migration the release applies with its risk class; any deprecation; and the delta to Known limitations. Release notes collects them by version. Read them before upgrading, particularly the migration list; a gated migration changes the procedure below.

Upgrade procedure

SQLite

  1. Read the release notes.
  2. Stop the replica cleanly: docker stop -t 30 marolum (or docker compose stop). A clean stop checkpoints the WAL and leaves no -wal or -shm sidecar. Exit code 143 is expected.
  3. Take and verify a cold backup. This step is mandatory, because rollback is a restore.
  4. Start the new digest against the same volume.
  5. Confirm /api/v1/readiness returns 200 and the console loads.

If the new image refuses to start because the upgrade carries a gated migration, nothing has been migrated. The log line names the revision and the authorization value; follow Gated migrations: start once with MAROLUM_SCHEMA_UPGRADE_APPLY=<revision>, confirm readiness, remove the variable.

Before choosing which image to start, you can read which release last migrated a stopped volume; see Reading the version stamp.

PostgreSQL, one replica

Same steps; the backup is your database tooling's backup (a base backup or pg_dump), taken while Marolum is stopped.

PostgreSQL, Enterprise replicas

Only startup-safe migrations permit a rolling deployment. When the release notes list a gated migration, scale to one replica, apply it as above, then scale back out. Migrations have one owner; waiting replicas reread the committed schema lineage. After restoring PostgreSQL, restart every replica.

Rollback

Upgrades are forward-only. An older image started against a database a newer one migrated exits with the database schema (…) is newer than this image supports (…), naming both revisions and touching nothing. That refusal is the design. When the newer release applied no migration, as 0.21.1 does after 0.20.2, there is nothing to refuse: the older image starts and the version stamp then names it. Rolling back is still a restore.

Rolling back a committed upgrade means:

  1. Stop and remove the replica.
  2. Restore the pre-upgrade backup per Backup and disaster recovery.
  3. Start the older image against the restored file.

Evidence accepted between the upgrade and the rollback is lost with the restore; backends converge forward on the next observation cycle.

Edition downgrade

A license lapse or downgrade never deletes evidence, changes an effective retention policy, or hides history. The rule: a license may gate an act, never a state. A downgrade may refuse to place a new legal hold but never releases one; may refuse to enable state retention for a new backend but never deletes an artifact; may refuse to begin a new PostgreSQL cutover but never migrates or locks an installation already on PostgreSQL. Custom roles stop being assignable and their holders fall back to viewer; existing stack grants keep narrowing reads; configured federated sign-in remains available, including connections beyond the new edition's allowance.

Safe diagnostics for a report

Only Marolum-authored lines in a documented closed format are safe to share. Include the log line verbatim, closed reason codes, HTTP status codes, the version and digest, the schema revision from the version stamp, and readiness and storage-health results. Never include the database, a backup, an export, Pulumi state, or a credential. See Troubleshooting.