Files
ProxmoxVE/ct/immich.sh
T
CanbiZ (MickLesk) 84d2c964e6 Immich: Pin to 3.3.0 / Update ML Python to 3.13 (#17770)
* Immich: pin v3.3.0 again

Reapplies #17759, reverted in #17767 because machine learning broke on 3.3.0; the fixes follow.

* Immich: run machine learning on Python 3.13

3.3.0 requires Python >=3.12 for machine learning and upstream builds both its CPU and OpenVINO images on 3.13. The CPU path still pinned 3.11, so uv sync failed on every update and install (#17762).

* Immich: stop when uv sync keeps failing

After three failed attempts the loop still reported the machine-learning step as done, so an update ended in "Updated successfully" with no usable venv and immich-ml failing on start. Exit with an error instead.

* Immich: only mention the HEIC patch when it applies

On 3.3.0 the sharp call it rewrites is gone, so every run printed "pattern not found, skipped" into the spinner line and then "Patched". Check for the pattern first and stay silent otherwise.

* BookOrbit: retry the client build when the bundler crashes

Since rolldown 1.2.8, vite build dies at random with SIGSEGV or SIGBUS
(rolldown#10860, closed upstream), which stopped the 3.3.0 update with exit
139 (#17753). Retry the client build up to three times before giving up.
2026-10-08 11:47:06 +02:00

573 lines
25 KiB
Bash

#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://immich.app | Github: https://github.com/immich-app/immich
APP="immich"
var_tags="${var_tags:-photos}"
var_disk="${var_disk:-20}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-6144}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/immich ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if [[ -f /etc/apt/sources.list.d/immich.list ]]; then
msg_error "Wrong Debian version detected!"
msg_error "You must upgrade your LXC to Debian Trixie before updating."
msg_error "Please visit https://github.com/community-scripts/ProxmoxVE/discussions/7726 for details."
echo "${TAB3} If you have upgraded your LXC to Trixie and you still see this message, please open an Issue in the Community-Scripts repo."
exit
fi
if ! grep -qE '(^|[[:space:]])testing([[:space:]]|$)' /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
msg_info "Adding Debian Testing repo"
if grep -q "trixie-updates" /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources
else
sed -i '/^[[:space:]]*Suites:.*trixie/ s/$/ testing/' /etc/apt/sources.list.d/debian.sources
fi
cat <<EOF >/etc/apt/preferences.d/preferences
Package: *
Pin: release a=unstable
Pin-Priority: 450
Package: *
Pin:release a=testing
Pin-Priority: 450
EOF
[[ -f /etc/apt/preferences.d/immich ]] && rm /etc/apt/preferences.d/immich
apt_update_safe
msg_ok "Added Debian Testing repo"
fi
if ! dpkg -l "libmimalloc3" | grep -q '3.1' || ! dpkg -l "libde265-dev" | grep -q '1.0.16'; then
msg_info "Installing/upgrading Testing repo packages"
$STD apt install -t testing libmimalloc3 libde265-dev -y
msg_ok "Installed/upgraded Testing repo packages"
fi
if [[ ! -f /etc/apt/sources.list.d/mise.list ]]; then
msg_info "Installing Mise"
curl -fSs https://mise.jdx.dev/gpg-key.pub | tee /etc/apt/keyrings/mise-archive-keyring.pub 1>/dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.pub arch=$(arch_resolve)] https://mise.jdx.dev/deb stable main" >/etc/apt/sources.list.d/mise.list
ensure_dependencies mise
msg_ok "Installed Mise"
fi
STAGING_DIR=/opt/staging
BASE_DIR=${STAGING_DIR}/base-images
SOURCE_DIR=${STAGING_DIR}/image-source
cd /tmp
RELEASE="v3.3.0"
if [[ -f ~/.intel_version ]]; then
INTEL_SRC="https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/machine-learning"
curl -fsSL "${INTEL_SRC}/scripts/install-intel-runtime.sh" -o ./intel-runtime 2>/dev/null ||
curl_with_retry "${INTEL_SRC}/Dockerfile" "./intel-runtime"
readarray -t INTEL_URLS < <(grep -oE 'https://github\.com/intel/[^[:space:]]+\.deb' ./intel-runtime)
INTEL_RELEASE="$(grep -oE 'intel-opencl-icd_[^_]+' ./intel-runtime | cut -d_ -f2)" || true
rm -f ./intel-runtime
if [[ -z "$INTEL_RELEASE" ]]; then
msg_warn "No Intel runtime found for Immich ${RELEASE}, keeping the installed one"
elif [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
msg_info "Updating Intel OpenVINO dependencies"
for url in "${INTEL_URLS[@]}"; do
curl_with_retry "$url" "$(basename "$url")"
done
$STD apt-mark unhold libigdgmm12
$STD apt install -y --allow-downgrades ./libigdgmm12*.deb
rm ./libigdgmm12*.deb
$STD apt install -y ./*.deb
rm ./*.deb
$STD apt-mark hold libigdgmm12
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
msg_ok "Updated Intel OpenVINO dependencies"
fi
fi
if [[ -f ~/.immich_library_revisions ]]; then
libraries=("libjxl" "jpegli" "libheif" "libraw" "imagemagick" "libvips")
cd "$BASE_DIR"
msg_warn "Checking for updates to custom image-processing libraries (recompile time: 2-15min per library)"
ensure_dependencies liblcms2-dev libjpeg62-turbo-dev libspng-dev libexif-dev
$STD git pull
for library in "${libraries[@]}"; do
compile_"$library"
done
msg_ok "Image-processing libraries up to date"
fi
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
cd /opt/immich/app/bin
$STD ./immich-admin enable-maintenance-mode || true
export MAINT_MODE=1
$STD cd -
msg_ok "Enabled Maintenance Mode"
fi
msg_info "Stopping Services"
systemctl stop immich-web
systemctl stop immich-ml
msg_ok "Stopped Services"
VCHORD_RELEASE="1.1.1"
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
PG_VERSION=${PG_VERSION:-16}
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
# dead tuples in smart_search/face_search make the REINDEX below fail with
# "missing chunk ... for toast value" on VectorChord 1.0.0 (#15588); must vacuum
# while still on the old extension version, a post-upgrade vacuum errors instead
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) smart_search;"
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) face_search;"
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${PG_VERSION}-vchord_*_$(arch_resolve).deb"
systemctl restart postgresql
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vchord UPDATE;"
$STD sudo -u postgres psql -d immich -c "REINDEX INDEX face_index;"
$STD sudo -u postgres psql -d immich -c "REINDEX INDEX clip_index;"
fi
ensure_dependencies ccache gcc-13 g++-13
INSTALL_DIR="/opt/${APP}"
UPLOAD_DIR="$(sed -n '/^IMMICH_MEDIA_LOCATION/s/[^=]*=//p' /opt/immich/.env)"
SRC_DIR="${INSTALL_DIR}/source"
APP_DIR="${INSTALL_DIR}/app"
PLUGIN_DIR="${APP_DIR}/plugins/immich-plugin-core"
ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata"
[[ -f "$ML_DIR"/ml_start.sh ]] && cp "$ML_DIR"/ml_start.sh "$INSTALL_DIR"
if grep -qs "set -a" "$APP_DIR"/bin/start.sh && grep -qs "warnings" "$APP_DIR"/bin/start.sh; then
cp "$APP_DIR"/bin/start.sh "$INSTALL_DIR"
else
cat <<EOF >"$INSTALL_DIR"/start.sh
#!/usr/bin/env bash
set -a
. ${INSTALL_DIR}/.env
set +a
/usr/bin/node --no-warnings ${APP_DIR}/dist/main.js "\$@"
EOF
chmod +x "$INSTALL_DIR"/start.sh
fi
(
shopt -s dotglob
rm -rf "${APP_DIR:?}"/*
)
setup_uv
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "${RELEASE}" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
export CI=1
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
$STD corepack prepare "pnpm@${PNPM_VERSION}" --activate
export PATH="/root/.local/share/pnpm/bin:$PATH"
$STD pnpm config set --global dangerouslyAllowAllBuilds true
msg_info "Updating Immich web and microservices"
cd "$SRC_DIR"/server
# server build
$STD pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter immich build
$STD pnpm --filter immich --prod --no-optional deploy "$APP_DIR"
export SHARP_FORCE_GLOBAL_LIBVIPS=true
$STD pnpm --dir "$APP_DIR/node_modules/sharp" exec npm run build
# Patch helmet.json: disable upgrade-insecure-requests for HTTP access
if [[ -f "$APP_DIR/helmet.json" ]]; then
jq '.contentSecurityPolicy.directives["upgrade-insecure-requests"] = null' "$APP_DIR/helmet.json" >"$APP_DIR/helmet.json.tmp" && mv "$APP_DIR/helmet.json.tmp" "$APP_DIR/helmet.json"
fi
cp "$APP_DIR"/package.json "$APP_DIR"/bin
sed -i "s|^start|${APP_DIR}/bin/start|" "$APP_DIR"/bin/immich-admin
# sdk, cli & web build
cd "$SRC_DIR"
echo "packageImportMethod: hardlink" >>./pnpm-workspace.yaml
unset SHARP_FORCE_GLOBAL_LIBVIPS
$STD pnpm --filter @immich/sdk --filter immich-web --filter @immich/cli build
$STD pnpm --filter @immich/cli --prod --no-optional deploy "$APP_DIR"/cli
cp -a web/build "$APP_DIR"/www
cp LICENSE "$APP_DIR"
[[ -f "$INSTALL_DIR"/start.sh ]] && mv "$INSTALL_DIR"/start.sh "$APP_DIR"/bin
# plugins
cd "$SRC_DIR"
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
mise_ok=0
for i in 1 2 3; do
$STD mise install && {
mise_ok=1
break
}
msg_warn "mise install failed (attempt $i/3) - retrying"
sleep 5
done
[[ "$mise_ok" -eq 1 ]] || exit 1
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
if ! command -v extism-js >/dev/null 2>&1; then
# extism-js ships as a bare gzip-compressed single binary (.gz) that
# fetch_and_deploy_gh_release cannot deploy; fetch + gunzip it directly.
EXTISM_ARCH="$(arch_resolve x86_64 aarch64)"
curl_download /tmp/extism-js.gz "https://github.com/extism/js-pdk/releases/download/v1.6.0/extism-js-${EXTISM_ARCH}-linux-v1.6.0.gz"
gunzip -f /tmp/extism-js.gz
install -m 0755 /tmp/extism-js /usr/local/bin/extism-js
rm -f /tmp/extism-js
fi
if ! command -v wasm-merge >/dev/null 2>&1; then
# extism-js needs binaryen's `wasm-merge` to build the plugin wasm. mise
# 2026.7.0's github backend no longer exposes `wasm-merge` on PATH (ubi only
# extracts a single binary), so install the pinned binaryen release from
# mise.toml directly. The extracted bin/ keeps libbinaryen.so alongside it.
BINARYEN_VERSION="$(grep -oiP 'binaryen"\s*=\s*"\Kversion_[0-9]+' "$SRC_DIR"/mise.toml | head -n1)"
[[ -z "$BINARYEN_VERSION" ]] && BINARYEN_VERSION="version_124"
BINARYEN_ARCH="$(arch_resolve x86_64 aarch64)"
curl_download /tmp/binaryen.tar.gz "https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VERSION}/binaryen-${BINARYEN_VERSION}-${BINARYEN_ARCH}-linux.tar.gz"
tar -xzf /tmp/binaryen.tar.gz -C /opt
rm -f /tmp/binaryen.tar.gz
export PATH="/opt/binaryen-${BINARYEN_VERSION}/bin:$PATH"
fi
$STD mise exec -- pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter @immich/plugin-core install --frozen-lockfile
$STD mise exec -- pnpm --filter @immich/sdk --filter @immich/plugin-sdk --filter @immich/plugin-core build
mkdir -p "$PLUGIN_DIR"
cp -r ./packages/plugin-core/dist "$PLUGIN_DIR"/dist
cp ./packages/plugin-core/manifest.json "$PLUGIN_DIR"
msg_ok "Updated Immich server, web, cli and plugins"
cd "$SRC_DIR"/machine-learning
mkdir -p "$ML_DIR"
# chown excluding upload dir contents (may be a mount with restricted permissions)
chown immich:immich "$INSTALL_DIR"
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
chown immich:immich "${UPLOAD_DIR:-$INSTALL_DIR/upload}" 2>/dev/null || true
chown immich:immich ./uv.lock
export VIRTUAL_ENV="${ML_DIR}"/ml-venv
if [[ -f ~/.openvino ]]; then
ML_PYTHON="python3.13"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV -Pnu immich uv python install "${ML_PYTHON}" && break
[[ $attempt -lt 3 ]] && msg_warn "Python download attempt $attempt failed, retrying..." && sleep 5
done
msg_ok "Pre-installed Python ${ML_PYTHON}"
msg_info "Updating Intel OpenVINO machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.13/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-313-$(arch_resolve "x86_64" "aarch64")-linux-gnu.so"
msg_ok "Updated Intel OpenVINO machine-learning"
else
ML_PYTHON="python3.13"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV -Pnu immich uv python install "${ML_PYTHON}" && break
[[ $attempt -lt 3 ]] && msg_warn "Python download attempt $attempt failed, retrying..." && sleep 5
done
msg_ok "Pre-installed Python ${ML_PYTHON}"
msg_info "Updating machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
msg_ok "Updated machine-learning"
fi
cd "$SRC_DIR"
cp -a machine-learning/{ann,immich_ml} "$ML_DIR"
[[ -f "$INSTALL_DIR"/ml_start.sh ]] && mv "$INSTALL_DIR"/ml_start.sh "$ML_DIR"
# Regenerate ml_start.sh if it is missing (e.g. lost by a previously interrupted update),
# otherwise immich-ml.service fails to start with status=203/EXEC
if [[ ! -f "$ML_DIR"/ml_start.sh ]]; then
cat <<EOF >"$ML_DIR"/ml_start.sh
#!/usr/bin/env bash
cd ${ML_DIR}
. ${VIRTUAL_ENV}/bin/activate
set -a
. ${INSTALL_DIR}/.env
set +a
python3 -m immich_ml
EOF
chmod +x "$ML_DIR"/ml_start.sh
fi
[[ -f ~/.openvino ]] && sed -i "/intra_op/s/int = 0/int = os.cpu_count() or 0/" "$ML_DIR"/immich_ml/config.py
ln -sf "$APP_DIR"/resources "$INSTALL_DIR"
cd "$APP_DIR"
grep -rl /usr/src | xargs -n1 sed -i "s|\/usr/src|$INSTALL_DIR|g"
grep -rlE "'/build'" | xargs -n1 sed -i "s|'/build'|'$APP_DIR'|g"
sed -i "s@\"/cache\"@\"$INSTALL_DIR/cache\"@g" "$ML_DIR"/immich_ml/config.py
[[ ! -f "$GEO_DIR/countryInfo.txt" ]] && curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$APP_DIR"/upload
ln -s "${UPLOAD_DIR:-/opt/immich/upload}" "$ML_DIR"/upload
ln -sfn "$GEO_DIR" "$APP_DIR/geodata"
[[ ! -f /usr/bin/immich ]] && ln -sf "$APP_DIR"/cli/bin/immich /usr/bin/immich
[[ ! -f /usr/bin/immich-admin ]] && ln -sf "$APP_DIR"/bin/immich-admin /usr/bin/immich-admin
if ! grep -q '^DB_HOSTNAME=' "$INSTALL_DIR"/.env; then
sed -i '/^DB_DATABASE_NAME/a DB_HOSTNAME=127.0.0.1' "$INSTALL_DIR"/.env
fi
if ! grep -q 'HELMET_FILE' "$INSTALL_DIR"/.env; then
sed -i -e '$a\' "$INSTALL_DIR"/.env
echo "IMMICH_HELMET_FILE=true" >>"$INSTALL_DIR"/.env
fi
if ! grep -q 'MODEL_REVISION' "$INSTALL_DIR"/.env; then
sed -i -e '$a\' "$INSTALL_DIR"/.env
echo "MACHINE_LEARNING_MODEL_REVISION=v2" >>"$INSTALL_DIR"/.env
fi
if grep -q 'ExecStart=/usr/bin/node' /etc/systemd/system/immich-web.service; then
sed -i '/^EnvironmentFile=/d' /etc/systemd/system/immich-web.service
sed -i "s|^ExecStart=.*|ExecStart=${APP_DIR}/bin/start.sh|" /etc/systemd/system/immich-web.service
systemctl daemon-reload
fi
# MickLesk temporary patch for HEIC thumbnail gen
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
if grep -qF "(0, sharp_1.default)(input).metadata()" "$MEDIA_REPO_JS" 2>/dev/null; then
msg_info "Patching media.repository.js"
sed -i '0,/(0, sharp_1\.default)(input)\.metadata()/s//(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()/' "$MEDIA_REPO_JS"
msg_ok "Patched media.repository.js"
fi
# chown excluding upload dir contents (may be a mount with restricted permissions)
chown immich:immich "$INSTALL_DIR"
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
chown immich:immich "${UPLOAD_DIR:-$INSTALL_DIR/upload}" 2>/dev/null || true
if [[ "${MAINT_MODE:-0}" == 1 ]]; then
msg_info "Disabling Maintenance Mode"
cd /opt/immich/app/bin
$STD ./immich-admin disable-maintenance-mode || true
unset MAINT_MODE
$STD cd -
msg_ok "Disabled Maintenance Mode"
fi
systemctl restart immich-ml immich-web
[[ -f /etc/systemd/system/immich-proxy.service ]] && systemctl restart immich-proxy
msg_ok "Updated successfully!"
fi
exit
}
function compile_libjxl() {
SOURCE=${SOURCE_DIR}/libjxl
LIBJXL_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)"
if [[ "$LIBJXL_REVISION" != "$(grep 'libjxl' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libjxl"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/libjxl/libjxl.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBJXL_REVISION"
$STD git submodule update --init --recursive --depth 1 --recommend-shallow
mkdir build
cd build
$STD cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=OFF \
-DJPEGXL_ENABLE_DOXYGEN=OFF \
-DJPEGXL_ENABLE_MANPAGES=OFF \
-DJPEGXL_ENABLE_BENCHMARK=OFF \
-DJPEGXL_ENABLE_EXAMPLES=OFF \
-DJPEGXL_FORCE_SYSTEM_BROTLI=ON \
-DJPEGXL_FORCE_SYSTEM_HWY=ON \
-DJPEGXL_ENABLE_HWY_AVX3=ON \
-DJPEGXL_ENABLE_HWY_AVX3_ZEN4=ON \
-DJPEGXL_ENABLE_HWY_SVE=OFF \
-DJPEGXL_ENABLE_HWY_SVE2=OFF \
-DJPEGXL_ENABLE_HWY_SVE2_128=ON \
-DJPEGXL_ENABLE_PLUGINS=ON \
..
$STD cmake --build . -- -j"$(nproc)"
$STD cmake --install .
ldconfig /usr/local/lib
$STD make clean
cd "$STAGING_DIR"
rm -rf "$SOURCE"/{build,third_party}
sed -i "s/libjxl: .*$/libjxl: $LIBJXL_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled libjxl"
fi
}
function compile_jpegli() {
SOURCE=${SOURCE_DIR}/jpegli
JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
JPEGLI_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/jpegli.json)"
if [[ "$JPEGLI_REVISION" != "$(grep 'jpegli' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling jpegli"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/google/jpegli.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$JPEGLI_REVISION"
$STD git submodule update --init --depth 1 --recommend-shallow third_party/libjpeg-turbo
$STD git apply -3 "$BASE_DIR"/server/sources/jpegli-patches/jpegli-empty-dht-marker.patch
$STD git apply -3 "$BASE_DIR"/server/sources/jpegli-patches/jpegli-icc-warning.patch
mkdir build
cd build
$STD cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTING=OFF \
-DJPEGLI_ENABLE_DOXYGEN=OFF \
-DJPEGLI_ENABLE_MANPAGES=OFF \
-DJPEGLI_ENABLE_BENCHMARK=OFF \
-DJPEGLI_ENABLE_TOOLS=OFF \
-DJPEGLI_ENABLE_DEVTOOLS=OFF \
-DJPEGLI_ENABLE_FUZZERS=OFF \
-DJPEGLI_ENABLE_JNI=OFF \
-DJPEGLI_ENABLE_OPENEXR=OFF \
-DJPEGLI_ENABLE_SJPEG=OFF \
-DJPEGLI_ENABLE_SKCMS=OFF \
-DJPEGLI_FORCE_SYSTEM_HWY=ON \
-DJPEGLI_FORCE_SYSTEM_LCMS2=ON \
-DJPEGLI_ENABLE_JPEGLI_LIBJPEG=ON \
-DJPEGLI_INSTALL_JPEGLI_LIBJPEG=ON \
-DJPEGLI_ENABLE_HWY_AVX3=ON \
-DJPEGLI_ENABLE_HWY_AVX3_ZEN4=ON \
-DJPEGLI_ENABLE_HWY_SVE=OFF \
-DJPEGLI_ENABLE_HWY_SVE2=OFF \
-DJPEGLI_ENABLE_HWY_SVE2_128=ON \
-DJPEGLI_LIBJPEG_LIBRARY_SOVERSION="$JPEGLI_LIBJPEG_LIBRARY_SOVERSION" \
-DJPEGLI_LIBJPEG_LIBRARY_VERSION="$JPEGLI_LIBJPEG_LIBRARY_VERSION" \
-DLIBJPEG_TURBO_VERSION_NUMBER=2001005 \
..
$STD cmake --build . -- -j"$(nproc)"
$STD cmake --install .
ldconfig /usr/local/lib
$STD make clean
cd "$STAGING_DIR"
rm -rf "$SOURCE"/{build,third_party}
sed -i "s/jpegli: .*$/jpegli: $JPEGLI_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled jpegli"
fi
}
function compile_libheif() {
SOURCE=${SOURCE_DIR}/libheif
ensure_dependencies libaom-dev
LIBHEIF_REVISION="ac1cb05c39008f01525c991ff8b88f84ddf70fd2"
# : "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
if [[ "${update:-}" ]] || [[ "$LIBHEIF_REVISION" != "$(grep 'libheif' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libheif"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/strukturag/libheif.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBHEIF_REVISION"
mkdir build
cd build
$STD cmake --preset=release-noplugins \
-DWITH_DAV1D=ON \
-DENABLE_PARALLEL_TILE_DECODING=ON \
-DWITH_LIBSHARPYUV=ON \
-DWITH_LIBDE265=ON \
-DWITH_AOM_DECODER=OFF \
-DWITH_AOM_ENCODER=ON \
-DWITH_X265=OFF \
-DWITH_EXAMPLES=OFF \
..
$STD make install -j"$(nproc)"
ldconfig /usr/local/lib
$STD make clean
cd "$STAGING_DIR"
rm -rf "$SOURCE"/build
sed -i "s/libheif: .*$/libheif: $LIBHEIF_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled libheif"
fi
}
function compile_libraw() {
SOURCE=${SOURCE_DIR}/libraw
LIBRAW_REVISION="e419de08001de28ae6988ecb22df47e52b9c5eaa"
# : "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libraw"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/LibRaw/LibRaw.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBRAW_REVISION"
$STD autoreconf --install
$STD ./configure --disable-examples
$STD make -j"$(nproc)"
$STD make install
ldconfig /usr/local/lib
$STD make clean
cd "$STAGING_DIR"
sed -i "s/libraw: .*$/libraw: $LIBRAW_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled libraw"
fi
}
function compile_imagemagick() {
SOURCE=$SOURCE_DIR/imagemagick
: "${IMAGEMAGICK_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/imagemagick.json)}"
if [[ "$IMAGEMAGICK_REVISION" != "$(grep 'imagemagick' ~/.immich_library_revisions | awk '{print $2}')" ]] ||
! grep -q 'DMAGICK_LIBRAW' /usr/local/lib/ImageMagick-7*/config-Q16HDRI/configure.xml; then
msg_info "Recompiling ImageMagick"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/ImageMagick/ImageMagick.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$IMAGEMAGICK_REVISION"
$STD ./configure --with-modules CPPFLAGS="-DMAGICK_LIBRAW_VERSION_TAIL=202502"
$STD make -j"$(nproc)"
$STD make install
ldconfig /usr/local/lib
$STD make clean
cd "$STAGING_DIR"
sed -i "s/imagemagick: .*$/imagemagick: $IMAGEMAGICK_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled ImageMagick"
fi
}
function compile_libvips() {
SOURCE=$SOURCE_DIR/libvips
LIBVIPS_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)"
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libvips"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBVIPS_REVISION"
$STD git apply "$BASE_DIR"/server/sources/libvips-patches/0001-put-other-loaders-ahead-of-dcrawload.patch
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
cd build
$STD ninja install
ldconfig /usr/local/lib
cd "$STAGING_DIR"
rm -rf "$SOURCE"/build
sed -i "s/libvips: .*$/libvips: $LIBVIPS_REVISION/" ~/.immich_library_revisions
msg_ok "Recompiled libvips"
fi
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:2283${CL}"