How I Thought About Forgejo Image Pinning and Upgrades
One of the smaller decisions that matters more than it looks is image pinning.
It is very easy to say:
"Just use latest."
That is also a good way to create avoidable upgrade surprises in a service that stores repositories, metadata, users, and automation state.
Why I Do Not Like Floating Latest Tags
The main problem is not ideology. It is predictability.
With a floating latest tag, you lose a clean answer to:
- what exactly is running,
- which update introduced a change,
- and how easily you can reproduce or roll back the deployment.
That tradeoff is rarely worth it for a service you expect to depend on.
The Pinning Spectrum
I think about image pinning as a spectrum:
- fully floating tags are fastest but least predictable,
- major-version pinning is a good operational compromise,
- minor-line pinning is more conservative,
- and digest pinning gives maximum reproducibility.
The right choice depends on how much control you want versus how much update friction you are willing to accept.
Why This Matters More For Forgejo
Forgejo is not a throwaway helper container.
It is a stateful service with:
- Git data,
- database state,
- SSH behavior,
- and CI-related expectations.
That means upgrades should be conscious events, not background drift.
The Rule I Actually Care About
The real rule is simple:
major upgrades should be intentional.
If I want to move a self-hosted forge to a new major line, I want that to happen because I decided to test and adopt it, not because a tag floated there while I was solving some unrelated problem.
The Broader Lesson
This is one of those choices that seems small until something breaks.
Then it becomes obvious that image pinning is not just about neatness. It is about making change legible.
That is exactly the kind of control I want in a self-hosted service that is supposed to become more reliable over time, not more mysterious.