Skip to main content

Self-Host Immich: Google Photos Alternative 2026

·OSSAlt Team
immichself-hostedphoto managementgoogle photosdocker
Share:

Self-Host Immich: The Google Photos Alternative That Actually Works in 2026

TL;DR

Immich (94K+ GitHub stars, AGPL-3.0) is the closest self-hosted replacement for Google Photos that exists today. The mobile apps are native quality, face recognition works well enough to use daily, and the Docker Compose setup takes under 30 minutes. With Google Photos storage costs creeping up and growing concerns about AI training on personal photos, Immich has become the default recommendation for anyone moving off cloud photo storage.

Key Takeaways

  • 94K+ GitHub stars — the fastest-growing self-hosted photo project by far, surpassing PhotoPrism and LibrePhotos
  • Native iOS and Android apps — background sync, share sheets, and offline access that feel like first-party software
  • ML face recognition — powered by InsightFace, groups photos by person automatically with assignable names
  • Natural language search — uses CLIP embeddings so you can search "sunset at the beach" and find relevant photos
  • Hardware-accelerated ML — GPU acceleration for NVIDIA, AMD, OpenVINO, and Apple Silicon reduces indexing time by 10-20x
  • Google Takeout import — official importer preserves original dates and metadata from exports
  • 4GB RAM minimum — 8GB recommended when ML features are active

Why Immich Beats Google Photos in 2026

Google Photos changed its pricing model in 2021, ending the free unlimited storage tier. Since then, storage costs compound every year, and many users are now hitting the 15GB free limit or paying $2.99–$9.99/month for Google One. More concerning: Google's Terms of Service allow using uploaded content to improve AI services, which is a meaningful privacy consideration for family photos.

Immich addresses both problems: you own the storage and the data never leaves your server.

But "self-hosted photo manager" used to mean accepting significant quality gaps — slow apps, broken sync, face recognition that kind of worked. Immich closed those gaps. The mobile apps for iOS and Android are built with proper background sync that reliably uploads photos without requiring the app to be open. The face recognition groups family members accurately enough that many users have fully replaced their Google Photos workflow.

The timeline view matches Google Photos almost exactly. The memories feature resurfaces photos from years past. Shared albums work. Video transcoding works. Location maps work. At 94K+ GitHub stars as of March 2026, Immich has earned its reputation as the self-hosted photo tool that doesn't require compromises.


Server Requirements

Minimum (Small Library, CPU-Only ML)

  • 2 CPU cores
  • 4GB RAM
  • Storage: photo library size + 20% overhead for thumbnails and ML model weights (~2GB for models)
  • OS: any Linux distro with Docker, or macOS/Windows with Docker Desktop
  • 4+ CPU cores
  • 8GB RAM
  • NVMe or SSD storage (HDD works but thumbnail generation is slow)
  • Gigabit LAN if doing initial migration of large libraries

GPU Acceleration (Optional)

Immich supports hardware-accelerated ML inference for Smart Search and Face Recognition:

  • NVIDIA: CUDA via ghcr.io/immich-app/machine-learning:release-cuda
  • AMD: ROCm via ghcr.io/immich-app/machine-learning:release-rocm
  • Intel: OpenVINO via ghcr.io/immich-app/machine-learning:release-openvino
  • Apple Silicon: CoreML via ghcr.io/immich-app/machine-learning:release-armnn

Without GPU acceleration, ML tasks use CPU. On a 4-core machine, indexing 10,000 photos takes approximately 2–4 hours. With a mid-range GPU, the same job completes in 10–20 minutes.


Docker Compose Setup

Create a working directory and download the official config:

mkdir immich && cd immich
wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget https://github.com/immich-app/immich/releases/latest/download/.env.example
cp .env.example .env

Edit .env with your settings:

# Required: set your upload path
UPLOAD_LOCATION=./library

# Required: generate a random secret
DB_PASSWORD=your-strong-password-here

# Optional: timezone
TZ=America/New_York

The full docker-compose.yml from the official repo:

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - 2283:2283
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/machine-learning:${IMMICH_VERSION:-release}
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/redis:6.2-alpine@sha256:2d1463258f2764328496376f5d965f20c6a67f66ea2b06dc42af351f75248792
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: >-
        pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USERNAME}" || exit 1;
        Sleeptime=15;
        retries=5;
        while [ $retries -gt 0 ]; do
          sleep $Sleeptime;
          retries=$((retries - 1));
          Sleeptime=10;
          pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USERNAME}" && exit 0;
        done;
        exit 1
      interval: 10s
      start_period: 60s
    restart: always

volumes:
  model-cache:

Start Immich:

docker compose up -d

Access the web UI at http://your-server-ip:2283. On first launch, create an admin account.


Reverse Proxy Setup

Nginx

server {
    listen 80;
    server_name photos.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    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;

    client_max_body_size 50000M;

    location / {
        proxy_pass http://127.0.0.1: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;

        # Required for video streaming
        proxy_buffering off;
        proxy_read_timeout 600s;
        send_timeout 600s;
    }
}

Traefik (Docker Label)

Add these labels to the immich-server service in your compose file:

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=letsencrypt"
  - "traefik.http.services.immich.loadbalancer.server.port=2283"

Migrating from Google Photos

Step 1: Export with Google Takeout

Go to takeout.google.com, select only Google Photos, and export. Large libraries will be split into multiple .zip files.

Step 2: Use the Official Immich CLI Importer

# Install the CLI
npm install -g @immich/cli

# Log in to your instance
immich login https://photos.yourdomain.com your@email.com yourpassword

# Import a Google Takeout directory (preserves dates from JSON sidecars)
immich upload --recursive /path/to/takeout/Google\ Photos/

The --recursive flag handles the nested folder structure. The CLI reads .json metadata files from Takeout exports and sets correct timestamps. Without this step, all photos would show today's date.

Step 3: Verify and Clean Up

After import, use the Immich web UI to check the Timeline view — photos should appear in chronological order going back to your earliest photos. Run a spot-check on a few years to confirm dates imported correctly.


Backup Strategy

Immich stores photos in a flat directory structure under UPLOAD_LOCATION. Back this up like any other important data.

Recommended approach with restic:

# Install restic
apt install restic

# Initialize a repository (example: local backup to external drive)
restic init --repo /mnt/backup/immich-photos

# Backup photos and database dump
docker exec immich_postgres pg_dump -U postgres immich > /tmp/immich-db.sql
restic -r /mnt/backup/immich-photos backup \
  /path/to/immich/library \
  /tmp/immich-db.sql

# Schedule daily backups (cron)
0 2 * * * /path/to/immich-backup.sh

The Postgres database is small (metadata, thumbnails paths, face data) — the heavy backup is the photo library itself. Store the DB dump alongside the library backup.


Performance Tips

1. Move ML to a separate machine. The immich-machine-learning container can run on a different server via the MACHINE_LEARNING_HOST environment variable. Useful if your NAS is low-power but you have a desktop with a GPU.

2. Enable hardware transcoding for video. Edit your .env:

IMMICH_MEDIA_LOCATION=/usr/src/app/upload

And in the server settings UI, set Hardware Acceleration to NVENC (NVIDIA) or VAAPI (Intel/AMD).

3. Set a thumbnail quality tier. In Administration > Settings > Thumbnail, lower resolution saves disk space with minimal visual impact for library browsing.

4. Exclude duplicates before import. Run the Google Takeout folders through a deduplication tool like fdupes before importing to avoid filling storage with duplicates from multiple Takeout exports.

5. Schedule ML jobs off-peak. In Administration > Jobs, set face detection and smart search to run at night to avoid impacting app responsiveness during day use.


Immich vs PhotoPrism vs LibrePhotos

FeatureImmichPhotoPrismLibrePhotos
GitHub Stars94K+36K+3K+
Mobile AppsNative iOS + AndroidPWA onlyPWA only
Face RecognitionInsightFace (good)TensorFlow (decent)Face.ai (basic)
Natural Language SearchCLIP embeddingsCLIPLimited
GPU AccelerationNVIDIA/AMD/Intel/AppleNVIDIA/AppleNone
Docker ComposeOfficial, simpleComplex, many optionsModerate
LicenseAGPL-3.0AGPL-3.0MIT

For a deeper comparison, see our full Immich vs PhotoPrism vs LibrePhotos breakdown.


Verdict

Immich is the only self-hosted photo manager that can genuinely replace Google Photos without meaningful quality regressions. The native apps, reliable background sync, face recognition, and CLIP search all work at a level that would feel at home in a commercial product. For anyone paying for Google One storage or concerned about privacy, the 30-minute setup investment pays off immediately.

If you're evaluating self-hosted cloud storage more broadly, see our best self-hosted Google Drive alternatives guide and the homelab software stack guide for the full picture.

Common Setup Issues

Photos not backing up from mobile

The most common issue after initial setup. Check three things: (1) The mobile app requires the server to be accessible on your local network or via a domain with valid TLS — a plain http://192.168.x.x:2283 URL works on Android but iOS requires HTTPS for background sync. (2) Battery optimization settings on Android kill background processes — add Immich to the battery exclusion list. (3) On iOS, grant Immich "Full Access" to Photos in Settings > Privacy > Photos, not just "Selected Photos".

ML jobs running but face recognition not appearing

After initial install, Smart Search and Face Detection jobs run in the background. On a large library, this takes hours or days. Progress is visible in Administration > Jobs. If jobs show "waiting" and never start, check that the immich-machine-learning container is running: docker ps | grep machine-learning. The ML container downloads model weights (~300MB) on first run and needs internet access.

Database migration errors on upgrade

Always stop the stack before upgrading (docker compose down) and never skip major versions. Immich uses Postgres migrations tied to specific releases. Check the release notes on GitHub for any breaking changes before pulling a new tag. Keeping the IMMICH_VERSION pinned to a specific release (e.g., v1.100.0) prevents unintended upgrades when running docker compose pull.

Storage running out faster than expected

Immich generates thumbnails at multiple resolutions for the web UI and mobile apps. For a 50GB photo library, expect 10–20GB of additional storage for thumbnails and transcoded videos. The ML model weights add another 2–3GB. Plan for 130–140% of your raw photo library size as the total storage requirement.

Video playback failing in browser

Immich transcodes videos to web-compatible formats in the background. Original iPhone HEVC videos won't play in Chrome until transcoded. The transcoding queue is visible in Administration > Jobs > Video Conversion. On CPU-only servers, this is slow — a 4-minute 4K video can take 10–20 minutes to transcode. GPU hardware encoding via NVENC dramatically reduces this.


Mobile App Features Worth Knowing

The Immich mobile apps are more capable than the feature list suggests. A few features that aren't obvious:

Background sync configuration: In the app's Backup settings, you can configure sync to happen only on WiFi, only when charging, and only during specific hours. For large libraries, throttling the initial backup prevents your home network from being saturated for days.

Shared albums: You can share albums with other Immich users on the same instance, or generate shareable links for external viewers (no account required). The external share links support optional passwords and expiry dates.

Memories: Every day, Immich surfaces "On this day" memories from past years — the same feature that drives engagement in Google Photos. This runs automatically once your library is indexed.

Map view: If your photos have GPS metadata (all modern smartphones embed this), Immich displays them on an interactive map. Useful for finding photos from a specific trip or location.

Stack similar photos: Immich can group burst shots and similar photos into stacks, showing only the best one in the timeline. This significantly reduces visual clutter for mobile photographers who take multiple shots of the same scene.


Immich for Families

Immich is particularly well-suited for family photo management because of its sharing features. Each family member can have their own account, with their own library of automatically-synced photos. You can create shared albums that multiple people contribute to — the family vacation album that both parents and kids add photos to. The "Memories" feature resurfaces shared moments: on a photo's anniversary, Immich shows it to everyone who has access.

The admin account can manage storage quotas per user, preventing one family member from filling the disk. For families migrating from iCloud Photos, Immich's iOS app provides background sync that replaces the iCloud Photos Library seamlessly — photos upload to your server instead of Apple's.

One important note: Immich is not designed for long-term cold archival. The database and thumbnail structure means you need to run the Docker stack to browse your library. For true long-term archival (disaster-proof, offline copies), supplement Immich with a periodic backup of the raw library/ directory to external storage or a cold storage provider. Your Immich data plus a raw backup of the upload directory gives you both a functional browsing interface and a recovery option if the server dies.


Updating Immich

Immich releases frequently — roughly weekly minor updates. The recommended update process:

cd /path/to/immich
docker compose pull
docker compose up -d

Monitor the release notes at github.com/immich-app/immich/releases before upgrading. Major releases (1.x → 1.(x+1)) may require database migrations that take time on large libraries.


Methodology

  • Sources consulted: 8
  • GitHub star data from GitHub.com, March 2026
  • Docker Compose config from official Immich releases
  • Date: March 2026

Comments

Get the free Self-Hosting Migration Guide

Complete guide to migrating from SaaS to self-hosted open-source — infrastructure, data migration, backups, and security. Plus weekly OSS picks.

No spam. Unsubscribe anytime.