How to Self-Host Immich on a VPS: Private Google Photos Alternative with AI Face Recognition
Immich is a high-performance, self-hosted photo and video backup solution with a Google Photos-like experience — automatic mobile backup, timeline view, face recognition, object detection, album sharing, map view, and a polished web and mobile interface. Google Photos charges $3/month for 100 GB and $10/month for 2 TB. Self-hosting Immich on a VPS gives you unlimited storage at disk cost, full data ownership, and privacy from cloud ML processing.
What Immich Provides
- Auto-backup: iOS and Android apps back up photos and videos automatically over Wi-Fi or cellular
- Face recognition: Groups photos by person using local ML inference — no data leaves your server
- Smart search: Search by object (“cat”, “beach”, “birthday cake”) using CLIP embeddings
- Timeline & albums: Chronological photo timeline, shared albums, partner sharing
- Map view: Photos plotted on a map using EXIF GPS data
- Video transcoding: Hardware-accelerated transcoding for browser playback
- Multi-user: Separate libraries per user, admin console
Server Requirements
- Minimum 2 GB RAM (4 GB recommended — ML models use 1–2 GB)
- Docker and Docker Compose
- Storage: depends on photo library size (photos compress to ~3–5 MB each; 10,000 photos ≈ 40 GB)
- CPU with AVX support (most modern VPS CPUs qualify)
Step 1: Download and Configure
mkdir -p /opt/immich && cd /opt/immich
wget -O docker-compose.yml \
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
nano .env
<code"># Required configuration: UPLOAD_LOCATION=/opt/immich/library # Where photos are stored on disk THUMBS_LOCATION=/opt/immich/thumbs # Thumbnail cache PROFILE_LOCATION=/opt/immich/profile # Profile photos VIDEO_LOCATION=/opt/immich/encoded-video # Transcoded video cache # Database DB_PASSWORD=StrongImmichDbPassword! DB_USERNAME=postgres DB_DATABASE_NAME=immich # Leave IMMICH_VERSION blank for latest IMMICH_VERSION= # Machine learning (keep enabled for face recognition and smart search) MACHINE_LEARNING_ENABLED=true
<code">mkdir -p /opt/immich/{library,thumbs,profile,encoded-video}
chmod 700 /opt/immich/library # Protect photo storage
chmod 600 .env
docker compose up -d
docker compose logs -f immich-server # Wait for startup
Step 2: Nginx Reverse Proxy
<code">sudo nano /etc/nginx/sites-available/immich
<code">server {
listen 80;
server_name photos.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name photos.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;
# Allow large video uploads
client_max_body_size 50000M;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
location / {
proxy_pass http://127.0.0.1:2283;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
# Required for large file uploads
proxy_request_buffering off;
}
}
<code">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
Step 3: Initial Setup
- Visit
https://photos.yourdomain.com - Create the first admin account
- Admin Console → Users → create accounts for family members
- Admin Console → Settings → configure storage template for organized file storage
Step 4: Mobile App Configuration
- Install Immich from App Store / Google Play
- Server URL:
https://photos.yourdomain.com - Log in with your account credentials
- Backup → enable auto-backup, select albums, set Wi-Fi-only or always-on
- Immich will begin uploading existing photos and backup new ones automatically
Step 5: Machine Learning Configuration
<code"># Machine learning runs as a separate container (immich-machine-learning)
# It handles:
# - Face detection and recognition (InsightFace model)
# - CLIP embeddings for smart object/scene search
# - Smart albums: "Sports", "Nature", "Documents"
# After first upload, trigger ML processing:
# Admin → Jobs → Run all failed jobs
# ML model storage location (downloaded automatically on first run):
# docker volume: immich_model-cache
# Tune ML container memory limit if needed:
# docker-compose.yml:
services:
immich-machine-learning:
deploy:
resources:
limits:
memory: 2G # Reduce to 1G on low-RAM VPS
Step 6: External Library (Import Existing Photos)
<code"># If you have existing photos on the VPS: # Admin → External Libraries → Create Library # Path: /mnt/existing-photos (mount your photo directory here) # Add to docker-compose.yml volumes: volumes: - /your/existing/photos:/mnt/existing-photos:ro # Read-only mount # Immich scans and imports metadata without copying files docker compose exec immich-server immich-admin media import
Step 7: S3-Compatible Storage (Cloudflare R2)
<code"># For very large photo libraries, store on S3 instead of VPS disk # Admin → Settings → Storage → S3 # Cloudflare R2 configuration (free egress): S3_ENDPOINT: https://ACCOUNT_ID.r2.cloudflarestorage.com S3_REGION: auto S3_BUCKET: immich-photos S3_ACCESS_KEY: your_r2_access_key S3_SECRET_KEY: your_r2_secret_key # Benefits: unlimited storage at $0.015/GB/month, no VPS disk limits
Backup Immich Data
<code"># Backup PostgreSQL database (metadata — face assignments, albums, users)
docker exec immich-postgres pg_dumpall -U postgres | \
gzip > /opt/backups/immich-db-$(date +%Y%m%d).sql.gz
# Backup photo library (or use Restic for encrypted backups to S3)
restic backup /opt/immich/library \
--tag immich \
--exclude /opt/immich/thumbs \
--exclude /opt/immich/encoded-video
# Note: thumbs and encoded-video can be regenerated — only backup library and DB
Updating Immich
<code">cd /opt/immich docker compose pull docker compose up -d # Check release notes before major updates: # https://github.com/immich-app/immich/releases
Getting Started
Immich with machine learning enabled needs 4 GB RAM — a 4 GB Ubuntu VPS at VPS.DO with large NVMe storage is the recommended configuration. Without machine learning (disable MACHINE_LEARNING_ENABLED), Immich runs on 2 GB RAM but loses face recognition and smart search. NVMe storage matters for photo serving performance — thumbnail generation and video streaming both benefit from fast I/O.
Conclusion
Self-hosted Immich delivers a Google Photos-quality experience — automatic mobile backup, AI face recognition, smart search, timeline view, and album sharing — with complete data privacy and no per-GB fees. For families with 50,000+ photos currently in Google Photos or iCloud, the combination of Immich on a VPS plus Cloudflare R2 storage costs $5–$15/month versus $10–$30/month for cloud storage, with the added benefit of data ownership and no vendor lock-in.