Self-Hosted Photo Library Integrity Workflow for Originals and Derivatives

Eva Wong is the Technical Writer and resident tinkerer at ZimaSpace. A lifelong geek with a passion for homelabs and open-source software, she specializes in translating complex technical concepts into accessible, hands-on guides. Eva believes that self-hosting should be fun, not intimidating. Through her tutorials, she empowers the community to demystify hardware setups, from building their first NAS to mastering Docker containers.

A healthy-looking photo timeline is not proof that the originals, database, and generated previews are all intact.

A self-hosted gallery can keep serving cached thumbnails after an original disappears, or retain perfect originals while workers fail to generate new derivatives. Separate required state from rebuildable state, verify original bytes outside the app, reconcile files with database records, and regenerate only one canary before testing an isolated restore. Stop immediately when checksums change, source storage becomes unstable, or a job writes to originals.

Define required state and regenerable state

Inventory originals, uploaded videos, sidecars, database, configuration, secrets, user accounts, albums, edits, and sharing records as required state. List thumbnails, transcoded video, face embeddings, and search indexes separately as derivatives that may be regenerable only if originals and application state remain intact.

A self-hosted deployment commonly places the library on capacity storage and the database or working path on faster media. One practical Immich storage account describes the library and hot-path storage split, which is why an integrity check must cover every mounted path rather than only the folder users browse.

Record application version, container image, mount definitions, database schema state, storage free space, and job queue status. Stop if any required path is missing or read-only unexpectedly; a regeneration job should not begin while the source of truth is uncertain.

Prove original bytes independently of the gallery

Generate or reuse a trusted checksum manifest for originals and compare it against the current tree in read-only mode. Reconcile file count, total bytes, unreadable files, unexpected zero-byte objects, and orphan paths. Open a stratified sample containing JPEG, HEIC, RAW, video, old years, and recent uploads outside the gallery.

Do not infer original health from visible thumbnails. A gallery can continue serving cached derivatives after an original is lost, and a healthy original can remain hidden when its preview pipeline fails. The distinction between originals and regenerable derivatives makes the direct-file check the first safety gate.

If hashes change or reads fail, pause import, cleanup, and derivative regeneration. Restore or image the failing storage before altering database records. The stage passes when required originals are readable and unexplained differences have an owner, a reason, and a recovery action.

Reconcile records, paths, and derivative jobs

Compare database asset records with filesystem paths in both directions: records without files and files without records. Check UID and GID, bind mounts, external-library roots, case sensitivity, and renamed directories before declaring assets missing. Preserve orphan lists instead of deleting either side automatically.

Then sample thumbnail, preview, transcode, metadata extraction, and machine-learning jobs. An independent troubleshooting article on intact originals with failed derivatives illustrates how intact uploads can coexist with gray tiles when storage, workers, or derivative paths fail.

Regenerate one canary derivative only after the original and database row match. A pass is a new preview with the expected owner, path, and client response; a fail stays scoped to worker logs, decoder, output storage, or queue state. Never launch a full-library rebuild until that canary remains correct after restart.

Restore the complete library into an isolated target

Restore originals, database, configuration, secrets, and required sidecars into a disposable environment with different ports and paths. Start dependencies in order, verify users and albums, then allow only the derivative jobs required for the sample set. Do not point the test instance at production writable storage.

Test login, timeline, search, album membership, download of original bytes, one edit, one share, and playback of a video. Compare downloaded hashes with the manifest and verify a second restart does not lose path mappings or recreate required state under the wrong owner.

Declare integrity proven only when the live library and isolated restore agree on required state and the canary derivatives rebuild from originals. Escalate database/file mismatches, growing checksum errors, or jobs that alter originals; retain manifests and logs so repair does not become an undocumented reimport.

Support & Tips

More to Read

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.