Compare commits

..

1 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
80af1b5b46 Notifiarr: change installation check from apt to systemd service 2026-01-29 12:44:50 +01:00
20 changed files with 134 additions and 602 deletions

76
.github/workflows/lock-issue.yaml generated vendored
View File

@@ -1,76 +0,0 @@
name: Lock closed issues
on:
schedule:
- cron: "0 0 * * *" # Run daily at midnight
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
lock:
runs-on: ubuntu-latest
steps:
- name: Lock old issues and PRs
uses: actions/github-script@v7
with:
script: |
const daysBeforeLock = 3;
const cutoffDate = new Date('2026-01-27T00:00:00Z');
const lockDate = new Date();
lockDate.setDate(lockDate.getDate() - daysBeforeLock);
// Exclude patterns (case-insensitive)
const excludePatterns = [
/automated pr/i,
/\[bot\]/i,
/dependabot/i
];
// Search for closed, unlocked issues older than 3 days
const issues = await github.rest.search.issuesAndPullRequests({
q: `repo:${context.repo.owner}/${context.repo.repo} is:closed is:unlocked updated:<${lockDate.toISOString().split('T')[0]}`,
per_page: 50
});
console.log(`Found ${issues.data.items.length} issues/PRs to process`);
for (const item of issues.data.items) {
// Skip excluded items
const shouldExclude = excludePatterns.some(pattern => pattern.test(item.title));
if (shouldExclude) {
console.log(`Skipped #${item.number}: "${item.title}" (matches exclude pattern)`);
continue;
}
const createdAt = new Date(item.created_at);
const isNew = createdAt >= cutoffDate;
try {
// Add comment only for new issues (created after 2026-01-27)
if (isNew) {
const comment = item.pull_request
? 'This pull request has been automatically locked. Please open a new issue for related bugs.'
: 'This issue has been automatically locked. Please open a new issue for related bugs and reference this issue if needed.';
await github.rest.issues.createComment({
...context.repo,
issue_number: item.number,
body: comment
});
}
// Lock the issue/PR
await github.rest.issues.lock({
...context.repo,
issue_number: item.number,
lock_reason: 'resolved'
});
console.log(`Locked #${item.number} (${item.pull_request ? 'PR' : 'Issue'})`);
} catch (error) {
console.log(`Failed to lock #${item.number}: ${error.message}`);
}
}

View File

@@ -391,48 +391,18 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-01-30
## 2026-01-29
### 🆕 New Scripts
- Alpine-Valkey [@MickLesk](https://github.com/MickLesk) ([#11320](https://github.com/community-scripts/ProxmoxVE/pull/11320))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Pin version to 2.5.2 [@vhsdream](https://github.com/vhsdream) ([#11335](https://github.com/community-scripts/ProxmoxVE/pull/11335))
- Kollection: Update to php 8.5 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11315](https://github.com/community-scripts/ProxmoxVE/pull/11315))
- Notifiarr: change installation check from apt to systemd service [@MickLesk](https://github.com/MickLesk) ([#11319](https://github.com/community-scripts/ProxmoxVE/pull/11319))
- #### ✨ New Features
- [FEAT] Immich: Enable Maintenance Mode before update [@vhsdream](https://github.com/vhsdream) ([#11342](https://github.com/community-scripts/ProxmoxVE/pull/11342))
- jellyfin: add logrotate instead of reducing log level [@MickLesk](https://github.com/MickLesk) ([#11326](https://github.com/community-scripts/ProxmoxVE/pull/11326))
- core: Add config file handling options | Fix Vikunja update with interactive overwrite [@MickLesk](https://github.com/MickLesk) ([#11317](https://github.com/community-scripts/ProxmoxVE/pull/11317))
- Immich: v2.5.0 [@vhsdream](https://github.com/vhsdream) ([#11240](https://github.com/community-scripts/ProxmoxVE/pull/11240))
- #### 💥 Breaking Changes
- fix: vikunja v1 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11308](https://github.com/community-scripts/ProxmoxVE/pull/11308))
- #### 🔧 Refactor
- Refactor: Byparr [@vhsdream](https://github.com/vhsdream) ([#11338](https://github.com/community-scripts/ProxmoxVE/pull/11338))
- cloudflare: Remove deprecated DNS-over-HTTPS proxy option [@MickLesk](https://github.com/MickLesk) ([#11068](https://github.com/community-scripts/ProxmoxVE/pull/11068))
### 💾 Core
- #### 🐞 Bug Fixes
- build.func: Replace storage variable with searchdomain variable [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11322](https://github.com/community-scripts/ProxmoxVE/pull/11322))
### 📂 Github
- Add workflow to lock closed issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11316](https://github.com/community-scripts/ProxmoxVE/pull/11316))
## 2026-01-28
### 🆕 New Scripts

View File

@@ -1,73 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: pshankinclarke (lazarillo)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://valkey.io/
APP="Alpine-Valkey"
var_tags="${var_tags:-alpine;database}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-1}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
if ! apk -e info newt >/dev/null 2>&1; then
apk add -q newt
fi
LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
while true; do
CHOICE=$(
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Valkey Management" --menu "Select option" 11 58 3 \
"1" "Update Valkey" \
"2" "Allow 0.0.0.0 for listening" \
"3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3
)
exit_status=$?
if [ $exit_status == 1 ]; then
clear
exit-script
fi
header_info
case $CHOICE in
1)
msg_info "Updating Valkey"
apk update && apk upgrade valkey
rc-service valkey restart
msg_ok "Updated Valkey"
msg_ok "Updated successfully!"
exit
;;
2)
msg_info "Setting Valkey to listen on all interfaces"
sed -i 's/^bind .*/bind 0.0.0.0/' /etc/valkey/valkey.conf
rc-service valkey restart
msg_ok "Valkey now listens on all interfaces!"
exit
;;
3)
msg_info "Setting Valkey to listen only on ${LXCIP}"
sed -i "s/^bind .*/bind ${LXCIP}/" /etc/valkey/valkey.conf
rc-service valkey restart
msg_ok "Valkey now listens only on ${LXCIP}!"
exit
;;
esac
done
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${APP} should be reachable on port 6379.
${BL}valkey-cli -h ${IP} -p 6379${CL} \n"

View File

@@ -35,54 +35,6 @@ function update_script() {
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
if ! dpkg -l | grep -q ffmpeg; then
msg_info "Installing dependencies"
$STD apt install -y --no-install-recommends \
ffmpeg \
libatk1.0-0 \
libcairo-gobject2 \
libcairo2 \
libdbus-glib-1-2 \
libfontconfig1 \
libfreetype6 \
libgdk-pixbuf-xlib-2.0-0 \
libglib2.0-0 \
libgtk-3-0 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libpangoft2-1.0-0 \
libx11-6 \
libx11-xcb1 \
libxcb-shm0 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrender1 \
libxt6 \
libxtst6 \
xvfb \
fonts-noto-color-emoji \
fonts-unifont \
xfonts-cyrillic \
xfonts-scalable \
fonts-liberation \
fonts-ipafont-gothic \
fonts-wqy-zenhei \
fonts-tlwg-loma-otf
$STD apt autoremove -y chromium
msg_ok "Installed dependencies"
fi
msg_info "Configuring Byparr"
cd /opt/Byparr
$STD uv sync --link-mode copy
$STD uv run camoufox fetch
msg_ok "Configured Byparr"
msg_info "Starting Service"
systemctl start byparr
msg_ok "Started Service"

View File

@@ -1,6 +0,0 @@
___ __ _ _ __ ____
/ | / /___ (_)___ ___ | | / /___ _/ / /_____ __ __
/ /| | / / __ \/ / __ \/ _ \_____| | / / __ `/ / //_/ _ \/ / / /
/ ___ |/ / /_/ / / / / / __/_____/ |/ / /_/ / / ,< / __/ /_/ /
/_/ |_/_/ .___/_/_/ /_/\___/ |___/\__,_/_/_/|_|\___/\__, /
/_/ /____/

View File

@@ -68,7 +68,7 @@ EOF
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=amd64] https://mise.jdx.dev/deb stable main" >/etc/apt/sources.list.d/mise.list
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.pub arch=amd64] https://mise.jdx.dev/deb stable main" | tee /etc/apt/sources.list.d/mise.list
$STD apt update
$STD apt install -y mise
msg_ok "Installed Mise"
@@ -112,16 +112,8 @@ EOF
msg_ok "Image-processing libraries up to date"
fi
RELEASE="2.5.2"
RELEASE="2.4.1"
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
cd /opt/immich/app/bin
$STD bash ./immich-admin enable-maintenance-mode
export MAINT_MODE=1
$STD cd -
msg_ok "Enabled Maintenance Mode"
fi
msg_info "Stopping Services"
systemctl stop immich-web
systemctl stop immich-ml
@@ -175,7 +167,7 @@ EOF
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v${RELEASE}" "$SRC_DIR"
msg_info "Updating Immich web and microservices"
msg_info "Updating ${APP} web and microservices"
cd "$SRC_DIR"/server
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
export CI=1
@@ -217,7 +209,7 @@ EOF
mkdir -p "$PLUGIN_DIR"
cp -r ./dist "$PLUGIN_DIR"/dist
cp ./manifest.json "$PLUGIN_DIR"
msg_ok "Updated Immich server, web, cli and plugins"
msg_ok "Updated ${APP} server, web, cli and plugins"
cd "$SRC_DIR"/machine-learning
mkdir -p "$ML_DIR" && chown -R immich:immich "$ML_DIR"
@@ -225,13 +217,12 @@ EOF
export VIRTUAL_ENV="${ML_DIR}"/ml-venv
if [[ -f ~/.openvino ]]; then
msg_info "Updating HW-accelerated machine-learning"
$STD uv add --no-sync --optional openvino onnxruntime-openvino==1.20.0 --active -n -p python3.12 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p python3.12 --managed-python
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.12/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-312-x86_64-linux-gnu.so"
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra openvino --active -n -p python3.11 --managed-python
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.11/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-311-x86_64-linux-gnu.so"
msg_ok "Updated HW-accelerated machine-learning"
else
msg_info "Updating machine-learning"
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p python3.11 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra cpu --active -n -p python3.11 --managed-python
msg_ok "Updated machine-learning"
fi
cd "$SRC_DIR"
@@ -250,16 +241,8 @@ EOF
ln -s "$GEO_DIR" "$APP_DIR"
chown -R immich:immich "$INSTALL_DIR"
if [[ "$MAINT_MODE" == 1 ]]; then
msg_info "Disabling Maintenance Mode"
cd /opt/immich/app/bin
$STD bash ./immich-admin disable-maintenance-mode
unset MAINT_MODE
$STD cd -
msg_ok "Disabled Maintenance Mode"
fi
msg_ok "Updated ${APP} to v${RELEASE}"
systemctl restart immich-ml immich-web
msg_ok "Updated successfully!"
fi
exit
}

View File

@@ -31,9 +31,7 @@ function update_script() {
msg_info "Stopping Service"
systemctl stop apache2
msg_ok "Stopped Service"
PHP_VERSION="8.5" PHP_APACHE="YES" PHP_MODULE="apcu,ctype,dom,fileinfo,iconv,pgsql" setup_php
msg_info "Creating a backup"
mv /opt/koillection/ /opt/koillection-backup
msg_ok "Backup created"

View File

@@ -33,11 +33,7 @@
},
"notes": [
{
"text": "After install, run: cloudflared tunnel login && cloudflared tunnel create <NAME>",
"type": "info"
},
{
"text": "Or create tunnel via Cloudflare Zero Trust Dashboard",
"text": "With an option to configure cloudflared as a DNS-over-HTTPS (DoH) proxy",
"type": "info"
}
]

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-01-30T06:16:23Z",
"generated": "2026-01-29T06:16:13Z",
"versions": [
{
"slug": "2fauth",
@@ -137,9 +137,9 @@
{
"slug": "bookstack",
"repo": "BookStackApp/BookStack",
"version": "v25.12.3",
"version": "v25.12.2",
"pinned": false,
"date": "2026-01-29T15:29:25Z"
"date": "2026-01-24T14:01:03Z"
},
{
"slug": "byparr",
@@ -179,9 +179,9 @@
{
"slug": "comfyui",
"repo": "comfyanonymous/ComfyUI",
"version": "v0.11.1",
"version": "v0.11.0",
"pinned": false,
"date": "2026-01-29T07:52:21Z"
"date": "2026-01-27T06:23:53Z"
},
{
"slug": "commafeed",
@@ -235,9 +235,9 @@
{
"slug": "discopanel",
"repo": "nickheyer/discopanel",
"version": "v1.0.29",
"version": "v1.0.27",
"pinned": false,
"date": "2026-01-30T04:58:19Z"
"date": "2026-01-28T04:32:34Z"
},
{
"slug": "dispatcharr",
@@ -515,9 +515,9 @@
{
"slug": "immich",
"repo": "immich-app/immich",
"version": "v2.5.2",
"version": "v2.4.1",
"pinned": true,
"date": "2026-01-29T15:24:34Z"
"date": "2025-12-19T15:50:12Z"
},
{
"slug": "inspircd",
@@ -543,9 +543,9 @@
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.988",
"version": "v0.24.980",
"pinned": false,
"date": "2026-01-30T05:55:43Z"
"date": "2026-01-29T05:04:22Z"
},
{
"slug": "joplin-server",
@@ -641,9 +641,9 @@
{
"slug": "leantime",
"repo": "Leantime/leantime",
"version": "v3.6.2",
"version": "v3.6.1",
"pinned": false,
"date": "2026-01-29T16:37:00Z"
"date": "2026-01-29T02:53:11Z"
},
{
"slug": "librenms",
@@ -732,9 +732,9 @@
{
"slug": "manyfold",
"repo": "manyfold3d/manyfold",
"version": "v0.132.0",
"version": "v0.131.0",
"pinned": false,
"date": "2026-01-29T13:53:21Z"
"date": "2026-01-09T15:00:15Z"
},
{
"slug": "mealie",
@@ -774,9 +774,9 @@
{
"slug": "metube",
"repo": "alexta69/metube",
"version": "2026.01.30",
"version": "2026.01.11",
"pinned": false,
"date": "2026-01-30T00:17:52Z"
"date": "2026-01-11T18:43:56Z"
},
{
"slug": "miniflux",
@@ -1096,9 +1096,9 @@
{
"slug": "pve-scripts-local",
"repo": "community-scripts/ProxmoxVE-Local",
"version": "v0.5.6",
"version": "v0.5.5",
"pinned": false,
"date": "2026-01-29T15:08:44Z"
"date": "2026-01-13T17:03:32Z"
},
{
"slug": "qbittorrent",
@@ -1271,9 +1271,9 @@
{
"slug": "stirling-pdf",
"repo": "Stirling-Tools/Stirling-PDF",
"version": "v2.4.2",
"version": "v2.4.1",
"pinned": false,
"date": "2026-01-29T23:11:15Z"
"date": "2026-01-29T00:04:47Z"
},
{
"slug": "streamlink-webui",
@@ -1404,9 +1404,9 @@
{
"slug": "tunarr",
"repo": "chrisbenincasa/tunarr",
"version": "v1.1.10",
"version": "v1.1.8",
"pinned": false,
"date": "2026-01-30T02:10:02Z"
"date": "2026-01-28T23:21:21Z"
},
{
"slug": "uhf",
@@ -1457,13 +1457,6 @@
"pinned": false,
"date": "2026-01-19T13:29:43Z"
},
{
"slug": "vikunja",
"repo": "go-vikunja/vikunja",
"version": "v1.0.0",
"pinned": false,
"date": "2026-01-28T11:12:59Z"
},
{
"slug": "wallabag",
"repo": "wallabag/wallabag",
@@ -1544,9 +1537,9 @@
{
"slug": "yubal",
"repo": "guillevc/yubal",
"version": "v0.3.1",
"version": "v0.3.0",
"pinned": false,
"date": "2026-01-29T12:45:35Z"
"date": "2026-01-26T23:05:35Z"
},
{
"slug": "zigbee2mqtt",

View File

@@ -43,10 +43,6 @@
{
"text": "For NVIDIA graphics cards, you'll need to install the same drivers in the container that you did on the host. In the container, run the driver installation script and add the CLI arg --no-kernel-module",
"type": "info"
},
{
"text": "Log rotation is configured in /etc/logrotate.d/jellyfin. To reduce verbosity, change MinimumLevel in /etc/jellyfin/logging.json to Warning or Error (disables fail2ban auth logging).",
"type": "info"
}
]
}

View File

@@ -25,17 +25,6 @@
"os": "Debian",
"version": "13"
}
},
{
"type": "alpine",
"script": "ct/alpine-valkey.sh",
"resources": {
"cpu": 1,
"ram": 256,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}
}
],
"default_credentials": {
@@ -46,10 +35,6 @@
{
"text": "Show Login Credentials, type `cat ~/valkey.creds` in the LXC console",
"type": "info"
},
{
"text": "Alpines Valkey package is compiled without TLS support. For TLS, use the Debian-based valkey script instead.",
"type": "info"
}
]
}

View File

@@ -1,45 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: pshankinclarke (lazarillo)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://valkey.io/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Valkey"
$STD apk add valkey valkey-openrc valkey-cli
sed -i 's/^bind .*/bind 0.0.0.0/' /etc/valkey/valkey.conf
PASS="$(head -c 100 /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c32)"
echo "requirepass $PASS" >>/etc/valkey/valkey.conf
echo "$PASS" >~/valkey.creds
chmod 600 ~/valkey.creds
MEMTOTAL_MB=$(free -m | grep ^Mem: | awk '{print $2}')
MAXMEMORY_MB=$((MEMTOTAL_MB * 75 / 100))
{
echo ""
echo "# Memory-optimized settings for small-scale deployments"
echo "maxmemory ${MAXMEMORY_MB}mb"
echo "maxmemory-policy allkeys-lru"
echo "maxmemory-samples 10"
} >>/etc/valkey/valkey.conf
msg_ok "Installed Valkey"
# Note: Alpine's valkey package is compiled without TLS support
# For TLS, use the Debian-based valkey script instead
$STD rc-update add valkey default
$STD rc-service valkey start
motd_ssh
customize
cleanup_lxc

View File

@@ -14,52 +14,17 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt -y install --no-install-recommends \
ffmpeg \
libatk1.0-0 \
libcairo-gobject2 \
libcairo2 \
libdbus-glib-1-2 \
libfontconfig1 \
libfreetype6 \
libgdk-pixbuf-xlib-2.0-0 \
libglib2.0-0 \
libgtk-3-0 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libpangoft2-1.0-0 \
libx11-6 \
libx11-xcb1 \
libxcb-shm0 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrender1 \
libxt6 \
libxtst6 \
xvfb \
fonts-noto-color-emoji \
fonts-unifont \
xfonts-cyrillic \
xfonts-scalable \
fonts-liberation \
fonts-ipafont-gothic \
fonts-wqy-zenhei \
fonts-tlwg-loma-otf
$STD apt -y install \
xauth \
xvfb \
scrot \
chromium \
chromium-driver \
ca-certificates
msg_ok "Installed Dependencies"
setup_uv
fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
msg_info "Configuring Byparr"
cd /opt/Byparr
$STD uv sync --link-mode copy
$STD uv run camoufox fetch
msg_ok "Configured Byparr"
setup_uv
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/byparr.service

View File

@@ -23,6 +23,41 @@ setup_deb822_repo \
$STD apt install -y cloudflared
msg_ok "Installed Cloudflared"
read -r -p "${TAB3}Would you like to configure cloudflared as a DNS-over-HTTPS (DoH) proxy? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Creating Service"
cat <<EOF >/usr/local/etc/cloudflared/config.yml
proxy-dns: true
proxy-dns-address: 0.0.0.0
proxy-dns-port: 53
proxy-dns-max-upstream-conns: 5
proxy-dns-upstream:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
#- https://8.8.8.8/dns-query
#- https://8.8.4.4/dns-query
#- https://9.9.9.9/dns-query
#- https://149.112.112.112/dns-query
EOF
cat <<EOF >/etc/systemd/system/cloudflared.service
[Unit]
Description=cloudflared DNS-over-HTTPS (DoH) proxy
After=syslog.target network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/cloudflared --config /usr/local/etc/cloudflared/config.yml
Restart=on-failure
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now cloudflared
msg_ok "Created Service"
fi
motd_ssh
customize
cleanup_lxc

View File

@@ -13,42 +13,6 @@ setting_up_container
network_check
update_os
echo ""
echo ""
echo -e "🤖 ${BL}Immich Machine Learning Options${CL}"
echo "─────────────────────────────────────────"
echo "Please choose your machine-learning type:"
echo ""
echo " 1) CPU only (default)"
echo " 2) Intel OpenVINO (requires GPU passthrough)"
echo ""
read -r -p "${TAB3}Select machine-learning type [1]: " ML_TYPE
ML_TYPE="${ML_TYPE:-1}"
if [[ "$ML_TYPE" == "2" ]]; then
msg_info "Installing OpenVINO dependencies"
touch ~/.openvino
$STD apt install -y --no-install-recommends patchelf
tmp_dir=$(mktemp -d)
$STD pushd "$tmp_dir"
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
)
for url in "${INTEL_URLS[@]}"; do
curl -fsSLO "$url"
done
$STD apt install -y ./libigdgmm12*.deb
rm ./libigdgmm12*.deb
$STD apt install -y ./*.deb
$STD apt-mark hold libigdgmm12
$STD popd
rm -rf "$tmp_dir"
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
msg_ok "Installed OpenVINO dependencies"
fi
setup_uv
msg_info "Installing dependencies"
@@ -122,11 +86,36 @@ msg_ok "Dependencies Installed"
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=amd64] https://mise.jdx.dev/deb stable main" >/etc/apt/sources.list.d/mise.list
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.pub arch=amd64] https://mise.jdx.dev/deb stable main" | tee /etc/apt/sources.list.d/mise.list
$STD apt update
$STD apt install -y mise
msg_ok "Installed Mise"
read -r -p "${TAB3}Install OpenVINO dependencies for Intel HW-accelerated machine-learning? y/N " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing OpenVINO dependencies"
touch ~/.openvino
$STD apt install -y --no-install-recommends patchelf
tmp_dir=$(mktemp -d)
$STD pushd "$tmp_dir"
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
)
for url in "${INTEL_URLS[@]}"; do
curl -fsSLO "$url"
done
$STD apt install -y ./libigdgmm12*.deb
rm ./libigdgmm12*.deb
$STD apt install -y ./*.deb
$STD apt-mark hold libigdgmm12
$STD popd
rm -rf "$tmp_dir"
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
msg_ok "Installed OpenVINO dependencies"
fi
msg_info "Configuring Debian Testing Repo"
sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources
cat <<EOF >/etc/apt/preferences.d/preferences
@@ -148,17 +137,28 @@ PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
msg_info "Setting up Postgresql Database"
VCHORD_RELEASE="0.5.3"
msg_info "Installing Vectorchord v${VCHORD_RELEASE}"
curl -fsSL "https://github.com/tensorchord/VectorChord/releases/download/${VCHORD_RELEASE}/postgresql-16-vchord_${VCHORD_RELEASE}-1_amd64.deb" -o vchord.deb
$STD apt install -y ./vchord.deb
rm vchord.deb
echo "$VCHORD_RELEASE" >~/.vchord_version
msg_ok "Installed Vectorchord v${VCHORD_RELEASE}"
DB_NAME="immich"
DB_USER="immich"
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c18)
sed -i -e "/^#shared_preload/s/^#//;/^shared_preload/s/''/'vchord.so'/" /etc/postgresql/16/main/postgresql.conf
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
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;"
$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;"
{
echo "${APPLICATION} DB Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/"$APPLICATION".creds
msg_ok "Set up Postgresql Database"
msg_info "Compiling Custom Photo-processing Library (extreme patience)"
LD_LIBRARY_PATH=/usr/local/lib
@@ -296,9 +296,9 @@ GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p "$INSTALL_DIR"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.2" "$SRC_DIR"
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.4.1" "$SRC_DIR"
msg_info "Installing Immich (patience)"
msg_info "Installing ${APPLICATION} (patience)"
cd "$SRC_DIR"/server
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
@@ -347,13 +347,12 @@ mkdir -p "$ML_DIR" && chown -R immich:immich "$INSTALL_DIR"
export VIRTUAL_ENV="${ML_DIR}/ml-venv"
if [[ -f ~/.openvino ]]; then
msg_info "Installing HW-accelerated machine-learning"
$STD uv add --no-sync --optional openvino onnxruntime-openvino==1.20.0 --active -n -p python3.12 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p python3.12 --managed-python
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.12/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-312-x86_64-linux-gnu.so"
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra openvino --active -n -p python3.11 --managed-python
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.11/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-311-x86_64-linux-gnu.so"
msg_ok "Installed HW-accelerated machine-learning"
else
msg_info "Installing machine-learning"
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p python3.11 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra cpu --active -n -p python3.11 --managed-python
msg_ok "Installed machine-learning"
fi
cd "$SRC_DIR"
@@ -385,7 +384,7 @@ msg_ok "Installed GeoNames data"
mkdir -p /var/log/immich
touch /var/log/immich/{web.log,ml.log}
msg_ok "Installed Immich"
msg_ok "Installed ${APPLICATION}"
msg_info "Modifying user, creating env file, scripts & services"
usermod -aG video,render immich
@@ -394,12 +393,11 @@ cat <<EOF >"${INSTALL_DIR}"/.env
TZ=$(cat /etc/timezone)
IMMICH_VERSION=release
NODE_ENV=production
IMMICH_ALLOW_SETUP=true
DB_HOSTNAME=127.0.0.1
DB_USERNAME=${PG_DB_USER}
DB_PASSWORD=${PG_DB_PASS}
DB_DATABASE_NAME=${PG_DB_NAME}
DB_USERNAME=${DB_USER}
DB_PASSWORD=${DB_PASS}
DB_DATABASE_NAME=${DB_NAME}
DB_VECTOR_EXTENSION=vectorchord
REDIS_HOSTNAME=127.0.0.1

View File

@@ -39,19 +39,8 @@ EOF
$STD apt update
$STD apt install -y jellyfin
# Configure log rotation to prevent disk fill (keeps fail2ban compatibility) (PR: #1690 / Issue: #11224)
cat <<EOF >/etc/logrotate.d/jellyfin
/var/log/jellyfin/*.log {
daily
rotate 3
maxsize 100M
missingok
notifempty
compress
delaycompress
copytruncate
}
EOF
sed -i 's/"MinimumLevel": "Information"/"MinimumLevel": "Error"/g' /etc/jellyfin/logging.json
chown -R jellyfin:adm /etc/jellyfin
sleep 10
systemctl restart jellyfin

View File

@@ -15,7 +15,7 @@ update_os
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
PG_VERSION="16" setup_postgresql
PHP_VERSION="8.5" PHP_APACHE="YES" PHP_MODULE="apcu,ctype,dom,fileinfo,iconv,pgsql" setup_php
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="apcu,ctype,dom,fileinfo,iconv,pgsql" setup_php
setup_composer
msg_info "Setting up PostgreSQL"

View File

@@ -990,7 +990,7 @@ base_settings() {
fi
MTU=${var_mtu:-""}
SD=${var_searchdomain:-""}
SD=${var_storage:-""}
NS=${var_ns:-""}
MAC=${var_mac:-""}
VLAN=${var_vlan:-""}

View File

@@ -5182,137 +5182,9 @@ function setup_meilisearch() {
if [[ -f /usr/bin/meilisearch ]]; then
if check_for_gh_release "meilisearch" "meilisearch/meilisearch"; then
msg_info "Updating MeiliSearch"
# Get current and new version for compatibility check
local CURRENT_VERSION NEW_VERSION
CURRENT_VERSION=$(/usr/bin/meilisearch --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) || CURRENT_VERSION="0.0.0"
NEW_VERSION="${CHECK_UPDATE_RELEASE#v}"
# Extract major.minor for comparison (Meilisearch requires dump/restore between minor versions)
local CURRENT_MAJOR_MINOR NEW_MAJOR_MINOR
CURRENT_MAJOR_MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f1,2)
NEW_MAJOR_MINOR=$(echo "$NEW_VERSION" | cut -d. -f1,2)
# Determine if migration is needed (different major.minor = incompatible DB format)
local NEEDS_MIGRATION=false
if [[ "$CURRENT_MAJOR_MINOR" != "$NEW_MAJOR_MINOR" ]]; then
NEEDS_MIGRATION=true
msg_info "MeiliSearch version change detected (${CURRENT_VERSION}${NEW_VERSION}), preparing data migration"
fi
# Read config values for dump/restore
local MEILI_HOST MEILI_PORT MEILI_MASTER_KEY MEILI_DUMP_DIR
MEILI_HOST="${MEILISEARCH_HOST:-127.0.0.1}"
MEILI_PORT="${MEILISEARCH_PORT:-7700}"
MEILI_DUMP_DIR="${MEILISEARCH_DUMP_DIR:-/var/lib/meilisearch/dumps}"
MEILI_MASTER_KEY=$(grep -E "^master_key\s*=" /etc/meilisearch.toml 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ')
# Create dump before update if migration is needed
local DUMP_UID=""
if [[ "$NEEDS_MIGRATION" == "true" ]] && [[ -n "$MEILI_MASTER_KEY" ]]; then
msg_info "Creating MeiliSearch data dump before upgrade"
# Trigger dump creation
local DUMP_RESPONSE
DUMP_RESPONSE=$(curl -s -X POST "http://${MEILI_HOST}:${MEILI_PORT}/dumps" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
-H "Content-Type: application/json" 2>/dev/null) || true
DUMP_UID=$(echo "$DUMP_RESPONSE" | grep -oP '"dumpUid":\s*"\K[^"]+' || true)
if [[ -n "$DUMP_UID" ]]; then
# Wait for dump to complete (check task status)
local TASK_UID
TASK_UID=$(echo "$DUMP_RESPONSE" | grep -oP '"taskUid":\s*\K[0-9]+' || true)
if [[ -n "$TASK_UID" ]]; then
msg_info "Waiting for dump task ${TASK_UID} to complete..."
local MAX_WAIT=120
local WAITED=0
while [[ $WAITED -lt $MAX_WAIT ]]; do
local TASK_STATUS
TASK_STATUS=$(curl -s "http://${MEILI_HOST}:${MEILI_PORT}/tasks/${TASK_UID}" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" 2>/dev/null | grep -oP '"status":\s*"\K[^"]+' || true)
if [[ "$TASK_STATUS" == "succeeded" ]]; then
msg_ok "MeiliSearch dump created successfully: ${DUMP_UID}"
break
elif [[ "$TASK_STATUS" == "failed" ]]; then
msg_warn "MeiliSearch dump failed, proceeding without migration"
DUMP_UID=""
break
fi
sleep 2
WAITED=$((WAITED + 2))
done
if [[ $WAITED -ge $MAX_WAIT ]]; then
msg_warn "MeiliSearch dump timed out, proceeding without migration"
DUMP_UID=""
fi
fi
else
msg_warn "Could not create MeiliSearch dump, proceeding with direct upgrade"
fi
fi
# Stop service and update binary
systemctl stop meilisearch
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary"
# If migration needed and dump was created, remove old data and import dump
if [[ "$NEEDS_MIGRATION" == "true" ]] && [[ -n "$DUMP_UID" ]]; then
local MEILI_DB_PATH
MEILI_DB_PATH=$(grep -E "^db_path\s*=" /etc/meilisearch.toml 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | tr -d ' ')
MEILI_DB_PATH="${MEILI_DB_PATH:-/var/lib/meilisearch/data}"
msg_info "Removing old MeiliSearch database for migration"
rm -rf "${MEILI_DB_PATH:?}"/*
# Start with dump import
msg_info "Starting MeiliSearch with dump import"
systemctl start meilisearch
# Import dump via API
local IMPORT_RESPONSE
IMPORT_RESPONSE=$(curl -s -X POST "http://${MEILI_HOST}:${MEILI_PORT}/dumps/${DUMP_UID}/import" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" 2>/dev/null) || true
# Wait for import to complete
local IMPORT_TASK_UID
IMPORT_TASK_UID=$(echo "$IMPORT_RESPONSE" | grep -oP '"taskUid":\s*\K[0-9]+' || true)
if [[ -n "$IMPORT_TASK_UID" ]]; then
msg_info "Waiting for dump import task ${IMPORT_TASK_UID} to complete..."
local MAX_WAIT=300
local WAITED=0
while [[ $WAITED -lt $MAX_WAIT ]]; do
local TASK_STATUS
TASK_STATUS=$(curl -s "http://${MEILI_HOST}:${MEILI_PORT}/tasks/${IMPORT_TASK_UID}" \
-H "Authorization: Bearer ${MEILI_MASTER_KEY}" 2>/dev/null | grep -oP '"status":\s*"\K[^"]+' || true)
if [[ "$TASK_STATUS" == "succeeded" ]]; then
msg_ok "MeiliSearch dump imported successfully"
break
elif [[ "$TASK_STATUS" == "failed" ]]; then
msg_warn "MeiliSearch dump import failed - manual intervention may be required"
break
fi
sleep 3
WAITED=$((WAITED + 3))
done
else
# Fallback: Start with --import-dump flag (for older API versions)
systemctl stop meilisearch
msg_info "Attempting dump import via command line"
/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml --import-dump "${MEILI_DUMP_DIR}/${DUMP_UID}.dump" &>/dev/null &
local MEILI_PID=$!
sleep 10
kill $MEILI_PID 2>/dev/null || true
systemctl start meilisearch
fi
else
systemctl start meilisearch
fi
systemctl start meilisearch
msg_ok "Updated MeiliSearch"
fi
return 0

View File

@@ -595,7 +595,7 @@ EOF
no)
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" "Supporting the software's development team is essential. Check their official website's Support Subscriptions for pricing. Without their dedicated work, we wouldn't have this exceptional software." 10 58
msg_error "Selected no to Disabling subscription nag"
[[ -f /etc/apt/apt.conf.d/no-nag-script ]] && rm /etc/apt/apt.conf.d/no-nag-script
rm /etc/apt/apt.conf.d/no-nag-script 2>/dev/null
;;
esac
apt --reinstall install proxmox-widget-toolkit &>/dev/null || msg_error "Widget toolkit reinstall failed"