Photo Backup with Immich
A self-hosted, Google-Photos-style photo and video backup with mobile auto-upload - closing the loop on the "photo backup" goal from Planning Your Homelab.
Planning Your Homelab named photo backup as one of the most common reasons people start a homelab in the first place. Vaultwarden showed how satisfying it feels to replace a paid cloud service with one you run yourself - Immich is the same trade for photos.
What Immich actually is
Immich is a self-hosted photo and video backup app modeled closely on Google Photos: mobile apps for iOS/Android with automatic background upload, timeline browsing, albums, and (optionally) face recognition and object/scene search - all running against your own storage instead of Google's.
Running it
Immich ships as several containers working together, not one - more moving parts than anything else in this tier, but the official install script handles the wiring for you.
services:
immich-server:
image: ghcr.io/immich-app/immich-server:release
container_name: immich-server
ports:
- "2283:2283"
volumes:
- ./library:/usr/src/app/upload
environment:
- DB_HOSTNAME=immich-postgres
- DB_USERNAME=immich
- DB_PASSWORD=${DB_PASSWORD}
- DB_DATABASE_NAME=immich
- REDIS_HOSTNAME=immich-redis
depends_on:
- immich-postgres
- immich-redis
restart: unless-stopped
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
container_name: immich-machine-learning
volumes:
- ./model-cache:/cache
restart: unless-stopped
immich-redis:
image: docker.io/valkey/valkey:9
container_name: immich-redis
restart: unless-stopped
immich-postgres:
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
container_name: immich-postgres
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_USER=immich
- POSTGRES_DB=immich
volumes:
- ./pgdata:/var/lib/postgresql/data
restart: unless-stopped
- Image tags and the exact service list change faster here than for
most self-hosted apps in this guide - use Immich's official
docker-compose.ymland.envfrom their install docs as your actual starting point, rather than copying the above verbatim. In particular, the Postgres image tag is version-pinned to a specific vector-extension build (the string afterpostgres:above) that changes with Immich releases - check the current tag before pulling, a stale one will simply fail to pull. immich-server'sDB_USERNAME/DB_PASSWORD/DB_DATABASE_NAMEmust match theimmich-postgresservice'sPOSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DBbelow exactly - a mismatch here is a common first-run failure (immich-servercan't authenticate to its own database) that shows up as the server container looping on restart.immich-machine-learningis what powers face grouping and "search for 'beach'" style queries. It's the one optional-feeling piece - see the resource note below.
Resource expectations: the server, Redis, and Postgres together are light - comparable to Vaultwarden. Machine learning is the real cost: budget at least 2 extra CPU cores and 2-4GB RAM while it's actively indexing a new library, tapering off once your existing photos are processed. A modest mini PC handles this fine for a household's library; it's just noticeably busier during the first big import.
Mobile app auto-upload
Install the Immich app, point it at http://server-ip:2283, log in,
and enable background backup. This is the entire point of running
Immich instead of just dropping files in a folder - your phone's
photos land on your own server automatically, same as they would with
a cloud service, without you doing anything after the initial setup.
Same caveat as Vaultwarden applies here: the mobile app works fine over plain HTTP on your home Wi-Fi, but background upload while you're out and about needs either the VPN approach from Remote Access (Intermediate) or a properly TLS-terminated reverse proxy - both out of scope until then. Until you're there, uploads simply queue on the phone and catch up whenever it's back on your home network, which is a perfectly reasonable place to leave things for now.
Backing it up
Two things matter here, and together they're bigger than a typical
service's ./data folder:
- The Postgres database - metadata: albums, face tags, sharing links. Small, but without it the library folder is just a pile of unsorted files.
- The
./libraryfolder - the actual photos and videos. This is the one exception to Backups 101's "you don't need to back up everything" guidance: this content usually is genuinely irreplaceable, unlike a media library you could re-rip or re-download.
Include both in the backup scope you set up in Backups 101, and treat this as the single highest-priority thing on this machine to get right - a lost, un-backed-up photo library is a different category of loss than a lost service you can just reinstall.
Notes and documents, if those were on your list too
Planning Your Homelab grouped "note-taking, photo backup, media streaming" together as common motivations. Photos and streaming now have real answers (Immich, and Jellyfin from First Services). If note-taking or scanned-document storage was also on your list, the good news is it's the same pattern again, not a new one to learn: Paperless-ngx for scanned documents and receipts (it OCRs and tags them automatically), or a lightweight self-hosted notes app like Trilium or a Joplin Server sync target. Each is a single container plus a bind-mounted data folder, same shape as everything else in this tier - not detailed here because there's genuinely nothing more to explain beyond what you've already done twice.
Next: File Sync with Nextcloud.