SELFHOST.COMPUTER

Immich on your own server: a Google Photos replacement

#immich#docker#backups

Immich is the self-hosted photo app people keep recommending when someone asks how to leave Google Photos. It has a phone app with automatic backup, face and object search, shared albums and a timeline that feels familiar. It is also hungry: it runs several containers and wants real RAM. This guide shows a setup that holds up, and how to size the server for it.

It builds on the Docker and Caddy setup. If you are still choosing a tool, read the Google Photos alternatives overview first.

What you need

  • RAM: 4 GB is the practical minimum. Immich plus Postgres, Redis (Valkey) and the machine-learning container sit around 3 GB at rest, and the first import spikes higher. 8 GB is comfortable.
  • CPU: face recognition and smart search run on the CPU unless you add a GPU. A big first import is slow on 2 cores, but it is a one-off.
  • Disk: your whole library, plus roughly 20% for thumbnails and transcoded video. Photos are the one thing you cannot afford to lose, so plan the backup before the upload.

A 4 GB VPS can run Immich alone, but not next to a pile of other services. Check with the VPS size calculator, or compare plans on the VPS voucher page. If the library is hundreds of gigabytes, a root server with big disks is usually cheaper than VPS storage.

Use the official compose files

Immich changes its stack between releases, and the database image has changed more than once. A hand-copied compose file from a blog (including this one) goes stale. Download the files from the latest release instead:

mkdir -p ~/stack/immich && cd ~/stack/immich
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

Open .env and change at least these:

UPLOAD_LOCATION=/srv/immich/library
DB_DATA_LOCATION=/srv/immich/postgres
TZ=Europe/Berlin
IMMICH_VERSION=v2
DB_PASSWORD=a-long-random-password

Use a generated string for DB_PASSWORD; the secret generator will do. Keep DB_DATA_LOCATION on local disk. Postgres on a network share (NFS, SMB) corrupts easily. The photo library can live on bigger or slower storage.

Pin IMMICH_VERSION to a major version, or an exact one, rather than release. Immich ships breaking changes and tells you in the release notes, so you want to update on purpose. See how to update containers safely.

Put Caddy in front

The official file publishes port 2283 on the host. Behind Caddy you do not want that open to the internet. Remove the ports: block from immich-server, and join it to the same Docker network as Caddy (for example with a shared external network). Then add a block to the Caddyfile:

photos.example.com {
    request_body {
        max_size 50GB
    }
    reverse_proxy immich-server:2283
}

The max_size line matters. Video uploads from a phone are large, and a proxy with a small body limit makes the app fail with confusing errors. Start everything with docker compose up -d, open the site and create the admin account. The first account becomes the admin.

Phone backup

Install the Immich app, enter your server URL, log in, and pick the albums to back up. Turn on background backup and, on Android, allow the app to ignore battery optimisation, otherwise it only uploads when open. Test it with a few photos before enabling the whole camera roll.

Let the jobs finish

After a big import the server will sit at full CPU for hours or days. That is thumbnail generation, face detection and the smart-search index. It is normal. In Administration, Jobs you can see the queues. If the box is struggling, lower the concurrency for the machine-learning jobs, and cap the container so it cannot starve the rest of the host:

  immich-machine-learning:
    mem_limit: 2g

The RAM budget post explains how to pick these limits and add swap as a safety net.

Back it up properly

Two things must be backed up: the photo library folder and the Postgres database. The database holds albums, faces, sharing and metadata. Without it, the files are just a pile of renamed images. Immich can write its own database dumps on a schedule (Administration, Settings, Backup). Point your restic backups at the library folder and that dump folder, and send them to a different machine or provider than the one running Immich. If you are weighing tools, the restic vs Borg vs Kopia comparison helps. Once a quarter, restore into a scratch folder to confirm it works.

Keep it private

Do you really need your photos reachable from the whole internet? Many people put Immich behind WireGuard or Tailscale and reach it by a private name. The phone app works fine over a VPN. If you do expose it, use a strong admin password, turn off open registration, and keep it updated, because it holds your most personal data.

Is it worth it?

If you have more than a few thousand photos and care about owning them, yes. If you only want cheap storage and don't want to be on call for it, a simple encrypted backup of your camera roll is less work. Compare the options in the Dropbox and Google Photos alternatives guides.

< all posts · netcup voucher codes

Keep reading