How to Self-Host Immich in 2026: Complete Setup Guide
What You're Setting Up
Immich (90K+ GitHub stars) replicates the Google Photos experience on your own server:
- Automatic backup from iOS and Android (native apps)
- AI-powered search ("find all photos of dogs at the beach")
- Face recognition with named people
- Timeline view, memories, shared albums
- Video support with transcoding
This guide takes you from zero to a production-ready Immich installation with mobile backup configured and AI features working.
Server Requirements
Minimum (Small Library, CPU Only)
- 2 CPU cores
- 4GB RAM
- Storage: enough for your photo library + 20% overhead for thumbnails and ML models
Recommended (Full AI Features)
- 4+ CPU cores
- 8GB RAM
- Storage: library + thumbnails (plan for 2-5x raw storage)
With GPU Acceleration
- NVIDIA GPU (compute capability 5.2+, driver 545+)
- 4GB VRAM minimum
- GPU dramatically speeds AI indexing (hours → minutes for large libraries)
Recommended Servers (Hetzner)
| Use Case | Server | Monthly |
|---|---|---|
| Personal (no GPU) | CAX21 (4GB ARM) | $6 |
| Family/team (no GPU) | CPX31 (8GB) | $10 |
| Fast AI indexing | CCX33 (16GB dedicated) | $35 |
Storage: Photo libraries grow. Use Hetzner Volumes ($0.044/GB/month) attached to your server rather than local SSD, or Hetzner Storage Box for S3-compatible storage.
Step 1: Prepare Your Server
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker and Docker Compose
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group change to take effect
# Verify
docker --version
docker compose version
Create Directory Structure
sudo mkdir -p /opt/immich
sudo chown $USER:$USER /opt/immich
mkdir -p /opt/immich/library
The /opt/immich/library directory stores your actual photos. If you're using a separate volume for storage, mount it to this path.
Step 2: Configure Immich
Download Configuration Files
cd /opt/immich
wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
Edit the .env File
nano .env
Set these critical values:
# Strong password - letters and numbers only (no special characters)
DB_PASSWORD=YourStrongPassword123
# Where your photos are stored
UPLOAD_LOCATION=/opt/immich/library
# Immich version (use "release" for latest stable)
IMMICH_VERSION=release
# Your timezone
TZ=America/New_York
# Postgres settings
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
Review the Docker Compose File
The default docker-compose.yml includes:
immich-server: Main application and APIimmich-microservices: Background job processingimmich-machine-learning: AI/ML container for smart search and face recognitionredis: Job queuedatabase: PostgreSQL with pgvector extension
For basic setups, the default file works without modification.
Step 3: Start Immich
cd /opt/immich
docker compose up -d
Initial startup takes 2-5 minutes as the database initializes. Monitor progress:
docker compose logs -f immich-server
Wait until you see messages about the server starting successfully.
Verify Running Containers
docker compose ps
All containers should show "running" status. If any are restarting, check logs:
docker compose logs [service-name]
Step 4: Initial Configuration
Access Immich at http://your-server-ip:2283
Create Admin Account
The first user to register automatically becomes the admin. Register with your email and password.
After registering:
- Go to Administration → Server Settings
- Set your server's external URL (important for mobile app connection)
Import Existing Photos (Optional)
If you have an existing photo library to import:
# Install Immich CLI
npm install -g @immich/cli
# Authenticate
immich login https://your-server-ip:2283 your@email.com
# Import directory (preserves original dates from EXIF)
immich upload --recursive /path/to/your/photos/
# Import Google Takeout export
immich upload --recursive /path/to/takeout/Google\ Photos/
The CLI processes photos in batches and shows progress. For large libraries (100GB+), run in a screen session:
screen -S immich-import
immich upload --recursive /path/to/photos/
# Detach: Ctrl+A, D
# Reattach: screen -r immich-import
Step 5: Set Up the Mobile App
This is Immich's killer feature — automatic phone backup.
Install the App
- iOS: App Store → search "Immich"
- Android: Google Play or F-Droid → search "Immich"
Connect to Your Server
- Open the Immich app
- Enter your server URL:
http://your-server-ip:2283orhttps://your-domain.com - Log in with your Immich credentials
If using IP address: You need to be on the same network, or use a VPN (Tailscale, WireGuard) to access your home/server network remotely.
If using a domain with HTTPS: You can connect from anywhere without a VPN. Set up a reverse proxy (step 7) first.
Configure Backup
- Tap the cloud icon (top right)
- Toggle "Backup" to On
- Select which albums to back up (default: all camera roll photos)
- Configure:
- Background backup: On (backs up even when app is closed)
- Require charging: Recommended for large initial backups
- WiFi only: Recommended to avoid cellular data charges
Android-Specific: Battery Optimization
Android aggressively kills background apps. Disable battery optimization for Immich:
- Settings → Apps → Immich → Battery
- Select "Unrestricted" or "Don't optimize"
Without this, background backup may not trigger reliably.
iOS-Specific: Background App Refresh
- Settings → General → Background App Refresh
- Enable for Immich
Verify Backup
Back in the app, the backup status should show photos uploading. For large libraries, initial backup takes hours to days depending on library size and connection speed.
Check Immich web UI: Photos should appear as they upload. They'll be AI-indexed in the background after upload.
Step 6: Configure AI Features
Immich's machine learning container handles:
- Smart Search: Search photos by content ("beach", "birthday cake", "dog")
- Facial Recognition: Detect and group faces, assign names
Verify ML Container is Running
docker compose logs immich-machine-learning
You should see messages about model loading. On first run, Immich downloads AI models (~1-2GB). This takes 5-15 minutes.
Monitor Indexing Progress
In Immich web UI:
- Administration → Jobs
- Look for "Smart Search" and "Face Detection" jobs
- These run automatically after photo upload
Initial indexing of a large library (10,000+ photos) takes hours on CPU, minutes with GPU acceleration.
Enable GPU Acceleration (NVIDIA)
If your server has an NVIDIA GPU with compute capability 5.2+:
- 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
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
- Edit
docker-compose.yml— replace theimmich-machine-learningservice:
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
runtime: nvidia
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu
volumes:
- model-cache:/cache
env_file:
- .env
restart: always
- Restart Immich:
docker compose up -d immich-machine-learning
GPU acceleration reduces AI indexing time by 5-20x depending on GPU model.
Step 7: Set Up HTTPS with Reverse Proxy
For remote access without VPN and for the mobile app to work from anywhere.
Option A: Caddy (Simplest)
Install Caddy:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
Configure /etc/caddy/Caddyfile:
photos.yourdomain.com {
reverse_proxy localhost:2283
}
sudo systemctl restart caddy
Caddy automatically obtains and renews SSL certificates via Let's Encrypt.
Option B: Nginx with Certbot
sudo apt install -y nginx certbot python3-certbot-nginx
Create /etc/nginx/sites-available/immich:
server {
listen 80;
server_name photos.yourdomain.com;
client_max_body_size 50000M;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
location / {
proxy_pass http://localhost:2283;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo ln -s /etc/nginx/sites-available/immich /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d photos.yourdomain.com
Important: Set client_max_body_size 50000M (or higher) to allow large video uploads.
Update Server URL in Mobile App
After setting up HTTPS, update the mobile app's server URL from http://IP:2283 to https://photos.yourdomain.com.
Step 8: Backup Strategy
Immich stores your photos — losing this data would be catastrophic.
What to Back Up
- Photo library:
/opt/immich/library(or whereverUPLOAD_LOCATIONpoints) - Database: PostgreSQL database containing metadata, albums, faces
- Model cache: Optional (can be re-downloaded)
Database Backup
# Manual backup
docker exec -t immich_postgres pg_dumpall -c -U postgres | gzip > /opt/backups/immich-db-$(date +%Y%m%d).sql.gz
# Automated backup script (add to crontab)
#!/bin/bash
BACKUP_DIR="/opt/backups/immich"
mkdir -p "$BACKUP_DIR"
docker exec -t immich_postgres pg_dumpall -c -U postgres | gzip > "$BACKUP_DIR/db-$(date +%Y%m%d).sql.gz"
# Keep last 7 days
find "$BACKUP_DIR" -name "db-*.sql.gz" -mtime +7 -delete
Add to crontab (crontab -e):
0 2 * * * /opt/immich/backup.sh
Library Backup
For the photo library, use:
- Rclone to sync to Backblaze B2 or AWS S3
- rsync to a secondary server
- Hetzner Storage Box as a backup destination
# Rclone to Backblaze B2 (configure rclone first)
rclone sync /opt/immich/library b2:your-bucket-name/immich-library --progress
3-2-1 Rule for Photos
- 3 copies of your photos
- 2 different storage media
- 1 offsite copy
Immich server + cloud backup + original device = 3 copies, 2 media, 1 offsite. This protects against hardware failure, accidental deletion, and site disasters.
Step 9: User Management
Add Additional Users
- Administration → Users → Create User
- Set email, password, name
- Configure storage quota (optional): limit how much each user can upload
Share Albums
- Open any album → Share
- Invite other Immich users by email
- Or create a public share link (link sharing)
Shared albums allow family members or colleagues to contribute photos to a common collection.
Updating Immich
Immich releases frequently. Update process:
cd /opt/immich
docker compose pull
docker compose up -d
Check release notes at github.com/immich-app/immich/releases before updating major versions.
Cost Comparison
| Setup | Monthly | Annual |
|---|---|---|
| Google Photos 2TB | $9.99 | $120 |
| iCloud 2TB | $9.99 | $120 |
| Immich (Hetzner CAX21 + 2TB volume) | $4 + $8.80 | $153 |
| Immich (Hetzner CAX11 + Storage Box 2TB) | $4 + $4.36 | $100 |
At 2TB, self-hosting is roughly cost-neutral but with unlimited family members and no per-account fees. At 5TB+, self-hosting saves substantially.
The real value: full data ownership, no subscription cancellation risk, and AI search features that work privately on your own hardware.
Find More Photo Management Tools
Browse all Google Photos alternatives on OSSAlt — compare Immich, PhotoPrism, LibrePhotos, and every other open source photo management platform with deployment guides.