Operate and recover

Update with a rollback plan

Review changes, preserve configuration and data, update one layer, test it, and retain a recovery target.

10 minute lesson

~~~

Home servers fail when unattended changes combine operating system, container, configuration, and data migrations at once. Four things changed, something broke, and now you’re bisecting instead of using the service. The discipline: update one layer at a time, know what you’re running before you change it, and keep a way back.

Know the current state first

Record the current container image before updating:

docker image inspect --format "{{index .RepoDigests 0}}" traefik/whoami:v1.11.0
# traefik/whoami@sha256:200689790a0a... (your exact digest will differ)

That digest pins the exact bytes you’re running today — more precise than the tag, which a publisher can move. Paste it into your notes. If the new version misbehaves, this line is your rollback target.

Then read release notes for migrations and breaking changes. The word to search for is “migration”: a version that rewrites its database on first start often can’t be downgraded by swapping the image back. For those, take a fresh backup of the service’s volume first — the backup becomes the rollback.

Update and test

Bump the pinned tag in compose.yaml (say, to the next release), then:

docker compose pull
docker compose up -d
docker compose logs --since 5m web

pull fetches the new image, up -d recreates the container on it, and the logs show the first minute of the new version’s life — where migration output and startup errors appear.

Smoke-test through the real hostname and inspect logs:

# from your laptop:
curl -I https://homeserver.lab.test
# HTTP/2 200

Test through https://homeserver.lab.test, not the loopback port, because users take the full path — DNS, proxy, TLS, container — and any layer can be the one the update broke.

Keep the way back open

Keep the prior image or backup until the new version proves stable — a few days of real use, not one successful curl. If you need to roll back and there was no data migration, restore the old pin and recreate:

docker compose up -d   # after restoring the previous tag in compose.yaml

The failure mode is the floating tag. Do not use an unbounded floating tag for critical stateful services: with image: app:latest, a routine pull can silently jump major versions, migrate your data, and leave you unable to say what you were running before. Pinned tags make updates boring, and boring is the goal.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →