
Most “an update broke my server” stories come from the same mistakes: updating everything at once, using :latest, and having no way back. Here’s a routine that fixes all three.
1. Read before you pull
For each stack, check the release notes for every version between what you run and the target, not just the newest one. Breaking changes are often in an intermediate release. (That’s what SafeToUpdate is for. Each verdict links to the official notes.)
Look for: “breaking”, “migration”, “deprecated”, “removed”, required config changes, and minimum versions of dependencies such as Postgres or Redis.
2. Take a restore point
- VM or LXC on Proxmox: take a snapshot or a
vzdumpbackup first. Snapshot mode keeps the guest running. See Proxmox Backup and Restore. - Bare Docker host: back up your Compose files,
.env, and named volumes (see the next post), and dump databases with the database’s own tool, e.g.pg_dumpall. Copying the files of a running database isn’t a reliable backup.
3. Update one stack at a time
cd ~/stacks/immich
# edit the pinned tag in compose.yaml / .env first
docker compose pull # download the new images
docker compose up -d # recreate only the containers whose image/config changed
docker compose logs -f --tail=100
docker compose pull only downloads images. docker compose up -d recreates the containers whose configuration or image changed.
4. Verify like you mean it
Don’t stop at “the container is running”. Log in, load real data, and check the logs for migration errors. Then wait a few minutes before you start the next stack.
5. Rollback plan
Revert the image tag and run docker compose up -d again. Caveat: if the new version already migrated the database schema, the old version may refuse to start. That’s why step 2 exists. Restore the database dump (or the VM snapshot) together with the old tag.
Checklist
- Notes read for every skipped version
- Snapshot / DB dump taken
- One stack at a time
- Logs and real usage verified
- Rollback steps known before starting