[HOW-TO] Install a Docker app (Immich) on Yunohost, integrated as much as I could - version 2026

Introduction

Disclaimer 1: This tutorial is a bit long and complex, and touches file that might break Yunohost or part of it. Do NOT proceed if you’re not sure of what you’re doing or you think it exceeds your current knowledge.
Disclaimer 2: Some parameters might be specific to your own current configuration.

Special mention to @tituspijean from who I took the inspiration to make this tutorial.

The idea of this tutorial is to install a Docker app, for whatever reason or need, without loosing too much integration in a standard Yunohost server.

In this example I’m going to be installing Immich on an already owned domain immich.mydomain.tld, but most of the process is applicable to other Docker apps.

We will use Redirect app to easily setup our Immich domain redirection.

We will use custom-backup to integrate the normal yunohost backup process to it.

:memo: Any feedback is welcome.

0. :check_box_with_check: Prerequisites:

  • Have Yunohost v12.* or above fully installed and ready to be used.

  • It must be reachable either publicly or in your own intranet depending on what you want, in this example I’ll be using a public domain.

1. :play_button: Install docker:

I’m not sure if Yunohost comes with docker preinstalled, but we will install docker using its official method, because the docker app on Debian is usually very outdated:

  • SSH into your server

  • Install docker keyrings:

sudo apt update
sudo apt install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  • Add the repository to apt source:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • Install and initiate docker to make sure everything is working:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable docker
sudo systemctl start docker
  • Disable docker iptables manipulation:
sudo nano /etc/docker/daemon.json

Insert this and save:

{
  "iptables": false,
  "bridge": "none"
}

To make sure that nftables is only touched by Yunohost and not docker we’ll switch to iptables-legacy instead of iptables-nft

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
  • Finally restart docker:
sudo systemctl restart docker

2. :play_button: Install Immich on Docker:

  • Again already SSHed in your server, let’s enter as super user:
sudo su
  • Create Immich’s folder and enter to it:
mkdir /opt/immich-docker
cd /opt/immich-docker
  • Let’s copy the example files, and set the .env file to be used:
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
mv example.env .env
  • Edit the docker .env file:
    In the .env file make sure that the DB_DATA_LOCATION and UPLOAD_LOCATION are correct, and set your database password at DB_PASWORD, also in my case as I was migrating from the yunohost version of Immich I decided to keep the same DB_USERNAME and DB_DATABASE_NAME
nano .env

Find an example of a .env file below:

example .env file
# /opt/immich-docker/.env
#
# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables

# The location where your uploaded files are stored
UPLOAD_LOCATION=/opt/immich-docker/immich-data

# The location where your database files are stored. Network shares are not supported for the database
DB_DATA_LOCATION=/opt/immich-docker/immich-db

# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
TZ=MX

# The Immich version to use. You can pin this to a specific version like "v2.1.0"
IMMICH_VERSION=v2

# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=CHANGE_THIS_TO_YOUR_DESIRED_DB_PASSWORD

# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=immich
DB_DATABASE_NAME=immich
  • :police_car_light: :police_car_light: :police_car_light: SUPER IMPORTANT!!! Edit the docker-compose.yml file:
    As we are going to use the Yunohost Redirect app in a future step, it’s super important to expose Immich only on a local level, we will expose the standard port 2283 on 127.0.0.1, therefore we MUST set this in our docker-compose file, at the immich-server config:
    ports:
      - '127.0.0.1:2283:2283'

And also use the docker-created network:

networks:
  default:
    name: immich_default
    driver: bridge

To edit the file:

nano docker-compose.yml

Find an example of a docker-compose file below, in this case it has some other tweaks:

example docker-compose.yml
# /opt/immich-docker/docker-compose.yml

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - '127.0.0.1:2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:2283/server-info"]
      interval: 30s
      timeout: 5s
      retries: 5



  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}
    # extends: # uncomment this section for hardware acceleration - see https://docs.immich.app/features/ml-hardware-acceleration
    #   file: hwaccel.ml.yml
    #   service: cpu # 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
    env_file:
      - .env
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3003"]
      interval: 30s
      timeout: 5s
      retries: 5


  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:18-vectorchord0.5.3-pgvector0.8.1
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
      # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
      # DB_STORAGE_TYPE: 'HDD'
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql
    shm_size: 128mb
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE_NAME}"]
      interval: 30s
      timeout: 5s
      retries: 5


volumes:
  model-cache:

networks:
  default:
    name: immich_default
    driver: bridge
  • Change the permissions for your folders to use the standard config:
chown -R 1000:1000 /opt/immich-docker/immich-data
chown -R 999:999 /opt/immich-docker/immich-db
  • Finally run Immich (make sure to be in the Immich folder) with:
docker compose up -d

3. :play_button: Install Redirect-ynh app:

  • Create your desired domain using Yunohost admin panel as you’d normally do, I will use immich.mydomain.tld as an example

  • Install Redirect app on your domain (immich.mydomain.tld), set the redirect-type as “Reverse-proxy”, and set the target as http://127.0.0.1:2283 that we configured in our docker-compose file.

  • You should now be able to access Immich on immich.mydomain.tld using your browser

  • Special tweak: Due to requirements of Immich (might not be necessary for other apps) we must edit the redirect.conf file to allow big files to go through it, the standard limit is 1MB if I’m not mistaken, which is not big enough for photos or videos:
    1- SSH into your server
    2- sudo nano /etc/nginx/conf.d/immich.mydomain.tld/redirect.conf
    3- Add this to the file:

# /etc/nginx/conf.d/immich.mydomain.tld/redirect.conf

  # ADDED TO ALLOW FILES TO BE UPLOADED
  client_max_body_size 10240M;
  proxy_request_buffering off;
  proxy_read_timeout 3600;
  proxy_send_timeout 3600;

And then restart nginx with:

sudo yunohost service restart nginx

4. :play_button: Integrate a backup:

Yunohost provides a really simple way to create a custom backup and we will make use of it.

  • Install the custom_backup app and add your Immich folder (/opt/immich-docker) to it.

That would be all, I hope this will help anyone willing to install a docker app on a Yunohost server.

4 Likes

It is worth noting that you specify Docker in Yunohost in the header, and this should assume that Docker is planned to be used specifically as a Yunohost application. However, later in the description, it becomes clear that you are installing Docker in parallel with Yunohost, next to it.
Actually, that’s what I did when it became clear that my VPS with 4 Gb of RAM was insufficient to install Docker as a Yunohost application. Why would you suddenly, it would seem…
“In parallel,” Docker installs perfectly and when working, unlike the notorious application of the same name inside Yunohost, it spends itself and a dozen more containers working, less memory than during a simple installation of Docker as a Yunohost application.
By the way, I had Docker installed long before the release of the 12th version of Yunohost and the upgrade to nftables. And for a while I suffered a lot, not being physically able to create new containers, due to incompatibility with nftables. After several Yunohost updates, unexpectedly, the containers started to be created again without errors. But there was also an unpleasant moment.
I have not yet been able to find out the exact cause of its occurrence, but at one not happy moment, Docker “breaks down” and loses all its rules. I’m getting out of this state while manually restarting the Docker service.

I’m not quite sure of what you mean in the beginning :sweat_smile:
I’ve installed Docker as a Debian app, I couldn’t find Docker in the official Yunohost apps catalog (YunoHost app store | Application Catalog) that’s why i’ve never thought that would be an option.

Is good to know that everything is working well now, I’m not such an old user of YNH as I started in v12 already.