CI/CD
Why do CI/CD systems insist on immutable artifacts?
Short answer
So that testing something means anything. If the artifact can change between the test and the deploy, then passing tests tells you about a thing that no longer exists.
The constraint behind it
A pipeline's value rests on a chain of inference: this artifact passed these tests, therefore deploying it is reasonably safe. Every link has to hold for the conclusion to.
A mutable reference breaks the chain silently. If `myapp:latest` is tested and then `myapp:latest` is deployed, those are two lookups of a name, not two uses of a thing. Anything pushed in between changes what runs while every check stays green.
The failure is invisible where people look. The repository is unchanged, the pipeline is green, and production is running something nobody tested.
◈ If it were the other way
What that system would look like
With mutable artifacts, rollback stops meaning anything. "Deploy the previous version" resolves a tag that may now point somewhere else, so you cannot reliably return to a known state.
Reproducing an incident becomes guesswork, because "we were running v2.1" no longer identifies specific bytes.
And promotion between environments loses its guarantee: what staging validated and what production received are two resolutions of the same name, which may differ.
◆ What it buys you
- A rollback that actually returns to a known state, because the previous artifact still exists and is still itself.
- Meaningful promotion. The thing that passed staging is bit-for-bit the thing production runs.
- Answerable questions after an incident: exactly what was running, and what was in it.
◑ What it costs you
- Storage and lifecycle work. Every build is a distinct artifact, so retention becomes a policy rather than an afterthought.
- Discipline in version handling. Tags have to be generated rather than reused, which is more machinery than `latest`.
- It does not come for free from tagging alone. An immutable *tag* is a convention; only a digest is enforced by content.
Where it bites in practice
In the gap between an immutable tag and a verified one. Teams stop using `latest`, adopt version tags, and reasonably believe the problem is solved — but a tag is still a mutable pointer that the registry lets you move. Only a digest, or a signature, makes immutability something you can check rather than something you agreed to.
What comes next
Did this get you to an answer?
No text box on purpose — please do not paste production logs anywhere