#23: record the other half of the image-tag trap

A pinned IMAGE_TAG solves 'latest never re-pulls' and introduces the mirror
problem: the pin is an instruction to run that exact image, so deploying
without bumping it re-pulls the old build and reports success. Redeploying
with 'ignore cache' does not help - that clears the build cache, and nothing
is built on the server.

Documents the two-step release and the asset-fingerprint check that tells you
which image is actually serving, rather than trusting a green deployment log.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5 committed 2026-08-02 19:29:54 -03:00
1 parent 084b1bc204
commit 3b6e95ed6c
1 file changed
+26
+26
View File
@@ -201,6 +201,32 @@ The tags are published by `release.yml`; `docker buildx imagetools inspect
ghcr.io/<owner>/lambdamail/webmail:latest` shows what `latest` currently points
at.
**Pinning has a second edge: bump it on every release.** A pinned tag is an
instruction to run *that* image, so a deploy triggered without changing it
re-pulls the same old build and succeeds — the UI simply does not change.
Redeploying with "ignore cache" does not help, because that clears the *build*
cache and nothing here is built on the server; the tag being requested is still
the old one. The two failure modes are mirror images: `latest` never updates
because Docker already has it, and a stale pin never updates because you asked
for it by name.
So a release is two steps, not one:
```bash
# 1. point the tag at the new commit
IMAGE_TAG=sha-$(git rev-parse HEAD)
# 2. then deploy
```
Confirm which one is actually serving before believing a green deployment:
```bash
curl -s https://<WEBMAIL_HOST>/user/login | grep -o '/_next/static/css/[a-z0-9]*\.css'
```
The asset fingerprint changes with every build. If it did not move, the old
image is still running whatever the deployment log said.
## Troubleshooting
**The web UI is up but nothing can log in.** The auth service refuses to start