Self-Host Immich: Google Photos Alternative 2026
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
Recommended (Full AI Features, Active Use)
- 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
| Feature | Immich | PhotoPrism | LibrePhotos |
|---|---|---|---|
| GitHub Stars | 94K+ | 36K+ | 3K+ |
| Mobile Apps | Native iOS + Android | PWA only | PWA only |
| Face Recognition | InsightFace (good) | TensorFlow (decent) | Face.ai (basic) |
| Natural Language Search | CLIP embeddings | CLIP | Limited |
| GPU Acceleration | NVIDIA/AMD/Intel/Apple | NVIDIA/Apple | None |
| Docker Compose | Official, simple | Complex, many options | Moderate |
| License | AGPL-3.0 | AGPL-3.0 | MIT |
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