Skip to content

Commit 0f9dc95

Browse files
CopilotJoulinar
andcommitted
Add Immich Machine Learning as software option (ID 216)
- Add software descriptor for ID 216 in Cloud category (arm64/amd64) - Add install block: downloads Immich source, installs uv, creates Python venv with ML deps via uv sync, sets up immich user/data dir/env file, enables ML in Immich server config if present, creates systemd service - Add uninstall block with shared-user handling and ML disable in server conf - Add immich-ml to dietpi-services - Add CI test entry with QEMU hardening override in dietpi-software.bash - Add URL checks for Immich version (216) and uv binary (216000) - Add CHANGELOG and README entries Co-authored-by: Joulinar <47155374+Joulinar@users.noreply.github.com>
1 parent 853fed8 commit 0f9dc95

File tree

6 files changed

+126
-1
lines changed

6 files changed

+126
-1
lines changed

.github/workflows/dietpi-software.bash

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ Process_Software()
315315
213) aSERVICES[i]='soju' aTCP[i]='6667';;
316316
214) aSERVICES[i]='whodb' aTCP[i]='8091';;
317317
215) aSERVICES[i]='immich' aTCP[i]='2283';;
318+
216) aSERVICES[i]='immich-ml' aTCP[i]='3003';;
318319
*) :;;
319320
esac
320321
aINSTALL[i]=1
@@ -344,6 +345,7 @@ do
344345
213) Process_Software 17 188;;
345346
183) Process_Software 87;;
346347
215) Process_Software 7 9 91 194;;
348+
216) Process_Software 130;;
347349
138|187) Process_Software 152;;
348350
75) Process_Software 83 87 89;;
349351
76) Process_Software 83 88 89;;
@@ -497,7 +499,7 @@ then
497499
# Forky
498500
if (( $dist > 8 ))
499501
then
500-
G_EXEC mkdir rootfs/etc/systemd/system/{mariadb,systemd-logind,apache2,mpd,vaultwarden,blynkserver,gogs,whodb,lazylibrarian,bazarr,immich}.service.d
502+
G_EXEC mkdir rootfs/etc/systemd/system/{mariadb,systemd-logind,apache2,mpd,vaultwarden,blynkserver,gogs,whodb,lazylibrarian,bazarr,immich,immich-ml}.service.d
501503
# ProtectHome/ProtectSystem/PrivateTmp/...: "Failed to set up mount namespacing: Invalid argument": https://github.com/systemd/systemd/issues/39951
502504
G_EXEC eval 'echo -e '\''[Service]\nProtectHome=0\nProtectSystem=0'\'' > rootfs/etc/systemd/system/mariadb.service.d/dietpi-container.conf'
503505
G_EXEC eval 'echo -e '\''[Service]\nProtectHome=0\nProtectSystem=0\nPrivateTmp=0\nReadWritePaths=\nProtectKernelModules=0\nProtectControlGroups=0\nProtectKernelLogs=0'\'' > rootfs/etc/systemd/system/systemd-logind.service.d/dietpi-container.conf'
@@ -511,6 +513,7 @@ then
511513
G_EXEC eval 'echo -e '\''[Service]\nProtectSystem=0\nProtectHome=0\nPrivateTmp=0\nPrivateDevices=0\nProtectKernelModules=0\nProtectControlGroups=0\nProtectKernelTunables=0\nProtectKernelLogs=0\nReadWritePaths='\'' > rootfs/etc/systemd/system/lazylibrarian.service.d/dietpi-container.conf'
512514
G_EXEC eval 'echo -e '\''[Service]\nProtectSystem=0\nProtectHome=0\nPrivateTmp=0\nPrivateDevices=0\nProtectControlGroups=0\nProtectKernelTunables=0\nReadWritePaths='\'' > rootfs/etc/systemd/system/bazarr.service.d/dietpi-container.conf'
513515
G_EXEC eval 'echo -e '\''[Service]\nProtectSystem=0\nProtectHome=0\nPrivateTmp=0\nPrivateDevices=0\nProtectKernelModules=0\nProtectControlGroups=0\nProtectKernelTunables=0\nProtectKernelLogs=0\nReadWritePaths='\'' > rootfs/etc/systemd/system/immich.service.d/dietpi-container.conf'
516+
G_EXEC eval 'echo -e '\''[Service]\nProtectSystem=0\nProtectHome=0\nPrivateTmp=0\nPrivateDevices=0\nProtectKernelModules=0\nProtectControlGroups=0\nProtectKernelTunables=0\nProtectKernelLogs=0\nReadWritePaths='\'' > rootfs/etc/systemd/system/immich-ml.service.d/dietpi-container.conf'
514517

515518
# /dev/console == /dev/pts/0 seen as "Inappropriate ioctl for device" leading to failing console-getty.service and StandardOutput=tty
516519
G_EXEC eval 'echo -e '\''#!/bin/dash\nexec /boot/dietpi/dietpi-login > /dev/console 2>&1'\'' > rootfs/var/lib/dietpi/postboot.d/dietpi-login'

.github/workflows/update_urls.bash

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@ aCHECK[$software_id]='curl -sSf '\''https://api.github.com/repos/WebAssembly/bin
370370
aARCH[$software_id]='aarch64 x86_64'
371371
aREGEX[$software_id]='https://github.com/WebAssembly/binaryen/releases/download/.*/binaryen-.*-$arch-linux.tar.gz'
372372

373+
# Immich Machine Learning (same Immich release)
374+
software_id=216
375+
aCHECK[$software_id]='curl -sSf '\''https://api.github.com/repos/immich-app/immich/releases/latest'\'' | mawk -F\" '\''/^ *"tag_name": "[^"]*",$/{print $4}'\'
376+
aREGEX[$software_id]='version='\''[^'\'']*'\'
377+
aREPLACE[$software_id]='version='\''$release'\'
378+
379+
# uv (for Immich Machine Learning)
380+
software_id=216000
381+
aCHECK[$software_id]='curl -sSf '\''https://api.github.com/repos/astral-sh/uv/releases/latest'\'' | mawk -F\" "/^ *\"browser_download_url\": \".*\/uv-$arch-unknown-linux-gnu\.tar\.gz\"$/{print \$4}"'
382+
aARCH[$software_id]='aarch64 x86_64'
383+
aREGEX[$software_id]='https://github.com/astral-sh/uv/releases/download/.*/uv-$arch-unknown-linux-gnu.tar.gz'
384+
373385
### URL check loop ###
374386

375387
for i in "${!aCHECK[@]}"

CHANGELOG.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ New images:
55

66
New software:
77
- Immich | This high performance self-hosted photo and video management solution has been added to our software catalogue. Available on x86_64 and ARMv8 only.
8+
- Immich Machine Learning | The machine learning server for Immich, enabling facial recognition and smart search via CLIP embeddings, has been added as a separate software option. It can be installed on the same system as Immich or on a remote machine. Available on x86_64 and ARMv8 only.
89
- RustDesk Client: Client software for the RustDesk desktop sharing platform. Fits perfect to our software package "RustDesk Server". An X11 desktop needs to be installed or will be installed during the RustDesk Client installation process.
910

1011
Enhancements:

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ Links to hardware and software manufacturers, sources and build instructions use
351351
- [Uptime Kuma](https://github.com/louislam/uptime-kuma)
352352
- [WhoDB](https://github.com/clidey/whodb)
353353
- [Immich](https://github.com/immich-app/immich)
354+
- [Immich Machine Learning](https://github.com/immich-app/immich)
354355
- [RustDesk Client](https://github.com/rustdesk/rustdesk)
355356

356357
---

dietpi/dietpi-services

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ _EOF_
211211
'filebrowser'
212212
'ocis'
213213
'immich'
214+
'immich-ml'
214215

215216
# - Emulation/Gaming
216217
'mineos'

dietpi/dietpi-software

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,15 @@ Available commands:
871871
(( $G_DISTRO < 8 )) && aSOFTWARE_AVAIL_G_DISTRO[$software_id,$G_DISTRO]=0
872872
# VectorChord only provides packages for amd64 and arm64
873873
(( $G_HW_ARCH == 3 || $G_HW_ARCH == 10 )) || aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,$G_HW_ARCH]=0
874+
#------------------
875+
software_id=216
876+
aSOFTWARE_NAME[$software_id]='Immich Machine Learning'
877+
aSOFTWARE_DESC[$software_id]='Machine learning server for Immich facial recognition and smart search'
878+
aSOFTWARE_CATX[$software_id]=4
879+
aSOFTWARE_DOCS[$software_id]='https://dietpi.com/docs/software/cloud/#immich'
880+
aSOFTWARE_DEPS[$software_id]='130'
881+
# onnxruntime only provides packages for amd64 and arm64
882+
(( $G_HW_ARCH == 3 || $G_HW_ARCH == 10 )) || aSOFTWARE_AVAIL_G_HW_ARCH[$software_id,$G_HW_ARCH]=0
874883

875884
# Gaming & Emulation
876885
#--------------------------------------------------------------------------------
@@ -12182,6 +12191,93 @@ ProtectClock=1
1218212191
NoNewPrivileges=1
1218312192
ReadWritePaths=-/mnt/dietpi_userdata/immich
1218412193

12194+
[Install]
12195+
WantedBy=multi-user.target
12196+
_EOF_
12197+
fi
12198+
12199+
if To_Install 216 immich-ml # Immich Machine Learning
12200+
then
12201+
# Download Immich source (machine-learning directory only)
12202+
local version=$(curl -sSfL 'https://api.github.com/repos/immich-app/immich/releases/latest' | mawk -F\" '/^ *"tag_name": "[^"]*",$/{print $4}')
12203+
[[ $version ]] || { version='v2.5.6'; G_DIETPI-NOTIFY 1 "Automatic latest ${aSOFTWARE_NAME[$software_id]} version detection failed. Version \"$version\" will be installed as fallback, but a newer version might be available. Please report this at: https://github.com/MichaIng/DietPi/issues"; }
12204+
aDEPS=('libgl1' 'libglib2.0-0' 'libgomp1')
12205+
Download_Install "https://github.com/immich-app/immich/archive/$version.tar.gz"
12206+
[[ -d '/opt/immich-ml' ]] && G_EXEC rm -R /opt/immich-ml
12207+
G_EXEC mv "immich-${version#v}/machine-learning" /opt/immich-ml
12208+
G_EXEC rm -R "immich-${version#v}"
12209+
12210+
# Install uv: https://github.com/astral-sh/uv
12211+
# NB: fallback_url is used by Download_Install when the dynamic URL detection fails
12212+
local arch='x86_64'
12213+
(( $G_HW_ARCH == 3 )) && arch='aarch64'
12214+
local fallback_url="https://github.com/astral-sh/uv/releases/download/0.8.15/uv-$arch-unknown-linux-gnu.tar.gz"
12215+
Download_Install "$(curl -sSfL 'https://api.github.com/repos/astral-sh/uv/releases/latest' | mawk -F\" "/^ *\"browser_download_url\": \".*\/uv-$arch-unknown-linux-gnu\.tar\.gz\"$/{print \$4}")"
12216+
G_EXEC mv uv /usr/local/bin/uv
12217+
G_EXEC rm -f uvx
12218+
12219+
# Install Python dependencies into a virtual environment
12220+
# NB: Python 3 (dep 130) provides Python >= 3.11 on Bookworm and Trixie, satisfying the ML requirement
12221+
# NB: --no-python-downloads prevents uv from fetching a Python runtime; uses system Python only
12222+
G_EXEC cd /opt/immich-ml
12223+
G_EXEC_OUTPUT=1 G_EXEC uv sync --frozen --extra cpu --no-dev --compile-bytecode --no-progress --no-python-downloads
12224+
G_EXEC cd "$G_WORKING_DIR"
12225+
12226+
# User: Reuse immich user if available, else create it
12227+
Create_User -d /mnt/dietpi_userdata/immich immich
12228+
12229+
# Data directory
12230+
G_EXEC mkdir -p /mnt/dietpi_userdata/immich/model-cache
12231+
G_EXEC chown -R immich:immich /mnt/dietpi_userdata/immich
12232+
12233+
# Env file
12234+
if [[ ! -f '/mnt/dietpi_userdata/immich/immich-ml.env' ]]
12235+
then
12236+
G_EXEC install -g immich -m 0640 /dev/null /mnt/dietpi_userdata/immich/immich-ml.env
12237+
cat << '_EOF_' > /mnt/dietpi_userdata/immich/immich-ml.env || exit 1
12238+
# Immich Machine Learning port and bind host (use 127.0.0.1 for local, 0.0.0.0 for remote ML)
12239+
IMMICH_PORT=3003
12240+
IMMICH_HOST=127.0.0.1
12241+
12242+
# Log level: verbose, debug, log, warn, error, fatal
12243+
IMMICH_LOG_LEVEL=warn
12244+
12245+
# Cache directory for downloaded AI model files
12246+
MACHINE_LEARNING_CACHE_FOLDER=/mnt/dietpi_userdata/immich/model-cache
12247+
_EOF_
12248+
fi
12249+
12250+
# Enable machine learning in Immich server config if present (no-op for standalone ML setups)
12251+
[[ -f '/mnt/dietpi_userdata/immich/immich.env' ]] && G_CONFIG_INJECT 'IMMICH_MACHINE_LEARNING_ENABLED=' 'IMMICH_MACHINE_LEARNING_ENABLED=true' /mnt/dietpi_userdata/immich/immich.env
12252+
12253+
# Service
12254+
cat << '_EOF_' > /etc/systemd/system/immich-ml.service || exit 1
12255+
[Unit]
12256+
Description=Immich Machine Learning (DietPi)
12257+
Wants=network-online.target
12258+
After=network-online.target
12259+
12260+
[Service]
12261+
SyslogIdentifier=Immich-ML
12262+
User=immich
12263+
WorkingDirectory=/opt/immich-ml
12264+
Environment=NO_COLOR=true
12265+
EnvironmentFile=/mnt/dietpi_userdata/immich/immich-ml.env
12266+
ExecStart=/opt/immich-ml/.venv/bin/python -m immich_ml
12267+
12268+
# Hardening
12269+
ProtectSystem=strict
12270+
ProtectHome=1
12271+
PrivateDevices=1
12272+
PrivateTmp=1
12273+
ProtectKernelTunables=1
12274+
ProtectKernelModules=1
12275+
ProtectControlGroups=1
12276+
ProtectKernelLogs=1
12277+
ProtectClock=1
12278+
NoNewPrivileges=1
12279+
ReadWritePaths=-/mnt/dietpi_userdata/immich
12280+
1218512281
[Install]
1218612282
WantedBy=multi-user.target
1218712283
_EOF_
@@ -14690,6 +14786,17 @@ _EOF_
1469014786
[[ -d '/mnt/dietpi_userdata/immich' ]] && G_WHIP_BUTTON_CANCEL_TEXT='Skip' G_WHIP_YESNO "Shall all ${aSOFTWARE_NAME[$software_id]} data at /mnt/dietpi_userdata/immich be removed as well?" && G_EXEC rm -R /mnt/dietpi_userdata/immich
1469114787
fi
1469214788

14789+
if To_Uninstall 216 # Immich Machine Learning
14790+
then
14791+
Remove_Service immich-ml
14792+
[[ -d '/opt/immich-ml' ]] && G_EXEC rm -Rf /opt/immich-ml
14793+
# Disable machine learning in Immich server config if still installed
14794+
[[ -f '/mnt/dietpi_userdata/immich/immich.env' ]] && G_CONFIG_INJECT 'IMMICH_MACHINE_LEARNING_ENABLED=' 'IMMICH_MACHINE_LEARNING_ENABLED=false' /mnt/dietpi_userdata/immich/immich.env
14795+
# Remove immich user and group only if main Immich is not installed
14796+
(( ${aSOFTWARE_INSTALL_STATE[215]} > 0 )) || { getent passwd immich > /dev/null && G_EXEC userdel immich; getent group immich > /dev/null && G_EXEC groupdel immich; }
14797+
[[ -d '/mnt/dietpi_userdata/immich' ]] && G_WHIP_BUTTON_CANCEL_TEXT='Skip' G_WHIP_YESNO "Shall all ${aSOFTWARE_NAME[$software_id]} data at /mnt/dietpi_userdata/immich be removed as well?" && G_EXEC rm -R /mnt/dietpi_userdata/immich
14798+
fi
14799+
1469314800
if To_Uninstall 169 # LazyLibrarian
1469414801
then
1469514802
Remove_Service lazylibrarian 1 1

0 commit comments

Comments
 (0)