Skip to content

Commit 1fd24bd

Browse files
immich (#4886)
1 parent fc78064 commit 1fd24bd

File tree

4 files changed

+832
-0
lines changed

4 files changed

+832
-0
lines changed

ct/headers/immich

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_ _ __
2+
(_)___ ___ ____ ___ (_)____/ /_
3+
/ / __ `__ \/ __ `__ \/ / ___/ __ \
4+
/ / / / / / / / / / / / / /__/ / / /
5+
/_/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/
6+

ct/immich.sh

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
#!/usr/bin/env bash
2+
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
3+
# Copyright (c) 2021-2025 community-scripts ORG
4+
# Author: vhsdream
5+
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
6+
# Source: https://immich.app
7+
8+
APP="immich"
9+
var_tags="${var_tags:-photos}"
10+
var_disk="${var_disk:-20}"
11+
var_cpu="${var_cpu:-4}"
12+
var_ram="${var_ram:-4096}"
13+
var_os="${var_os:-debian}"
14+
var_version="${var_version:-12}"
15+
var_unprivileged="${var_unprivileged:-1}"
16+
17+
header_info "$APP"
18+
variables
19+
color
20+
catch_errors
21+
22+
function update_script() {
23+
header_info
24+
check_container_storage
25+
check_container_resources
26+
if [[ ! -d /opt/immich ]]; then
27+
msg_error "No ${APP} Installation Found!"
28+
exit
29+
fi
30+
STAGING_DIR=/opt/staging
31+
BASE_DIR=${STAGING_DIR}/base-images
32+
SOURCE_DIR=${STAGING_DIR}/image-source
33+
if [[ -f ~/.intel_version ]]; then
34+
curl -fsSLO https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile
35+
readarray -t INTEL_URLS < <(sed -n "/intel/p" ./Dockerfile | awk '{print $3}')
36+
INTEL_RELEASE="$(grep "intel-opencl-icd" ./Dockerfile | awk -F '_' '{print $2}')"
37+
if [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
38+
msg_info "Updating Intel iGPU dependencies"
39+
for url in "${INTEL_URLS[@]}"; do
40+
curl -fsSLO "$url"
41+
done
42+
$STD dpkg -i ./*.deb
43+
rm ./*.deb
44+
msg_ok "Intel iGPU dependencies updated"
45+
fi
46+
rm ~/Dockerfile
47+
fi
48+
if [[ -f ~/.immich_library_revisions ]]; then
49+
libraries=("libjxl" "libheif" "libraw" "imagemagick" "libvips")
50+
readarray -d '' NEW_REVISIONS < <(for library in "${libraries[@]}"; do
51+
echo "$library: $(curl -fsSL https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/sources/"$library".json | jq -cr '.revision' -)"
52+
done)
53+
UPDATED_REVISIONS="$(comm -13 <(sort ~/.immich_library_revisions) <(echo -n "${NEW_REVISIONS[@]}" | sort))"
54+
if [[ "$UPDATED_REVISIONS" ]]; then
55+
readarray -t NAMES < <(echo "$UPDATED_REVISIONS" | awk -F ':' '{print $1}')
56+
rm -rf "$SOURCE_DIR"
57+
mkdir -p "$SOURCE_DIR"
58+
cd "$BASE_DIR"
59+
$STD git pull
60+
cd "$STAGING_DIR"
61+
for name in "${NAMES[@]}"; do
62+
if [[ "$name" == "libjxl" ]]; then
63+
msg_info "Recompiling libjxl"
64+
SOURCE=${SOURCE_DIR}/libjxl
65+
JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
66+
JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
67+
: "${LIBJXL_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libjxl.json)}"
68+
$STD git clone https://github.com/libjxl/libjxl.git "$SOURCE"
69+
cd "$SOURCE"
70+
$STD git reset --hard "$LIBJXL_REVISION"
71+
$STD git submodule update --init --recursive --depth 1 --recommend-shallow
72+
$STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-empty-dht-marker.patch
73+
$STD git apply "$BASE_DIR"/server/sources/libjxl-patches/jpegli-icc-warning.patch
74+
mkdir build
75+
cd build
76+
$STD cmake \
77+
-DCMAKE_BUILD_TYPE=Release \
78+
-DBUILD_TESTING=OFF \
79+
-DJPEGXL_ENABLE_DOXYGEN=OFF \
80+
-DJPEGXL_ENABLE_MANPAGES=OFF \
81+
-DJPEGXL_ENABLE_PLUGIN_GIMP210=OFF \
82+
-DJPEGXL_ENABLE_BENCHMARK=OFF \
83+
-DJPEGXL_ENABLE_EXAMPLES=OFF \
84+
-DJPEGXL_FORCE_SYSTEM_BROTLI=ON \
85+
-DJPEGXL_FORCE_SYSTEM_HWY=ON \
86+
-DJPEGXL_ENABLE_JPEGLI=ON \
87+
-DJPEGXL_ENABLE_JPEGLI_LIBJPEG=ON \
88+
-DJPEGXL_INSTALL_JPEGLI_LIBJPEG=ON \
89+
-DJPEGXL_ENABLE_PLUGINS=ON \
90+
-DJPEGLI_LIBJPEG_LIBRARY_SOVERSION="$JPEGLI_LIBJPEG_LIBRARY_SOVERSION" \
91+
-DJPEGLI_LIBJPEG_LIBRARY_VERSION="$JPEGLI_LIBJPEG_LIBRARY_VERSION" \
92+
-DLIBJPEG_TURBO_VERSION_NUMBER=2001005 \
93+
..
94+
$STD cmake --build . -- -j"$(nproc)"
95+
$STD cmake --install .
96+
ldconfig /usr/local/lib
97+
$STD make clean
98+
cd "$STAGING_DIR"
99+
rm -rf "$SOURCE"/{build,third_party}
100+
msg_ok "Recompiled libjxl"
101+
fi
102+
if [[ "$name" == "libheif" ]]; then
103+
msg_info "Recompiling libheif"
104+
SOURCE=${SOURCE_DIR}/libheif
105+
: "${LIBHEIF_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libheif.json)}"
106+
$STD git clone https://github.com/strukturag/libheif.git "$SOURCE"
107+
cd "$SOURCE"
108+
$STD git reset --hard "$LIBHEIF_REVISION"
109+
mkdir build
110+
cd build
111+
$STD cmake --preset=release-noplugins \
112+
-DWITH_DAV1D=ON \
113+
-DENABLE_PARALLEL_TILE_DECODING=ON \
114+
-DWITH_LIBSHARPYUV=ON \
115+
-DWITH_LIBDE265=ON \
116+
-DWITH_AOM_DECODER=OFF \
117+
-DWITH_AOM_ENCODER=OFF \
118+
-DWITH_X265=OFF \
119+
-DWITH_EXAMPLES=OFF \
120+
..
121+
$STD make install -j "$(nproc)"
122+
ldconfig /usr/local/lib
123+
$STD make clean
124+
cd "$STAGING_DIR"
125+
rm -rf "$SOURCE"/build
126+
msg_ok "Recompiled libheif"
127+
fi
128+
if [[ "$name" == "libraw" ]]; then
129+
msg_info "Recompiling libraw"
130+
SOURCE=${SOURCE_DIR}/libraw
131+
: "${LIBRAW_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libraw.json)}"
132+
$STD git clone https://github.com/libraw/libraw.git "$SOURCE"
133+
cd "$SOURCE"
134+
$STD git reset --hard "$LIBRAW_REVISION"
135+
$STD autoreconf --install
136+
$STD ./configure
137+
$STD make -j"$(nproc)"
138+
$STD make install
139+
ldconfig /usr/local/lib
140+
$STD make clean
141+
cd "$STAGING_DIR"
142+
msg_ok "Recompiled libraw"
143+
fi
144+
if [[ "$name" == "imagemagick" ]]; then
145+
msg_info "Recompiling ImageMagick"
146+
SOURCE=$SOURCE_DIR/imagemagick
147+
: "${IMAGEMAGICK_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/imagemagick.json)}"
148+
$STD git clone https://github.com/ImageMagick/ImageMagick.git "$SOURCE"
149+
cd "$SOURCE"
150+
$STD git reset --hard "$IMAGEMAGICK_REVISION"
151+
$STD ./configure --with-modules
152+
$STD make -j"$(nproc)"
153+
$STD make install
154+
ldconfig /usr/local/lib
155+
$STD make clean
156+
cd "$STAGING_DIR"
157+
msg_ok "Recompiled ImageMagick"
158+
fi
159+
if [[ "$name" == "libvips" ]]; then
160+
msg_info "Recompiling libvips"
161+
SOURCE=$SOURCE_DIR/libvips
162+
: "${LIBVIPS_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libvips.json)}"
163+
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
164+
cd "$SOURCE"
165+
$STD git reset --hard "$LIBVIPS_REVISION"
166+
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
167+
cd build
168+
$STD ninja install
169+
ldconfig /usr/local/lib
170+
cd "$STAGING_DIR"
171+
rm -rf "$SOURCE"/build
172+
msg_ok "Recompiled libvips"
173+
fi
174+
done
175+
echo -n "${NEW_REVISIONS[@]}" >~/.immich_library_revisions
176+
msg_ok "Image-processing libraries compiled"
177+
fi
178+
fi
179+
RELEASE=$(curl -s https://api.github.com/repos/immich-app/immich/releases?per_page=1 | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
180+
if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
181+
msg_info "Stopping ${APP} services"
182+
systemctl stop immich-web
183+
systemctl stop immich-ml
184+
msg_ok "Stopped ${APP}"
185+
if [[ "$(cat /opt/${APP}_version.txt)" < "1.133.0" ]]; then
186+
msg_info "Upgrading to the VectorChord PostgreSQL extension"
187+
NUMBER="$(
188+
sed -n '2p' <(
189+
sudo -u postgres psql -A -d immich <<EOF
190+
SELECT atttypmod as dimsize
191+
FROM pg_attribute f
192+
JOIN pg_class c ON c.oid = f.attrelid
193+
WHERE c.relkind = 'r'::char
194+
AND f.attnum > 0
195+
AND c.relname = 'smart_search'::text
196+
AND f.attname = 'embedding'::text;
197+
EOF
198+
)
199+
)"
200+
$STD sudo -u postgres psql -d immich <<EOF
201+
DROP INDEX IF EXISTS clip_index;
202+
DROP INDEX IF EXISTS face_index;
203+
ALTER TABLE smart_search ALTER COLUMN embedding SET DATA TYPE real[];
204+
ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE real[];
205+
EOF
206+
$STD apt-get update
207+
$STD apt-get install postgresql-16-pgvector -y
208+
curl -fsSL https://github.com/tensorchord/VectorChord/releases/download/0.3.0/postgresql-16-vchord_0.3.0-1_amd64.deb -o vchord.deb
209+
$STD dpkg -i vchord.deb
210+
rm vchord.deb
211+
sed -i "s|vectors.so|vchord.so|" /etc/postgresql/16/main/postgresql.conf
212+
systemctl restart postgresql.service
213+
$STD sudo -u postgres psql -d immich <<EOF
214+
CREATE EXTENSION IF NOT EXISTS vchord CASCADE;
215+
ALTER TABLE smart_search ALTER COLUMN embedding SET DATA TYPE vector($NUMBER);
216+
ALTER TABLE face_search ALTER COLUMN embedding SET DATA TYPE vector(512);
217+
EOF
218+
$STD apt purge vectors-pg16 -y
219+
msg_ok "Database upgrade complete"
220+
fi
221+
INSTALL_DIR="/opt/${APP}"
222+
UPLOAD_DIR="$(sed -n '/^IMMICH_MEDIA_LOCATION/s/[^=]*=//p' /opt/immich/.env)"
223+
SRC_DIR="${INSTALL_DIR}/source"
224+
APP_DIR="${INSTALL_DIR}/app"
225+
ML_DIR="${APP_DIR}/machine-learning"
226+
GEO_DIR="${INSTALL_DIR}/geodata"
227+
cp "$ML_DIR"/ml_start.sh "$INSTALL_DIR"
228+
rm -rf "${APP_DIR:?}"/*
229+
rm -rf "$SRC_DIR"
230+
immich_zip=$(mktemp)
231+
curl -fsSL "https://github.com/immich-app/immich/archive/refs/tags/v${RELEASE}.zip" -o "$immich_zip"
232+
msg_info "Updating ${APP} web and microservices"
233+
unzip -q "$immich_zip"
234+
mv "$APP-$RELEASE"/ "$SRC_DIR"
235+
mkdir -p "$ML_DIR"
236+
cd "$SRC_DIR"/server
237+
$STD npm install -g node-gyp node-pre-gyp
238+
$STD npm ci
239+
$STD npm run build
240+
$STD npm prune --omit=dev --omit=optional
241+
cd "$SRC_DIR"/open-api/typescript-sdk
242+
$STD npm ci
243+
$STD npm run build
244+
cd "$SRC_DIR"/web
245+
$STD npm ci
246+
$STD npm run build
247+
cd "$SRC_DIR"
248+
cp -a server/{node_modules,dist,bin,resources,package.json,package-lock.json,start*.sh} "$APP_DIR"/
249+
cp -a web/build "$APP_DIR"/www
250+
cp LICENSE "$APP_DIR"
251+
msg_ok "Updated ${APP} web and microservices"
252+
253+
cd "$SRC_DIR"/machine-learning
254+
$STD python3 -m venv "$ML_DIR"/ml-venv
255+
if [[ -f ~/.openvino ]]; then
256+
msg_info "Updating HW-accelerated machine-learning"
257+
(
258+
source "$ML_DIR"/ml-venv/bin/activate
259+
$STD pip3 install -U uv
260+
uv -q sync --extra openvino --no-cache --active
261+
)
262+
patchelf --clear-execstack "$ML_DIR"/ml-venv/lib/python3.11/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-311-x86_64-linux-gnu.so
263+
msg_ok "Updated HW-accelerated machine-learning"
264+
else
265+
msg_info "Updating machine-learning"
266+
(
267+
source "$ML_DIR"/ml-venv/bin/activate
268+
$STD pip3 install -U uv
269+
uv -q sync --extra cpu --no-cache --active
270+
)
271+
msg_ok "Updated machine-learning"
272+
fi
273+
cd "$SRC_DIR"
274+
cp -a machine-learning/{ann,immich_ml} "$ML_DIR"
275+
cp "$INSTALL_DIR"/ml_start.sh "$ML_DIR"
276+
if [[ -f ~/.openvino ]]; then
277+
sed -i "/intra_op/s/int = 0/int = os.cpu_count() or 0/" "$ML_DIR"/immich_ml/config.py
278+
fi
279+
ln -sf "$APP_DIR"/resources "$INSTALL_DIR"
280+
cd "$APP_DIR"
281+
grep -Rl /usr/src | xargs -n1 sed -i "s|\/usr/src|$INSTALL_DIR|g"
282+
grep -RlE "'/build'" | xargs -n1 sed -i "s|'/build'|'$APP_DIR'|g"
283+
sed -i "s@\"/cache\"@\"$INSTALL_DIR/cache\"@g" "$ML_DIR"/immich_ml/config.py
284+
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$APP_DIR"/upload
285+
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$ML_DIR"/upload
286+
ln -s "$GEO_DIR" "$APP_DIR"
287+
288+
msg_info "Updating Immich CLI"
289+
$STD npm install --build-from-source sharp
290+
rm -rf "$APP_DIR"/node_modules/@img/sharp-{libvips*,linuxmusl-x64}
291+
$STD npm i -g @immich/cli
292+
msg_ok "Updated Immich CLI"
293+
294+
sed -i "s|pgvecto.rs|vectorchord|" /opt/"${APP}"/.env
295+
296+
chown -R immich:immich "$INSTALL_DIR"
297+
echo "$RELEASE" >/opt/"${APP}"_version.txt
298+
msg_ok "Updated ${APP} to v${RELEASE}"
299+
300+
msg_info "Cleaning up"
301+
rm -f "$immich_zip"
302+
$STD apt-get -y autoremove
303+
$STD apt-get -y autoclean
304+
msg_ok "Cleaned"
305+
else
306+
msg_ok "${APP} is already at v${RELEASE}"
307+
fi
308+
systemctl restart immich-ml immich-web
309+
exit
310+
}
311+
312+
start
313+
build_container
314+
description
315+
316+
msg_ok "Completed Successfully!\n"
317+
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
318+
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
319+
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:2283${CL}"

frontend/public/json/immich.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "Immich",
3+
"slug": "immich",
4+
"categories": [
5+
13
6+
],
7+
"date_created": "2025-03-30",
8+
"type": "ct",
9+
"updateable": true,
10+
"privileged": false,
11+
"interface_port": 2283,
12+
"documentation": "https://immich.app/docs/overview/introduction",
13+
"website": "https://immich.app",
14+
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/immich.webp",
15+
"config_path": "/opt/immich/.env",
16+
"description": "High performance self-hosted photo and video management solution.",
17+
"install_methods": [
18+
{
19+
"type": "default",
20+
"script": "ct/immich.sh",
21+
"resources": {
22+
"cpu": 4,
23+
"ram": 4096,
24+
"hdd": 20,
25+
"os": "Debian",
26+
"version": "12"
27+
}
28+
}
29+
],
30+
"default_credentials": {
31+
"username": null,
32+
"password": null
33+
},
34+
"notes": [
35+
{
36+
"text": "During installation, HW-accelerated machine-learning (with OpenVINO) is an available option. This also allows for HW-accelerated transcoding, but it must be enabled in Video Transcoding Settings",
37+
"type": "info"
38+
},
39+
{
40+
"text": "If using OpenVINO HW machine-learning, increase RAM because OpenVINO is memory-intensive",
41+
"type": "info"
42+
},
43+
{
44+
"text": "To change upload location, edit 'IMMICH_MEDIA_LOCATION' in `/opt/immich/.env`",
45+
"type": "info"
46+
}
47+
]
48+
}

0 commit comments

Comments
 (0)