๐ŸŽฏ New! Master certifications with Performance-Based Questions (PBQ) โ€” realistic hands-on practice for CompTIA & Cisco exams!

Immich Complete Self-Hosting Guide: From Installation to Advanced Configuration

Published on January 9, 2026


Introduction

Immich is a powerful, open-source, self-hosted photo and video management solution designed as a privacy-focused alternative to Google Photos. It offers AI-powered features like facial recognition, smart search, automatic mobile uploads, and a beautiful timeline interfaceโ€”all while keeping your precious memories under your complete control.

This comprehensive guide covers every aspect of Immich deployment, from basic installation to advanced configurations including GPU acceleration, reverse proxy setup, OAuth authentication, and enterprise-grade backup strategies.

Who Is This Guide For?

  • Beginners wanting to set up their first self-hosted photo management system
  • Intermediate users looking to optimize their existing Immich installation
  • Advanced users seeking GPU acceleration, OAuth integration, or enterprise configurations
  • NAS users (Synology, Unraid, TrueNAS) wanting to leverage existing hardware

What Makes Immich Special?

FeatureDescription
AI-Powered SearchCLIP-based semantic search (โ€œphotos of dogs at beachโ€)
Facial RecognitionAutomatic face detection and grouping
Mobile AppNative iOS and Android apps with auto-backup
Timeline ViewGoogle Photos-like experience
External LibrariesIndex existing photo collections without moving files
Hardware AccelerationGPU support for ML and video transcoding
Multi-User SupportFamily sharing with user management

โš ๏ธ Important Warning: Immich is under active development. While stable for daily use, it should NOT be your only backup solution. Always maintain redundant backups of your photos.


Part 1: Understanding Immich Architecture

Before diving into installation, understanding Immichโ€™s microservice architecture helps with troubleshooting and optimization.

Core Components

Immich consists of five main containers working together:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         IMMICH STACK                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                 โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚   โ”‚   immich-server    โ”‚       โ”‚  immich-machine    โ”‚           โ”‚
โ”‚   โ”‚   (Web UI + API)   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ–บโ”‚    -learning       โ”‚           โ”‚
โ”‚   โ”‚     Port 2283      โ”‚       โ”‚  (AI Processing)   โ”‚           โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚             โ”‚                                                   โ”‚
โ”‚             โ–ผ                                                   โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚
โ”‚   โ”‚     PostgreSQL     โ”‚       โ”‚       Redis        โ”‚           โ”‚
โ”‚   โ”‚   (Metadata DB)    โ”‚       โ”‚   (Task Queue/     โ”‚           โ”‚
โ”‚   โ”‚                    โ”‚       โ”‚      Cache)        โ”‚           โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚                                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ContainerPurposeNotes
immich-serverWeb interface, API, background tasksMain entry point for users
immich-machine-learningFacial recognition, CLIP search, object detectionCan be GPU-accelerated
postgresStores all metadata, user data, album infoMust be on local SSD
redisJob queue coordination, cachingIn-memory database

Critical Data Locations

Understanding where Immich stores data is essential for backups:

LocationContainsBackup Priority
UPLOAD_LOCATION/libraryOriginal uploaded photos/videosCRITICAL
UPLOAD_LOCATION/uploadFiles being processedImportant
UPLOAD_LOCATION/profileUser profile picturesImportant
UPLOAD_LOCATION/thumbsGenerated thumbnailsCan regenerate
UPLOAD_LOCATION/encoded-videoTranscoded videosCan regenerate
DB_DATA_LOCATIONPostgreSQL database filesCRITICAL

Part 2: System Requirements

Hardware Requirements

ComponentMinimumRecommendedLarge Libraries (500K+ assets)
RAM4 GB8 GB32-64 GB
CPU2 cores4 cores8+ cores (modern AMD/Intel)
OS Storage50 GB SSD100 GB NVMe250 GB+ NVMe
Media StorageVariableSSD for thumbnailsSSD for DB + HDD for media
GPUNot requiredNVIDIA GTX 1060+RTX 3060/4060 12GB

Storage Layout Recommendations

For optimal performance, consider this storage strategy:

/โ”€โ”€ NVMe SSD (Fast, Local)
โ”‚   โ”œโ”€โ”€ /var/lib/postgresql (Database) โ”€โ”€โ”€ CRITICAL: Never on NAS!
โ”‚   โ”œโ”€โ”€ /immich/thumbs (Thumbnails)
โ”‚   โ””โ”€โ”€ /immich/cache (Typesense/ML cache)
โ”‚
โ””โ”€โ”€ HDD Array or NAS
    โ””โ”€โ”€ /immich/library (Original photos/videos)

Operating System Compatibility

OSSupport LevelNotes
Linux (Ubuntu/Debian)โœ… BestRecommended for production
Linux (Other distros)โœ… GoodDocker works on most distros
Windows (WSL2)โš ๏ธ FunctionalPerformance overhead, NTFS issues
macOSโš ๏ธ FunctionalDocker Desktop limitations
Synology DSMโœ… GoodContainer Manager supported
Unraidโœ… GoodCommunity templates available

Filesystem Requirements

  • Recommended: EXT4, ZFS, APFS, Btrfs
  • Not Recommended: NTFS (Windows), exFAT
  • Critical: PostgreSQL database must be on local storage, never on network shares

Part 3: Docker Installation

This is the preferred setup for Immich.

Step 1: Remove Old Docker Versions

# Remove potentially conflicting packages
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
  sudo apt-get remove -y $pkg 2>/dev/null
done

What this does: Removes outdated Docker packages from the default repositories that might conflict with the official Docker installation.

Step 2: Add Dockerโ€™s Official Repository

# Update package index and install prerequisites
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# Create directory for keyrings
sudo install -m 0755 -d /etc/apt/keyrings

# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add Docker repository to apt sources
echo 
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu   $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | 
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

What this does: Adds Dockerโ€™s official package repository, ensuring you get the latest Docker version with all features and security updates.

Step 3: Install Docker Engine

# Update package index with new repository
sudo apt-get update

# Install Docker Engine and plugins
sudo apt-get install -y 
  docker-ce 
  docker-ce-cli 
  containerd.io 
  docker-buildx-plugin 
  docker-compose-plugin

Package breakdown:

  • docker-ce: Docker Community Edition (the engine)
  • docker-ce-cli: Command-line interface
  • containerd.io: Container runtime
  • docker-buildx-plugin: Enhanced build capabilities
  • docker-compose-plugin: Docker Compose V2 (uses docker compose instead of docker-compose)
# Add current user to docker group
sudo usermod -aG docker $USER

# Apply group changes (or log out and back in)
newgrp docker

What this does: Allows running Docker commands without sudo. You must log out and log back in for changes to take effect permanently.

Step 5: Verify Installation

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker with hello-world
docker run hello-world

Option B: Windows (Docker Desktop + WSL2)

โš ๏ธ Note: Windows installations may experience performance issues and NTFS-related problems. Linux is strongly recommended for production use.

Step 1: Install WSL2

Open PowerShell as Administrator:

# Install WSL with Ubuntu
wsl --install

# Restart your computer when prompted

Step 2: Install Docker Desktop

  1. Download Docker Desktop from docker.com
  2. Run the installer
  3. Critical: Ensure โ€œUse WSL 2 instead of Hyper-Vโ€ is checked
  4. Complete installation and restart if prompted

Step 3: Configure Docker Desktop

  1. Open Docker Desktop
  2. Navigate to Settings โ†’ Resources โ†’ WSL Integration
  3. Toggle ON your default WSL distro (usually Ubuntu)
  4. Click Apply & Restart

Step 4: Verify Installation

In PowerShell or Windows Terminal:

docker --version
docker compose version

Option C: macOS (Docker Desktop)

Step 1: Install Docker Desktop

  1. Download Docker Desktop from docker.com
    • Apple Silicon (M1/M2/M3/M4): Download the โ€œApple Chipโ€ version
    • Intel Macs: Download the โ€œIntel Chipโ€ version
  2. Drag Docker.app to Applications folder
  3. Launch Docker from Applications

Step 2: Configure Resources

  1. Open Docker Desktop
  2. Navigate to Settings โ†’ Resources
  3. Allocate at least 4GB RAM (8GB recommended)
  4. Enable โ€œUse Virtualization frameworkโ€ for Apple Silicon

Option D: Synology NAS (Container Manager)

Prerequisites

  • Synology DSM 7.2 or later
  • Container Manager package installed (from Package Center)
  • At least 4GB RAM (8GB recommended)

Step 1: Create Folder Structure

Using File Station, create the following folder structure:

/docker/immich-app/
โ”œโ”€โ”€ postgres/
โ”œโ”€โ”€ library/
โ”œโ”€โ”€ .env (file)
โ””โ”€โ”€ docker-compose.yml (file)

Step 2: Download Configuration Files

On your computer, download:

Upload these files to /docker/immich-app/ using File Station.

Step 3: Configure Environment File

  1. Rename example.env to .env
  2. Edit the file (you may need to rename to .env.txt to edit, then rename back)
  3. Key changes:
    • UPLOAD_LOCATION=/volume1/docker/immich-app/library
    • DB_DATA_LOCATION=/volume1/docker/immich-app/postgres
    • TZ=Your/Timezone
    • DB_PASSWORD=YourSecurePassword

Step 4: Create Project in Container Manager

  1. Open Container Manager โ†’ Project
  2. Click Create
  3. Set project name: immich-app
  4. Set path: /docker/immich-app
  5. Container Manager will detect docker-compose.yml
  6. Click Next โ†’ Done to build and start

Step 5: Configure Firewall (if enabled)

  1. Control Panel โ†’ Security โ†’ Firewall
  2. Create rule to allow port 2283

Part 4: Immich Configuration

Step 1: Create Project Directory

# Create and navigate to Immich directory
mkdir -p ~/immich-app
cd ~/immich-app

Step 2: Download Configuration Files

Linux/macOS:

# Download docker-compose.yml
wget -O docker-compose.yml 
  https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

# Download example.env and rename to .env
wget -O .env 
  https://github.com/immich-app/immich/releases/latest/download/example.env

Windows (PowerShell):

# Download docker-compose.yml
Invoke-WebRequest -Uri "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml" -OutFile "docker-compose.yml"

# Download example.env and rename to .env
Invoke-WebRequest -Uri "https://github.com/immich-app/immich/releases/latest/download/example.env" -OutFile ".env"

Step 3: Configure Environment Variables

Edit the .env file:

# Linux/macOS
nano .env

# Windows - use Notepad or your preferred editor
notepad .env

Essential Variables to Configure:

# ==========================================
# UPLOAD LOCATION - Where photos are stored
# ==========================================
# Linux: Use absolute path to your storage location
UPLOAD_LOCATION=/mnt/data/immich/library

# Windows: Use WSL-style path for Docker
# UPLOAD_LOCATION=/run/desktop/mnt/host/d/Photos/Immich

# ==========================================
# DATABASE LOCATION - MUST BE LOCAL SSD!
# ==========================================
# Never use NAS/network storage for database
DB_DATA_LOCATION=/var/lib/immich/postgres

# ==========================================
# TIMEZONE - Set to your local timezone
# ==========================================
# Find yours: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=America/New_York

# ==========================================
# IMMICH VERSION
# ==========================================
# Options: 'release' (stable), 'v1.x.x' (specific version)
IMMICH_VERSION=release

# ==========================================
# DATABASE PASSWORD - CHANGE THIS!
# ==========================================
# Use only alphanumeric characters (A-Za-z0-9)
# Avoid special characters that may cause parsing issues
DB_PASSWORD=YourSecureAlphanumericPassword123

# ==========================================
# DATABASE CONFIGURATION
# ==========================================
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

All Available Environment Variables:

VariableDescriptionDefault
UPLOAD_LOCATIONPath for uploaded photos/videos./library
DB_DATA_LOCATIONPath for PostgreSQL data./postgres
IMMICH_VERSIONDocker image version tagrelease
DB_PASSWORDPostgreSQL passwordpostgres
DB_USERNAMEPostgreSQL usernamepostgres
DB_DATABASE_NAMEDatabase nameimmich
TZTimezoneNone
IMMICH_LOG_LEVELLog verbosity (verbose/debug/log/warn/error)log
REDIS_URLCustom Redis connection stringInternal

Step 4: Create Required Directories

# Create directories for data storage
sudo mkdir -p /mnt/data/immich/library
sudo mkdir -p /var/lib/immich/postgres

# Set proper ownership (adjust user as needed)
sudo chown -R $USER:$USER /mnt/data/immich
sudo chown -R $USER:$USER /var/lib/immich

Part 5: Launching Immich

Step 1: Start the Containers

# Navigate to your Immich directory
cd ~/immich-app

# Pull images and start containers in detached mode
docker compose up -d

Command breakdown:

  • docker compose: The Docker Compose V2 command
  • up: Download images (if needed) and start containers
  • -d: Detached mode (runs in background)

Step 2: Monitor Startup

# Watch container logs in real-time
docker compose logs -f

# Press Ctrl+C to exit log view

Initial startup takes 2-5 minutes as the database initializes.

Step 3: Verify All Containers Are Running

# Check container status
docker compose ps

Expected output:

NAME                         STATUS          PORTS
immich_machine_learning      Up (healthy)
immich_postgres              Up (healthy)    
immich_redis                 Up (healthy)
immich_server                Up (healthy)    0.0.0.0:2283->2283/tcp

All containers should show โ€œUpโ€ status.

Step 4: Access Web Interface

  1. Open your browser
  2. Navigate to: http://YOUR_SERVER_IP:2283
    • Or http://localhost:2283 if running locally

Step 5: Create Admin Account

  1. Click โ€œGetting Startedโ€
  2. Create your administrator account:
    • Email: Your email address
    • Password: A strong, unique password
    • Name: Your display name
  3. Click Sign Up

Part 6: Mobile App Setup

Download the App

PlatformSource
iOSApp Store
AndroidGoogle Play
Android (F-Droid)F-Droid

Configure the App

Step 1: Connect to Server

  1. Open the Immich app
  2. Enter server URL: http://YOUR_SERVER_IP:2283/api
    • Note the /api suffix is required for some versions
  3. Tap Connect

๐Ÿ’ก Tip: For external access, youโ€™ll need to set up a reverse proxy with HTTPS (covered later in this guide).

Step 2: Log In

Enter your Immich account credentials (the admin account or a user account).

Step 3: Configure Auto Backup

  1. After logging in, tap the cloud icon (top right)
  2. Tap Select albums to backup
  3. Choose albums to sync (e.g., โ€œCameraโ€, โ€œRecentโ€)
  4. Configure backup options:
    • Automatic Foreground Backup: Uploads when app is open
    • Automatic Background Backup: Uploads periodically in background
    • Wi-Fi Only: Only upload on Wi-Fi connections

Platform-Specific Optimization

iOS Background Backup

For reliable background uploads on iOS:

  1. Open Settings โ†’ General โ†’ Background App Refresh
  2. Ensure Immich is toggled ON
  3. Consider enabling Location permission for the app (helps iOS wake the app)

Android Battery Optimization

Android may kill background apps aggressively. To prevent this:

  1. Open device Settings
  2. Navigate to Apps โ†’ Immich โ†’ Battery
  3. Set to Unrestricted or No restrictions
  4. Visit dontkillmyapp.com for device-specific instructions

Part 7: External Libraries (Import Existing Photos)

Immichโ€™s External Library feature lets you view, search, and enjoy AI features on existing photo collections without copying files.

Understanding External Libraries

AspectUpload LibraryExternal Library
Files managed by Immichโœ… YesโŒ No
Files can be deleted via Immichโœ… YesโŒ No (read-only)
AI/ML featuresโœ… Fullโœ… Full
Supports NAS storageโš ๏ธ Not recommendedโœ… Yes

Step 1: Mount External Storage to Docker

Edit your docker-compose.yml:

services:
  immich-server:
    # ... existing configuration ...
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      # Add your external library mounts:
      - /mnt/nas/photos:/external/nas-photos:ro
      - /mnt/usb-drive/pictures:/external/usb-pictures:ro

Path format: /host/path:/container/path:ro

  • Left side: Path on your host machine
  • Right side: Path inside the Docker container
  • :ro: Read-only access (recommended for external libraries)

Step 2: Restart Immich

docker compose down
docker compose up -d

Step 3: Add External Library in Web UI

  1. Log in to Immich web interface as admin
  2. Navigate to Administration โ†’ External Libraries
  3. Click Create Library
  4. Configure:
    • Owner: Select the user who will own this library
    • Name: Descriptive name (e.g., โ€œNAS Photosโ€)
    • Import Path: /external/nas-photos (the container path)
  5. Click Create

Step 4: Scan the Library

  1. Click the three dots menu next to your new library
  2. Click Scan Library
  3. Wait for the scan to complete (may take hours for large libraries)

Automatic Scanning

Configure automatic rescanning for new photos:

  1. Go to Administration โ†’ Settings โ†’ Library
  2. Enable Watch for file changes
  3. Set Scan interval (e.g., every 24 hours)

Part 8: Reverse Proxy Setup (HTTPS)

For security and external access, you should run Immich behind a reverse proxy with HTTPS.

Important Requirements

  • Immich must be served at the root path of a domain (not a sub-path like /immich)
  • Required headers: Host, X-Real-IP, X-Forwarded-Proto, X-Forwarded-For
  • Large upload support: client_max_body_size 50000M or equivalent
  • Timeout: At least 10 minutes (600 seconds)

Option A: Nginx Reverse Proxy

Step 1: Install Nginx and Certbot

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx

Step 2: Create Nginx Configuration

Create /etc/nginx/sites-available/immich:

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name photos.yourdomain.com;
    
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS Server
server {
    listen 443 ssl http2;
    server_name photos.yourdomain.com;

    # SSL Configuration (will be filled by certbot)
    ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;

    # Allow large uploads (50GB)
    client_max_body_size 50000M;
    
    # Optimize upload buffering
    client_body_buffer_size 512k;
    proxy_request_buffering off;

    # Timeouts for long-running operations
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    send_timeout 600s;

    location / {
        proxy_pass http://127.0.0.1:2283;
        
        # Required headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Step 3: Enable the Site

# Create symlink to enable site
sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# If test passes, reload Nginx
sudo systemctl reload nginx

Step 4: Obtain SSL Certificate

sudo certbot --nginx -d photos.yourdomain.com

Follow the prompts to complete certificate issuance.


Option B: Traefik Reverse Proxy

If youโ€™re using Traefik (v3), add labels to your docker-compose.yml:

services:
  immich-server:
    # ... existing configuration ...
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.immich.rule=Host(`photos.yourdomain.com`)"
      - "traefik.http.routers.immich.entrypoints=websecure"
      - "traefik.http.routers.immich.tls.certresolver=myresolver"
      - "traefik.http.services.immich.loadbalancer.server.port=2283"

Critical: Increase Traefik timeout to prevent video upload failures:

In your Traefik configuration:

entryPoints:
  websecure:
    address: ":443"
    transport:
      respondingTimeouts:
        readTimeout: 600s
        writeTimeout: 600s

Option C: Cloudflare Tunnel

For users who canโ€™t open ports, Cloudflare Tunnel provides a secure alternative:

  1. Install cloudflared on your server
  2. Create a tunnel in Cloudflare Dashboard
  3. Add a public hostname pointing to http://localhost:2283

โš ๏ธ Note: Cloudflareโ€™s 100MB upload limit on free plans may interfere with large video uploads.


Part 9: GPU Acceleration (Machine Learning)

GPU acceleration dramatically speeds up facial recognition, object detection, and CLIP search indexing.

Supported Backends

BackendGPU TypeNotes
CUDANVIDIABest performance, requires driver 545+
OpenVINOIntel (Arc/iGPU)Good for Intel systems
ROCmAMDExperimental
ARM NNARM MaliFor ARM devices

CUDA Setup (NVIDIA GPUs)

Requirements

  • NVIDIA GPU with Compute Capability 5.2 or higher
  • NVIDIA Driver version 545 or newer
  • NVIDIA Container Toolkit installed

Step 1: Install NVIDIA Container Toolkit

# Add NVIDIA repository
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | 
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | 
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | 
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Install toolkit
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# Configure Docker to use NVIDIA runtime
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Step 2: Download Hardware Acceleration Config

cd ~/immich-app

# Download hwaccel.ml.yml
wget -O hwaccel.ml.yml 
  https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml

Step 3: Modify docker-compose.yml

Edit your docker-compose.yml to enable CUDA:

services:
  immich-machine-learning:
    container_name: immich_machine_learning
    # Change image to CUDA variant
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
    extends:
      file: hwaccel.ml.yml
      service: cuda  # Use 'cuda' backend
    volumes:
      - model-cache:/cache
    restart: always

Step 4: Restart Immich

docker compose down
docker compose up -d

Step 5: Verify GPU Usage

# Check if GPU is being used
nvidia-smi

# Check ML container logs
docker logs immich_machine_learning

OpenVINO Setup (Intel GPUs)

Step 1: Modify docker-compose.yml

services:
  immich-machine-learning:
    container_name: immich_machine_learning
    # Change image to OpenVINO variant
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-openvino
    extends:
      file: hwaccel.ml.yml
      service: openvino  # Use 'openvino' backend
    volumes:
      - model-cache:/cache
    restart: always

Part 10: Backup and Restore

Proper backups are critical. Immich stores metadata in PostgreSQL and cannot rebuild from photos alone.

What to Backup

ItemLocationMethodPriority
DatabasePostgreSQLpg_dumpallCRITICAL
Original PhotosUPLOAD_LOCATION/libraryFile copyCRITICAL
Uploads in ProgressUPLOAD_LOCATION/uploadFile copyHigh
Profile PicturesUPLOAD_LOCATION/profileFile copyHigh
ThumbnailsUPLOAD_LOCATION/thumbsSkip (regeneratable)Low
Transcoded VideosUPLOAD_LOCATION/encoded-videoSkip (regeneratable)Low

Database Backup

Linux Backup Command

# Create database backup with timestamp
docker exec -t immich_postgres pg_dumpall 
  --clean --if-exists --username=postgres | 
  gzip > "/backup/immich-db-$(date +%Y%m%d-%H%M%S).sql.gz"

Windows PowerShell Backup Command

docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgres > "C:ackupimmich-db.sql"

Automated Backup Script

Create /usr/local/bin/backup-immich.sh:

#!/bin/bash

# Configuration
BACKUP_DIR="/backup/immich"
IMMICH_DIR="/home/user/immich-app"
UPLOAD_LOCATION="/mnt/data/immich/library"
RETENTION_DAYS=30

# Create backup directory
mkdir -p "$BACKUP_DIR"
DATE=$(date +%Y%m%d-%H%M%S)

# Backup database
echo "Backing up database..."
docker exec -t immich_postgres pg_dumpall 
  --clean --if-exists --username=postgres | 
  gzip > "$BACKUP_DIR/db-$DATE.sql.gz"

# Backup photos (incremental using rsync)
echo "Backing up photos..."
rsync -av --delete 
  "$UPLOAD_LOCATION/library/" 
  "$BACKUP_DIR/library/"

rsync -av --delete 
  "$UPLOAD_LOCATION/upload/" 
  "$BACKUP_DIR/upload/"

rsync -av --delete 
  "$UPLOAD_LOCATION/profile/" 
  "$BACKUP_DIR/profile/"

# Cleanup old database backups
find "$BACKUP_DIR" -name "db-*.sql.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup completed: $DATE"

Make it executable and schedule with cron:

chmod +x /usr/local/bin/backup-immich.sh

# Add to crontab (daily at 3 AM)
echo "0 3 * * * /usr/local/bin/backup-immich.sh" | crontab -

Database Restore

โš ๏ธ Warning: Restore requires a fresh Immich installation. Existing data will be lost.

Step 1: Stop Immich and Reset Database

cd ~/immich-app

# Stop all containers and remove database volume
docker compose down -v

# Pull latest images
docker compose pull

# Create containers without starting
docker compose create

# Start only PostgreSQL
docker start immich_postgres

# Wait for PostgreSQL to initialize
sleep 15

Step 2: Restore Database

# Restore from backup (Linux)
gunzip < "/backup/immich-db-20260109.sql.gz" | 
  docker exec -i immich_postgres psql --username=postgres

# Restore from backup (Windows PowerShell)
Get-Content "C:ackupimmich-db.sql" | docker exec -i immich_postgres psql --username=postgres

Step 3: Start All Services

docker compose up -d

Step 4: Restore Photo Files

Ensure your backed-up library, upload, and profile folders are in the correct UPLOAD_LOCATION path.


Part 11: OAuth/SSO Authentication

Immich supports OpenID Connect (OIDC) for single sign-on integration.

Supported Identity Providers

  • Authelia
  • Authentik
  • Keycloak
  • Google Workspace
  • Any OIDC-compatible provider

Authentik Setup Example

Step 1: Create Application in Authentik

  1. Log in to Authentik admin
  2. Go to Applications โ†’ Applications โ†’ Create with Provider
  3. Configure:
    • Name: Immich
    • Provider Type: OAuth2/OpenID Connect
    • Client ID: Note this value
    • Client Secret: Note this value
    • Redirect URIs:
      • https://photos.yourdomain.com/auth/login
      • https://photos.yourdomain.com/user-settings
      • app.immich:///oauth-callback

Step 2: Configure Immich

  1. In Immich, go to Administration โ†’ Settings โ†’ OAuth Authentication
  2. Enable OAuth
  3. Configure:
    • Issuer URL: https://authentik.yourdomain.com/application/o/immich/.well-known/openid-configuration
    • Client ID: (from Authentik)
    • Client Secret: (from Authentik)
    • Scope: openid email profile
    • Auto Register: Enable to auto-create users
    • Auto Launch: Enable to redirect to OAuth automatically

Authelia Setup Example

Add to Authelia configuration (configuration.yml):

identity_providers:
  oidc:
    clients:
      - id: immich
        description: Immich Photos
        secret: '$pbkdf2-sha512$...'  # Hashed secret
        redirect_uris:
          - https://photos.yourdomain.com/auth/login
          - https://photos.yourdomain.com/user-settings
          - app.immich:///oauth-callback
        scopes:
          - openid
          - profile
          - email
        grant_types:
          - authorization_code
        token_endpoint_auth_method: client_secret_basic

Part 12: Troubleshooting

Common Issues and Solutions

Issue: โ€œConnection Refusedโ€ / Cannot Access Web UI

Check container status:

docker compose ps

Check container logs:

docker compose logs immich-server

Verify port binding:

docker port immich_server
# Should show: 2283/tcp -> 0.0.0.0:2283

Firewall check (Linux):

sudo ufw allow 2283

Issue: โ€œError Loading Imageโ€ / Missing Thumbnails

Regenerate thumbnails:

  1. Go to Administration โ†’ Jobs
  2. Run Generate Thumbnails for all assets

Force regenerate:

docker compose exec -T immich-server npm run cli -- jobs run thumbnails --all

Issue: Machine Learning Not Working

Check ML container logs:

docker logs immich_machine_learning

Verify ML container is healthy:

docker compose ps immich-machine-learning

Common causes:

  • Insufficient RAM (need 4GB minimum)
  • CPU doesnโ€™t support AVX instructions (older CPUs)

Issue: Database Errors / Crash Loop

Cause: Database on network storage or corrupt database

Check database location:

echo $DB_DATA_LOCATION
# Must be local storage, NOT NAS

Repair database:

docker exec -it immich_postgres psql -U postgres -c "REINDEX DATABASE immich; VACUUM FULL;"

Issue: iOS App Canโ€™t Connect on Local Network

Check router settings:

  • Enable โ€œHairpin NATโ€ or โ€œNAT Loopbackโ€ on your router

Check iOS settings:

  1. Settings โ†’ Privacy & Security โ†’ Local Network
  2. Ensure Immich is toggled ON

Issue: Uploads Failing (Error 499)

Cause: Reverse proxy timeout too short

Fix for Nginx:

proxy_read_timeout 600s;
proxy_send_timeout 600s;

Fix for Traefik:

entryPoints:
  websecure:
    transport:
      respondingTimeouts:
        readTimeout: 600s

Viewing Logs

# All containers
docker compose logs -f

# Specific container
docker compose logs -f immich-server
docker compose logs -f immich-machine-learning
docker compose logs -f immich-postgres

Part 13: Maintenance and Updates

Updating Immich

cd ~/immich-app

# Download latest configuration files
wget -O docker-compose.yml 
  https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

# Pull new images
docker compose pull

# Recreate containers with new images
docker compose up -d

# (Optional) Remove old unused images
docker image prune -f

๐Ÿ’ก Tip: Always backup your database before updating!

Version Pinning

For production stability, pin to a specific version in .env:

IMMICH_VERSION=v1.125.0

Health Checks

Check all services are healthy:

docker compose ps

Check disk space:

df -h

Check container resource usage:

docker stats

Part 14: Best Practices Summary

Security

  • โœ… Always use HTTPS in production (reverse proxy)
  • โœ… Never expose port 2283 directly to internet
  • โœ… Use strong, unique passwords
  • โœ… Enable OAuth/SSO when possible
  • โœ… Keep Immich updated

Performance

  • โœ… PostgreSQL database on local SSD (never NAS)
  • โœ… Consider GPU acceleration for large libraries
  • โœ… Use external libraries for NAS storage
  • โœ… Allocate sufficient RAM (8GB+ recommended)

Reliability

  • โœ… Implement 3-2-1 backup strategy
  • โœ… Backup database regularly (daily)
  • โœ… Test restore procedures periodically
  • โœ… Monitor disk space and logs

Data Safety

  • โš ๏ธ Immich is NOT a backup solution by itself
  • โœ… Maintain original copies of important photos
  • โœ… Use cloud backup services as additional layer
  • โœ… Document your configuration for disaster recovery

Conclusion

You now have a comprehensive understanding of Immich deployment, from basic installation to advanced configurations. Whether youโ€™re running Immich on a simple home server or a complex NAS setup with GPU acceleration and OAuth, this guide provides the foundation for a robust, private photo management solution.

Next Steps

  1. Start simple: Get basic Immich running first
  2. Add security: Set up reverse proxy with HTTPS
  3. Optimize: Consider GPU acceleration for large libraries
  4. Automate: Implement automated backups
  5. Expand: Add external libraries and family members

Resources


Last updated: January 2026 | Compatible with Immich v2.x

Comments

Sign in to join the discussion!

Your comments help others in the community.