
Immich is a modern photo server with mobile clients.
Table of Contents
- Why Immich
- VPS specs
- Install overview
- Mobile sync
- Backups
1. Why Immich
Self-hosted, fast, and easy to use.
2. VPS specs
SSD and enough RAM for indexing.
3. Install overview
Use Docker Compose; set HTTPS and storage paths.
4. Mobile sync
Use official apps; keep network stable.
5. Backups
Back up media and DB regularly.
See /vps-hosting for plans.
Why Immich beats other self-hosted photo apps in 2026
Immich is the photo/video library most people end up on after trying PhotoPrism, Lychee, and Nextcloud Photos. It has:
- iOS / Android apps with reliable background backup.
- Face recognition, smart search (CLIP), object detection.
- Time-lapse, map view, shared albums, partner sharing.
- Multi-user with per-user storage.
Active development pace is the highest in the self-hosted photo space.
VPS sizing reality
Immich does CPU-heavy ML on import (face detection, CLIP embeddings, smart search). Backfilling 100k photos can take hours.
| Library size | vCPU | RAM | Storage | Notes |
|---|---|---|---|---|
| < 5k photos, 1 user | 2 | 4 GB | photos + 5 GB | small VPS, slow first scan |
| 5-50k, 1-2 users | 4 | 8 GB | photos + 10 GB | reasonable |
| 50-200k, family | 6-8 | 16 GB | photos + 30 GB | dedicated CPU helps |
| 200k+, multi-user | 8+ | 32 GB | NVMe required | consider GPU host for ML |
The DB and Redis-equivalent are tiny; ML and image preview generation dominate.
docker-compose that runs in production
name: immich
services:
immich-server:
image: ghcr.io/immich-app/immich-server:release
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file: .env
ports:
- "127.0.0.1:2283:2283"
depends_on: [redis, database]
restart: always
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
volumes:
- model-cache:/cache
env_file: .env
restart: always
redis:
image: docker.io/redis:6.2-alpine
healthcheck: { test: [ "CMD-SHELL", "redis-cli ping || exit 1" ] }
restart: always
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
restart: always
volumes:
model-cache:
Reverse proxy 2283 with Caddy or nginx; never expose directly.
.env that matters
UPLOAD_LOCATION=/srv/immich/library
DB_DATA_LOCATION=/srv/immich/postgres
DB_PASSWORD=CHANGE_ME
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
TZ=Europe/Amsterdam
IMMICH_VERSION=release
First-run trap
After deploy, the first ML scan can saturate CPU for hours. If you notice the box being unresponsive:
# pause ML jobs from the admin UI: Administration > Jobs
# or rate-limit via concurrency
In Administration > Settings > Machine Learning, lower concurrency from 2 to 1 on smaller VPS.
Backups
Two things to back up:
UPLOAD_LOCATION(the photos themselves).- The Postgres database (metadata, faces, albums).
# postgres dump
docker exec -t immich-database pg_dumpall -c -U postgres > /backups/immich-$(date +%F).sql
If you only back up the photos, you lose facial recognition, albums, and metadata on restore.
Common breakage
| Symptom | Cause | Fix |
|---|---|---|
| Mobile app uploads fail | server URL behind self-signed cert | use a proper Let's Encrypt cert |
| Face detection never finishes | ML container OOM | raise RAM, drop ML concurrency |
| Library shows 0 photos | UPLOAD_LOCATION owned by wrong UID | chown -R 1000:1000 |
| Postgres won't start after upgrade | data dir path moved | check Immich release notes for breaking changes |
