Skip to content

Move a site's pin

A site runs the image its pin names. Moving it is a merge request in Nerthus.Infra, a plan a person reads, and then the agents on that site's hosts picking it up on their own tick.

What a pin is, and where it lives

One row in inventory/pins.yaml, with the id sites/<site>/image:

pin:
  sites/dev/image:
    value: registry.gitlab.com/margonem/nerthus/it/nerthus.platform@sha256:dd889c…
    source: nerthus.platform `versions.lock` at v0.3.0, read 2026-09-16

Beside it, in inventory/sites.yaml, the site's platform_version — the minor line that image runs. Both move together, and the version is what says which way the pin moved: a digest has no order, so "forward" is a question only a version can answer.

The value is always a digest and never a tag. A tag that moves is a deploy nobody reviewed, and the one thing allowed to write these bytes is a release: image:release in nerthus.platform records the digest in versions.lock, and that file is where this value is copied from.

Moving it

  1. Read the digest and the version out of nerthus.platform's versions.lock at the release tag you are moving to.
  2. In a branch of Nerthus.Infra, edit the pin row's value and source, and the site's platform_version.
  3. Open the merge request. Its pipeline runs validate and plan --against state; the plan prints the pin row changing, which is the diff a reviewer reads.
  4. Merge on green. Nothing is deployed by the merge itself.
  5. Each host of the site picks it up on its next agent tick: the rendered compose file changes because the digest is in it, so the stack is pulled and brought up. A host is never pushed to.

Rolling back

A rollback is a higher version, not an older digest. The cookbook records the version it converged per site, and refuses a host whose recorded version is newer than the one now declared — so an older platform_version arriving as an ordinary merge request is stopped at the host rather than half-applied across the site. To go back to what a previous release ran, cut a new release carrying it and move the pin forward to that.

When a site has no pin

Then it has no row here, and that is a legitimate state: a site-host whose declaration names no pin is refused at load, naming the value it lacks. A host nothing is supposed to run on does not quietly run nothing.