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?
| Feature | Description |
|---|---|
| AI-Powered Search | CLIP-based semantic search (โphotos of dogs at beachโ) |
| Facial Recognition | Automatic face detection and grouping |
| Mobile App | Native iOS and Android apps with auto-backup |
| Timeline View | Google Photos-like experience |
| External Libraries | Index existing photo collections without moving files |
| Hardware Acceleration | GPU support for ML and video transcoding |
| Multi-User Support | Family 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) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ | Container | Purpose | Notes |
|---|---|---|
immich-server | Web interface, API, background tasks | Main entry point for users |
immich-machine-learning | Facial recognition, CLIP search, object detection | Can be GPU-accelerated |
postgres | Stores all metadata, user data, album info | Must be on local SSD |
redis | Job queue coordination, caching | In-memory database |
Critical Data Locations
Understanding where Immich stores data is essential for backups:
| Location | Contains | Backup Priority |
|---|---|---|
UPLOAD_LOCATION/library | Original uploaded photos/videos | CRITICAL |
UPLOAD_LOCATION/upload | Files being processed | Important |
UPLOAD_LOCATION/profile | User profile pictures | Important |
UPLOAD_LOCATION/thumbs | Generated thumbnails | Can regenerate |
UPLOAD_LOCATION/encoded-video | Transcoded videos | Can regenerate |
DB_DATA_LOCATION | PostgreSQL database files | CRITICAL |
Part 2: System Requirements
Hardware Requirements
| Component | Minimum | Recommended | Large Libraries (500K+ assets) |
|---|---|---|---|
| RAM | 4 GB | 8 GB | 32-64 GB |
| CPU | 2 cores | 4 cores | 8+ cores (modern AMD/Intel) |
| OS Storage | 50 GB SSD | 100 GB NVMe | 250 GB+ NVMe |
| Media Storage | Variable | SSD for thumbnails | SSD for DB + HDD for media |
| GPU | Not required | NVIDIA 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
| OS | Support Level | Notes |
|---|---|---|
| Linux (Ubuntu/Debian) | โ Best | Recommended for production |
| Linux (Other distros) | โ Good | Docker works on most distros |
| Windows (WSL2) | โ ๏ธ Functional | Performance overhead, NTFS issues |
| macOS | โ ๏ธ Functional | Docker Desktop limitations |
| Synology DSM | โ Good | Container Manager supported |
| Unraid | โ Good | Community 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
Option A: Linux (Ubuntu/Debian) - Recommended
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 interfacecontainerd.io: Container runtimedocker-buildx-plugin: Enhanced build capabilitiesdocker-compose-plugin: Docker Compose V2 (usesdocker composeinstead ofdocker-compose)
Step 4: Configure Non-Root Access (Optional but Recommended)
# 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
- Download Docker Desktop from docker.com
- Run the installer
- Critical: Ensure โUse WSL 2 instead of Hyper-Vโ is checked
- Complete installation and restart if prompted
Step 3: Configure Docker Desktop
- Open Docker Desktop
- Navigate to Settings โ Resources โ WSL Integration
- Toggle ON your default WSL distro (usually Ubuntu)
- 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
- Download Docker Desktop from docker.com
- Apple Silicon (M1/M2/M3/M4): Download the โApple Chipโ version
- Intel Macs: Download the โIntel Chipโ version
- Drag Docker.app to Applications folder
- Launch Docker from Applications
Step 2: Configure Resources
- Open Docker Desktop
- Navigate to Settings โ Resources
- Allocate at least 4GB RAM (8GB recommended)
- 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:
docker-compose.ymlfrom Immich GitHub releasesexample.envfrom Immich GitHub releases
Upload these files to /docker/immich-app/ using File Station.
Step 3: Configure Environment File
- Rename
example.envto.env - Edit the file (you may need to rename to
.env.txtto edit, then rename back) - Key changes:
UPLOAD_LOCATION=/volume1/docker/immich-app/libraryDB_DATA_LOCATION=/volume1/docker/immich-app/postgresTZ=Your/TimezoneDB_PASSWORD=YourSecurePassword
Step 4: Create Project in Container Manager
- Open Container Manager โ Project
- Click Create
- Set project name:
immich-app - Set path:
/docker/immich-app - Container Manager will detect
docker-compose.yml - Click Next โ Done to build and start
Step 5: Configure Firewall (if enabled)
- Control Panel โ Security โ Firewall
- 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:
| Variable | Description | Default |
|---|---|---|
UPLOAD_LOCATION | Path for uploaded photos/videos | ./library |
DB_DATA_LOCATION | Path for PostgreSQL data | ./postgres |
IMMICH_VERSION | Docker image version tag | release |
DB_PASSWORD | PostgreSQL password | postgres |
DB_USERNAME | PostgreSQL username | postgres |
DB_DATABASE_NAME | Database name | immich |
TZ | Timezone | None |
IMMICH_LOG_LEVEL | Log verbosity (verbose/debug/log/warn/error) | log |
REDIS_URL | Custom Redis connection string | Internal |
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 commandup: 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
- Open your browser
- Navigate to:
http://YOUR_SERVER_IP:2283- Or
http://localhost:2283if running locally
- Or
Step 5: Create Admin Account
- Click โGetting Startedโ
- Create your administrator account:
- Email: Your email address
- Password: A strong, unique password
- Name: Your display name
- Click Sign Up
Part 6: Mobile App Setup
Download the App
| Platform | Source |
|---|---|
| iOS | App Store |
| Android | Google Play |
| Android (F-Droid) | F-Droid |
Configure the App
Step 1: Connect to Server
- Open the Immich app
- Enter server URL:
http://YOUR_SERVER_IP:2283/api- Note the
/apisuffix is required for some versions
- Note the
- 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
- After logging in, tap the cloud icon (top right)
- Tap Select albums to backup
- Choose albums to sync (e.g., โCameraโ, โRecentโ)
- 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:
- Open Settings โ General โ Background App Refresh
- Ensure Immich is toggled ON
- Consider enabling Location permission for the app (helps iOS wake the app)
Android Battery Optimization
Android may kill background apps aggressively. To prevent this:
- Open device Settings
- Navigate to Apps โ Immich โ Battery
- Set to Unrestricted or No restrictions
- 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
| Aspect | Upload Library | External 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
- Log in to Immich web interface as admin
- Navigate to Administration โ External Libraries
- Click Create Library
- 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)
- Click Create
Step 4: Scan the Library
- Click the three dots menu next to your new library
- Click Scan Library
- Wait for the scan to complete (may take hours for large libraries)
Automatic Scanning
Configure automatic rescanning for new photos:
- Go to Administration โ Settings โ Library
- Enable Watch for file changes
- 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 50000Mor 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:
- Install
cloudflaredon your server - Create a tunnel in Cloudflare Dashboard
- 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
| Backend | GPU Type | Notes |
|---|---|---|
| CUDA | NVIDIA | Best performance, requires driver 545+ |
| OpenVINO | Intel (Arc/iGPU) | Good for Intel systems |
| ROCm | AMD | Experimental |
| ARM NN | ARM Mali | For 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
| Item | Location | Method | Priority |
|---|---|---|---|
| Database | PostgreSQL | pg_dumpall | CRITICAL |
| Original Photos | UPLOAD_LOCATION/library | File copy | CRITICAL |
| Uploads in Progress | UPLOAD_LOCATION/upload | File copy | High |
| Profile Pictures | UPLOAD_LOCATION/profile | File copy | High |
| Thumbnails | UPLOAD_LOCATION/thumbs | Skip (regeneratable) | Low |
| Transcoded Videos | UPLOAD_LOCATION/encoded-video | Skip (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
- Log in to Authentik admin
- Go to Applications โ Applications โ Create with Provider
- 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/loginhttps://photos.yourdomain.com/user-settingsapp.immich:///oauth-callback
Step 2: Configure Immich
- In Immich, go to Administration โ Settings โ OAuth Authentication
- Enable OAuth
- 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
- Issuer URL:
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:
- Go to Administration โ Jobs
- 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:
- Settings โ Privacy & Security โ Local Network
- 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
- Start simple: Get basic Immich running first
- Add security: Set up reverse proxy with HTTPS
- Optimize: Consider GPU acceleration for large libraries
- Automate: Implement automated backups
- Expand: Add external libraries and family members
Resources
- Official Documentation: immich.app/docs
- GitHub Repository: github.com/immich-app/immich
- Community Discord: discord.gg/immich
- Reddit: r/immich
Last updated: January 2026 | Compatible with Immich v2.x
Comments
Sign in to join the discussion!
Your comments help others in the community.