I've been paying Google for extra storage since 2019. Not a lot โ $2.99/month for the 200 GB plan โ but the principle started bothering me more than the price. Every family photo, every vacation video, every screenshot of a receipt I'll never look at again: all sitting on someone else's infrastructure, training someone else's models, subject to someone else's terms of service changes.
So I moved everything to Immich, running on the same Proxmox node that already handles my other self-hosted services. After three months of daily use, I can say this: Immich is the first self-hosted photo platform that doesn't feel like a compromise. Here's exactly how I set it up and what I learned.
Why Immich Over the Alternatives
I tried PhotoPrism and LibrePhotos before landing on Immich. PhotoPrism is solid but felt sluggish on my hardware, and the mobile app experience never matched what I was used to. LibrePhotos had promising ML features but the project's pace slowed considerably.
Immich hit different. The mobile app on both iOS and Android feels native โ background upload works reliably, the timeline view mirrors Google Photos almost exactly, and the face recognition actually groups people correctly after minimal manual intervention. The project has over 110,000 GitHub stars as of early 2026 and reached its first stable release in late 2025.
The killer features that sealed it for me: CLIP-based semantic search (search "dog on beach" and it actually finds your dog on a beach), hardware-accelerated machine learning, multi-user support with separate libraries, and a locked folder for sensitive photos.
Hardware Requirements
Immich is more resource-hungry than most self-hosted apps. The ML pipeline โ face detection, face recognition, CLIP embedding โ needs real compute. Here's what I'd recommend as minimums:
I'm running this on a Beelink SER5 MAX with a Ryzen 7 5800H, 32 GB RAM, and a 1 TB NVMe for the OS plus a 4 TB Samsung 870 EVO SATA SSD passed through to the Immich VM for photo storage. Total cost for the storage upgrade was about $200.
If you're starting from scratch, a Minisforum UM790 Pro or Beelink GTi Ultra would be excellent choices โ both have enough horsepower to handle Immich's ML pipeline alongside other home lab services. For dedicated photo storage, a WD Red Plus 8TB NAS drive gives you plenty of runway.
Setting Up the Proxmox VM
I prefer running Immich in a dedicated VM rather than an LXC container. Docker-in-LXC works but adds complexity with device passthrough, and I wanted clean GPU access for ML acceleration.
Create an Ubuntu 24.04 VM in Proxmox with these specs:
# Proxmox VM settings
CPU: 4 cores (host type for AVX2 support)
RAM: 8192 MB
Disk: 50 GB on fast storage (OS + Docker)
Network: virtio bridge
The critical setting is CPU type โ set it to host instead of the default kvm64. Immich's ML models use AVX2 instructions, and without host CPU passthrough, you'll get cryptic crashes in the machine learning container.
# On the Proxmox host, verify AVX2 support
grep -o 'avx2' /proc/cpuinfo | head -1
After the VM is up, SSH in and install Docker:
# Install Docker on Ubuntu 24.04
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Deploying Immich with Docker Compose
Immich provides an official Docker Compose file that bundles everything: the server, microservices, machine learning, Redis, and PostgreSQL. Don't try to cobble together your own โ their stack is well-tuned.
# Create Immich directory
mkdir -p ~/immich && cd ~/immichDownload the official compose file and env template
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
Edit the .env file with your settings:
# .env - key settings to change
UPLOAD_LOCATION=/mnt/photos/immich-uploads
DB_PASSWORD=$(openssl rand -base64 32)
IMMICH_VERSION=release
The UPLOAD_LOCATION is where your original photos land. Point this at your bulk storage โ not the OS drive. I mounted my 4 TB SATA SSD at /mnt/photos and set permissions accordingly:
# Mount the storage drive (adjust /dev/sdX to your device)
sudo mkfs.ext4 /dev/sdb
sudo mkdir -p /mnt/photos
sudo mount /dev/sdb /mnt/photosAdd to fstab for persistence
echo '/dev/sdb /mnt/photos ext4 defaults 0 2' | sudo tee -a /etc/fstabSet ownership
sudo chown -R $USER:$USER /mnt/photos
Fire it up:
docker compose up -d
First boot takes a few minutes as it pulls all images and initializes the PostgreSQL database. Watch the logs:
docker compose logs -f
Once you see the server container reporting healthy, hit http:// in your browser.
Configuring Machine Learning Acceleration
The default ML setup runs on CPU, which works but is slow. Processing a library of 50,000 photos took about 18 hours on my Ryzen 7. With proper configuration, you can cut that dramatically.
Intel iGPU (OpenVINO)
If your mini PC has an Intel CPU with integrated graphics (most Intel NUC and Beelink models), you can use OpenVINO for ML acceleration. Modify your docker-compose.yml:
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release-openvino
devices:
- /dev/dri:/dev/dri
volumes:
- model-cache:/cache
NVIDIA GPU (CUDA)
If you've got a discrete NVIDIA card (even an old GTX 1650 works great for this), install the NVIDIA Container Toolkit first:
# Install NVIDIA Container Toolkit
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 update && sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Then update the ML service in docker-compose.yml:
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release-cuda
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
- model-cache:/cache
With CUDA acceleration on even a modest GPU, that 50,000-photo library processes in about 2 hours instead of 18.
Mobile App Setup and Auto-Backup
This is where Immich really shines. Install the app from Google Play or the App Store, then:
1. Enter your server URL: http://
2. Create your account (first account becomes admin)
3. Enable background backup in the app settings
For remote access outside your home network, you have two clean options:
Option A: Tailscale (what I use) โ Install Tailscale on both the Immich VM and your phone. Access Immich via its Tailscale IP. Zero port forwarding, zero exposure to the internet.
# On the Immich VM
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
Option B: Reverse proxy with Caddy โ If you have a domain and want HTTPS access:
# Caddyfile
photos.yourdomain.com {
reverse_proxy localhost:2283
}
I strongly recommend Tailscale for this use case. Exposing a photo library to the public internet, even behind HTTPS, is a bigger attack surface than necessary.
The Gotchas Nobody Mentions
Database Backups Are Critical
Your photos are files on disk, but the metadata, face recognition data, albums, and sharing settings live in PostgreSQL. Lose that database and you lose all your organization. Set up automated backups:
# Add to crontab: daily database backup
0 3 * docker exec immich_postgres pg_dumpall -U postgres | gzip > /mnt/photos/backups/immich-db-$(date +\%Y\%m\%d).sql.gz
I also replicate these backups to a Synology DS224+ NAS using rsync. Having your photos and their database backup on separate physical devices is non-negotiable.
External Libraries Need Careful Planning
If you have an existing photo collection (like I did โ 150 GB of photos from years of Google Takeout exports), use Immich's External Library feature rather than copying everything into the upload directory. This lets Immich index photos in-place without doubling your storage usage.
# In docker-compose.yml, add the volume mount
immich-server:
volumes:
- /mnt/photos/google-takeout:/mnt/media/google-takeout:ro
Then in the Immich admin panel, create an external library pointing to /mnt/media/google-takeout. The :ro mount flag ensures Immich can't modify your originals.
Memory Tuning for PostgreSQL
The default PostgreSQL config is conservative. If you're giving the VM 8+ GB of RAM, tune it:
# Create a custom postgresql.conf
cat << EOF > ~/immich/custom-postgresql.conf
shared_buffers = 1GB
effective_cache_size = 3GB
work_mem = 64MB
maintenance_work_mem = 512MB
EOF
Mount it in docker-compose.yml:
immich_postgres:
volumes:
- ./custom-postgresql.conf:/etc/postgresql/postgresql.conf
command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
This made a noticeable difference in search speed and timeline loading with large libraries.
Storage Planning
Before migrating, do the math. Check your Google Photos storage usage and plan accordingly:
Remember: Immich stores original files plus generates thumbnails and encoded versions. Budget about 1.3x your original library size for total storage consumption.
Three Months In: Was It Worth It?
Absolutely. The migration itself took a weekend โ mostly waiting for Google Takeout to export and Immich's ML pipeline to process everything. Day-to-day usage is indistinguishable from Google Photos for the things I actually do: scroll the timeline, search for people or places, share albums with my wife.
The search quality genuinely surprised me. CLIP-based semantic search means I can type "Christmas 2023" or "park with playground" and get relevant results. Face recognition grouped my family correctly after I named about 10 faces manually.
What I gained: full ownership of my data, no monthly fees, no storage limits beyond my hardware, and zero concern about Google deciding to change their pricing or terms. What I gave up: Google's lens integration and the ability to search from any device without Tailscale. That's a trade I'll make every time.
If you're already running a Proxmox home lab, adding Immich is one of the highest-value self-hosted services you can deploy. It solves a real problem, the project is actively maintained with a large community, and the experience is polished enough that non-technical family members can use it without support tickets.
Disclosure: This post contains affiliate links. If you purchase through these links, I may earn a small commission at no extra cost to you.
