How to Self-Host Immich on a VPS: Private Google Photos Alternative with AI Face Recognition

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

  1. Visit https://photos.yourdomain.com
  2. Create the first admin account
  3. Admin Console → Users → create accounts for family members
  4. Admin Console → Settings → configure storage template for organized file storage

Step 4: Mobile App Configuration

  1. Install Immich from App Store / Google Play
  2. Server URL: https://photos.yourdomain.com
  3. Log in with your account credentials
  4. Backup → enable auto-backup, select albums, set Wi-Fi-only or always-on
  5. 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.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!