Immich Server
Self-Host Your Photos
Immich is a open-source photo and video management solution, think Google Photos, but running on your own server. You get automatic mobile backup, AI-powered search, face recognition, and a slick interface, all without your data ever leaving your hands.
How to get it running
Before getting started, we need a place to install Immich and review the hardware specifications. Immich supports NVIDIA GPU acceleration, but it can also run entirely on a CPU if no GPU is available. In my case, I run Immich in Docker container without a graphics card, and it runs without issues. Check this guide on how_to_setup_docker
Requirements
- docker - (min 6GB of RAM and 2 CPU cores)
- (Nvidia gfx card) - optionel
Nvidia GFX card setup
If you intend to use a GPU for hardware acceleration, you should verify that your system can detect the graphics card. If your setup does not include a GPU, you can skip this step SSH in to the server
1
lspci
Immich supports NVIDIA GPUs with CUDA 5.2 or higher, which includes cards such as the GeForce GTX 950 and newer models.
The next step is configuring your GPU to be used inside the Docker container.
1
ubuntu-drivers devices
After installing the required drivers, your output should look similar to the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dock@ImiichCT:/opt/pool/immich$ ubuntu-drivers devices
ERROR:root:aplay command not found
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00002204sv00001043sd000087B3bc03sc00i00
vendor : NVIDIA Corporation
model : GA102 [GeForce RTX 3090]
driver : nvidia-driver-570 - distro non-free
driver : nvidia-driver-580-server-open - distro non-free
driver : nvidia-driver-535-server-open - distro non-free
driver : nvidia-driver-570-server - distro non-free
driver : nvidia-driver-570-open - distro non-free
driver : nvidia-driver-535-server - distro non-free
driver : nvidia-driver-580 - distro non-free
driver : nvidia-driver-580-server - distro non-free
driver : nvidia-driver-570-server-open - distro non-free
driver : nvidia-driver-580-open - distro non-free recommended
driver : xserver-xorg-video-nouveau - distro free builtin
Check for the distro’s non-free recommended driver. The current latest version is nvidia-driver-580-open. Install this version to ensure proper GPU support.
1
sudo ubuntu-drivers install -y nvidia-driver-580
Then reboot the server
1
sudo reboot
At this point, your GPU should be detected and running properly.
1
nvidia-smi
The output should look similar to the following. (Disclaimer: I don’t have an NVIDIA GPU in this container; this example is taken from a different container.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
hal@ai:~$ nvidia-smi
Sun Mar 15 07:57:25 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.48.01 Driver Version: 590.48.01 CUDA Version: 13.1 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 3090 On | 00000000:01:00.0 Off | N/A |
| 0% 52C P8 40W / 350W | 12282MiB / 24576MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 628698 C python3 12274MiB |
+-----------------------------------------------------------------------------------------+
hal@ai:~$
To enable GPU support in the container, the GPU must be installed on the host and made accessible to the Docker container.
So, we need to set up the production repository.
1
2
3
4
5
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
Then we need to update the packages
1
sudo apt-get update
Now it’s time to install the packages for the NVIDIA Container Toolkit.
1
2
3
4
5
6
export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.19.0-1
sudo apt-get install -y \
nvidia-container-toolkit=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
nvidia-container-toolkit-base=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
libnvidia-container-tools=${NVIDIA_CONTAINER_TOOLKIT_VERSION} \
libnvidia-container1=${NVIDIA_CONTAINER_TOOLKIT_VERSION}
And setup docker to use the toolkit
1
sudo nvidia-ctk runtime configure --runtime=docker
Restart the docker
1
sudo systemctl restart docker
Then test if it works inside the container
1
docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
Now you should see (note this is from a diffrent container where i use my GPU)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
hal@ai:/opt/pool/ai-stack$ docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
Mon Mar 16 08:03:57 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.48.01 Driver Version: 590.48.01 CUDA Version: 13.1 |
+-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 3090 Off | 00000000:01:00.0 Off | N/A |
| 0% 40C P8 13W / 350W | 1248MiB / 24576MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
hal@ai:/opt/pool/ai-stack$
Immich setup
Check for docker
1
docker -v
And you should see something like this
1
2
dock@ImiichCT:/opt/immich$ docker -v
Docker version 29.3.0, build 5927d80
I use /opt/pool/immich as my path
1
sudo mkdir -p /opt/pool/immich
We need to change the folder ownership so we don’t have to type sudo every time.
1
sudo chown user:user -R /opt/pool
Next, navigate to the directory
1
cd /opt/pool/immich
Time to create the compose.yml file
1
nano compose.yml
Add the content below to your YML file. I won’t cover the YML syntax in depth, but there are a few important aspects to pay attention to.
- /mnt/photos:/mnt/photos:ro
If you plan to use a network share, uncomment this line. The details of the network share will be discussed later, but it’s not required at this stage.
1
2
3
extends:
file: hwaccel.ml.yml
service: cuda
If your setup includes an NVIDIA graphics card, uncomment this line to enable GPU support.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
name: immich
services:
immich-server:
container_name: immich_photo_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
extends:
file: hwaccel.transcoding.yml
service: ${TRANSCODING_BACKEND:-cpu}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
# - /mnt/photos:/mnt/photos:ro ## uncomment if you are using a network share
- /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/immich-machine-learning:${IMMICH_VERSION:-release}-cuda
#extends: - ## uncomment if you use a Nvidia GPU
#file: hwaccel.ml.yml
#service: cuda
volumes:
- model-cache:/cache
env_file:
- .env
restart: always
healthcheck:
disable: false
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
DB_STORAGE_TYPE: ${DB_STORAGE_TYPE:-SSD}
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
env_file:
- .env
restart: always
volumes:
model-cache:
After that, configure the .env file. The key aspect to focus on in this file is the
- UPLOAD_LOCATION=./library
- DB_DATA_LOCATION=./postgres
- DB_PASSWORD=password
- DB_USERNAME=user
UPLOAD_LOCATION=./library #This setting determines where your photo library will be stored. In my setup, I pointed it to my NAS to keep the container image small. Then, within the Immich admin panel, I mounted an external library linking all my photos from the NAS to Immich. In short: the container itself remains lightweight, while all your photos are stored externally on the NAS and fully accessible in Immich.
- UPLOAD_LOCATION=./mnt/immich (Instructions for setting this up are provided later in the guide.)
- Inside Immich i added a External Library ( we do this when Immich is up and running in the admin panel)
1
nano .env
Paste the content below into the file, and make sure to update the settings mentioned above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Required paths
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
# Optional timezone (not needed if localtime is mounted)
# TZ=Etc/UTC
# Version control
IMMICH_VERSION=release
# Postgres authentication
DB_PASSWORD=password
DB_USERNAME=user
DB_DATABASE_NAME=immich
# Optional tuning
DB_STORAGE_TYPE=SSD ## Change to HDD if you have a spinning harddisk
# transcoding
TRANSCODING_BACKEND=nvenc
Now we need to make the hwaccel.ml.yml file If u use a Nvidia GFX card do this if not skip
1
nano hwaccel.ml.yml
Paste this in it
1
2
3
4
5
6
7
8
9
10
services:
cuda:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu
Now for transcoding
1
nano hwaccel.transcoding.yml
Paste this in it if you use a Nvidia GFX card if not skip
1
2
3
4
5
6
7
8
9
10
11
12
services:
nvenc:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities:
- gpu
- compute
- video
SMB Share
To use an SMB network share with Immich, I have a folder called photo on my OpenMediaVault server, which is shared over SMB. This guide won’t cover the SMB setup itself, but I plan to create a dedicated guide for that in the near future.
make a dir for the credentials
1
sudo mkdir -p /etc/smb-credentials
create credentials file
1
sudo nano /etc/smb-credentials/photos
Make sure to replace the credentials in the configuration with the username and password that have access to your network share.
1
2
username=user
password=password
Adjust the file permissions as needed. In my case, I set them to root with mode 600, meaning only root has read and write access.
1
2
sudo chmod 600 /etc/smb-credentials/photos
sudo chown root:root /etc/smb-credentials/photos
Verify that the file permissions have been applied properly and are functioning as intended.
1
ls -l /etc/smb-credentials/photos
Update fstab to mount the share
1
sudo nano /etc/fstab
Make/paste the mount path in botton of the file (correct the ip/share to your need)
1
//10.10.10.8/photos /mnt/photos cifs credentials=/etc/smb-credentials/photos,iocharset=utf8,vers=3.0,ro,nofail 0 0
For this to work we need cifs-utils installed so we need some additional packages
1
sudo apt update && sudo apt install cifs-utils
Now reboot
1
sudo reboot
First start
Now we can start the server and see the results of all the setup work we’ve done.
1
2
cd /opt/pool/immich
docker compose up -d
Check it with
1
docker ps
Connect to the server
- http://10.10.10.8:2283
Enjoy …
Links
Immich Github
Immich Backup & Retore
Nvidia CUDA GPU
NVIDIA Container Toolkit

