Self-Hosting Immich on Proxmox: Replacing Google Photos Without Losing Your Mind
Self-Hosting

Self-Hosting Immich on Proxmox: Replacing Google Photos Without Losing Your Mind

Ricardo Gil
April 6, 2026
8 min read
#Immich #Self-Hosting #Proxmox #Google Photos #Docker #Home Lab #Photo Management #Machine Learning

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:

  • CPU: Intel i5 or AMD Ryzen 5 (the ML models benefit from AVX2 support)
  • RAM: 16 GB minimum, 32 GB recommended if you're running other services on the same node
  • Storage: Fast SSD for the database and thumbnails, bulk storage for originals
  • GPU (optional but recommended): Intel Quick Sync (iGPU) for hardware transcoding, or a discrete NVIDIA GPU for ML acceleration
  • 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:

    bash
    # 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.

    bash
    # On the Proxmox host, verify AVX2 support
    grep -o 'avx2' /proc/cpuinfo | head -1

    After the VM is up, SSH in and install Docker:

    bash
    # 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.

    bash
    # Create Immich directory
    mkdir -p ~/immich && cd ~/immich

    Download 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:

    bash
    # .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:

    bash
    # 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/photos

    Add to fstab for persistence

    echo '/dev/sdb /mnt/photos ext4 defaults 0 2' | sudo tee -a /etc/fstab

    Set ownership

    sudo chown -R $USER:$USER /mnt/photos

    Fire it up:

    bash
    docker compose up -d

    First boot takes a few minutes as it pulls all images and initializes the PostgreSQL database. Watch the logs:

    bash
    docker compose logs -f

    Once you see the server container reporting healthy, hit http://:2283 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:

    yaml
    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:

    bash
    # 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:

    yaml
    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://:2283/api 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.

    bash
    # 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:

    bash
    # 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:

    bash
    # 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.

    bash
    # 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:

    bash
    # 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:

    yaml
    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:

  • Under 500 GB: A single 2 TB Samsung 870 EVO gives you plenty of room to grow
  • 500 GB โ€“ 2 TB: A WD Red Plus 4TB NAS drive offers the best price per TB
  • Over 2 TB: Consider a dedicated NAS like the Synology DS224+ with Seagate IronWolf 8TB drives in a mirrored configuration
  • 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.

    ๐Ÿ“ฌWeekly Newsletter

    Get the best home lab & AI content

    No spam. One email per week. Unsubscribe anytime.

    Share this article