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

  1. Create a project directory:
mkdir -p ~/immich && cd ~/immich
  1. Create .env:
cat > .env << 'EOF'
# Database
DB_PASSWORD=change...hmod 600 .env
  1. 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:
  1. Start the stack:
docker compose up -d
  1. 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

  1. Open your browser:
http://your-server-ip:2283
  1. Click “Getting Started”.
  2. Create the administrator account:
  3. Email, password, name
  4. 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

  1. After uploading photos, go to Administration → Jobs.
  2. Click the Run button next to each job:
  3. Thumbnail Generation (creates preview images)
  4. Metadata Extraction (reads EXIF, GPS)
  5. Smart Search (AI-powered semantic search)
  6. Face Detection (finds faces in photos)
  7. Face Recognition (groups faces into people)
  8. Duplicate Detection (finds similar images)

  9. 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:

  1. Uncomment the deploy block in immich-machine-learning service.
  2. Install NVIDIA Container Toolkit (see Jellyfin guide).
  3. 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:// or https://
  • If using a reverse proxy, verify Websockets are enabled
  • Check that immich_server container is healthy: docker compose ps

High RAM Usage During Scan

  • The immich_machine_learning container 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


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-comparison for readers choosing a photo platform
  • mobile/tailscale-homelab-guide for secure remote access without port forwarding
  • conclusion/homelab-backup-strategy for 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.