Skip to content

Releases: heyvaldemar/zammad-traefik-letsencrypt-docker-compose

v1.7.6

Choose a tag to compare

@heyvaldemar heyvaldemar released this 23 Sep 21:24

Changed

  • The freshness check has its own workflow, Pin Freshness. It ran inside Deployment Verification, whose badge is the one at the top of this README. Across the fleet, nine red runs in ten were a pin one version behind - which the fleet's triage moves within the day - and a reader cannot tell that from a stack that does not boot. The badge now says whether the stack boots. The job itself is unchanged.
  • ghcr.io/zammad/zammad:7.1.3 moved to ghcr.io/zammad/zammad:7.2.0. The freshness check reported the lag; the deploy job booted the stack on the new image before this landed.

Upgrading

git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.

Full history in CHANGELOG.md.

What upstream changed

Read by fleet triage from the upstream release notes (or the commits between the tags) against this compose file, before the bump was applied.

Upstream changes 7.1.3 -> 7.2.0

Verdict: SAFE TO APPLY — the compose file's pinned Elasticsearch (8.19.20) already satisfies the new minimum the notes require, and no other breaking change needs host action beyond an index rebuild and a routing-scheme check.

Breaking changes

  • Elasticsearch 7 is no longer supported, 8.15 is the new minimum. "the supported range is now Elasticsearch 8.15 up to, but not including, 10 ... Upgrade the Elasticsearch installation to 8.15 or newer before updating to Zammad 7.2." This compose file already pins elasticsearch:8.19.20, so it satisfies the requirement — but this is exactly the class of mismatch this review watches for, and it is fine here only because the pin was already compliant.
  • Reverse proxy scheme handling changed. "The Docker images rebuild their nginx configuration from the shipped one on every start, so the change applies to them automatically ... If Zammad was reachable over HTTPS only because the proxy in front of it sent Forwarded or X-Forwarded-Ssl ... configure the scheme in Zammad's own web server instead: set NGINX_SERVER_SCHEME=https." This compose file already sets NGINX_SERVER_SCHEME: https explicitly on the zammad service, and Traefik terminates TLS in front of it, so this should be unaffected — but verify after upgrade that login still works, since the notes also record Fixes #6305 - CSRF token verification failure during login after updating to Zammad 7.1 as a related regression that was still being patched in this range.
  • Elasticsearch index gains a new field. "The 'Suggested searches' shortcut menu added to the Knowledge Base search introduced a new publication_state field ... Existing indices do not contain the field ... Rebuild the search index after the update: zammad run rake zammad:searchindex:rebuild"
  • Self-links rejected, link-add endpoint now reports failures correctly. "A rejected link now answers 422 Unprocessable Content ... Update integrations that treat every response of the endpoint as a success." Only relevant if something automates /api/v1/links/add.
  • Out-of-range dates now rejected on write. "Saving a value like 20026-08-18 now fails with the validation error 'must have a year between 1 and 9999' ... correct existing out-of-range dates to make the affected records findable again." Only actionable if such data exists.
  • Stricter default CSP (frame-ancestors 'self'). "Setups that previously re-enabled embedding by overriding the X-Frame-Options header at the reverse proxy are blocked again by it." Only relevant if Zammad is iframe-embedded elsewhere.

Variables

None renamed or newly required for this compose file. (The commit log mentions a MALLOC_ARENA_MAX/ZAMMAD_RUBY_MALLOC_ARENA_MAX naming fix, but that variable is not set in this compose file or .env.example, so nothing to change here.)

Data and dependencies

  • Elasticsearch minimum raised to 8.15 (see above) — already satisfied by the pinned 8.19.20.
  • No database version requirement changes noted for PostgreSQL.
  • No changed ports, volumes, or paths in the notes.

Before applying

  • Take the routine backup before any Zammad upgrade (the backup service in this stack, or an equivalent snapshot).
  • After the upgrade completes, run: zammad run rake zammad:searchindex:rebuild to pick up the new publication_state field.
  • Confirm login still works post-upgrade given the scheme-handling change and the #6305 CSRF fix landing in this range; this stack's NGINX_SERVER_SCHEME: https setting is already correct, so this is a smoke test, not a config change.
  • If any user- or organization-facing dates were ever set outside the year 1–9999, expect saves on those records to start failing with a validation error; find and correct them if so.

WHAT THE IMAGES THEMSELVES DIFFER IN

  • New GEM_PATH, LD_PRELOAD (libjemalloc.so.2), and ZAMMAD_DOCKER=true environment defaults, and an updated PATH prepending /usr/local/bundle/ruby/current/bin. These line up with the commit log entry "Maintenance: switch Dockerfile to jemalloc as recommended by Rails" — an internal memory-allocator change, not something this compose file overrides or needs to react to. No action required; noted for completeness since it is a genuine image-level difference the notes only partially describe (jemalloc is mentioned; the GEM_PATH/PATH/ZAMMAD_DOCKER env additions are not).

Notes read

  • Commit log (compare API) between 7.1.3 and 7.2.0 for zammad/zammad — no dedicated GitHub release notes exist for these tags.
  • BREAKING_CHANGES.md, sections "Upcoming releases", "7.2", and "7.1" (the range being moved through); earlier sections (7.0 and below) were skipped as out of range.

v1.7.5

Choose a tag to compare

@heyvaldemar heyvaldemar released this 21 Sep 18:31

Security

  • postgres:17-alpine was rebuilt upstream; the pin moved from sha256:f02121de6f74… to sha256:b0f9560a2de0…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
  • traefik:3.7 was rebuilt upstream; the pin moved from sha256:1c32e7c36820… to sha256:24841fe2de73…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.

Upgrading

git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.

Full history in CHANGELOG.md.

v1.7.4

Choose a tag to compare

@heyvaldemar heyvaldemar released this 19 Sep 16:15

Security

  • redis:7.4 was rebuilt upstream; the pin moved from sha256:71da9275c5f3… to sha256:c6eabf748fc7…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
  • memcached:1.6-alpine was rebuilt upstream; the pin moved from sha256:69ecd3c5701c… to sha256:9e4de012dc60…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.

Upgrading

git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.

Full history in CHANGELOG.md.

v1.7.3

Choose a tag to compare

@heyvaldemar heyvaldemar released this 18 Sep 14:55

Security

  • postgres:17-alpine was rebuilt upstream; the pin moved from sha256:18cfe3ef5e68… to sha256:f02121de6f74…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
  • memcached:1.6-alpine was rebuilt upstream; the pin moved from sha256:c29847751abb… to sha256:69ecd3c5701c…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.
  • traefik:3.7 was rebuilt upstream; the pin moved from sha256:f86a2cab1b5c… to sha256:1c32e7c36820…. Same version, same tag, a rebuilt base image — the usual shape of a security fix in a base layer.

Upgrading

git pull (or ./update.sh), then docker compose up -d. Containers on a refreshed image are recreated; data volumes and .env are untouched. This release was cut by fleet triage after the deploy job booted the stack on the refreshed images.

Full history in CHANGELOG.md.

v1.7.2

Choose a tag to compare

@heyvaldemar heyvaldemar released this 14 Sep 17:15

The restore roundtrip loaded the dump into a throwaway database of the same image, counted the tables, and passed if there were more than ten.

Ten is a number written in the test. It passes for a dump that restored a fifth of the schema, and it keeps passing as the application grows and the real number moves away from it.

The running stack knows how many tables it has. Asking it means the comparison stays true as the schema changes, and a partial restore fails instead of being blessed by a threshold nobody revisits. When the counts differ, the failure names the tables that did not come back.

A live schema the test cannot read is a failure rather than a pass: this check must not be able to succeed by failing to look.

Upgrading: git pull or ./update.sh. Nothing in the running stack changes — this is the test suite.

v1.7.1

Choose a tag to compare

@heyvaldemar heyvaldemar released this 07 Sep 20:51

Changed

  • update.sh names any new required variable before it moves. An update can add a required variable; docker compose up used to stop on it after the checkout, with the tree already on the new tag. The script now lists the variables that appeared in .env.example since your version and refuses, before anything has moved, when a required one is not in your .env. Names only, never values.

Upgrading

git pull (or ./update.sh). Nothing running changes: this release adds or extends the update script and touches no image pin.

Full history in CHANGELOG.md.

v1.7.0

Choose a tag to compare

@heyvaldemar heyvaldemar released this 06 Sep 01:46

Fixed

  • A backup interrupted halfway no longer looks like a finished one. The
    backup script writes the dump and the file archive under a .partial name
    and renames each only once its write has succeeded. It already renamed a
    failed file to .failed, but that branch only runs if the shell lives long
    enough to reach it — a container stopped mid-dump does not, and left a
    truncated file under exactly the name a restore would pick. The rest of the
    fleet was fixed for this on 4 September; this repository was missed, because
    its loop lives in scripts/backup.sh rather than in the compose file.
  • Pruning now removes .partial and .failed files too, and no longer
    depends on a glob expanding.

Added

  • Backup and restore tested end to end, nine assertions against the live
    stack, driven through the script's own one-shot entrypoints rather than its
    daily schedule. The dump is a complete gzip containing real SQL, the file
    archive lists, no .partial survives a completed cycle, and the dump
    restores into a throwaway database built from the same image as the live one
    with zero SQL errors and a real schema.
  • The failure case is exercised, not assumed. A dump pointed at an
    unreachable database must be reported as failed, must leave nothing under a
    name a restore would choose, and must keep the partial file as .failed for
    diagnosis.

v1.6.0

Choose a tag to compare

@heyvaldemar heyvaldemar released this 05 Sep 03:27

Added

  • A shutdown grace period for PostgreSQL and Redis. Docker stops a container with
    SIGTERM and ten seconds, then SIGKILL. That default is not always enough:
    PostgreSQL has a checkpoint to write, MariaDB has InnoDB to flush, and Redis
    saves its dataset on the way out. Killed halfway, the next start does crash
    recovery, and a Redis holding another application's file locks leaves them
    behind for a person to clear by hand. Sixty seconds now, overridable per
    service with <PREFIX>_STOP_GRACE_PERIOD in .env. The backup sidecar is
    deliberately left alone: its failure mode is a truncated dump file, which a
    longer grace period does not fix.

v1.5.0

Choose a tag to compare

@heyvaldemar heyvaldemar released this 03 Sep 14:43

Added

  • Per-image version overrides. Every pin in the x-images block is
    now ${<PREFIX>_IMAGE_TAG:-repo:${<PREFIX>_IMAGE_VERSION:-tag@sha256:digest}}.
    Set <PREFIX>_IMAGE_VERSION in .env to run a different version of one
    image while every other pin stays as tested (Compose pulls that tag
    without a digest), or <PREFIX>_IMAGE_TAG to replace the whole
    reference as before. A deployment that sets neither is unchanged. The
    freshness job, the Trivy matrix and the fleet digest automation resolve
    the nested default before reading a pin. Needs Docker Compose v2.5 or
    newer (2022): v2.0 to v2.4 leave the inner ${...} unexpanded and
    docker compose up fails with an invalid reference instead of
    deploying something unexpected.

Upgrading

git pull (or ./update.sh). A deployment that sets no _IMAGE_VERSION or _IMAGE_TAG variable renders exactly the same image references as before, so docker compose up -d recreates nothing. Requires Docker Compose v2.5 or newer.

Full history in CHANGELOG.md.

v1.4.0

Choose a tag to compare

@heyvaldemar heyvaldemar released this 03 Sep 04:31

Security

  • Container hardening. Every service runs with
    security_opt: no-new-privileges:true (no privilege escalation via
    setuid binaries even if a process escapes its initial capability
    set). Infrastructure containers (the reverse proxy, databases,
    caches, backups) drop every Linux capability and add back only what
    their entrypoints need (bind :80/:443, chown a data directory, drop to
    the service user). Application containers keep the default capability
    set: upstream images assume it, and a wrong guess there is a boot loop
    in production, not a hardening win. CI boots the stack under these
    settings on every push.

Upgrading

git pull and docker compose up -d (or ./update.sh). Containers are recreated once with the new security settings; data volumes are untouched.

Full history in CHANGELOG.md.