Feeling generous? Fund my lavish lifestyle 💅.

🔑 445F 8079 96F7 0586 B715 C7B8 A138 06B1 FA2A 676B / RSS

A Blog by Expatriotic

Immich

The path: Buying Server Hardware Tips → Foundation → Tailscale → Docker → Immich

Immich is a self-hosted photo library: phone apps with automatic backup, facial recognition, search, albums, sharing. It's the killer app of self-hosting — the one that finally makes normal family members care about your server.

Prerequisites, and I mean it: a foundation (Path A or B), Tailscale serve HTTPS working — we're baking that URL into your phone today and never touching it again — and Docker + Dockge.

1. Decide where photos live, before installing

The most important decision in this guide, and it's boring on purpose: the upload library goes on your biggest disk, not the OS disk. If you did the second-disk step in guide one, you already have /mnt/photos. If not, point it at a folder you understand — and know that migrating later is a project.

mkdir -p /mnt/photos/immich-library /mnt/photos/immich-db

2. Get the files

Immich ships its own compose file. Don't copy one from a forum — pull it from the official release:

mkdir -p /opt/stacks/immich && cd /opt/stacks/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/env.example

The .env holds your answers to a handful of questions:

Variable Set it to Notes
UPLOAD_LOCATION /mnt/photos/immich-library The big disk. The whole point
DB_DATA_LOCATION /mnt/photos/immich-db Database next to it
IMMICH_VERSION release Their recommended tag; Immich moves fast
DB_PASSWORD long random string openssl rand -base64 24 generates one
TZ Asia/Bangkok Yours, obviously

Leave the database image line exactly as shipped — Immich pins a specific database build for a reason. Don't "help."

3. Launch and lock the front door

docker compose up -d
docker compose ps   # all containers Up

First login: your https://server-name.your-tailnet.ts.net URL (from the Tailscale guide, via tailscale serve --bg 2283 if you haven't yet). Register the admin account, then immediately go to Administration → Settings and disable open registration. You built a photo server, not a hostel.

4. The phone apps

Install the Immich app (Android/iOS). Three settings:

  1. Server URL: your https://...ts.net address.
  2. Background backup: on. Photos upload themselves from now on.
  3. Android — battery unrestricted: Settings → Apps → Immich → Battery → Unrestricted. Not optional: "optimized" quietly murders background uploads and you'll swear the app is broken. Ask me how I know. On a de-Googled phone it's the same dance as any sandboxed app — GrapheneOS guide.

On iOS, enable background refresh and let Tailscale run on-demand. Phones upload only when Tailscale is on — feature, not bug.

First bulk upload of years of photos: Wi-Fi, plugged in, foreground. Indexing runs on your CPU and a big library can take a day or three. It's working, not stuck — watch it from the server inside tmux if you want to see the gears turn.

5. Updates and backups

Updates (monthly is fine):

cd /opt/stacks/immich
docker compose pull && docker compose up -d

Skim the release notes first — Immich is one of the fastest-moving self-hosted apps in existence, and that's the price of the features.

Backups — know what actually matters:

# database dump before any update, or on a schedule
docker exec -t immich_postgres pg_dump -U postgres -d immich \
  > /mnt/photos/immich-db-dump-$(date +%F).sql

Golden rule: don't wipe photos off your phone until a backup exists and you've opened it. A backup you've never restored from is a hope, not a backup.

That's it. You own your photos the way you own your Bitcoin: not your keys, not your coins — not your disk, not your memories.

Next in the series: notes that sync end-to-end encrypted through your own CouchDB, over the same Tailscale front door.


← Previous: Docker and Dockge | Next: Obsidian LiveSync

#privacy #self-hosting #tips