thenug.net

replacing google photos with immich - self-hosted photo backup with face recognition

Immich is a self-hosted Google Photos alternative with automatic iPhone backup, face recognition, and semantic search. here's how it's set up on a homelab mini PC and how 6,700+ photos got migrated from Google Takeout.

why replace google photos with immich

Google Photos is convenient until it isn't - storage limits, privacy concerns, or just wanting to own your data. Immich replicates the Google Photos experience on your own hardware. face grouping, album organization, map view, and "search by what's in the photo" all work - no cloud subscription required.

the stack

Immich isn't a single container. it runs four:

the ML container uses CUDA on the RTX 3070. face clustering and semantic search are significantly faster with GPU acceleration than on CPU.

importing from google photos

Google Takeout exports photos as a mix of tgz archives with JSON sidecar files containing metadata — timestamps, GPS coordinates, album membership. the sidecars matter: without them, every photo shows the export date instead of when it was actually taken.

immich-go handles the import correctly:

# extract the takeout archives first
mkdir ~/takeout-extracted
tar -xzf ~/Downloads/takeout-*.tgz -C ~/takeout-extracted

# upload with metadata preserved
immich-go upload from-google-photos --no-ui \
  --server=http://10.0.3.21:2283 \
  --api-key=YOUR_KEY \
  ~/takeout-extracted

the --no-ui flag is required — the TUI breaks in some terminal environments. point it at the extracted folder, not the tgz directly.

immich-go reads the JSON sidecars, sets correct dates and GPS data, and preserves album structure. it deduplicates by file hash, so running it multiple times or mixing with iPhone backups doesn't create duplicates.

iphone backup

the Immich iOS app connects directly to the local server and backs up the camera roll in the background, exactly like Google Photos. new photos sync automatically on the same network. deduplication handles the overlap with Takeout imports.

the ml jobs

after import, Immich queues background jobs for every photo: thumbnail generation, face detection, CLIP embedding. these run through the ML container. with CUDA, a library of 6,700 photos finishes in under an hour. without GPU it takes significantly longer.

once done, the face grouping UI shows clusters of recognized faces to name, and the search bar understands queries like "beach sunset" or "birthday cake" without any manual tagging.

gotchas

don't enable storage template before importing. the storage template feature renames and reorganizes files on disk. enabling it before the initial import means immich-go can't match incoming files to already-imported ones by path, and you'll get duplicates.

immich needs its own Postgres. the pgvecto.rs extension required for vector search isn't available in standard Postgres images. immich ships its own Postgres image (ghcr.io/immich-app/postgres) that includes it. it can't share the homelab's shared Postgres instance.

hardware for self-hosted photo storage

Immich needs two things: storage space for photos and some compute for the ML jobs. a mini PC with 16-32GB RAM handles the server, database, and ML processing. for photo storage, a NAS drive or external USB drive works - the photos just need to be on a reliable filesystem that Docker can mount. the GPU acceleration is nice for initial import but not required - Immich works fine on CPU, just slower for the initial face recognition pass.

MinisForum UM760 mini PC for self-hosted Immich photo backup server
MinisForum UM760 Slim Mini PC

AMD Ryzen - compact, fanless, low power

Runs Immich, face recognition, and photo backup from home

view on amazon

affiliate link - helps support the blog

eli5

imagine moving your entire photo collection out of a rented storage unit (Google Photos) and into a room in your house. the room has all the same features — automatic labeling, face grouping, search by what's in the picture — except it runs on your hardware and nobody else has a key. the moving truck (immich-go) reads the labels Google put on every box (JSON sidecars) so nothing ends up mislabeled or in the wrong album. once everything is moved in, a very fast assistant (the GPU) goes through every photo and builds an index so you can find anything instantly.


← back to blog