Updates
When there is a new version, administrators see the hint Update next to Licence under Settings, and get an e-mail with what it brings. What each version brought is in the changelog.
Which version runs
The images come under several names:
| Tag | Meaning |
|---|---|
0.26.1 | Exactly this version. |
0.26 | The latest bug fix of 0.26 – without new features. |
stable | The version we have released for installations. It follows the releases with some delay. |
latest | The newest release, as soon as it is out. |
For an installation that updates itself, stable is right (with Watchtower or Keel) or a version range (with Flux); for one you update by hand, a fixed version.
By hand
With Docker Compose, set DDM_VERSION in .env and restart:
docker compose pull
docker compose up -d
With Kubernetes, change the version in ddm.yaml and apply the file again (kubectl -n ddm apply -f ddm.yaml). If ddm.yaml on the Kubernetes page has changed since your version, take that over too.
The CMS backs up the database and applies the migrations before it accepts requests. With Docker Compose, the render worker and the reader app only start after that.
New installation files
compose.yaml and ddm.yaml carry their version (DDM_DEPLOY_VERSION). Usually a new DDM version runs with the files you have. For the two cases where it does not:
- Fixes (0.26.1 → 0.26.2) never need new files. If your installation follows
0.26, or0.26.xwith Flux, its files always fit. - A new version (0.26 → 0.27) may need new files. Then Settings › Licence and the mail about the new version say: "needs new installation files". In that case, take over
compose.yamlorddm.yamlfrom this guide before updating – keep your settings in.env, orconfig.envandsecrets.env– and then update.
If an installation runs with files older than its version needs – because it updated itself with stable, say – its administrators see Check next to Licence under Settings, and there what to do; the CMS writes it into its log too.
Supported versions
We support the versions from one we name to your installation with every licence renewal. If it runs an older one, its administrators see Check next to Licence and get one mail. The installation keeps running – but fixes, security fixes too, come only for newer versions.
Automatically with Docker Compose
Set DDM_VERSION=stable in .env. Watchtower with --label-enable then updates the services with the label com.centurylinklabs.watchtower.enable – the CMS, the render worker and the reader app, not Postgres – as soon as we release a version:
docker run -d --name watchtower --restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.docker/config.json:/config.json:ro \
containrrr/watchtower --label-enable --schedule "0 0 3 * * *"
Automatically with Kubernetes
Two tools fit. They work differently:
| Keel | Flux | |
|---|---|---|
| Follows | the stable tag – every version we release | a version range, for example every 0.26.x |
| Changes | the deployments in the cluster directly | ddm.yaml in your Git repository; Flux then applies it |
| Fits when | you look after the cluster by hand | you already run the cluster with Flux from Git |
Neither updates Postgres: its 18 tag only changes with a new major version, which needs the data converted.
During an update the CMS restarts and applies the migrations; DDM is then unavailable for a minute or two.
Keel
Keel checks at regular intervals whether there is a new image under the stable tag, and restarts the app with it. It uses the deployments' registry secret ddm-registry for that.
- Install Keel:
helm repo add keel https://charts.keel.sh helm repo update helm upgrade --install keel keel/keel --namespace keel --create-namespace - Use
stable: inddm.yaml, givecms,render-workerandclientthe tagstableinstead of a version –…/cms:stableand so on – and apply:kubectl -n ddm apply -f ddm.yaml - Hand the three apps to Keel:
kubectl -n ddm annotate deployment cms render-worker client --overwrite \ keel.sh/policy=force \ keel.sh/match-tag=true \ keel.sh/trigger=poll \ keel.sh/pollSchedule="@every 6h"forcewithmatch-tagmeans: the same tag, a new image – exactly what happens understablewhen we release a version. Keel looks every six hours.
From then on the installation updates itself. kubectl -n keel logs deploy/keel shows whether Keel found anything.
Flux
Flux's image automation reads the versions in our registry, writes the newest matching one into ddm.yaml in your Git repository and applies it from there. It follows a version range, not the stable tag – most safely the fixes of your version (0.26.x); you then move to the next version (0.27) by hand.
It needs a cluster that Flux runs from a Git repository, with the two image controllers – for a new cluster:
flux bootstrap gitlab --owner=<group> --repository=<repository> --path=clusters/production \
--components-extra=image-reflector-controller,image-automation-controller
- Put
ddm.yamlin the repository, for example underclusters/production/ddm/, with an exact version (…/cms:0.26.1). The markers telling Flux where to write a new version –# {"$imagepolicy": …}behind the three image lines – are already in it. - Let Flux read the registry – with the same deploy token, as a secret in the
flux-systemnamespace:kubectl -n flux-system create secret docker-registry ddm-registry \ --docker-server=registry.gitlab.com \ --docker-username=<token name> --docker-password=<token> - What Flux watches and where it writes:
ddm-updates.yaml, below, in the same folder. Setrange(three times),pathand the commits' e-mail address in it. - Commit and push. Flux checks every hour; every new
0.26.xlands as a commit in your repository and in the cluster. For the next version, setrangeto0.27.x(three times) and the three versions inddm.yamlby hand.
# Updates by Flux's image automation, for an installation Flux runs from a
# Git repository (user guide, „Updates"): beside `ddm.yaml`, in the folder
# Flux applies. It reads our registry every hour and writes the newest
# version in `range` into `ddm.yaml` — behind the `$imagepolicy` comments —
# commits and pushes it.
#
# Set before committing:
# - `range`, three times: your version's fixes, e.g. `0.26.x`;
# - `path`: the folder `ddm.yaml` is in, from the repository's root;
# - the commit's `email`, and `branch` if yours is not `main`.
# It reads the registry with the Secret `ddm-registry` in `flux-system` —
# the deploy token, as in the `ddm` namespace.
# cms: where its versions are, and which one applies.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata: { name: ddm-cms, namespace: flux-system }
spec:
image: registry.gitlab.com/iq-me/new-ddm-images/cms
interval: 1h
secretRef: { name: ddm-registry }
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata: { name: ddm-cms, namespace: flux-system }
spec:
imageRepositoryRef: { name: ddm-cms }
filterTags: { pattern: '^\d+\.\d+\.\d+$' }
policy: { semver: { range: '0.26.x' } }
---
# render-worker: where its versions are, and which one applies.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata: { name: ddm-render-worker, namespace: flux-system }
spec:
image: registry.gitlab.com/iq-me/new-ddm-images/render-worker
interval: 1h
secretRef: { name: ddm-registry }
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata: { name: ddm-render-worker, namespace: flux-system }
spec:
imageRepositoryRef: { name: ddm-render-worker }
filterTags: { pattern: '^\d+\.\d+\.\d+$' }
policy: { semver: { range: '0.26.x' } }
---
# client: where its versions are, and which one applies.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata: { name: ddm-client, namespace: flux-system }
spec:
image: registry.gitlab.com/iq-me/new-ddm-images/client
interval: 1h
secretRef: { name: ddm-registry }
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata: { name: ddm-client, namespace: flux-system }
spec:
imageRepositoryRef: { name: ddm-client }
filterTags: { pattern: '^\d+\.\d+\.\d+$' }
policy: { semver: { range: '0.26.x' } }
---
# Writes the new versions into ddm.yaml and pushes them.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata: { name: ddm, namespace: flux-system }
spec:
interval: 1h
sourceRef: { kind: GitRepository, name: flux-system }
git:
checkout: { ref: { branch: main } }
commit:
author: { name: Flux, email: flux@example.com }
messageTemplate: Update DDM
push: { branch: main }
update: { path: ./clusters/production/ddm, strategy: Setters }
flux get images all shows whether Flux found anything.
What you should not do
- Don't go back a version. A new version changes the database; an older one no longer understands it afterwards. If something doesn't work after an update, restore the backup from before the update and write to us.
- Don't update Postgres automatically. A new major version (18 → 19) needs the data to be converted – see Postgres.