Reading time: ~15 minutes
Audience: Users leaving Google Photos due to storage limits or privacy concerns
Last tested: Immich v1.131, PostgreSQL 16, Redis 7.4, June 2026
What Is Immich?
Overview
Immich is an open-source, self-hosted photo and video backup solution designed as a direct alternative to Google Photos, iCloud, and Amazon Photos. It offers automatic mobile uploads, AI-powered face recognition, duplicate detection, map-based browsing, and shared albums — all running on your own server.
Unlike Nextcloud’s basic photo viewer, Immich is purpose-built for large media libraries (100,000+ photos) with fast scrolling, instant search, and RAW file support.
Key Benefits
| Feature | Immich | Google Photos | Nextcloud Photos |
|---|---|---|---|
| Cost | Free (your hardware) | $2–20/month | Free (your hardware) |
| AI face recognition | ✅ On-device or server | ✅ Cloud | ❌ |
| Auto-upload mobile | ✅ iOS & Android | ✅ | Limited |
| RAW / HEIC support | ✅ | ✅ | Basic |
| Map timeline | ✅ | ✅ | ❌ |
| Duplicate detection | ✅ | ❌ | ❌ |
| Facial recognition privacy | Local only | Cloud processed | N/A |
Prerequisites
Hardware Requirements
| Library Size | RAM | CPU | Storage | GPU (Optional) |
|---|---|---|---|---|
| < 10,000 photos | 4 GB | 2 cores | 100 GB SSD | Not needed |
| 10,000–50,000 | 8 GB | 4 cores | 500 GB SSD | Intel UHD / NVIDIA for AI |
| 50,000–200,000 | 16 GB | 6 cores | 2 TB SSD | Recommended |
| 200,000+ | 32 GB | 8+ cores | 4 TB NVMe | Strongly recommended |
RAM is the critical bottleneck. PostgreSQL with pgvecto.rs (Immich’s vector search extension) consumes significant memory during initial face recognition scans.
Software Requirements
- Docker Engine 24.0+ and Docker Compose plugin
- A Linux host with a static IP
- (Optional) Reverse proxy for HTTPS
- Mobile device with the Immich app (iOS or Android)
Step 1: Create the Docker Compose Stack
Objective
Write a production-ready Compose file with all required Immich services.
Step-by-Step Instructions
- Create a project directory:
mkdir -p ~/immich && cd ~/immich
- Create
.env:
cat > .env << 'EOF'
# Database
DB_PASSWORD=change...hmod 600 .env
- Create
docker-compose.yml:
version: "3.8"
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:release
restart: unless-stopped
ports:
- 2283:2283
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
depends_on:
- redis
- database
- typesense
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:2283/api/server/ping"]
interval: 30s
timeout: 10s
retries: 3
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:release
restart: unless-stopped
volumes:
- model-cache:/cache
env_file:
- .env
# Uncomment for NVIDIA GPU acceleration:
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
typesense:
container_name: immich_typesense
image: typesense/typesense:0.25.2
restart: unless-stopped
environment:
- TYPESENSE_API_KEY=${TYPESENSE_API_KEY}
- TYPESENSE_DATA_DIR=/data
- GLOG_minloglevel=1
volumes:
- ts-data:/data
command: "--data-dir /data --api-key ${TYPESENSE_API_KEY}"
redis:
container_name: immich_redis
image: redis:7.4-alpine
restart: unless-stopped
database:
container_name: immich_postgres
image: tensorchord/pgvecto-rs:pg16-v0.2.0
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
PGDATA: /var/lib/postgresql/data
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE_NAME} || exit 1
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
volumes:
pgdata:
model-cache:
ts-data:
- Start the stack:
docker compose up -d
- Verify all containers are healthy:
docker compose ps
Step 2: Initial Configuration
Objective
Complete the web setup and create your admin account.
Step-by-Step Instructions
- Open your browser:
http://your-server-ip:2283
- Click “Getting Started”.
- Create the administrator account:
- Email, password, name
- Log in and explore the web UI.
Key settings to configure first:
-
Administration → Settings → Storage Template: Define how uploaded files are organized. Default is
YYYY/MM/YYYY-MM-DD/filename. -
Administration → Settings → External Libraries (Optional): If you have an existing photo collection on disk, mount it read-only and add it as an external library. Immich will index it without moving files.
-
Administration → Settings → Machine Learning: Enable Face Recognition, Smart Search, and Duplicate Detection.
Step 3: Mobile Auto-Upload Setup
Objective
Configure the Immich mobile app to back up photos automatically.
Step-by-Step Instructions
iOS:
1. Install Immich from the App Store.
2. Enter server URL: http://your-server-ip:2283 (or HTTPS domain)
3. Log in with your credentials.
4. Tap Profile (bottom right) → Backup
5. Enable:
- Backup
- Background backup
- Wi-Fi only (recommended to save mobile data)
- Albums to backup: select Camera Roll or all albums
Android: 1. Install Immich from F-Droid or Play Store. 2. Log in to your server. 3. Tap Albums → Backup 4. Enable backup and select albums. 5. For reliable background sync, disable battery optimization for the Immich app in Android settings.
Pro Tip: The first backup of 10,000+ photos can take days over Wi-Fi. Leave the app open and plugged in overnight for the initial sync.
Step 4: Reverse Proxy and HTTPS
Objective
Secure remote access with a reverse proxy.
Step-by-Step Instructions
NGINX Proxy Manager configuration:
| Field | Value |
|---|---|
| Domain Names | photos.yourdomain.com |
| Scheme | http |
| Forward Hostname / IP | immich_server (if on same Docker network) or host IP |
| Forward Port | 2283 |
| Websockets Support | ✅ Enabled |
| Block Common Exploits | ✅ Enabled |
Custom NGINX snippet for large uploads:
Immich uploads large video files. Increase the body size limit:
client_max_body_size 50G;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_request_buffering off;
proxy_buffering off;
In NGINX Proxy Manager, add this to the Advanced tab of the Proxy Host.
Step 5: Running Face Recognition and Smart Search
Objective
Trigger the initial AI scan of your uploaded photos.
Step-by-Step Instructions
- After uploading photos, go to Administration → Jobs.
- Click the Run button next to each job:
- Thumbnail Generation (creates preview images)
- Metadata Extraction (reads EXIF, GPS)
- Smart Search (AI-powered semantic search)
- Face Detection (finds faces in photos)
- Face Recognition (groups faces into people)
-
Duplicate Detection (finds similar images)
-
Monitor progress in the same panel. A library of 10,000 photos takes 2–4 hours on a 4-core CPU, or 30 minutes with GPU acceleration.
To enable GPU for machine learning:
- Uncomment the
deployblock inimmich-machine-learningservice. - Install NVIDIA Container Toolkit (see Jellyfin guide).
- Restart the stack:
docker compose down
docker compose up -d
Pro Tips
Tip 1: Use External Libraries for Existing Collections
If you have 500 GB of existing photos on a NAS, do not re-upload them. Mount the NAS folder read-only and add it as an external library in Immich. Run the metadata and thumbnail jobs to index them.
Tip 2: Set Up Backup to a Second Location
Immich stores originals in the UPLOAD_LOCATION. Back this up alongside the PostgreSQL database:
docker exec immich_postgres pg_dump -U immich immich > immich-backup_$(date +%Y%m%d).sql
rsync -avP ${UPLOAD_LOCATION}/ /backup/immich-uploads/
Tip 3: Shared Albums for Family
Create user accounts for family members under Administration → Users. Each user gets their own private library. Create shared albums and invite others to view or contribute.
Tip 4: Handle HEIC Efficiently
iPhones shoot HEIC by default. Immich stores the original HEIC and generates a JPEG thumbnail. This saves ~40% storage compared to storing JPEG originals. Do not convert HEIC to JPEG before uploading.
Troubleshooting Common Issues
“Failed to connect to server” on Mobile App
- Ensure the server URL includes the protocol:
http://orhttps:// - If using a reverse proxy, verify Websockets are enabled
- Check that
immich_servercontainer is healthy:docker compose ps
High RAM Usage During Scan
- The
immich_machine_learningcontainer can spike to 4–8 GB RAM during initial face recognition. This is normal. - If the container is killed (OOM), increase Docker memory limits or add swap:
bash sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile
Duplicate Detection Not Finding Duplicates
- Duplicate detection only runs on images with similar perceptual hashes. Slightly cropped or re-encoded images may not match.
- Adjust the similarity threshold in Administration → Settings → Machine Learning.
Conclusion
Summary
You now have Immich running with PostgreSQL, Redis, Typesense, and optional GPU-accelerated machine learning. Your mobile devices can auto-upload, and you have AI-powered search, face recognition, and duplicate detection — all on hardware you control.
Next Steps
- Compare Immich vs Nextcloud for photo backup
- Set up a backup target with BorgBackup or Restic
- Add hardware transcoding for video previews
- Monitor your Immich stack with Grafana
Affiliate Opportunities
- SSD Storage: Samsung 990 PRO or WD Black SN850X for photo libraries
- Mini PCs: Intel N305 with 32 GB RAM for medium-sized collections
- NAS: Synology or TrueNAS systems for backing up the upload volume
Internal Linking Strategy
what-is→/nextcloud-immich-comparisonfor readers choosing a photo platformmobile→/tailscale-homelab-guidefor secure remote access without port forwardingconclusion→/homelab-backup-strategyfor protecting your photo archive
CTA
How many photos are you backing up with Immich? Share your library size and server specs in the comments!
Subscribe to the WordForge newsletter for weekly self-hosting and privacy-focused guides.