pywkt

Fresh Install of Immich on a Proxmox VM

Immich is probably the best self hosted and local way to manage, store and view your photos. I've been using it for quite a while now to backup photos from my phone, but in the past I had the NUC doing all the heavy-lifting. In this guide I'm going to pass that off to a better equipped machine and also pass through Quicksync for transcoding videos. I'm also going to set up a dataset in TrueNAS to store all the photos. And of course I'll be doing all of this in Proxmox.

Update 2025/05/02

Welp, here we are again, re-installing Immich because of breaking changes. I pretty much only use Immich a few times a year which means I don't regularly update my Docker image. Today I logged in and saw that I was on 1.111.0 and 1.132.3 is the latest version. Naturally I'm like, "Cool, just a few minor releases, may as well update." So I run a sudo docker compose pull, update and start the containers. Surprise ...broken.

To be fair, it has been almost a year since I last updated, but still, this is a bit ridiculous. But whatever.

I'm going to attempt to back up/restore my data, but I'm not 100% it's going to work out, but we'll see...

I was able to get my original/outdated version running by removing the existing images and setting the version variable in the .env.

The rest of the guide has been updated with instructions for installing the latest release of Immich as of May 02, 2025.


Ubuntu Server Setup

Normally I would prefer to use an LXC instead of a full VM, but Immich suggests using Docker and I don't feel like setting up each service one by one, so that means I'll be doing this in a VM. I really don't like running Docker in an LXC.

Create a new VM in Proxmox (ref)

I'm using Ubuntu 24.04, 4 cores, 4GB of ram and 100GB HDD. Yes, 100GB is overkill, but I've been screwed too many times by this damn app/docker/logs/etc. Not messing around on this one.

Once that's up and running go through the install process. When it asks if you want any packages pre installed, don't select any, just skip through.

Now you should be logged in and in the terminal.

Update the system

sudo apt update && sudo apt upgrade

The next two steps are optional, but I'll be using Vim as my text editor and Zsh as my bash. Install some quality-of-life packages

sudo apt install neovim zsh

Install oh-my-zsh

sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Docker

Install Docker Stuff

sudo apt install apt-transport-https ca-certificates curl software-properties-common

Add GPG key

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Add Docker repo to apt

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update

sudo apt update

Check to see that it's ready to go. If you see something like (Installed), you're good to go.

apt-cache policy docker-ce

Install

sudo apt install docker-ce

Check

sudo systemctl status docker

You should see the docker version.


Docker Compose

Docker is cool, but Docker Compose is a better way of using it. Let's get that going now.

Create a directory for Docker Stuff

mkdir -p ~/.docker/cli-plugins/

Install Docker Compose

curl -SL https://github.com/docker/compose/releases/download/v2.3.3/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

Set permissions

chmod +x ~/.docker/cli-plugins/docker-compose

Check version

sudo docker compose version

You should now see the Docker Compose version. If you've used Docker Compose before and you're used to the command being docker-compose, just know that they've updated it and the new command is now docker compose. Everything else should be the same, but there's just no hyphen (-) anymore.


This is where we start to deviate on our own path. My Immich server is going to be storing all the photos on my TrueNAS server, so we need to set up a dataset to hold everything and then link it up with our VM.


TrueNAS

Create a dataset in TrueNAS and set up the permissions as you wish. When developing I tend to set read/write for everyone and only allow specific IP addresses in the NFS rules, but it's up to you.

Set up an NFS share for the dataset you just created and put in the IP address of your Immich VM in the allow list. Or you can just put you local subnet and allow all devices on your network, whatever works for you.


Back on the Immich VM.

NFS

Install nfs-common

sudo apt install nfs-common

Make shared directory for images. I like to keep all my external/network shares in the /mnt folder.

sudo mkdir /mnt/immich-nas

Obviously replace the next line with the IP address/path of you TrueNAS dataset.

sudo mount 192.168.X.X:/mnt/<pool>/<dataset> /mnt/immich-nas

Check that it mounted

df -h

In the Filesystem column you should see the IP address of the NAS and the path of the dataset. The Mounted On column should have /mnt/immich-nas

Set the Immich server to mount this folder when it boots up

sudo nvim /etc/fstab

Add to the bottom of the file

192.168.X.X:/mnt/<pool>/<dataset> /mnt/immich-v2 nfs auto,nofail,noatime,nolock,intr,tcp,actimeo=1800 0 0

Immich

Now that we're all set up it's finally time to install Immich.

Create a directory for the Docker files

mkdir ~/immich-app

Navigate to the new directory

cd ~/immich-app

Download the Docker Compose file

wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml

Download the .env file

wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

Download the hardware acceleration file (optional)

wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.yml

Edit the .env file

  • Change UPLOAD_LOCATION value to /mnt/immich-nas
  • Update DB_PASSWORD to a random string

Quicksync

Since my Proxmox server is an Intel NUC with Quicksync, I'm going to pass that through to the VM so Immich can use it to transcode. If you aren't going to use Quicksync or don't have it available you can skip this part.

Install some hardware packages

sudo apt install --install-recommends linux-generic-hwe-22.04

Update: change 22.04 to the version of your Ubuntu server if you're not on 22.04

Download/install the Intel Compute-Runtime stuff Follow the steps on this page.

https://github.com/intel/compute-runtime/releases

Log in to the Proxmox web ui and add the Intel driver to the VM

  • Select the VM
  • Go to the Hardware tab
  • Click Add > PCI
  • Select the Intel graphics driver option
  • Stop and restart VM
  • SSH back in

Once you're back in the VM, type ls -l /dev/dri

You should see something like renderD128 listed now.

Download the hwaccel.transcoding file to the directory with the docker-compose.yml

wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml

Enable the hardware acceleration in the docker-compose file

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
     extends:
       file: hwaccel.transcoding.yml
       service: quicksync # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding

Start Immich with Docker compose

sudo docker compose up

Once everything is up and running and there are no errors, you can stop the container and run it with

sudo docker compose up -d

At this point the Immich server should be up and running and you should be able to log in/create the admin account by going to

http://192.168.X.X:2283

Remote Machine Learning

The Intel NUC is a pretty great server, but I'm planning on throwing a bunch of photos in here and I want to use Immich's facial recognition features. This can really bog down the NUC so I'm going to offload this work to another machine I have in the house that I mainly use for AI/ML/LLM stuff. The Following steps will be done on that computer, which is running Ubuntu 22.04, but the full desktop version with an RTX 3060 graphics card.

Note: Since I'm using an NVIDIA card I'm going to use the cuda tag for the image, you may need to replace that with the one that matches your setup.

Make sure you have the NVIDIA Container Toolkit installed. Just follow the guide here: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html

This computer didn't already have Docker installed so I followed the steps above for installing Docker/Docker Compose.

Create a folder for the Docker Compose file

mkdir -p ~/immich-ml && cd ~/immich-ml

Download the hwaccel.ml.yml file from the repo

wget https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml

Create the compose file

touch docker-compose.yml

Edit the file

nvim docker-compose.yml

Add the Following

name: immich_remote_ml
 
services:
  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release-cuda}
    extends:
      file: hwaccel.ml.yml
      service: cuda # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    restart: always
    ports:
      - 3003:3003
 
volumes:
  model-cache:

Save, exit and run the container

sudo docker compose up

You can also add the -d flag here, but since it's my first time running this I'm going to omit that so I can see the logs.

Open up the Immich web ui and log in as the administrator if you've already set that up. If not just go to http://192.168.X.X:2283 and set up the admin account now.

Once logged in as the administrator, click the Administration button at the top right and go to Settings > Machine Learning Settings

In the URL textfield, put in the IP address of the machine running the immich-machine-learning container with the port 3003.

http://192.168.X.X:3003

Save the settings.

I'll be testing that the GPU is working by running the Face Detection job, so I uploaded a handful of photos with people in them.

Navigate to the Jobs section of the Administrator Settings and run the Face Detection.

If you didn't start the container with the -d flag, you should see some logs in your immich_machine_learning container.

Before setting up GPU:

[05/02/25 21:20:43] INFO     Application startup complete.
[05/02/25 21:20:50] INFO     Loading detection model 'buffalo_l' to memory
[05/02/25 21:20:50] INFO     Setting execution providers to
                             ['CPUExecutionProvider'], in descending order of
                             preference
[05/02/25 21:20:50] INFO     Loading recognition model 'buffalo_l' to memory
[05/02/25 21:20:50] INFO     Setting execution providers to
                             ['CPUExecutionProvider'], in descending order of
                             preference

Note the CPUExecutionProvider, that's not what we want.

After setting up the GPU you should see something like this:

[05/02/25 21:23:54] INFO     Application startup complete.
[05/02/25 21:24:39] INFO     Loading detection model 'buffalo_l' to memory
[05/02/25 21:24:39] INFO     Setting execution providers to
                             ['CUDAExecutionProvider', 'CPUExecutionProvider'],
                             in descending order of preference
[05/02/25 21:24:40] INFO     Loading recognition model 'buffalo_l' to memory
[05/02/25 21:24:40] INFO     Setting execution providers to
                             ['CUDAExecutionProvider', 'CPUExecutionProvider'],
                             in descending order of preference

Now we can see that the CUDAExecutionProvider is first and it will fallback to the CPU if needed. A+++++


In the past I've run in to issues where the Immich logs take up so much space it fills up the VM storage. So I like to set the Log Level to either Error or Fatal once I'm confident everything is working as it should.

And that's that. We've got Immich up and running with all the machine learning stuff offloaded to a computer that can handle it and Quicksync ready to transcode all those stupid hevc (or whatever) files from people with iPhones. Even if you're the only one using it, I still suggest making yourself a new account that isn't the admin account. Keep the admin account just for admin stuff.


I was originally planning on trying to restore my previous albums, but at this point I feel like I'll just re-upload everything and deal with it. Sucks, but hey, that's Immich for ya'. Maybe one day they'll get on a regular versioning system so you don't have to read release notes for every release. Seriously, I was something like, 20 releases behind, that's a lot, but they're putting out around 3-4 releases a month. Am I supposed to go through and read the changelogs for every single one? Today I just saw that the latest was still on the same major version I was running so I updated. Really shouldn't have to go through all this every single time...