mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-11-13 17:56:21 +01:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afef3ff79f | ||
|
|
e96fa5bd50 | ||
|
|
46f0678031 | ||
|
|
519e279d89 | ||
|
|
7735372244 | ||
|
|
609bfd09d7 | ||
|
|
80b315a0bc |
No files matched your search
Generated
+1
-10
@@ -657,15 +657,6 @@ jobs:
|
||||
// and a log that does not fit loses its beginning: the end is where
|
||||
// a failure shows.
|
||||
const budget = Math.floor(52000 / rows.length);
|
||||
// A check run summary holds 65535 BYTES, not characters, and log
|
||||
// emoji take 3-4 bytes each. Cut at a character boundary and close
|
||||
// a ~~~~ block left open.
|
||||
const fitBytes = (text, max) => {
|
||||
if (Buffer.byteLength(text) <= max) return text;
|
||||
let cut = Buffer.from(text).subarray(0, max - 300).toString('utf8').replace(/�+$/, '');
|
||||
if ((cut.match(/^~~~~/gm) || []).length % 2) cut += '\n~~~~';
|
||||
return `${cut}\n\n… cut to fit GitHub's size limit; the full report is in the PR comment and the logs in the run artifacts.`;
|
||||
};
|
||||
const tail = (text, max) => {
|
||||
text = fence(text).trimEnd();
|
||||
if (text.length <= max) return text;
|
||||
@@ -748,7 +739,7 @@ jobs:
|
||||
title: armOnly
|
||||
? `ARM64 ${armPassed}/${armRows.length} passed (information only)`
|
||||
: `${passed}/${coreRows.length} passed${armRows.length ? ` (+ ARM ${armPassed}/${armRows.length}, not counted)` : ''}`,
|
||||
summary: fitBytes(summary, 65000),
|
||||
summary: summary.slice(0, 65000),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
+13
-39
@@ -373,20 +373,6 @@ setup_error() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Any answer means the app is up, unless it says it isn't: nothing at all,
|
||||
# 404/410 (the printed URL leads nowhere), 5xx (server error, proxy without
|
||||
# backend), or a 3xx left after 5 redirects (a loop). 401/403 are a login
|
||||
# wall (warpgate answers 401), 400 a quirk of the app: both pass.
|
||||
url_ok() { [[ "$1" =~ ^[1-4][0-9][0-9]$ && ! "$1" =~ ^(3[0-9][0-9]|404|410)$ ]]; }
|
||||
url_why() {
|
||||
case "$1" in
|
||||
404 | 410) echo "the printed URL leads nowhere" ;;
|
||||
5??) echo "server error" ;;
|
||||
3??) echo "still redirecting after 5 hops" ;;
|
||||
*) echo "the app never answered" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- Reserve a container ID ---------------------------------------------------
|
||||
# A lock file per ID, not just "first free one", because the engine only creates
|
||||
# the container minutes later and two jobs would otherwise pick the same ID.
|
||||
@@ -629,8 +615,8 @@ take_screenshot() {
|
||||
}
|
||||
|
||||
# Is the app up? No failed services, and the URL the script tells the user to
|
||||
# open, e.g. http://${IP}:1337/admin, answers without an error (see url_ok;
|
||||
# redirects are followed, so a jump to /login is fine). A script that prints no URL has no web UI to check.
|
||||
# open, e.g. http://${IP}:1337/admin, answers 200 (after redirects, so a jump
|
||||
# to /login is fine). A script that prints no URL has no web UI to check.
|
||||
# Run after the install and again after the update. Sets health_problem.
|
||||
app_url() { # the URL the script at $1 tells the user to open
|
||||
local pattern
|
||||
@@ -653,13 +639,13 @@ check_health() {
|
||||
local waited
|
||||
for ((waited = 0; waited < URL_WAIT; waited += 5)); do
|
||||
http_code=$(curl -sk -L --max-redirs 5 -o /dev/null -w '%{http_code}' --max-time 10 "$url" || true)
|
||||
url_ok "$http_code" && break
|
||||
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] && break
|
||||
sleep 5
|
||||
done
|
||||
# Also when the check fails: an error page explains more than a status code.
|
||||
[[ "$http_code" =~ ^[1-5][0-9][0-9]$ ]] && take_screenshot "$1"
|
||||
url_ok "$http_code" ||
|
||||
{ health_problem="${url} answered ${http_code/#000/nothing} within ${URL_WAIT}s ($(url_why "$http_code"))"; return 1; }
|
||||
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] ||
|
||||
{ health_problem="${url} answered ${http_code/#000/nothing} instead of 200 within ${URL_WAIT}s"; return 1; }
|
||||
}
|
||||
|
||||
check_health screenshot.png || fail "$health_problem"
|
||||
@@ -668,10 +654,10 @@ check_health screenshot.png || fail "$health_problem"
|
||||
# A fresh install is already on the latest release, so a plain `update` would
|
||||
# only say "No update available" and never run update_script's real path. The
|
||||
# version files the install wrote (~/.<app>, one per fetch_and_deploy_gh_release)
|
||||
# that update_script checks are set back first (see below); check_for_gh_release
|
||||
# then sees an update and runs it all. Apps deployed from a branch
|
||||
# (fetch_and_deploy_gh_branch, checked with check_for_gh_branch) store a commit
|
||||
# hash instead of a version. `update` is the /usr/bin/update the install generated: it pulls
|
||||
# that update_script checks are set back to 0.0.0-ci first; check_for_gh_release then sees an update and
|
||||
# runs it all. Apps deployed from a branch (fetch_and_deploy_gh_branch, checked
|
||||
# with check_for_gh_branch) store a commit hash instead of a version; the
|
||||
# engine compares both as plain strings, so 0.0.0-ci works for them too. `update` is the /usr/bin/update the install generated: it pulls
|
||||
# ct/<app>.sh from the URL this container was built from, i.e. the PR's tree.
|
||||
UPDATE_FAKE="0.0.0-ci"
|
||||
update_fail() {
|
||||
@@ -695,23 +681,11 @@ tracked=$(grep -oE 'check_for_[a-z]*_?release[[:space:]]+("[^"]*"|[^[:space:]]+)
|
||||
if [[ -n "$tracked" && "$tracked" != *'$'* ]]; then
|
||||
version_files=$(grep -xF -f <(sed 's|^|/root/.|' <<<"$tracked") <<<"$version_files" || true)
|
||||
fi
|
||||
# A version keeps its digits and gets "-dev" (6.7.16.0 -> 6.7.16.0-dev): the
|
||||
# engine ranks that below the release, so the update runs, and an
|
||||
# update_script that reads the installed series (shopware: composer
|
||||
# "~6.7.0" from ~/.shopware) still gets the real one. 0.0.0-ci broke that.
|
||||
# A commit hash (or a bare number) has no series and gets 0.0.0-ci.
|
||||
declare -A update_fake=()
|
||||
for f in $version_files; do
|
||||
cur=$(guest_exec cat "$f" 2>/dev/null | tr -d '\r\n')
|
||||
if [[ "$cur" =~ ^v?[0-9]+(\.[0-9A-Za-z_+-]+)+$ ]]; then
|
||||
update_fake[$f]="${cur}-dev"
|
||||
else
|
||||
update_fake[$f]="$UPDATE_FAKE"
|
||||
fi
|
||||
guest_exec sh -c "echo '${update_fake[$f]}' > '$f'; rm -f '$f.pending'" ||
|
||||
guest_exec sh -c "echo '$UPDATE_FAKE' > '$f'; rm -f '$f.pending'" ||
|
||||
update_fail "could not reset $f"
|
||||
echo "Update test: set back $f from ${cur} to ${update_fake[$f]}"
|
||||
done
|
||||
[[ -n "$version_files" ]] && echo "Update test: set back $(tr '\n' ' ' <<<"$version_files")to ${UPDATE_FAKE}"
|
||||
|
||||
phase="update"
|
||||
# Upgrade test: the container pulls its update from where it was installed
|
||||
@@ -772,8 +746,8 @@ fi
|
||||
if strip_ansi <"$UPDATE_RAW" | grep -qi 'updated successfully'; then
|
||||
update_status="updated"
|
||||
for f in $version_files; do
|
||||
[[ "$(guest_exec cat "$f" 2>/dev/null)" != "${update_fake[$f]}" ]] ||
|
||||
update_fail "reported success, but $f is still ${update_fake[$f]}"
|
||||
[[ "$(guest_exec cat "$f" 2>/dev/null)" != "$UPDATE_FAKE" ]] ||
|
||||
update_fail "reported success, but $f is still ${UPDATE_FAKE}"
|
||||
done
|
||||
else
|
||||
# Ran cleanly without updating anything: no version file to fake (apt/npm
|
||||
|
||||
Generated
+3
-3
@@ -121,7 +121,7 @@ vm_build_and_check() {
|
||||
for ((waited = 0; waited < VM_URL_WAIT; waited += 10)); do
|
||||
vm_running || fail "VM ${ctid} stopped by itself while its web UI was awaited"
|
||||
http_code=$(curl -sk -L --max-redirs 5 -o /dev/null -w '%{http_code}' --max-time 10 "$url" || true)
|
||||
url_ok "$http_code" && break
|
||||
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] && break
|
||||
sleep 10
|
||||
done
|
||||
[[ "$http_code" =~ ^[1-5][0-9][0-9]$ ]] && take_screenshot screenshot.png
|
||||
@@ -130,8 +130,8 @@ vm_build_and_check() {
|
||||
sleep 20
|
||||
fi
|
||||
[[ -s "$OUT_DIR/screenshot.png" ]] || vm_console_shot
|
||||
if [[ -n "$url" ]] && ! url_ok "$http_code"; then
|
||||
fail "${url} answered ${http_code/#000/nothing} within ${VM_URL_WAIT}s"
|
||||
if [[ -n "$url" && ! "$http_code" =~ ^2[0-9][0-9]$ ]]; then
|
||||
fail "${url} answered ${http_code/#000/nothing} instead of 200 within ${VM_URL_WAIT}s"
|
||||
fi
|
||||
vm_running || fail "VM ${ctid} stopped by itself"
|
||||
|
||||
|
||||
@@ -581,15 +581,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-11-13
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fetch the install script before the container is created [@MickLesk](https://github.com/MickLesk) ([core#236](https://github.com/community-scripts/core/pull/236))
|
||||
- Download a corrupt local template again instead of keeping it [@MickLesk](https://github.com/MickLesk) ([core#235](https://github.com/community-scripts/core/pull/235))
|
||||
- core: say why a container stopped by itself during its setup [@MickLesk](https://github.com/MickLesk) ([core#234](https://github.com/community-scripts/core/pull/234))
|
||||
- Shield pct start and the template check from a closed console [@MickLesk](https://github.com/MickLesk) ([core#239](https://github.com/community-scripts/core/pull/239))
|
||||
|
||||
## 2026-11-12
|
||||
|
||||
### 🆕 New Scripts
|
||||
@@ -600,7 +591,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- OnlyOffice: change ct port to 8083 [@MickLesk](https://github.com/MickLesk) ([#18642](https://github.com/community-scripts/ProxmoxVE/pull/18642))
|
||||
- dotnetaspwebapi: start the service only once an app is deployed [@MickLesk](https://github.com/MickLesk) ([#18639](https://github.com/community-scripts/ProxmoxVE/pull/18639))
|
||||
- Whisparr-eros: set the first login and save it [@MickLesk](https://github.com/MickLesk) ([#18617](https://github.com/community-scripts/ProxmoxVE/pull/18617))
|
||||
|
||||
@@ -608,18 +598,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
- Updated ASP.NET Web App script to Debian and adds a .Net selection [@kris701](https://github.com/kris701) ([#18628](https://github.com/community-scripts/ProxmoxVE/pull/18628))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- github: bump workflow actions to their current majors [@MickLesk](https://github.com/MickLesk) ([core#240](https://github.com/community-scripts/core/pull/240))
|
||||
- Say what the host sees when a container gets no address [@MickLesk](https://github.com/MickLesk) ([core#230](https://github.com/community-scripts/core/pull/230))
|
||||
- Fall back to public DNS for Alpine containers too [@MickLesk](https://github.com/MickLesk) ([core#231](https://github.com/community-scripts/core/pull/231))
|
||||
- Do not fail a finished install over the monitoring service [@MickLesk](https://github.com/MickLesk) ([core#232](https://github.com/community-scripts/core/pull/232))
|
||||
- Deploy a release by moving it, and stop on a full disk² [@MickLesk](https://github.com/MickLesk) ([core#233](https://github.com/community-scripts/core/pull/233))
|
||||
- core: say when pct create fails because timedatectl does not answer [@MickLesk](https://github.com/MickLesk) ([core#237](https://github.com/community-scripts/core/pull/237))
|
||||
- ref: stop calling every exit 255 a dpkg error [@MickLesk](https://github.com/MickLesk) ([core#238](https://github.com/community-scripts/core/pull/238))
|
||||
- Write uv's shell completions without STD [@MickLesk](https://github.com/MickLesk) ([core#241](https://github.com/community-scripts/core/pull/241))
|
||||
- Generate database passwords with random_password / Keep the database helpers' credentials files private [@MickLesk](https://github.com/MickLesk) ([core#242](https://github.com/community-scripts/core/pull/242))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- github: bump workflow actions to their current majors [@MickLesk](https://github.com/MickLesk) ([#18637](https://github.com/community-scripts/ProxmoxVE/pull/18637))
|
||||
|
||||
+69
-204
@@ -38,12 +38,20 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! grep -qE '(^|[[:space:]])testing([[:space:]]|$)' /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
|
||||
if ! grep -qsE '^[[:space:]]*Suites:.*(^|[[:space:]])testing([[:space:]]|$)' /etc/apt/sources.list.d/*.sources; 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
|
||||
elif grep -qsE '^[[:space:]]*Suites:.*trixie' /etc/apt/sources.list.d/debian.sources; then
|
||||
sed -i '/^[[:space:]]*Suites:.*trixie/ s/$/ testing/' /etc/apt/sources.list.d/debian.sources
|
||||
else
|
||||
cat <<EOF >/etc/apt/sources.list.d/testing.sources
|
||||
Types: deb
|
||||
URIs: http://deb.debian.org/debian
|
||||
Suites: testing
|
||||
Components: main
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
EOF
|
||||
fi
|
||||
cat <<EOF >/etc/apt/preferences.d/preferences
|
||||
Package: *
|
||||
@@ -71,9 +79,6 @@ EOF
|
||||
fetch_and_deploy_gh_release "mise" "jdx/mise" "singlefile" "latest" "/usr/local/bin" "mise-v*-linux-${MISE_ARCH}"
|
||||
fi
|
||||
|
||||
STAGING_DIR=/opt/staging
|
||||
BASE_DIR=${STAGING_DIR}/base-images
|
||||
SOURCE_DIR=${STAGING_DIR}/image-source
|
||||
cd /tmp
|
||||
RELEASE="v3.4.1"
|
||||
if [[ -f ~/.intel_version ]]; then
|
||||
@@ -100,21 +105,8 @@ EOF
|
||||
msg_ok "Updated Intel OpenVINO dependencies"
|
||||
fi
|
||||
fi
|
||||
# Without the revision file the refresh was skipped and sharp failed on an old libvips (#17914).
|
||||
[[ -f ~/.immich_library_revisions ]] || msg_warn "No record of the compiled image-processing libraries, rebuilding all of them"
|
||||
for lib in imagemagick jpegli libheif libjxl libraw libvips; do
|
||||
grep -q "^${lib}:" ~/.immich_library_revisions 2>/dev/null || echo "${lib}: unknown" >>~/.immich_library_revisions
|
||||
done
|
||||
[[ -d "$BASE_DIR/.git" ]] || $STD git clone -b main https://github.com/immich-app/base-images "$BASE_DIR"
|
||||
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 libopenjp2-7-dev pigz
|
||||
$STD git pull
|
||||
for library in "${libraries[@]}"; do
|
||||
compile_"$library"
|
||||
done
|
||||
msg_ok "Image-processing libraries up to date"
|
||||
# Libraries the prebuilt image-processing libraries link against; pigz compresses database backups.
|
||||
ensure_dependencies liblcms2-dev libjpeg62-turbo-dev libspng-dev libexif-dev libopenjp2-7-dev libaom-dev pigz
|
||||
|
||||
# 3.3.0 reads geodata/countryInfo.txt; the update before #17823 saved it into app/ instead.
|
||||
if [[ -d /opt/immich/geodata && ! -s /opt/immich/geodata/countryInfo.txt ]]; then
|
||||
@@ -131,6 +123,7 @@ EOF
|
||||
|
||||
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
|
||||
msg_warn "The update takes 5-15 minutes, do not interrupt it"
|
||||
fetch_prebuilt_libs
|
||||
PREV_IMMICH="${CS_PREVIOUS_VERSION:-$(cat ~/.immich)}"
|
||||
INSTALL_DIR="/opt/${APP}"
|
||||
UPLOAD_DIR="$(sed -n '/^IMMICH_MEDIA_LOCATION/s/[^=]*=//p' /opt/immich/.env)"
|
||||
@@ -157,6 +150,7 @@ EOF
|
||||
systemctl stop immich-web
|
||||
systemctl stop immich-ml
|
||||
msg_ok "Stopped Services"
|
||||
install_prebuilt_libs
|
||||
VCHORD_RELEASE="1.1.1"
|
||||
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
||||
PG_VERSION=${PG_VERSION:-16}
|
||||
@@ -174,7 +168,6 @@ EOF
|
||||
$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
|
||||
|
||||
[[ -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
|
||||
@@ -434,193 +427,65 @@ EOF
|
||||
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 -- third_party
|
||||
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"
|
||||
# Immich ships the custom photo-processing libraries (libjxl, jpegli, libheif,
|
||||
# libraw, ImageMagick, libvips) prebuilt in its own OCI base image; the release's
|
||||
# Dockerfile pins it. fetch_prebuilt_libs downloads and unpacks it while Immich
|
||||
# still runs, so a failure leaves the install as it was. install_prebuilt_libs
|
||||
# copies it into /usr/local once the services are stopped.
|
||||
function fetch_prebuilt_libs() {
|
||||
PREBUILT_BUNDLE=""
|
||||
BASE_REF="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/server/Dockerfile" | awk '/^FROM ghcr.io\/immich-app\/base-server-dev/ {print $2; exit}')" || true
|
||||
if [[ -z "$BASE_REF" ]]; then
|
||||
msg_error "Could not read the base image from Immich ${RELEASE}'s Dockerfile. Immich was not updated."
|
||||
exit 115
|
||||
fi
|
||||
[[ "$(cat ~/.immich_base_image 2>/dev/null)" == "$BASE_REF" ]] && return 0
|
||||
msg_info "Fetching prebuilt image-processing libraries"
|
||||
# skopeo refuses a reference with both a tag and a digest; the digest is the pin.
|
||||
local image="$BASE_REF"
|
||||
[[ "$BASE_REF" == *@sha256:* ]] && image="ghcr.io/immich-app/base-server-dev@${BASE_REF#*@}"
|
||||
if ! { command -v skopeo && command -v umoci; } >/dev/null 2>&1 &&
|
||||
! $STD apt install -y --no-install-recommends skopeo umoci; then
|
||||
msg_error "Could not install skopeo and umoci, which Immich needs for its image-processing libraries. Immich was not updated."
|
||||
exit 105
|
||||
fi
|
||||
local oci_dir
|
||||
oci_dir="$(mktemp -d)"
|
||||
PREBUILT_BUNDLE="$(mktemp -d)"
|
||||
if ! $STD skopeo copy --override-os linux --override-arch "$(arch_resolve amd64 arm64)" "docker://${image}" "oci:${oci_dir}:img"; then
|
||||
rm -rf "$oci_dir" "$PREBUILT_BUNDLE"
|
||||
msg_error "Could not download Immich's base image (${image}). Immich was not updated."
|
||||
exit 115
|
||||
fi
|
||||
if ! $STD umoci unpack --image "${oci_dir}:img" "$PREBUILT_BUNDLE"; then
|
||||
rm -rf "$oci_dir" "$PREBUILT_BUNDLE"
|
||||
msg_error "Could not unpack Immich's base image. Immich needs Proxmox VE 9.1 or newer; it was not updated."
|
||||
exit 105
|
||||
fi
|
||||
rm -rf "$oci_dir"
|
||||
msg_ok "Fetched prebuilt image-processing libraries"
|
||||
}
|
||||
|
||||
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="$(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}')" ]] ||
|
||||
[[ "$(vips -l foreign 2>/dev/null)" != *jp2kload* ]]; 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"
|
||||
function install_prebuilt_libs() {
|
||||
[[ -n "${PREBUILT_BUNDLE:-}" ]] || return 0
|
||||
msg_info "Installing prebuilt image-processing libraries"
|
||||
# The libraries, headers and ImageMagick data, without the node runtime, global
|
||||
# node modules and ffmpeg of the node base image: this script provides those.
|
||||
tar -C "${PREBUILT_BUNDLE}/rootfs/usr/local" \
|
||||
--exclude=./bin/node --exclude=./bin/npm --exclude=./bin/npx --exclude=./bin/corepack \
|
||||
--exclude=./bin/ffmpeg --exclude=./bin/ffprobe \
|
||||
--exclude=./lib/node_modules --exclude=./include/node \
|
||||
-cf - . | tar -C /usr/local -xf -
|
||||
rm -rf "$PREBUILT_BUNDLE"
|
||||
ldconfig /usr/local/lib
|
||||
if ! vips --version >/dev/null 2>&1 || ! pkg-config --exists vips; then
|
||||
msg_error "The prebuilt libvips from ${BASE_REF} does not work in this container."
|
||||
exit 1
|
||||
fi
|
||||
echo "$BASE_REF" >~/.immich_base_image
|
||||
# Leftovers of the libraries this script used to compile.
|
||||
rm -rf /opt/staging/base-images /opt/staging/image-source ~/.immich_library_revisions
|
||||
msg_ok "Installed prebuilt image-processing libraries"
|
||||
}
|
||||
|
||||
start
|
||||
|
||||
+1
-1
@@ -52,4 +52,4 @@ 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}:8083${CL}"
|
||||
echo -e "${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/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: Renan Bastos (renanbastos93)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/temporalio/temporal
|
||||
|
||||
APP="Temporal"
|
||||
var_tags="${var_tags:-workflow;automation}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-no}" # unset = ask the user; server, UI and CLI all ship linux_arm64 assets, but not yet run on arm64
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/temporal ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "temporal" "temporalio/temporal"; then
|
||||
msg_info "Stopping Temporal"
|
||||
systemctl stop temporal-ui temporal
|
||||
msg_ok "Stopped Temporal"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"
|
||||
|
||||
msg_info "Migrating Temporal Database"
|
||||
set -a && source /etc/temporal/temporal.env && set +a
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
|
||||
msg_ok "Migrated Temporal Database"
|
||||
|
||||
msg_info "Starting Temporal"
|
||||
systemctl start temporal temporal-ui
|
||||
msg_ok "Started Temporal"
|
||||
msg_ok "Updated Temporal successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "temporal-ui" "temporalio/ui-server"; then
|
||||
msg_info "Stopping Temporal UI"
|
||||
systemctl stop temporal-ui
|
||||
msg_ok "Stopped Temporal UI"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"
|
||||
|
||||
msg_info "Starting Temporal UI"
|
||||
systemctl start temporal-ui
|
||||
msg_ok "Started Temporal UI"
|
||||
msg_ok "Updated Temporal UI successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "temporal-cli" "temporalio/cli"; then
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"
|
||||
msg_ok "Updated Temporal CLI successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
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}:8080${CL}"
|
||||
echo -e "${INFO}${YW}gRPC endpoint for workers and SDKs: ${IP}:7233${CL}"
|
||||
+45
-177
@@ -69,13 +69,9 @@ $STD apt install --no-install-recommends -y \
|
||||
git \
|
||||
redis \
|
||||
pigz \
|
||||
autoconf \
|
||||
build-essential \
|
||||
python3-dev \
|
||||
automake \
|
||||
cmake \
|
||||
jq \
|
||||
libtool \
|
||||
libltdl-dev \
|
||||
libgdk-pixbuf-2.0-dev \
|
||||
libbrotli-dev \
|
||||
@@ -96,8 +92,6 @@ $STD apt install --no-install-recommends -y \
|
||||
libltdl7 \
|
||||
libopenjp2-7 \
|
||||
libopenjp2-7-dev \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
mesa-utils \
|
||||
mesa-va-drivers \
|
||||
@@ -114,8 +108,7 @@ $STD apt install --no-install-recommends -y \
|
||||
libhwy-dev \
|
||||
libwebp-dev \
|
||||
libaom-dev \
|
||||
unzip \
|
||||
ccache
|
||||
unzip
|
||||
|
||||
setup_deb822_repo \
|
||||
"jellyfin" \
|
||||
@@ -202,179 +195,54 @@ sed -i "s/^#shared_preload.*/shared_preload_libraries = 'vchord.so'/" /etc/postg
|
||||
systemctl restart postgresql.service
|
||||
PG_DB_NAME="immich" PG_DB_USER="immich" PG_DB_GRANT_SUPERUSER="true" PG_DB_SKIP_ALTER_ROLE="true" setup_postgresql_db
|
||||
|
||||
msg_info "Installing GCC-13 (available as fallback compiler)"
|
||||
$STD apt install -y gcc-13 g++-13
|
||||
msg_ok "Installed GCC-13"
|
||||
|
||||
msg_warn "Compiling Custom Photo-processing Libraries (can take anywhere from 15min to 2h)"
|
||||
LD_LIBRARY_PATH=/usr/local/lib
|
||||
export LD_RUN_PATH=/usr/local/lib
|
||||
STAGING_DIR=/opt/staging
|
||||
BASE_REPO="https://github.com/immich-app/base-images"
|
||||
BASE_DIR=${STAGING_DIR}/base-images
|
||||
SOURCE_DIR=${STAGING_DIR}/image-source
|
||||
$STD git clone -b main "$BASE_REPO" "$BASE_DIR"
|
||||
mkdir -p "$SOURCE_DIR"
|
||||
|
||||
msg_info "(1/6) Compiling libjxl"
|
||||
cd "$STAGING_DIR"
|
||||
SOURCE=${SOURCE_DIR}/libjxl
|
||||
LIBJXL_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)"
|
||||
$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 -- third_party
|
||||
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 .
|
||||
# Immich ships the custom photo-processing libraries (libjxl, jpegli, libheif,
|
||||
# libraw, ImageMagick, libvips) prebuilt in its own OCI base image. Pull the one
|
||||
# the release's Dockerfile pins (skopeo + umoci, no container runtime) and use its
|
||||
# /usr/local. There is no compile fallback: this needs Proxmox VE 9.1 or newer.
|
||||
msg_info "Deploying prebuilt image-processing libraries"
|
||||
BASE_REF="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/server/Dockerfile" | awk '/^FROM ghcr.io\/immich-app\/base-server-dev/ {print $2; exit}')" || true
|
||||
if [[ -z "$BASE_REF" ]]; then
|
||||
msg_error "Could not read the base image from Immich ${RELEASE}'s Dockerfile."
|
||||
exit 115
|
||||
fi
|
||||
# skopeo refuses a reference with both a tag and a digest; the digest is the pin.
|
||||
BASE_IMAGE="$BASE_REF"
|
||||
[[ "$BASE_REF" == *@sha256:* ]] && BASE_IMAGE="ghcr.io/immich-app/base-server-dev@${BASE_REF#*@}"
|
||||
if ! $STD apt install -y --no-install-recommends skopeo umoci; then
|
||||
msg_error "Could not install skopeo and umoci, which Immich needs for its image-processing libraries."
|
||||
exit 105
|
||||
fi
|
||||
OCI_DIR="$(mktemp -d)"
|
||||
OCI_BUNDLE="$(mktemp -d)"
|
||||
if ! $STD skopeo copy --override-os linux --override-arch "$(arch_resolve amd64 arm64)" "docker://${BASE_IMAGE}" "oci:${OCI_DIR}:img"; then
|
||||
rm -rf "$OCI_DIR" "$OCI_BUNDLE"
|
||||
msg_error "Could not download Immich's base image (${BASE_IMAGE})."
|
||||
exit 115
|
||||
fi
|
||||
if ! $STD umoci unpack --image "${OCI_DIR}:img" "$OCI_BUNDLE"; then
|
||||
rm -rf "$OCI_DIR" "$OCI_BUNDLE"
|
||||
msg_error "Could not unpack Immich's base image. Immich needs Proxmox VE 9.1 or newer."
|
||||
exit 105
|
||||
fi
|
||||
# The libraries, headers and ImageMagick data, without the node runtime, global
|
||||
# node modules and ffmpeg of the node base image: this script provides those.
|
||||
tar -C "${OCI_BUNDLE}/rootfs/usr/local" \
|
||||
--exclude=./bin/node --exclude=./bin/npm --exclude=./bin/npx --exclude=./bin/corepack \
|
||||
--exclude=./bin/ffmpeg --exclude=./bin/ffprobe \
|
||||
--exclude=./lib/node_modules --exclude=./include/node \
|
||||
-cf - . | tar -C /usr/local -xf -
|
||||
rm -rf "$OCI_DIR" "$OCI_BUNDLE"
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
ldconfig /usr/local/lib
|
||||
$STD make clean
|
||||
cd "$STAGING_DIR"
|
||||
rm -rf "$SOURCE"/{build,third_party}
|
||||
msg_ok "(1/6) Compiled libjxl"
|
||||
|
||||
msg_info "(2/6) Compiling 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)"
|
||||
$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}
|
||||
msg_ok "(2/6) Compiled jpegli"
|
||||
|
||||
msg_info "(3/6) Compiling libheif"
|
||||
SOURCE=${SOURCE_DIR}/libheif
|
||||
LIBHEIF_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)"
|
||||
$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
|
||||
msg_ok "(3/6) Compiled libheif"
|
||||
|
||||
msg_info "(4/6) Compiling libraw"
|
||||
SOURCE=${SOURCE_DIR}/libraw
|
||||
LIBRAW_REVISION="e419de08001de28ae6988ecb22df47e52b9c5eaa"
|
||||
# : "${LIBRAW_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/libraw.json)}"
|
||||
$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"
|
||||
msg_ok "(4/6) Compiled libraw"
|
||||
|
||||
msg_info "(5/6) Compiling imagemagick"
|
||||
SOURCE=$SOURCE_DIR/imagemagick
|
||||
: "${IMAGEMAGICK_REVISION:=$(jq -cr '.revision' $BASE_DIR/server/sources/imagemagick.json)}"
|
||||
$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"
|
||||
msg_ok "(5/6) Compiled imagemagick"
|
||||
|
||||
msg_info "(6/6) Compiling libvips"
|
||||
SOURCE=$SOURCE_DIR/libvips
|
||||
LIBVIPS_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)"
|
||||
$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
|
||||
msg_ok "(6/6) Compiled libvips"
|
||||
cat <<EOF >~/.immich_library_revisions
|
||||
imagemagick: $IMAGEMAGICK_REVISION
|
||||
jpegli: $JPEGLI_REVISION
|
||||
libheif: $LIBHEIF_REVISION
|
||||
libjxl: $LIBJXL_REVISION
|
||||
libraw: $LIBRAW_REVISION
|
||||
libvips: $LIBVIPS_REVISION
|
||||
EOF
|
||||
msg_ok "Custom Photo-processing Libraries Compiled Successfully"
|
||||
if ! vips --version >/dev/null 2>&1 || ! pkg-config --exists vips; then
|
||||
msg_error "The prebuilt libvips from ${BASE_IMAGE} does not work in this container."
|
||||
exit 1
|
||||
fi
|
||||
echo "$BASE_REF" >~/.immich_base_image
|
||||
msg_ok "Deployed prebuilt image-processing libraries"
|
||||
|
||||
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)"
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Renan Bastos (renanbastos93)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/temporalio/temporal
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="temporal" PG_DB_USER="temporal" PG_DB_SCHEMA_PERMS="true" setup_postgresql_db
|
||||
|
||||
fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"
|
||||
fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"
|
||||
fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"
|
||||
|
||||
msg_info "Configuring Temporal"
|
||||
mkdir -p /etc/temporal/config/dynamicconfig /etc/temporal/ui
|
||||
ln -sf /opt/temporal-cli/temporal /usr/bin/temporal
|
||||
cat <<EOF >/etc/temporal/temporal.env
|
||||
SQL_PLUGIN=postgres12
|
||||
SQL_HOST=127.0.0.1
|
||||
SQL_PORT=5432
|
||||
SQL_USER=temporal
|
||||
SQL_PASSWORD=${PG_DB_PASS}
|
||||
EOF
|
||||
chmod 600 /etc/temporal/temporal.env
|
||||
cat <<'EOF' >/etc/temporal/config/production.yaml
|
||||
# enable-template
|
||||
log:
|
||||
stdout: true
|
||||
level: info
|
||||
|
||||
persistence:
|
||||
defaultStore: postgres-default
|
||||
visibilityStore: postgres-visibility
|
||||
numHistoryShards: 4
|
||||
datastores:
|
||||
postgres-default:
|
||||
sql:
|
||||
pluginName: {{ env "SQL_PLUGIN" | quote }}
|
||||
databaseName: "temporal"
|
||||
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
|
||||
connectProtocol: "tcp"
|
||||
user: {{ env "SQL_USER" | quote }}
|
||||
password: {{ env "SQL_PASSWORD" | quote }}
|
||||
maxConns: 20
|
||||
maxIdleConns: 20
|
||||
maxConnLifetime: "1h"
|
||||
postgres-visibility:
|
||||
sql:
|
||||
pluginName: {{ env "SQL_PLUGIN" | quote }}
|
||||
databaseName: "temporal_visibility"
|
||||
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
|
||||
connectProtocol: "tcp"
|
||||
user: {{ env "SQL_USER" | quote }}
|
||||
password: {{ env "SQL_PASSWORD" | quote }}
|
||||
maxConns: 10
|
||||
maxIdleConns: 10
|
||||
maxConnLifetime: "1h"
|
||||
|
||||
global:
|
||||
membership:
|
||||
maxJoinDuration: 30s
|
||||
broadcastAddress: "127.0.0.1"
|
||||
|
||||
services:
|
||||
frontend:
|
||||
rpc:
|
||||
grpcPort: 7233
|
||||
membershipPort: 6933
|
||||
bindOnIP: "0.0.0.0"
|
||||
|
||||
matching:
|
||||
rpc:
|
||||
grpcPort: 7235
|
||||
membershipPort: 6935
|
||||
bindOnLocalHost: true
|
||||
|
||||
history:
|
||||
rpc:
|
||||
grpcPort: 7234
|
||||
membershipPort: 6934
|
||||
bindOnLocalHost: true
|
||||
|
||||
worker:
|
||||
rpc:
|
||||
grpcPort: 7239
|
||||
membershipPort: 6939
|
||||
bindOnLocalHost: true
|
||||
|
||||
clusterMetadata:
|
||||
enableGlobalNamespace: false
|
||||
failoverVersionIncrement: 10
|
||||
masterClusterName: "active"
|
||||
currentClusterName: "active"
|
||||
clusterInformation:
|
||||
active:
|
||||
enabled: true
|
||||
initialFailoverVersion: 1
|
||||
rpcName: "frontend"
|
||||
rpcAddress: "127.0.0.1:7233"
|
||||
|
||||
dcRedirectionPolicy:
|
||||
policy: "noop"
|
||||
|
||||
archival:
|
||||
history:
|
||||
state: "disabled"
|
||||
visibility:
|
||||
state: "disabled"
|
||||
|
||||
namespaceDefaults:
|
||||
archival:
|
||||
history:
|
||||
state: "disabled"
|
||||
visibility:
|
||||
state: "disabled"
|
||||
|
||||
dynamicConfigClient:
|
||||
filepath: "/etc/temporal/config/dynamicconfig/production.yaml"
|
||||
pollInterval: "60s"
|
||||
EOF
|
||||
cat <<EOF >/etc/temporal/config/dynamicconfig/production.yaml
|
||||
limit.maxIDLength:
|
||||
- value: 255
|
||||
constraints: {}
|
||||
EOF
|
||||
cat <<EOF >/etc/temporal/ui/production.yaml
|
||||
temporalGrpcAddress: 127.0.0.1:7233
|
||||
port: 8080
|
||||
enableUi: true
|
||||
defaultNamespace: default
|
||||
cors:
|
||||
cookieInsecure: true
|
||||
allowOrigins:
|
||||
- http://${LOCAL_IP}:8080
|
||||
EOF
|
||||
msg_ok "Configured Temporal"
|
||||
|
||||
msg_info "Initializing Temporal Database"
|
||||
set -a && source /etc/temporal/temporal.env && set +a
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility create-database
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal setup-schema -v 0.0
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility setup-schema -v 0.0
|
||||
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
|
||||
msg_ok "Initialized Temporal Database"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<EOF >/etc/systemd/system/temporal.service
|
||||
[Unit]
|
||||
Description=Temporal Server
|
||||
After=network.target postgresql.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/temporal
|
||||
EnvironmentFile=/etc/temporal/temporal.env
|
||||
ExecStart=/opt/temporal/temporal-server --root /etc/temporal --env production --allow-no-auth start
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/systemd/system/temporal-ui.service
|
||||
[Unit]
|
||||
Description=Temporal UI
|
||||
After=network.target temporal.service
|
||||
Wants=temporal.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/temporal-ui
|
||||
ExecStart=/opt/temporal-ui/ui-server --root /etc/temporal --config ui --env production start
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now temporal temporal-ui
|
||||
msg_ok "Created Services"
|
||||
|
||||
msg_info "Creating Default Namespace"
|
||||
for _ in {1..60}; do
|
||||
temporal operator cluster health &>/dev/null && break
|
||||
sleep 1
|
||||
done
|
||||
$STD temporal operator namespace create --namespace default
|
||||
msg_ok "Created Default Namespace"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
Reference in new issue
Block a user