From 3e4541df00ea7cd871a2fa0267616695f484c600 Mon Sep 17 00:00:00 2001
From: Javier Pastor
Date: Sun, 27 Jul 2025 20:11:55 +0200
Subject: [PATCH 001/312] Remove commercial modules & add verbose install -
Added option to remove commercial modules - Added option to update system and
modules
---
ct/freepbx.sh | 67 ++++++++++++++++++
frontend/public/json/freepbx.json | 40 +++++++++++
install/freepbx-install.sh | 111 ++++++++++++++++++++++++++++++
misc/build.func | 20 +++---
4 files changed, 228 insertions(+), 10 deletions(-)
create mode 100644 ct/freepbx.sh
create mode 100644 frontend/public/json/freepbx.json
create mode 100644 install/freepbx-install.sh
diff --git a/ct/freepbx.sh b/ct/freepbx.sh
new file mode 100644
index 00000000..d7526bcd
--- /dev/null
+++ b/ct/freepbx.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+source <(curl -s https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: Arian Nasr (arian-nasr)
+# Updated by: Javier Pastor (vsc55)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://www.freepbx.org/
+
+APP="FreePBX"
+var_tags="pbx;voip;telephony"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-10}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -f /lib/systemd/system/freepbx.service ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ msg_info "Updating $APP LXC"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ msg_ok "Updated $APP LXC"
+
+ msg_info "Updating $APP Modules"
+ $STD fwconsole ma updateall
+ $STD fwconsole reload
+ msg_ok "Updated $APP Modules"
+
+ exit
+}
+
+start
+
+if whiptail --title "Commercial Modules" --yesno "Remove Commercial modules?" --defaultno 10 50; then
+ export ONLY_OPENSOURCE="yes"
+
+ if whiptail --title "Firewall Module" --yesno "Do you want to KEEP the Firewall module (and sysadmin)?" 10 50; then
+ export REMOVE_FIREWALL="no"
+ else
+ export REMOVE_FIREWALL="yes"
+ fi
+else
+ export ONLY_OPENSOURCE="no"
+ export REMOVE_FIREWALL="no"
+fi
+
+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 "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/frontend/public/json/freepbx.json b/frontend/public/json/freepbx.json
new file mode 100644
index 00000000..11040c04
--- /dev/null
+++ b/frontend/public/json/freepbx.json
@@ -0,0 +1,40 @@
+{
+ "name": "FreePBX",
+ "slug": "freepbx",
+ "categories": [
+ 0
+ ],
+ "date_created": "2025-05-22",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 80,
+ "documentation": "https://sangomakb.atlassian.net/wiki/spaces/FP/overview?homepageId=8454359",
+ "website": "https://www.freepbx.org/",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/freepbx.webp",
+ "config_path": "",
+ "description": "FreePBX is a web-based open-source graphical user interface that manages Asterisk, a voice over IP and telephony server.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/freepbx.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 10,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "This script uses the official FreePBX install script. Check it here: https://github.com/FreePBX/sng_freepbx_debian_install",
+ "type": "info"
+ }
+ ]
+}
diff --git a/install/freepbx-install.sh b/install/freepbx-install.sh
new file mode 100644
index 00000000..c5da1138
--- /dev/null
+++ b/install/freepbx-install.sh
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: Arian Nasr (arian-nasr)
+# Updated by: Javier Pastor (vsc55)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://www.freepbx.org/
+
+INSTALL_URL="https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh"
+INSTALL_PATH="/opt/sng_freepbx_debian_install.sh"
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+ONLY_OPENSOURCE="${ONLY_OPENSOURCE:-no}"
+REMOVE_FIREWALL="${REMOVE_FIREWALL:-no}"
+msg_ok "Remove Commercial modules is set to: $ONLY_OPENSOURCE"
+msg_ok "Remove Firewall module is set to: $REMOVE_FIREWALL"
+
+msg_info "Downloading FreePBX installation script..."
+if curl -fsSL "$INSTALL_URL" -o "$INSTALL_PATH"; then
+ msg_ok "Download completed successfully"
+else
+ curl_exit_code=$?
+ msg_error "Error downloading FreePBX installation script (curl exit code: $curl_exit_code)"
+ msg_error "Aborting!"
+ exit 1
+fi
+
+if [[ "$VERBOSE" == "yes" ]]; then
+ msg_info "Installing FreePBX (Verbose)\n"
+else
+ msg_info "Installing FreePBX, be patient, this takes time..."
+fi
+$STD bash "$INSTALL_PATH"
+
+if [[ $ONLY_OPENSOURCE == "yes" ]]; then
+ msg_info "Removing Commercial modules..."
+
+ end_count=0
+ max=5
+ count=0
+ while fwconsole ma list | awk '/Commercial/ {found=1} END {exit !found}'; do
+ count=$((count + 1))
+ while read -r module; do
+ msg_info "Removing module: $module"
+
+ if [[ "$REMOVE_FIREWALL" == "no" ]] && [[ "$module" == "sysadmin" ]]; then
+ msg_warn "Skipping sysadmin module removal, it is required for Firewall!"
+ continue
+ fi
+
+ code=0
+ $STD fwconsole ma -f remove $module || code=$?
+ if [[ $code -ne 0 ]]; then
+ msg_error "Module $module could not be removed - error code $code"
+ else
+ msg_ok "Module $module removed successfully"
+ fi
+ done < <(fwconsole ma list | awk '/Commercial/ {print $2}')
+
+ [[ $count -ge $max ]] && break
+
+ com_list=$(fwconsole ma list)
+ end_count=$(awk '/Commercial/ {count++} END {print count + 0}' <<< "$com_list")
+ awk '/Commercial/ {found=1} END {exit !found}' <<< "$com_list" || break
+ if [[ "$REMOVE_FIREWALL" == "no" ]] && \
+ [[ $end_count -eq 1 ]] && \
+ [[ $(awk '/Commercial/ {print $2}' <<< "$com_list") == "sysadmin" ]]; then
+ break
+ fi
+
+ msg_warn "Not all commercial modules could be removed, retrying (attempt $count of $max)..."
+ done
+
+ if [[ $REMOVE_FIREWALL == "yes" ]] && [[ $end_count -gt 0 ]]; then
+ msg_info "Removing Firewall module..."
+ if $STD fwconsole ma -f remove firewall; then
+ msg_ok "Firewall module removed successfully"
+ else
+ msg_error "Firewall module could not be removed, please check manually!"
+ fi
+ fi
+
+ if [[ $end_count -eq 0 ]]; then
+ msg_ok "All commercial modules removed successfully"
+ elif [[ $end_count -eq 1 ]] && [[ $REMOVE_FIREWALL == "no" ]] && [[ $(fwconsole ma list | awk '/Commercial/ {print $2}') == "sysadmin" ]]; then
+ msg_ok "Only sysadmin module left, which is required for Firewall, skipping removal"
+ else
+ msg_warn "Some commercial modules could not be removed, please check the web interface for removal manually!"
+ fi
+
+ msg_info "Reloading FreePBX..."
+ $STD fwconsole reload
+ msg_ok "FreePBX reloaded completely"
+fi
+msg_ok "Installed FreePBX finished"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -f "$INSTALL_PATH"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/misc/build.func b/misc/build.func
index c8b1ff4b..0364736f 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -16,14 +16,14 @@ variables() {
CT_TYPE=${var_unprivileged:-$CT_TYPE}
}
-source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func)
+source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/api.func)
if command -v curl >/dev/null 2>&1; then
- source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
+ source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/core.func)
load_functions
#echo "(build.func) Loaded core.func via curl"
elif command -v wget >/dev/null 2>&1; then
- source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
+ source <(wget -qO- https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/core.func)
load_functions
#echo "(build.func) Loaded core.func via wget"
fi
@@ -986,7 +986,7 @@ install_script() {
header_info
echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}"
METHOD="advanced"
- source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func)
+ source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/config-file.func)
config_file
;;
5)
@@ -1059,7 +1059,7 @@ check_container_storage() {
}
start() {
- source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
+ source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/tools.func)
if command -v pveversion >/dev/null 2>&1; then
install_script
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
@@ -1125,9 +1125,9 @@ build_container() {
TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null
if [ "$var_os" == "alpine" ]; then
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1161,7 +1161,7 @@ build_container() {
-unprivileged $CT_TYPE
$PW
"
- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)"
+ bash -c "$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/create_lxc.sh)"
if [ $? -ne 0 ]; then
exit 200
fi
@@ -1351,7 +1351,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then
+ if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/install/"$var_install".sh)"; then
exit $?
fi
}
@@ -1365,7 +1365,7 @@ description() {
cat <
-
+
${APP} LXC
From 70f35283fa7053a826f02a9a4b104cbf2973aa63 Mon Sep 17 00:00:00 2001
From: Javier Pastor
Date: Sun, 3 Aug 2025 13:02:19 +0200
Subject: [PATCH 002/312] revert build.func
---
misc/build.func | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 0364736f..c8b1ff4b 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -16,14 +16,14 @@ variables() {
CT_TYPE=${var_unprivileged:-$CT_TYPE}
}
-source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/api.func)
+source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func)
if command -v curl >/dev/null 2>&1; then
- source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/core.func)
+ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
load_functions
#echo "(build.func) Loaded core.func via curl"
elif command -v wget >/dev/null 2>&1; then
- source <(wget -qO- https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/core.func)
+ source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
load_functions
#echo "(build.func) Loaded core.func via wget"
fi
@@ -986,7 +986,7 @@ install_script() {
header_info
echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}"
METHOD="advanced"
- source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/config-file.func)
+ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func)
config_file
;;
5)
@@ -1059,7 +1059,7 @@ check_container_storage() {
}
start() {
- source <(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/tools.func)
+ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
if command -v pveversion >/dev/null 2>&1; then
install_script
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
@@ -1125,9 +1125,9 @@ build_container() {
TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null
if [ "$var_os" == "alpine" ]; then
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/alpine-install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1161,7 +1161,7 @@ build_container() {
-unprivileged $CT_TYPE
$PW
"
- bash -c "$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/misc/create_lxc.sh)"
+ bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)"
if [ $? -ne 0 ]; then
exit 200
fi
@@ -1351,7 +1351,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/vsc55/community-scripts-ProxmoxVED/refs/heads/freepbx/install/"$var_install".sh)"; then
+ if ! lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/"$var_install".sh)"; then
exit $?
fi
}
@@ -1365,7 +1365,7 @@ description() {
cat <
-
+
${APP} LXC
From cf39acc554e4d07017025c93f0a2d369727a8f31 Mon Sep 17 00:00:00 2001
From: David Bennett
Date: Thu, 14 Aug 2025 10:46:05 -0500
Subject: [PATCH 003/312] feat: add Resilio Sync LXC container script
Adds new LXC container script for Resilio Sync peer-to-peer file synchronization.
Includes container creation script, install script, and frontend json following project conventions.
---
ct/resiliosync.sh | 44 +++++++++++++++++++++++++++
frontend/public/json/resiliosync.json | 35 +++++++++++++++++++++
install/resiliosync-install.sh | 32 +++++++++++++++++++
3 files changed, 111 insertions(+)
create mode 100644 ct/resiliosync.sh
create mode 100644 frontend/public/json/resiliosync.json
create mode 100644 install/resiliosync-install.sh
diff --git a/ct/resiliosync.sh b/ct/resiliosync.sh
new file mode 100644
index 00000000..eff0f8d5
--- /dev/null
+++ b/ct/resiliosync.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: David Bennett (dbinit)
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+# Source: https://www.resilio.com/sync
+
+APP="Resilio Sync"
+var_tags="${var_tags:-sync}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-8}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+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 /var/lib/resilio-sync ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ msg_info "Updating ${APP} LXC"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ msg_ok "Updated Successfully"
+ 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 "${TAB}${GATEWAY}${BGN}https://${IP}:8888${CL}"
diff --git a/frontend/public/json/resiliosync.json b/frontend/public/json/resiliosync.json
new file mode 100644
index 00000000..222786e1
--- /dev/null
+++ b/frontend/public/json/resiliosync.json
@@ -0,0 +1,35 @@
+{
+ "name": "Resilio Sync",
+ "slug": "resiliosync",
+ "categories": [
+ 11
+ ],
+ "date_created": "2025-08-14",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "config_path": "/etc/resilio-sync/config.json",
+ "interface_port": 8888,
+ "documentation": "https://help.resilio.com/",
+ "website": "https://www.resilio.com/sync",
+ "logo": "https://www.resilio.com/images/sync-appicon-blue-bg.svg",
+ "description": "Fast, reliable, and simple file sync and share solution, powered by P2P technology. Sync files across all your devices without storing them in the cloud.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/resiliosync.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/install/resiliosync-install.sh b/install/resiliosync-install.sh
new file mode 100644
index 00000000..8b03ff9e
--- /dev/null
+++ b/install/resiliosync-install.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: David Bennett (dbinit)
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+# Source: https://www.resilio.com/sync
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Resilio Sync"
+curl -fsSL "https://linux-packages.resilio.com/resilio-sync/key.asc" >/etc/apt/trusted.gpg.d/resilio-sync.asc
+echo "deb [signed-by=/etc/apt/trusted.gpg.d/resilio-sync.asc] http://linux-packages.resilio.com/resilio-sync/deb resilio-sync non-free" >/etc/apt/sources.list.d/resilio-sync.list
+$STD apt-get update
+$STD apt-get install -y resilio-sync
+sed -i 's/127.0.0.1:8888/0.0.0.0:8888/g' /etc/resilio-sync/config.json
+$STD systemctl enable resilio-sync
+$STD systemctl restart resilio-sync
+msg_ok "Installed Resilio Sync"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 211afc9130b9049986998e33d6ef2d23306c5d79 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 18:06:57 -0500
Subject: [PATCH 004/312] Added initial scripts for litellm
---
ct/litellm.sh | 45 +++++++++++++++++
frontend/public/json/litellm.json | 35 ++++++++++++++
install/litellm-install.sh | 80 +++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+)
create mode 100644 ct/litellm.sh
create mode 100644 frontend/public/json/litellm.json
create mode 100644 install/litellm-install.sh
diff --git a/ct/litellm.sh b/ct/litellm.sh
new file mode 100644
index 00000000..a8e9b6af
--- /dev/null
+++ b/ct/litellm.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: stout01
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/BerriAI/litellm
+
+APP="litellm"
+var_tags="${var_tags:-ai;interface}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-4}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -f /etc/systemd/system/litellm.service ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ msg_info "Updating $APP LXC"
+ $STD apt-get update
+ pip install litellm[proxy] --upgrade
+ msg_ok "Updated $APP LXC"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:4000${CL}"
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
new file mode 100644
index 00000000..e77c7291
--- /dev/null
+++ b/frontend/public/json/litellm.json
@@ -0,0 +1,35 @@
+{
+ "name": "LiteLLM",
+ "slug": "litellm",
+ "categories": [
+ 20
+ ],
+ "date_created": "2025-08-07",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 4000,
+ "documentation": "https://docs.litellm.ai/",
+ "config_path": "/opt/litellm.env",
+ "website": "https://www.litellm.ai/",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
+ "description": "LiteLLM description is here",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/litellm.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 4,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": "admin",
+ "password": "sk-1234"
+ },
+ "notes": []
+}
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
new file mode 100644
index 00000000..bbaa31f3
--- /dev/null
+++ b/install/litellm-install.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: stout01
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/BerriAI/litellm
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Setup Python3"
+$STD apt-get install -y \
+ python3 \
+ python3-dev \
+ python3-pip
+rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
+msg_ok "Setup Python3"
+
+msg_info "Installing ${APPLICATION}"
+$STD pip install 'litellm[proxy]'
+$STD pip install 'prisma'
+msg_ok "Installed ${APPLICATION}"
+
+PG_VERSION="17" setup_postgresql
+
+msg_info "Setting up PostgreSQL"
+DB_NAME="litellm_db"
+DB_USER="${APPLICATION}"
+DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "CREATE EXTENSION IF NOT EXISTS pg_trgm;" $DB_NAME
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
+{
+ echo "${APPLICATION} Credentials"
+ echo "Database Name: $DB_NAME"
+ echo "Database User: $DB_USER"
+ echo "Database Password: $DB_PASS"
+} >>~/litellm.creds
+msg_ok "Set up PostgreSQL"
+
+msg_info "Creating Service"
+mkdir -p /opt
+cat </opt/${APPLICATION}.env
+LITELLM_MASTER_KEY=sk-1234
+DATABASE_URL=postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
+STORE_MODEL_IN_DB=true
+USE_PRISMA_MIGRATE=true
+EOF
+
+cat </etc/systemd/system/${APPLICATION}.service
+[Unit]
+Description=LiteLLM
+
+[Service]
+Type=simple
+EnvironmentFile=/opt/${APPLICATION}.env
+ExecStart=litellm
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now "${APPLICATION}"
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 155e431b2a90fc27c1b4a4e550e59d93b20be886 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 18:57:07 -0500
Subject: [PATCH 005/312] Refactored to use config yaml
---
install/litellm-install.sh | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index bbaa31f3..98c12eed 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -48,21 +48,21 @@ msg_ok "Set up PostgreSQL"
msg_info "Creating Service"
mkdir -p /opt
-cat </opt/${APPLICATION}.env
-LITELLM_MASTER_KEY=sk-1234
-DATABASE_URL=postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
-STORE_MODEL_IN_DB=true
-USE_PRISMA_MIGRATE=true
+cat </opt/"${APPLICATION}".yaml
+general_settings:
+ master_key: sk-1234
+ database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
+ store_model_in_db: true
+ use_prisma_migrate: true
EOF
-cat </etc/systemd/system/${APPLICATION}.service
+cat </etc/systemd/system/"${APPLICATION}".service
[Unit]
Description=LiteLLM
[Service]
Type=simple
-EnvironmentFile=/opt/${APPLICATION}.env
-ExecStart=litellm
+ExecStart=litellm --config /opt/"${APPLICATION}".yaml
Restart=always
[Install]
From 758f198acd65217d06a8a6afabe3ef09efa1789e Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 19:06:07 -0500
Subject: [PATCH 006/312] Added prisma migrate param
---
install/litellm-install.sh | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 98c12eed..0634a783 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -53,7 +53,6 @@ general_settings:
master_key: sk-1234
database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
store_model_in_db: true
- use_prisma_migrate: true
EOF
cat </etc/systemd/system/"${APPLICATION}".service
@@ -62,7 +61,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=litellm --config /opt/"${APPLICATION}".yaml
+ExecStart=litellm --config /opt/${APPLICATION}.yaml --use_prisma_migrate
Restart=always
[Install]
From 950e7403c4d62f3bc8fd365af5a02d2a3d76a490 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 19:17:55 -0500
Subject: [PATCH 007/312] Updated config file path
---
frontend/public/json/litellm.json | 38 +++++++++++++++----------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
index e77c7291..fe5d1048 100644
--- a/frontend/public/json/litellm.json
+++ b/frontend/public/json/litellm.json
@@ -1,35 +1,35 @@
{
- "name": "LiteLLM",
- "slug": "litellm",
"categories": [
20
],
+ "config_path": "/opt/litellm.yaml",
"date_created": "2025-08-07",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 4000,
- "documentation": "https://docs.litellm.ai/",
- "config_path": "/opt/litellm.env",
- "website": "https://www.litellm.ai/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
+ "default_credentials": {
+ "password": "sk-1234",
+ "username": "admin"
+ },
"description": "LiteLLM description is here",
+ "documentation": "https://docs.litellm.ai/",
"install_methods": [
{
- "type": "default",
- "script": "ct/litellm.sh",
"resources": {
"cpu": 2,
- "ram": 2048,
"hdd": 4,
"os": "Debian",
+ "ram": 2048,
"version": "12"
- }
+ },
+ "script": "ct/litellm.sh",
+ "type": "default"
}
],
- "default_credentials": {
- "username": "admin",
- "password": "sk-1234"
- },
- "notes": []
+ "interface_port": 4000,
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
+ "name": "LiteLLM",
+ "notes": [],
+ "privileged": false,
+ "slug": "litellm",
+ "type": "ct",
+ "updateable": true,
+ "website": "https://www.litellm.ai/"
}
From 6789151eb256a355896b294c66b45f7759fb5a6e Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 19:31:12 -0500
Subject: [PATCH 008/312] Add .DS_Store to .gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index c6f9a448..4effcb9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.vscode/settings.json
+.DS_Store
From 0c0cf83cacdd05c16df2eb8d5e52b15e55a262bb Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 19:31:59 -0500
Subject: [PATCH 009/312] Added note about updating the master key
---
frontend/public/json/litellm.json | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
index fe5d1048..7ae25020 100644
--- a/frontend/public/json/litellm.json
+++ b/frontend/public/json/litellm.json
@@ -26,7 +26,12 @@
"interface_port": 4000,
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
"name": "LiteLLM",
- "notes": [],
+ "notes": [
+ {
+ "text": "Update master key in the config file",
+ "type": "info"
+ }
+ ],
"privileged": false,
"slug": "litellm",
"type": "ct",
From de08adb1ca33947882ac87336d21bf39b18e733c Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Thu, 7 Aug 2025 20:56:27 -0500
Subject: [PATCH 010/312] Updated litellm description
---
frontend/public/json/litellm.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
index 7ae25020..45ca3da4 100644
--- a/frontend/public/json/litellm.json
+++ b/frontend/public/json/litellm.json
@@ -8,7 +8,7 @@
"password": "sk-1234",
"username": "admin"
},
- "description": "LiteLLM description is here",
+ "description": "LLM proxy to call 100+ LLMs in a unified interface & track spend, set budgets per virtual key/user",
"documentation": "https://docs.litellm.ai/",
"install_methods": [
{
From 29c6d816eeb07db859021854d494ed914ffd3ff6 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Fri, 8 Aug 2025 07:40:41 +0200
Subject: [PATCH 011/312] Delete .gitignore
---
.gitignore | 2 --
1 file changed, 2 deletions(-)
delete mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 4effcb9e..00000000
--- a/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.vscode/settings.json
-.DS_Store
From 8b1d332217975f73f85b6b3b26cf6b198da0ad76 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:39:11 -0500
Subject: [PATCH 012/312] Reverted changes to .gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..c6f9a448
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.vscode/settings.json
From 3df502a1c2f7656b06b22d3736e0d2411d461150 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:41:35 -0500
Subject: [PATCH 013/312] Changed url to point to the VED repo
---
ct/litellm.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index a8e9b6af..a541cb1b 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: stout01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
@@ -23,7 +23,7 @@ function update_script() {
header_info
check_container_storage
check_container_resources
-
+
if [[ ! -f /etc/systemd/system/litellm.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
From 6a20775d088ffd8281e0564672f4f07b78b12273 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:42:21 -0500
Subject: [PATCH 014/312] Removed LXC from message
---
ct/litellm.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index a541cb1b..c8e69fcf 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -28,10 +28,10 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_info "Updating $APP LXC"
+ msg_info "Updating $APP"
$STD apt-get update
pip install litellm[proxy] --upgrade
- msg_ok "Updated $APP LXC"
+ msg_ok "Updated $APP"
exit
}
From 9ff98daafc1bce6abe62ac62f5f8cecc43edcaea Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:42:46 -0500
Subject: [PATCH 015/312] Removed unneeded commented line
---
install/litellm-install.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 0634a783..304798fb 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -34,7 +34,6 @@ DB_USER="${APPLICATION}"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "CREATE EXTENSION IF NOT EXISTS pg_trgm;" $DB_NAME
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
From 7813fa19b861bc507e8abae355dda35cd8a45b57 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:46:44 -0500
Subject: [PATCH 016/312] Replaced app name variable with just the application
name
---
install/litellm-install.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 304798fb..41dc2fc6 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -47,26 +47,26 @@ msg_ok "Set up PostgreSQL"
msg_info "Creating Service"
mkdir -p /opt
-cat </opt/"${APPLICATION}".yaml
+cat </opt/litellm.yaml
general_settings:
master_key: sk-1234
database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
store_model_in_db: true
EOF
-cat </etc/systemd/system/"${APPLICATION}".service
+cat </etc/systemd/system/litellm.service
[Unit]
Description=LiteLLM
[Service]
Type=simple
-ExecStart=litellm --config /opt/${APPLICATION}.yaml --use_prisma_migrate
+ExecStart=litellm --config /opt/litellm.yaml --use_prisma_migrate
Restart=always
[Install]
WantedBy=multi-user.target
EOF
-systemctl enable -q --now "${APPLICATION}"
+systemctl enable -q --now litellm
msg_ok "Created Service"
motd_ssh
From c094133ea1e3d2bc27d1c45b3df264abd645569f Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 15:50:40 -0500
Subject: [PATCH 017/312] unsorted and unformatted litellm.json
---
frontend/public/json/litellm.json | 38 +++++++++++++++----------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
index 45ca3da4..24ab079e 100644
--- a/frontend/public/json/litellm.json
+++ b/frontend/public/json/litellm.json
@@ -1,40 +1,40 @@
{
+ "name": "LiteLLM",
+ "slug": "litellm",
"categories": [
20
],
- "config_path": "/opt/litellm.yaml",
"date_created": "2025-08-07",
- "default_credentials": {
- "password": "sk-1234",
- "username": "admin"
- },
- "description": "LLM proxy to call 100+ LLMs in a unified interface & track spend, set budgets per virtual key/user",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 4000,
"documentation": "https://docs.litellm.ai/",
+ "config_path": "/opt/litellm.yaml",
+ "website": "https://www.litellm.ai/",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
+ "description": "LLM proxy to call 100+ LLMs in a unified interface & track spend, set budgets per virtual key/user",
"install_methods": [
{
+ "type": "default",
+ "script": "ct/litellm.sh",
"resources": {
"cpu": 2,
+ "ram": 2048,
"hdd": 4,
"os": "Debian",
- "ram": 2048,
"version": "12"
- },
- "script": "ct/litellm.sh",
- "type": "default"
+ }
}
],
- "interface_port": 4000,
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
- "name": "LiteLLM",
+ "default_credentials": {
+ "username": "admin",
+ "password": "sk-1234"
+ },
"notes": [
{
"text": "Update master key in the config file",
"type": "info"
}
- ],
- "privileged": false,
- "slug": "litellm",
- "type": "ct",
- "updateable": true,
- "website": "https://www.litellm.ai/"
+ ]
}
From ec0de310e8e42c4131fbb84d4d2ac8f124fc57f8 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 16:49:55 -0500
Subject: [PATCH 018/312] Refactored litellm script to use uv
---
ct/litellm.sh | 5 +++--
frontend/public/json/litellm.json | 2 +-
install/litellm-install.sh | 24 +++++++++++-------------
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index c8e69fcf..db655293 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -28,9 +28,10 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
+
msg_info "Updating $APP"
- $STD apt-get update
- pip install litellm[proxy] --upgrade
+ PYTHON_VERSION="3.13" setup_uv
+ $STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
msg_ok "Updated $APP"
exit
}
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
index 24ab079e..b2e7b7d7 100644
--- a/frontend/public/json/litellm.json
+++ b/frontend/public/json/litellm.json
@@ -10,7 +10,7 @@
"privileged": false,
"interface_port": 4000,
"documentation": "https://docs.litellm.ai/",
- "config_path": "/opt/litellm.yaml",
+ "config_path": "/opt/litellm/litellm.yaml",
"website": "https://www.litellm.ai/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
"description": "LLM proxy to call 100+ LLMs in a unified interface & track spend, set budgets per virtual key/user",
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 41dc2fc6..ed65b4ac 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -13,18 +13,16 @@ setting_up_container
network_check
update_os
-msg_info "Setup Python3"
-$STD apt-get install -y \
- python3 \
- python3-dev \
- python3-pip
-rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
-msg_ok "Setup Python3"
+PYTHON_VERSION="3.13" setup_uv
-msg_info "Installing ${APPLICATION}"
-$STD pip install 'litellm[proxy]'
-$STD pip install 'prisma'
-msg_ok "Installed ${APPLICATION}"
+msg_info "Setting up Virtual Environment"
+mkdir -p /opt/litellm
+cd /opt/litellm
+$STD uv venv /opt/litellmtwo/.venv
+$STD /opt/litellmtwo/.venv/bin/python -m ensurepip --upgrade
+$STD /opt/litellmtwo/.venv/bin/python -m pip install --upgrade pip
+$STD /opt/litellmtwo/.venv/bin/python -m pip install litellm[proxy] prisma
+msg_ok "Installed LiteLLM"
PG_VERSION="17" setup_postgresql
@@ -47,7 +45,7 @@ msg_ok "Set up PostgreSQL"
msg_info "Creating Service"
mkdir -p /opt
-cat </opt/litellm.yaml
+cat </opt/litellm/litellm.yaml
general_settings:
master_key: sk-1234
database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
@@ -60,7 +58,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=litellm --config /opt/litellm.yaml --use_prisma_migrate
+ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
Restart=always
[Install]
From 9bf97a6995a9e8fc499d0ca42312c7a0b5b0c36a Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 16:52:28 -0500
Subject: [PATCH 019/312] Updated urls for testing
---
ct/litellm.sh | 2 +-
misc/build.func | 4 ++--
misc/install.func | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index db655293..99f9366c 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: stout01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
diff --git a/misc/build.func b/misc/build.func
index c40a57bd..2197741e 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1129,7 +1129,7 @@ build_container() {
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1438,7 +1438,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
+ lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/install/${var_install}.sh)"
}
destroy_lxc() {
diff --git a/misc/install.func b/misc/install.func
index e3751c29..a4ef9464 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -196,7 +196,7 @@ EOF
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
msg_ok "Customized Container"
fi
- echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
+ echo "bash -c \"\$(curl -fsSL https://github.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
From 2b8ac5458b5ae029c8a630c53fe4209846a9be8d Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Fri, 8 Aug 2025 16:58:56 -0500
Subject: [PATCH 020/312] Revert "Updated urls for testing"
This reverts commit 89c3c77bf5c5ae858233d409f696014426ba21b1.
---
ct/litellm.sh | 2 +-
misc/build.func | 4 ++--
misc/install.func | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 99f9366c..db655293 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: stout01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
diff --git a/misc/build.func b/misc/build.func
index 2197741e..c40a57bd 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1129,7 +1129,7 @@ build_container() {
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1438,7 +1438,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/install/${var_install}.sh)"
+ lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
}
destroy_lxc() {
diff --git a/misc/install.func b/misc/install.func
index a4ef9464..e3751c29 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -196,7 +196,7 @@ EOF
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
msg_ok "Customized Container"
fi
- echo "bash -c \"\$(curl -fsSL https://github.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/ct/${app}.sh)\"" >/usr/bin/update
+ echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
From 0188bcfe3c297930fe8b628b135c4a4050d627bb Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:27:11 -0500
Subject: [PATCH 021/312] use static text for db_user
---
install/litellm-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index ed65b4ac..9c9d82f3 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -28,7 +28,7 @@ PG_VERSION="17" setup_postgresql
msg_info "Setting up PostgreSQL"
DB_NAME="litellm_db"
-DB_USER="${APPLICATION}"
+DB_USER="litellm"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
From 79211aeb18fe89594512d8fb675d085214ea792a Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:28:24 -0500
Subject: [PATCH 022/312] Add missing venv_path
---
ct/litellm.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index db655293..2fb7fcb4 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -30,6 +30,7 @@ function update_script() {
fi
msg_info "Updating $APP"
+ VENV_PATH="/opt/litellm/.venv"
PYTHON_VERSION="3.13" setup_uv
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
msg_ok "Updated $APP"
From 84358ce5b4a2ce3e79b7cf5cad386decf2521a4c Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:30:47 -0500
Subject: [PATCH 023/312] Start and stop service while updating
---
ct/litellm.sh | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 2fb7fcb4..975f93c8 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -29,11 +29,19 @@ function update_script() {
exit
fi
+ msg_info "Stopping ${APP}"
+ systemctl stop litellm.service
+ msg_ok "Stopped ${APP}"
+
msg_info "Updating $APP"
VENV_PATH="/opt/litellm/.venv"
PYTHON_VERSION="3.13" setup_uv
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
- msg_ok "Updated $APP"
+
+ msg_info "Starting ${APP}"
+ systemctl start litellm.service
+ msg_ok "Started ${APP}"
+ msg_ok "Updated Successfully"
exit
}
From 9c1670fc9d4446baa06b84a67a2d0341c91cfde0 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:31:08 -0500
Subject: [PATCH 024/312] Reapply "Updated urls for testing"
This reverts commit 2b8ac5458b5ae029c8a630c53fe4209846a9be8d.
---
ct/litellm.sh | 2 +-
misc/build.func | 4 ++--
misc/install.func | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 975f93c8..5b317fa5 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: stout01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
diff --git a/misc/build.func b/misc/build.func
index c40a57bd..2197741e 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1129,7 +1129,7 @@ build_container() {
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1438,7 +1438,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
+ lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/install/${var_install}.sh)"
}
destroy_lxc() {
diff --git a/misc/install.func b/misc/install.func
index e3751c29..a4ef9464 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -196,7 +196,7 @@ EOF
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
msg_ok "Customized Container"
fi
- echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
+ echo "bash -c \"\$(curl -fsSL https://github.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
From a52b8e4bdd426a2414f8a447ea8ff6f8caec6178 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:38:04 -0500
Subject: [PATCH 025/312] Remove --use_prisma_migrate. The latest release
removed this param
---
install/litellm-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 9c9d82f3..9b7845f1 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -58,7 +58,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
+ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml
Restart=always
[Install]
From 5f81621758aed4c7c7f5ad7f172d0ea276434c21 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 15:49:25 -0500
Subject: [PATCH 026/312] Fixed error in the folder paths
---
install/litellm-install.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 9b7845f1..008b5dc4 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -18,10 +18,10 @@ PYTHON_VERSION="3.13" setup_uv
msg_info "Setting up Virtual Environment"
mkdir -p /opt/litellm
cd /opt/litellm
-$STD uv venv /opt/litellmtwo/.venv
-$STD /opt/litellmtwo/.venv/bin/python -m ensurepip --upgrade
-$STD /opt/litellmtwo/.venv/bin/python -m pip install --upgrade pip
-$STD /opt/litellmtwo/.venv/bin/python -m pip install litellm[proxy] prisma
+$STD uv venv /opt/litellm/.venv
+$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
+$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
+$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
msg_ok "Installed LiteLLM"
PG_VERSION="17" setup_postgresql
From d597345310f6d45de275b69c7a17d8f21f70e930 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 16:32:24 -0500
Subject: [PATCH 027/312] Testing an older version
---
install/litellm-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 008b5dc4..c264d252 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -21,7 +21,7 @@ cd /opt/litellm
$STD uv venv /opt/litellm/.venv
$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
-$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
+$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy]==1.75.4 prisma
msg_ok "Installed LiteLLM"
PG_VERSION="17" setup_postgresql
@@ -58,7 +58,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml
+ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
Restart=always
[Install]
From d8543f0404bf47b065104679504066d036589fa6 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 16:50:44 -0500
Subject: [PATCH 028/312] Use uv to run litellm
---
install/litellm-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index c264d252..57380a44 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -58,7 +58,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=/opt/litellm/.venv/bin/litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
+ExecStart=uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
Restart=always
[Install]
From 0e460e8cc07cf0be5bccf1fd62553acd6f3a3c71 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 16:51:39 -0500
Subject: [PATCH 029/312] Test using latest again
---
install/litellm-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 57380a44..9790280b 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -21,7 +21,7 @@ cd /opt/litellm
$STD uv venv /opt/litellm/.venv
$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
-$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy]==1.75.4 prisma
+$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
msg_ok "Installed LiteLLM"
PG_VERSION="17" setup_postgresql
@@ -58,7 +58,7 @@ Description=LiteLLM
[Service]
Type=simple
-ExecStart=uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_migrate
+ExecStart=uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml
Restart=always
[Install]
From baae9af2fae1035cee71b159f36f1044c1779558 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 17:08:17 -0500
Subject: [PATCH 030/312] Update DB schema before creating service
---
install/litellm-install.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index 9790280b..c8a1fc75 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -43,7 +43,7 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
} >>~/litellm.creds
msg_ok "Set up PostgreSQL"
-msg_info "Creating Service"
+msg_info "Configuring LiteLLM"
mkdir -p /opt
cat </opt/litellm/litellm.yaml
general_settings:
@@ -52,6 +52,10 @@ general_settings:
store_model_in_db: true
EOF
+uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
+msg_ok "Configured LiteLLM"
+
+msg_info "Creating Service"
cat </etc/systemd/system/litellm.service
[Unit]
Description=LiteLLM
@@ -64,6 +68,7 @@ Restart=always
[Install]
WantedBy=multi-user.target
EOF
+
systemctl enable -q --now litellm
msg_ok "Created Service"
From ab8d446e16f55a33aad5caf710bcd7dab3687e65 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 17:30:01 -0500
Subject: [PATCH 031/312] Moved updating message below setup_uv
---
ct/litellm.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 5b317fa5..4c5d7c9d 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -33,9 +33,10 @@ function update_script() {
systemctl stop litellm.service
msg_ok "Stopped ${APP}"
- msg_info "Updating $APP"
VENV_PATH="/opt/litellm/.venv"
PYTHON_VERSION="3.13" setup_uv
+
+ msg_info "Updating $APP"
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
msg_info "Starting ${APP}"
From 6dac15a71279de2de9a6c63f16b7715c034ee3dc Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 17:40:06 -0500
Subject: [PATCH 032/312] Update db schema after updating litellm
---
ct/litellm.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 4c5d7c9d..e196542b 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -39,6 +39,10 @@ function update_script() {
msg_info "Updating $APP"
$STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
+ msg_info "Updating DB Schema"
+ uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
+ msg_ok "DB Schema Updated"
+
msg_info "Starting ${APP}"
systemctl start litellm.service
msg_ok "Started ${APP}"
From bd5f2f52bce0d54022ce17e4564507694c161ee1 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 17:47:02 -0500
Subject: [PATCH 033/312] Reordered install steps
---
install/litellm-install.sh | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
index c8a1fc75..b79341f9 100644
--- a/install/litellm-install.sh
+++ b/install/litellm-install.sh
@@ -13,18 +13,8 @@ setting_up_container
network_check
update_os
-PYTHON_VERSION="3.13" setup_uv
-
-msg_info "Setting up Virtual Environment"
-mkdir -p /opt/litellm
-cd /opt/litellm
-$STD uv venv /opt/litellm/.venv
-$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
-$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
-$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
-msg_ok "Installed LiteLLM"
-
PG_VERSION="17" setup_postgresql
+PYTHON_VERSION="3.13" setup_uv
msg_info "Setting up PostgreSQL"
DB_NAME="litellm_db"
@@ -43,6 +33,15 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
} >>~/litellm.creds
msg_ok "Set up PostgreSQL"
+msg_info "Setting up Virtual Environment"
+mkdir -p /opt/litellm
+cd /opt/litellm
+$STD uv venv /opt/litellm/.venv
+$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
+$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
+$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
+msg_ok "Installed LiteLLM"
+
msg_info "Configuring LiteLLM"
mkdir -p /opt
cat </opt/litellm/litellm.yaml
From 8a663669bd4ba9de84134348a12f93dac3b47a10 Mon Sep 17 00:00:00 2001
From: Andrew Stout
Date: Sat, 16 Aug 2025 21:14:11 -0500
Subject: [PATCH 034/312] Revert "Reapply "Updated urls for testing""
This reverts commit 9c1670fc9d4446baa06b84a67a2d0341c91cfde0.
---
ct/litellm.sh | 2 +-
misc/build.func | 4 ++--
misc/install.func | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index e196542b..847b7d8b 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: stout01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
diff --git a/misc/build.func b/misc/build.func
index 2197741e..c40a57bd 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1129,7 +1129,7 @@ build_container() {
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-install.func)"
else
- export FUNCTIONS_FILE_PATH="$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/misc/install.func)"
+ export FUNCTIONS_FILE_PATH="$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/install.func)"
fi
export DIAGNOSTICS="$DIAGNOSTICS"
export RANDOM_UUID="$RANDOM_UUID"
@@ -1438,7 +1438,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
- lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/install/${var_install}.sh)"
+ lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
}
destroy_lxc() {
diff --git a/misc/install.func b/misc/install.func
index a4ef9464..e3751c29 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -196,7 +196,7 @@ EOF
systemctl restart $(basename $(dirname $GETTY_OVERRIDE) | sed 's/\.d//')
msg_ok "Customized Container"
fi
- echo "bash -c \"\$(curl -fsSL https://github.com/stout01/ProxmoxVED/refs/heads/ved-litellm-script/ct/${app}.sh)\"" >/usr/bin/update
+ echo "bash -c \"\$(curl -fsSL https://github.com/community-scripts/ProxmoxVED/raw/main/ct/${app}.sh)\"" >/usr/bin/update
chmod +x /usr/bin/update
if [[ -n "${SSH_AUTHORIZED_KEY}" ]]; then
mkdir -p /root/.ssh
From fa12a13c151e3883d21ec38fd54b2d8db5668eb3 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Mon, 18 Aug 2025 05:51:49 +0000
Subject: [PATCH 035/312] Update .app files
---
ct/headers/litellm | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 ct/headers/litellm
diff --git a/ct/headers/litellm b/ct/headers/litellm
new file mode 100644
index 00000000..0b7dba63
--- /dev/null
+++ b/ct/headers/litellm
@@ -0,0 +1,6 @@
+ ___ __ ____
+ / (_) /____ / / /___ ___
+ / / / __/ _ \/ / / __ `__ \
+ / / / /_/ __/ / / / / / / /
+/_/_/\__/\___/_/_/_/ /_/ /_/
+
From a06f218b03f425f078121dd9fc57eeaa4fd53271 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:06:08 +0200
Subject: [PATCH 036/312] Merge branch 'main' of
https://github.com/community-scripts/ProxmoxVED
---
ct/twingate-connector.sh | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/ct/twingate-connector.sh b/ct/twingate-connector.sh
index f87be0a0..681c96a3 100644
--- a/ct/twingate-connector.sh
+++ b/ct/twingate-connector.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: twingate-andrewb
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-2}"
var_os="${var_os:-ubuntu}"
-var_version="${var_version:-22.04}"
+var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -25,16 +25,14 @@ function update_script() {
check_container_resources
if [[ ! -f /lib/systemd/system/twingate-connector.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
+ msg_error "No ${APP} Installation Found!"
+ exit
fi
msg_info "Updating ${APP}"
-
- apt update
- apt install -yq twingate-connector
- systemctl restart twingate-connector
-
+ $STD apt update
+ $STD apt install -yq twingate-connector
+ $STD systemctl restart twingate-connector
msg_ok "Updated Successfully"
exit
}
From b64a4601d7193cea820781a114ec8e6d370b2396 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:10:09 +0200
Subject: [PATCH 037/312] Update frigate-install.sh
---
install/frigate-install.sh | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 52884f07..862c8d83 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -15,11 +15,7 @@ update_os
msg_info "Installing Dependencies (Patience)"
$STD apt-get install -y \
- git automake build-essential xz-utils libtool ccache pkg-config \
- libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev \
- libjpeg-dev libpng-dev libtiff-dev gfortran openexr libatlas-base-dev libssl-dev libtbb-dev \
- libopenexr-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev gcc gfortran \
- libopenblas-dev liblapack-dev libusb-1.0-0-dev jq moreutils tclsh libhdf5-dev libopenexr-dev nginx
+ $STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
@@ -99,7 +95,7 @@ msg_ok "NGINX with Custom Modules Built"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "latest" "/usr/local/go2rtc/bin" "go2rtc_linux_amd64"
-fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.16.0-beta4" "/opt/frigate"
+fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "latest" "/opt/frigate"
fetch_and_deploy_gh_release "libusb" "libusb/libusb" "tarball" "v1.0.29" "/opt/frigate/libusb"
msg_info "Setting Up Hardware Acceleration"
@@ -242,6 +238,32 @@ systemctl daemon-reload
systemctl enable -q --now frigate
msg_ok "Frigate service enabled"
+msg_info "Setting environmental variables"
+cat <>/root/.bashrc
+export TERM='xterm-256color'
+export DEFAULT_FFMPEG_VERSION='7.0'
+export NVIDIA_VISIBLE_DEVICES='all'
+export ENV NVIDIA_DRIVER_CAPABILITIES='compute,video,utility'
+export PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
+export TOKENIZERS_PARALLELISM=true
+export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
+export OPENCV_FFMPEG_LOGLEVEL=8
+export HAILORT_LOGGER_PATH=NONE
+export INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:5.0"
+export S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
+export S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
+export CCACHE_DIR=/root/.ccache
+export CCACHE_MAXSIZE=2G
+EOF
+msg_ok "Environment set"
+
+msg_info "Building Nginx with Custom Modules"
+$STD bash /opt/frigate/docker/main/build_nginx.sh
+sed -i 's/if \[\[ "\$VERSION_ID" == "12" \]\]; then/if \[\[ "\$VERSION_ID" == "13" \]\]; then/' /opt/frigate/docker/main/build_nginx.sh
+sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
+ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
+msg_ok "Built Nginx"
+
# msg_info "Setup Frigate"
# ln -sf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc
# cd /opt/frigate
From 709ed8917e08f38e0d3c19c66bc6e7aaaef2b6a9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:10:53 +0200
Subject: [PATCH 038/312] Update twingate-connector.sh
---
ct/twingate-connector.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/twingate-connector.sh b/ct/twingate-connector.sh
index 681c96a3..09181aa7 100644
--- a/ct/twingate-connector.sh
+++ b/ct/twingate-connector.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: twingate-andrewb
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
From ea4316169c9706dcdfa7102ee7b68c57f3a4d9d1 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:25:06 +0200
Subject: [PATCH 039/312] little mods
---
ct/twingate-connector.sh | 4 ++--
frontend/public/json/twingate-connector.json | 12 ++++++++----
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/ct/twingate-connector.sh b/ct/twingate-connector.sh
index 09181aa7..f1a05c9a 100644
--- a/ct/twingate-connector.sh
+++ b/ct/twingate-connector.sh
@@ -8,8 +8,8 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
APP="twingate-connector"
var_tags="${var_tags:-network;connector;twingate}"
var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-2}"
+var_ram="${var_ram:-1024}"
+var_disk="${var_disk:-3}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
diff --git a/frontend/public/json/twingate-connector.json b/frontend/public/json/twingate-connector.json
index 55eeaacb..e9aa195e 100644
--- a/frontend/public/json/twingate-connector.json
+++ b/frontend/public/json/twingate-connector.json
@@ -12,7 +12,7 @@
"documentation": "https://www.twingate.com/docs/",
"config_path": "/etc/twingate/connector.conf",
"website": "https://www.twingate.com",
- "logo": "https://avatars.githubusercontent.com/u/97470429?s=200&v=4",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/twingate.webp",
"description": "Twingate Connectors are lightweight software components that establish secure, least-privileged access between private network resources and authorized users without exposing the network to the internet. They act as outbound-only bridges between your protected resources and the Twingate infrastructure, ensuring zero-trust access without the need for a VPN.",
"install_methods": [
{
@@ -20,10 +20,10 @@
"script": "ct/twingate-connector.sh",
"resources": {
"cpu": 1,
- "ram": 2048,
- "hdd": 2,
+ "ram": 1024,
+ "hdd": 3,
"os": "Ubuntu",
- "version": "22.04"
+ "version": "24.04"
}
}
],
@@ -32,6 +32,10 @@
"password": null
},
"notes": [
+ {
+ "text": "You can get your Twingate access or refresh tokens from the Twingate Admin Console. `https://auth.twingate.com/signup-v2`",
+ "type": "info"
+ },
{
"text": "If you need to update your access or refresh tokens, they can be found in /etc/twingate/connector.conf",
"type": "info"
From bb4ccbf06df2065e81615f3a893ef038874e3185 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:33:05 +0200
Subject: [PATCH 040/312] Update viseron-install.sh
---
install/viseron-install.sh | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index 7253f90c..fc9aa2d7 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -35,6 +35,15 @@ msg_ok "Installed Dependencies"
# fi
# msg_ok "Hardware Acceleration Configured"
+msg_info "Setting up Python Environment"
+PYTHON_VERSION="3.12" setup_uv /opt/viseron
+msg_ok "Python Environment Setup"
+
+msg_info "Installing Viseron"
+RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/latest | jq -r '.tag_name' | sed 's/^v//')
+uv pip install "viseron==${RELEASE}"
+msg_ok "Installed Viseron $RELEASE"
+
fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
msg_info "Setting up Viseron (Patience)"
From 1cf9b0699067a55ee3a121ec53f61704b5a1ae3b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:35:08 +0200
Subject: [PATCH 041/312] Update frigate-install.sh
---
install/frigate-install.sh | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 862c8d83..5805fffd 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -14,8 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y \
- $STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
+$STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
From 86088220f5fd3af6ee41ce21f632d0c1e0bd4f37 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:37:15 +0200
Subject: [PATCH 042/312] Update viseron-install.sh
---
install/viseron-install.sh | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index fc9aa2d7..d27eed4c 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -44,15 +44,15 @@ RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/l
uv pip install "viseron==${RELEASE}"
msg_ok "Installed Viseron $RELEASE"
-fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
+# fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
-msg_info "Setting up Viseron (Patience)"
-cd /opt/viseron
-uv venv .venv
-$STD uv pip install --upgrade pip setuptools wheel
-$STD uv pip install -r requirements.txt --python /opt/viseron/.venv/bin/python
-ln -s /opt/viseron/.venv/bin/viseron /usr/local/bin/viseron
-msg_ok "Setup Viseron"
+# msg_info "Setting up Viseron (Patience)"
+# cd /opt/viseron
+# uv venv .venv
+# $STD uv pip install --upgrade pip setuptools wheel
+# $STD uv pip install -r requirements.txt --python /opt/viseron/.venv/bin/python
+# ln -s /opt/viseron/.venv/bin/viseron /usr/local/bin/viseron
+# msg_ok "Setup Viseron"
msg_info "Creating Configuration Directory"
mkdir -p /config
From c831e7e9f963068dfe0c865a62874d2d49ca81f2 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:41:40 +0200
Subject: [PATCH 043/312] Update viseron-install.sh
---
install/viseron-install.sh | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index d27eed4c..313ee000 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -39,9 +39,16 @@ msg_info "Setting up Python Environment"
PYTHON_VERSION="3.12" setup_uv /opt/viseron
msg_ok "Python Environment Setup"
+msg_info "Setting up Python Environment"
+mkdir -p /opt/viseron
+cd /opt/viseron
+uv venv .
+msg_ok "Python Environment Setup"
+
msg_info "Installing Viseron"
-RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/latest | jq -r '.tag_name' | sed 's/^v//')
-uv pip install "viseron==${RELEASE}"
+RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/latest |
+ jq -r '.tag_name' | sed 's/^v//')
+/opt/viseron/bin/uv pip install "viseron==${RELEASE}"
msg_ok "Installed Viseron $RELEASE"
# fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
From 82d9d6235b0348f085911c46022dc19824826e31 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:46:17 +0200
Subject: [PATCH 044/312] Update frigate-install.sh
---
install/frigate-install.sh | 74 ++------------------------------------
1 file changed, 2 insertions(+), 72 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 5805fffd..980fabca 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -18,80 +18,10 @@ $STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,l
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
-$STD apt-get install -y \
- python3 python3-dev python3-setuptools python3-distutils python3-pip python3-venv
-$STD pip install --upgrade pip --break-system-packages
+$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip}
+$STD pip install --upgrade pip
msg_ok "Setup Python3"
-msg_info "Setup NGINX"
-apt-get update
-apt-get -y build-dep nginx
-apt-get -y install wget build-essential ccache patch ca-certificates
-update-ca-certificates -f
-export PATH="/usr/lib/ccache:$PATH"
-
-cd /tmp
-wget -nv https://nginx.org/download/nginx-1.29.0.tar.gz
-tar -xf nginx-1.29.0.tar.gz
-cd nginx-1.29.0
-
-mkdir /tmp/nginx-vod
-wget -nv https://github.com/kaltura/nginx-vod-module/archive/refs/tags/1.31.tar.gz
-tar -xf 1.31.tar.gz -C /tmp/nginx-vod --strip-components=1
-sed -i 's/MAX_CLIPS (128)/MAX_CLIPS (1080)/g' /tmp/nginx-vod/vod/media_set.h
-patch -d /tmp/nginx-vod -p1 <<'EOF'
---- a/vod/avc_hevc_parser.c
-+++ b/vod/avc_hevc_parser.c
-@@ -3,6 +3,9 @@
- bool_t
- avc_hevc_parser_rbsp_trailing_bits(bit_reader_state_t* reader)
- {
-+ // https://github.com/blakeblackshear/frigate/issues/4572
-+ return TRUE;
-+
- uint32_t one_bit;
-
- if (reader->stream.eof_reached)
-EOF
-# secure-token module
-mkdir /tmp/nginx-secure-token
-wget -nv https://github.com/kaltura/nginx-secure-token-module/archive/refs/tags/1.5.tar.gz
-tar -xf 1.5.tar.gz -C /tmp/nginx-secure-token --strip-components=1
-
-# ngx-devel-kit
-mkdir /tmp/ngx-devel-kit
-wget -nv https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.3.tar.gz
-tar -xf v0.3.3.tar.gz -C /tmp/ngx-devel-kit --strip-components=1
-
-# set-misc module
-mkdir /tmp/nginx-set-misc
-wget -nv https://github.com/openresty/set-misc-nginx-module/archive/refs/tags/v0.33.tar.gz
-tar -xf v0.33.tar.gz -C /tmp/nginx-set-misc --strip-components=1
-
-# configure & build
-cd /tmp/nginx-1.29.0
-./configure --prefix=/usr/local/nginx \
- --with-file-aio \
- --with-http_sub_module \
- --with-http_ssl_module \
- --with-http_auth_request_module \
- --with-http_realip_module \
- --with-threads \
- --add-module=/tmp/ngx-devel-kit \
- --add-module=/tmp/nginx-set-misc \
- --add-module=/tmp/nginx-vod \
- --add-module=/tmp/nginx-secure-token \
- --with-cc-opt="-O3 -Wno-error=implicit-fallthrough"
-
-make CC="ccache gcc" -j"$(nproc)"
-make install
-ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
-
-# cleanup
-rm -rf /tmp/nginx-1.29.0* /tmp/nginx-vod /tmp/nginx-secure-token /tmp/ngx-devel-kit /tmp/nginx-set-misc
-
-msg_ok "NGINX with Custom Modules Built"
-
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "latest" "/usr/local/go2rtc/bin" "go2rtc_linux_amd64"
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "latest" "/opt/frigate"
From 24728236d6544b0d14e5045e5c580c5fb08ea7cc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 08:50:22 +0200
Subject: [PATCH 045/312] Update viseron-install.sh
---
install/viseron-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index 313ee000..4984e9d3 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -41,8 +41,8 @@ msg_ok "Python Environment Setup"
msg_info "Setting up Python Environment"
mkdir -p /opt/viseron
-cd /opt/viseron
-uv venv .
+uv venv --python "python3.12" /opt/viseron
+/opt/viseron/bin/uv pip install --upgrade pip setuptools wheel
msg_ok "Python Environment Setup"
msg_info "Installing Viseron"
From af2e10edb67a4961f925c4a53b68ac2bcf8aef00 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:07:39 +0200
Subject: [PATCH 046/312] fixes
---
install/frigate-install.sh | 16 ++++++++--------
install/viseron-install.sh | 16 ++++++++--------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 980fabca..fdd601f7 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -27,14 +27,14 @@ fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "latest" "/us
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "latest" "/opt/frigate"
fetch_and_deploy_gh_release "libusb" "libusb/libusb" "tarball" "v1.0.29" "/opt/frigate/libusb"
-msg_info "Setting Up Hardware Acceleration"
-$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
-if [[ "$CTTYPE" == "0" ]]; then
- chgrp video /dev/dri
- chmod 755 /dev/dri
- chmod 660 /dev/dri/*
-fi
-msg_ok "Set Up Hardware Acceleration"
+# msg_info "Setting Up Hardware Acceleration"
+# $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
+# if [[ "$CTTYPE" == "0" ]]; then
+# chgrp video /dev/dri
+# chmod 755 /dev/dri
+# chmod 660 /dev/dri/*
+# fi
+# msg_ok "Set Up Hardware Acceleration"
msg_info "Setting up Python venv"
cd /opt/frigate
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index 4984e9d3..f4cdb35f 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -23,7 +23,7 @@ $STD apt-get install -y \
libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav \
build-essential python3-dev python3-gi pkg-config libcairo2-dev gir1.2-glib-2.0 \
- cmake gfortran libopenblas-dev liblapack-dev libgirepository1.0-dev
+ cmake gfortran libopenblas-dev liblapack-dev libgirepository1.0-dev git
msg_ok "Installed Dependencies"
@@ -35,20 +35,20 @@ msg_ok "Installed Dependencies"
# fi
# msg_ok "Hardware Acceleration Configured"
-msg_info "Setting up Python Environment"
-PYTHON_VERSION="3.12" setup_uv /opt/viseron
-msg_ok "Python Environment Setup"
+PYTHON_VERSION="3.12" setup_uv
msg_info "Setting up Python Environment"
mkdir -p /opt/viseron
uv venv --python "python3.12" /opt/viseron
-/opt/viseron/bin/uv pip install --upgrade pip setuptools wheel
+uv pip install --python /opt/viseron/bin/python --upgrade pip setuptools wheel
msg_ok "Python Environment Setup"
msg_info "Installing Viseron"
RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/latest |
- jq -r '.tag_name' | sed 's/^v//')
-/opt/viseron/bin/uv pip install "viseron==${RELEASE}"
+ jq -r '.tag_name')
+uv pip install --python /opt/viseron/bin/python \
+ "git+https://github.com/roflcoopter/viseron.git@${RELEASE}"
+uv pip install --python /opt/viseron/bin/python -r https://raw.githubusercontent.com/roflcoopter/viseron/${RELEASE}/requirements.txt
msg_ok "Installed Viseron $RELEASE"
# fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
@@ -133,7 +133,7 @@ Type=simple
User=root
WorkingDirectory=/opt/viseron
Environment=PATH=/opt/viseron/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-ExecStart=/opt/viseron/.venv/bin/viseron --config /config/viseron.yaml
+ExecStart=/opt/viseron/bin/viseron --config /config/viseron.yaml
Restart=always
RestartSec=10
From 64e3fbe983f36baf27630dcb72c25c1e7b9b5280 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:23:47 +0200
Subject: [PATCH 047/312] Update viseron-install.sh
---
install/viseron-install.sh | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index f4cdb35f..63e16e6f 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -37,18 +37,16 @@ msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
+fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
+
msg_info "Setting up Python Environment"
-mkdir -p /opt/viseron
uv venv --python "python3.12" /opt/viseron
uv pip install --python /opt/viseron/bin/python --upgrade pip setuptools wheel
msg_ok "Python Environment Setup"
msg_info "Installing Viseron"
-RELEASE=$(curl -fsSL https://api.github.com/repos/roflcoopter/viseron/releases/latest |
- jq -r '.tag_name')
-uv pip install --python /opt/viseron/bin/python \
- "git+https://github.com/roflcoopter/viseron.git@${RELEASE}"
-uv pip install --python /opt/viseron/bin/python -r https://raw.githubusercontent.com/roflcoopter/viseron/${RELEASE}/requirements.txt
+uv pip install --python /opt/viseron/bin/python -e .
+uv pip install --python /opt/viseron/bin/python -r requirements.txt
msg_ok "Installed Viseron $RELEASE"
# fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
@@ -133,7 +131,7 @@ Type=simple
User=root
WorkingDirectory=/opt/viseron
Environment=PATH=/opt/viseron/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-ExecStart=/opt/viseron/bin/viseron --config /config/viseron.yaml
+ExecStart=/opt/viseron/bin/python -m viseron --config /config/viseron.yaml
Restart=always
RestartSec=10
From f7f22e260715aec009874644785dfe44f41b0058 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:27:19 +0200
Subject: [PATCH 048/312] Update frigate-install.sh
---
install/frigate-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index fdd601f7..8674bbd9 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -18,7 +18,7 @@ $STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,l
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
-$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip}
+$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip,python3-venv}
$STD pip install --upgrade pip
msg_ok "Setup Python3"
From 779762c3dd782223324f6c40733013e3c30cdb9c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:50:50 +0200
Subject: [PATCH 049/312] fixes
---
install/frigate-install.sh | 2 --
install/viseron-install.sh | 24 ++++++------------------
2 files changed, 6 insertions(+), 20 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 8674bbd9..8dc59553 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -140,7 +140,6 @@ StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
-systemctl daemon-reload
systemctl enable -q --now go2rtc
msg_ok "go2rtc service enabled"
@@ -163,7 +162,6 @@ StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
-systemctl daemon-reload
systemctl enable -q --now frigate
msg_ok "Frigate service enabled"
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index 63e16e6f..a57f6356 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -17,7 +17,6 @@ PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Dependencies"
$STD apt-get install -y \
- python3 python3-pip python3-venv \
python3-opencv jq \
libgl1-mesa-glx libglib2.0-0 \
libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \
@@ -36,28 +35,17 @@ msg_ok "Installed Dependencies"
# msg_ok "Hardware Acceleration Configured"
PYTHON_VERSION="3.12" setup_uv
-
fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
msg_info "Setting up Python Environment"
-uv venv --python "python3.12" /opt/viseron
-uv pip install --python /opt/viseron/bin/python --upgrade pip setuptools wheel
+uv venv --python "python3.12" /opt/viseron/.venv
+uv pip install --python /opt/viseron/.venv/bin/python --upgrade pip setuptools wheel
msg_ok "Python Environment Setup"
-msg_info "Installing Viseron"
-uv pip install --python /opt/viseron/bin/python -e .
-uv pip install --python /opt/viseron/bin/python -r requirements.txt
-msg_ok "Installed Viseron $RELEASE"
-
-# fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
-
-# msg_info "Setting up Viseron (Patience)"
-# cd /opt/viseron
-# uv venv .venv
-# $STD uv pip install --upgrade pip setuptools wheel
-# $STD uv pip install -r requirements.txt --python /opt/viseron/.venv/bin/python
-# ln -s /opt/viseron/.venv/bin/viseron /usr/local/bin/viseron
-# msg_ok "Setup Viseron"
+msg_info "Setup Viseron (Patience)"
+UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -e /opt/viseron/.
+UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -r /opt/viseron/requirements.txt
+msg_ok "Setup Viseron"
msg_info "Creating Configuration Directory"
mkdir -p /config
From f3790114303075e9180dfc4bf8adfa36296237dd Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 09:51:40 +0200
Subject: [PATCH 050/312] Update frigate-install.sh
---
install/frigate-install.sh | 222 +------------------------------------
1 file changed, 1 insertion(+), 221 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 8dc59553..bc4eba13 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -176,7 +176,7 @@ export TOKENIZERS_PARALLELISM=true
export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
export OPENCV_FFMPEG_LOGLEVEL=8
export HAILORT_LOGGER_PATH=NONE
-export INCLUDED_FFMPEG_VERSIONS="${DEFAULT_FFMPEG_VERSION}:5.0"
+export INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
export S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
export S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
export CCACHE_DIR=/root/.ccache
@@ -191,226 +191,6 @@ sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-o
ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
msg_ok "Built Nginx"
-# msg_info "Setup Frigate"
-# ln -sf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc
-# cd /opt/frigate
-# $STD pip install -r /opt/frigate/docker/main/requirements.txt --break-system-packages
-# $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt --break-system-packages
-# $STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt
-# pip3 install -U /wheels/*.whl
-# cp -a /opt/frigate/docker/main/rootfs/. /
-# export TARGETARCH="amd64"
-# export DEBIAN_FRONTEND=noninteractive
-# echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
-# echo "libedgetpu1-max libedgetpu/install-confirm-max select true" | debconf-set-selections
-
-# msg_info "Ensure /etc/apt/sources.list.d/debian.sources exists with deb-src"
-# mkdir -p /etc/apt/sources.list.d
-# cat >/etc/apt/sources.list.d/debian.sources <<'EOF'
-# Types: deb deb-src
-# URIs: http://deb.debian.org/debian
-# Suites: bookworm
-# Components: main
-# Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
-# EOF
-# msg_ok "Stub /etc/apt/sources.list.d/debian.sources created"
-
-# msg_info "Updating APT cache"
-# $STD apt-get update
-# msg_ok "APT cache updated"
-
-# msg_info "Building Nginx with Custom Modules"
-# $STD bash /opt/frigate/docker/main/build_nginx.sh
-# sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
-# ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
-# msg_ok "Built Nginx"
-
-# msg_info "Cleanup stub debian.sources"
-# rm -f /etc/apt/sources.list.d/debian.sources
-# $STD apt-get update
-# msg_ok "Removed stub and updated APT cache"
-
-# $STD /opt/frigate/docker/main/install_deps.sh
-# $STD apt update
-# $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg
-# $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
-# $STD pip3 install -U /wheels/*.whl
-# ldconfig
-# $STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt
-# $STD /opt/frigate/.devcontainer/initialize.sh
-# $STD make version
-# cd /opt/frigate/web
-# $STD npm install
-# $STD npm run build
-# cp -r /opt/frigate/web/dist/* /opt/frigate/web/
-# cp -r /opt/frigate/config/. /config
-# sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
-# cat </config/config.yml
-# mqtt:
-# enabled: false
-# cameras:
-# test:
-# ffmpeg:
-# #hwaccel_args: preset-vaapi
-# inputs:
-# - path: /media/frigate/person-bicycle-car-detection.mp4
-# input_args: -re -stream_loop -1 -fflags +genpts
-# roles:
-# - detect
-# - rtmp
-# detect:
-# height: 1080
-# width: 1920
-# fps: 5
-# EOF
-# ln -sf /config/config.yml /opt/frigate/config/config.yml
-# if [[ "$CTTYPE" == "0" ]]; then
-# sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group
-# else
-# sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group
-# fi
-# echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
-# msg_ok "Installed Frigate"
-
-# # read -p "Semantic Search requires a dedicated GPU and at least 16GB RAM. Would you like to install it? (y/n): " semantic_choice
-# # if [[ "$semantic_choice" == "y" ]]; then
-# # msg_info "Configuring Semantic Search & AI Models"
-# # mkdir -p /opt/frigate/models/semantic_search
-# # curl -fsSL -o /opt/frigate/models/semantic_search/clip_model.pt https://huggingface.co/openai/clip-vit-base-patch32/resolve/main/pytorch_model.bin
-# # msg_ok "Semantic Search Models Installed"
-# # else
-# # msg_ok "Skipped Semantic Search Setup"
-# # fi
-
-# msg_info "Building and Installing libUSB without udev"
-# wget -qO /tmp/libusb.zip https://github.com/libusb/libusb/archive/v1.0.29.zip
-# unzip -q /tmp/libusb.zip -d /tmp/
-# cd /tmp/libusb-1.0.29
-# ./bootstrap.sh
-# ./configure --disable-udev --enable-shared
-# make -j$(nproc --all)
-# make install
-# ldconfig
-# rm -rf /tmp/libusb.zip /tmp/libusb-1.0.29
-# msg_ok "Installed libUSB without udev"
-
-# msg_info "Installing Coral Object Detection Model (Patience)"
-# cd /opt/frigate
-# export CCACHE_DIR=/root/.ccache
-# export CCACHE_MAXSIZE=2G
-# cd libusb
-# $STD ./bootstrap.sh
-# $STD ./configure --disable-udev --enable-shared
-# $STD make -j $(nproc --all)
-# cd /opt/frigate/libusb/libusb
-# mkdir -p /usr/local/lib
-# $STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib'
-# mkdir -p /usr/local/include/libusb-1.0
-# $STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'
-# ldconfig
-# cd /
-# wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite
-# wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite
-# cp /opt/frigate/labelmap.txt /labelmap.txt
-# wget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download
-# tar xzf yamnet-tflite-classification-tflite-v1.tar.gz
-# rm -rf yamnet-tflite-classification-tflite-v1.tar.gz
-# mv 1.tflite cpu_audio_model.tflite
-# cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt
-# mkdir -p /media/frigate
-# wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4
-# msg_ok "Installed Coral Object Detection Model"
-
-# msg_info "Installing Tempio"
-# sed -i 's|/rootfs/usr/local|/usr/local|g' /opt/frigate/docker/main/install_tempio.sh
-# TARGETARCH="amd64"
-# $STD /opt/frigate/docker/main/install_tempio.sh
-# chmod +x /usr/local/tempio/bin/tempio
-# ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
-# msg_ok "Installed Tempio"
-
-# msg_info "Creating Services"
-# cat </etc/systemd/system/create_directories.service
-# [Unit]
-# Description=Create necessary directories for logs
-
-# [Service]
-# Type=oneshot
-# ExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs'
-
-# [Install]
-# WantedBy=multi-user.target
-# EOF
-# systemctl enable -q --now create_directories
-# sleep 3
-# cat </etc/systemd/system/go2rtc.service
-# [Unit]
-# Description=go2rtc service
-# After=network.target
-# After=create_directories.service
-# StartLimitIntervalSec=0
-
-# [Service]
-# Type=simple
-# Restart=always
-# RestartSec=1
-# User=root
-# ExecStartPre=+rm /dev/shm/logs/go2rtc/current
-# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
-# StandardOutput=file:/dev/shm/logs/go2rtc/current
-# StandardError=file:/dev/shm/logs/go2rtc/current
-
-# [Install]
-# WantedBy=multi-user.target
-# EOF
-# systemctl enable -q --now go2rtc
-# sleep 3
-# cat </etc/systemd/system/frigate.service
-# [Unit]
-# Description=Frigate service
-# After=go2rtc.service
-# After=create_directories.service
-# StartLimitIntervalSec=0
-
-# [Service]
-# Type=simple
-# Restart=always
-# RestartSec=1
-# User=root
-# # Environment=PLUS_API_KEY=
-# ExecStartPre=+rm /dev/shm/logs/frigate/current
-# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
-# StandardOutput=file:/dev/shm/logs/frigate/current
-# StandardError=file:/dev/shm/logs/frigate/current
-
-# [Install]
-# WantedBy=multi-user.target
-# EOF
-# systemctl enable -q --now frigate
-# sleep 3
-# cat </etc/systemd/system/nginx.service
-# [Unit]
-# Description=Nginx service
-# After=frigate.service
-# After=create_directories.service
-# StartLimitIntervalSec=0
-
-# [Service]
-# Type=simple
-# Restart=always
-# RestartSec=1
-# User=root
-# ExecStartPre=+rm /dev/shm/logs/nginx/current
-# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
-# StandardOutput=file:/dev/shm/logs/nginx/current
-# StandardError=file:/dev/shm/logs/nginx/current
-
-# [Install]
-# WantedBy=multi-user.target
-# EOF
-# systemctl enable -q --now nginx
-# msg_ok "Configured Services"
-
motd_ssh
customize
From d01ae72a5f7b0a1f677cfbc9bbe4763ccf85c73a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 10:21:02 +0200
Subject: [PATCH 051/312] fixes
---
install/frigate-install.sh | 2 ++
install/viseron-install.sh | 41 ++++++++++++++++++++++++++++----------
2 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index bc4eba13..6078c189 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -152,6 +152,8 @@ After=go2rtc.service network.target
[Service]
WorkingDirectory=/opt/frigate
Environment="PATH=/opt/frigate/venv/bin"
+Environment="PYTHONPATH=/opt/frigate"
+ExecStartPre=/bin/mkdir -p /media/frigate/recordings /media/frigate/clips /media/frigate/snapshots
ExecStart=/opt/frigate/venv/bin/python3 -u -m frigate
Restart=always
RestartSec=5
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index a57f6356..f2ae8d01 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -13,8 +13,6 @@ setting_up_container
network_check
update_os
-PYTHON_VERSION="3.12" setup_uv
-
msg_info "Installing Dependencies"
$STD apt-get install -y \
python3-opencv jq \
@@ -23,9 +21,28 @@ $STD apt-get install -y \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav \
build-essential python3-dev python3-gi pkg-config libcairo2-dev gir1.2-glib-2.0 \
cmake gfortran libopenblas-dev liblapack-dev libgirepository1.0-dev git
-
msg_ok "Installed Dependencies"
+PYTHON_VERSION="3.12" setup_uv
+PG_VERSION="16" setup_postgresql
+
+msg_info "Setting up PostgreSQL Database"
+DB_NAME=viseron
+DB_USER=viseron_usr
+DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
+{
+ echo "Hanko-Credentials"
+ echo "Hanko Database User: $DB_USER"
+ echo "Hanko Database Password: $DB_PASS"
+ echo "Hanko Database Name: $DB_NAME"
+} >>~/hanko.creds
+msg_ok "Set up PostgreSQL Database"
+
# msg_info "Setting up Hardware Acceleration"
# if [[ "$CTTYPE" == "0" ]]; then
# chgrp video /dev/dri
@@ -45,14 +62,10 @@ msg_ok "Python Environment Setup"
msg_info "Setup Viseron (Patience)"
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -e /opt/viseron/.
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -r /opt/viseron/requirements.txt
+mkdir -p /config/{recordings,snapshots,segments,event_clips,thumbnails}
+for d in recordings snapshots segments event_clips thumbnails; do ln -s "/config/$d" "/$d" 2>/dev/null || true; done
msg_ok "Setup Viseron"
-msg_info "Creating Configuration Directory"
-mkdir -p /config
-mkdir -p /config/recordings
-mkdir -p /config/logs
-msg_ok "Created Configuration Directory"
-
msg_info "Creating Default Configuration"
cat </config/viseron.yaml
# Viseron Configuration
@@ -105,6 +118,14 @@ motion_detection:
enabled: true
threshold: 25
sensitivity: 0.8
+
+storage:
+ connection_string: postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME
+ recordings: /recordings
+ snapshots: /snapshots
+ segments: /segments
+ event_clips: /event_clips
+ thumbnails: /thumbnails
EOF
msg_ok "Created Default Configuration"
@@ -119,7 +140,7 @@ Type=simple
User=root
WorkingDirectory=/opt/viseron
Environment=PATH=/opt/viseron/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
-ExecStart=/opt/viseron/bin/python -m viseron --config /config/viseron.yaml
+ExecStart=/opt/viseron/.venv/bin/python -m viseron --config /config/viseron.yaml
Restart=always
RestartSec=10
From 5a735d09e58fe6944a4c5b35ef1893a8cbdd49ff Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:29:10 +0200
Subject: [PATCH 052/312] test
---
install/frigate-install.sh | 18 +++++++++++++++---
install/viseron-install.sh | 12 ++++++++++++
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 6078c189..3d5be25a 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -14,7 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
+$STD apt-get install -y {git,ffmpeg,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
@@ -48,7 +48,7 @@ msg_ok "Python venv ready"
msg_info "Building Web UI"
cd /opt/frigate/web
-$STD npm install
+$STD npm ci
$STD npm run build
msg_ok "Web UI built"
@@ -75,6 +75,11 @@ mkdir -p /config
ln -sf /opt/frigate/config/config.yml /config/config.yml
mkdir -p /media/frigate
wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4
+cat <<'EOF' >/opt/frigate/frigate/version.py
+VERSION = "0.16.0"
+EOF
+ln -sf /usr/lib/ffmpeg/7.0/bin/ffmpeg /usr/bin/ffmpeg
+ln -sf /usr/lib/ffmpeg/7.0/bin/ffprobe /usr/bin/ffprobe
msg_ok "Config ready"
msg_info "Building and Installing libUSB without udev"
@@ -121,6 +126,13 @@ chmod +x /usr/local/tempio/bin/tempio
ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
msg_ok "Installed Tempio"
+msg_info "Copying model files"
+cp /opt/frigate/cpu_model.tflite /
+cp /opt/frigate/edgetpu_model.tflite /
+cp /opt/frigate/audio-labelmap.txt /
+cp /opt/frigate/labelmap.txt /
+msg_ok "Copied model files"
+
# ------------------------------------------------------------
# systemd Units
msg_info "Creating systemd service for go2rtc"
@@ -187,8 +199,8 @@ EOF
msg_ok "Environment set"
msg_info "Building Nginx with Custom Modules"
-$STD bash /opt/frigate/docker/main/build_nginx.sh
sed -i 's/if \[\[ "\$VERSION_ID" == "12" \]\]; then/if \[\[ "\$VERSION_ID" == "13" \]\]; then/' /opt/frigate/docker/main/build_nginx.sh
+$STD bash /opt/frigate/docker/main/build_nginx.sh
sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
msg_ok "Built Nginx"
diff --git a/install/viseron-install.sh b/install/viseron-install.sh
index f2ae8d01..f15a0f42 100644
--- a/install/viseron-install.sh
+++ b/install/viseron-install.sh
@@ -60,6 +60,18 @@ uv pip install --python /opt/viseron/.venv/bin/python --upgrade pip setuptools w
msg_ok "Python Environment Setup"
msg_info "Setup Viseron (Patience)"
+if ls /dev/nvidia* >/dev/null 2>&1; then
+ msg_info "GPU detected → Installing PyTorch with CUDA"
+ UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python \
+ torch==2.8.0 torchvision==0.19.0 torchaudio==2.8.0
+ msg_ok "Installed Torch with CUDA"
+else
+ msg_info "No GPU detected → Installing CPU-only PyTorch"
+ UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python \
+ torch==2.8.0+cpu torchvision==0.19.0+cpu torchaudio==2.8.0+cpu \
+ --extra-index-url https://download.pytorch.org/whl/cpu
+ msg_ok "Installed Torch CPU-only"
+fi
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -e /opt/viseron/.
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -r /opt/viseron/requirements.txt
mkdir -p /config/{recordings,snapshots,segments,event_clips,thumbnails}
From 60274543040686df018ac4abaf5b476fbf66d85e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:35:50 +0200
Subject: [PATCH 053/312] ente
---
ct/ente.sh | 42 ++++++++++++++
install/ente-install.sh | 126 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 168 insertions(+)
create mode 100644 ct/ente.sh
create mode 100644 install/ente-install.sh
diff --git a/ct/ente.sh b/ct/ente.sh
new file mode 100644
index 00000000..3074d79b
--- /dev/null
+++ b/ct/ente.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: MickLesk (CanbiZ)
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+# Source: https://www.debian.org/
+
+APP="Ente"
+var_tags="${var_tags:-photos}"
+var_cpu="${var_cpu:-4}"
+var_ram="${var_ram:-4096}"
+var_disk="${var_disk:-10}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+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 /var ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ msg_info "Updating $APP LXC"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ msg_ok "Updated $APP LXC"
+ exit
+}
+
+start
+build_container
+description
+
+msg_ok "Completed Successfully!"
+msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!"
diff --git a/install/ente-install.sh b/install/ente-install.sh
new file mode 100644
index 00000000..edcd8b0c
--- /dev/null
+++ b/install/ente-install.sh
@@ -0,0 +1,126 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: MickLesk
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/ente-io/ente
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies"
+$STD apt-get install -y \
+ libsodium23 libsodium-dev pkg-config caddy
+msg_ok "Installed Dependencies"
+
+PG_VERSION="17" setup_postgresql
+setup_go
+NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
+fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "latest" "/opt/ente"
+
+msg_info "Setting up PostgreSQL"
+DB_NAME="ente_db"
+DB_USER="ente"
+DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
+{
+ echo "Ente Credentials"
+ echo "Database Name: $DB_NAME"
+ echo "Database User: $DB_USER"
+ echo "Database Password: $DB_PASS"
+} >>~/ente.creds
+msg_ok "Set up PostgreSQL"
+
+msg_info "Building Museum (server)"
+cd /opt/ente/server
+$STD corepack enable
+$STD go mod tidy
+$STD go build cmd/museum/main.go
+cp config/example.yaml museum.yaml
+msg_ok "Built Museum"
+
+msg_info "Generating Secrets"
+$STD go run tools/gen-random-keys/main.go >secrets.txt
+msg_ok "Generated Secrets"
+
+msg_info "Creating Museum Service"
+cat </etc/systemd/system/ente-museum.service
+[Unit]
+Description=Ente Museum Server
+After=network.target postgresql.service
+
+[Service]
+WorkingDirectory=/opt/ente/server
+ExecStart=/opt/ente/server/main
+Restart=always
+Environment="DATABASE_URL=postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME"
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now ente-museum
+msg_ok "Created Museum Service"
+
+msg_info "Building Web Applications"
+cd /opt/ente/web
+$STD yarn install
+export NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080
+export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://localhost:3002
+$STD yarn build
+$STD yarn build:accounts
+$STD yarn build:auth
+$STD yarn build:cast
+mkdir -p /var/www/ente/apps
+cp -r apps/photos/out /var/www/ente/apps/photos
+cp -r apps/accounts/out /var/www/ente/apps/accounts
+cp -r apps/auth/out /var/www/ente/apps/auth
+cp -r apps/cast/out /var/www/ente/apps/cast
+msg_ok "Built Web Applications"
+
+msg_info "Configuring Caddy"
+cat </etc/caddy/Caddyfile
+:3000 {
+ root * /var/www/ente/apps/photos
+ file_server
+ try_files {path} {path}.html /index.html
+}
+:3001 {
+ root * /var/www/ente/apps/accounts
+ file_server
+ try_files {path} {path}.html /index.html
+}
+:3002 {
+ root * /var/www/ente/apps/photos
+ file_server
+ try_files {path} {path}.html /index.html
+}
+:3003 {
+ root * /var/www/ente/apps/auth
+ file_server
+ try_files {path} {path}.html /index.html
+}
+:3004 {
+ root * /var/www/ente/apps/cast
+ file_server
+ try_files {path} {path}.html /index.html
+}
+EOF
+systemctl reload caddy
+msg_ok "Configured Caddy"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 8adac20faab7a8aec0090b4d6cce71defffe77a9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:40:53 +0200
Subject: [PATCH 054/312] fix libsodium
---
install/ente-install.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/install/ente-install.sh b/install/ente-install.sh
index edcd8b0c..4b0b3839 100644
--- a/install/ente-install.sh
+++ b/install/ente-install.sh
@@ -44,6 +44,8 @@ msg_info "Building Museum (server)"
cd /opt/ente/server
$STD corepack enable
$STD go mod tidy
+export CGO_CFLAGS="$(pkg-config --cflags libsodium)"
+export CGO_LDFLAGS="$(pkg-config --libs libsodium)"
$STD go build cmd/museum/main.go
cp config/example.yaml museum.yaml
msg_ok "Built Museum"
From d6aa91c7aafef2cf3faf0f92ed4a056d8b3c943d Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:50:41 +0200
Subject: [PATCH 055/312] Update ente-install.sh
---
install/ente-install.sh | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/install/ente-install.sh b/install/ente-install.sh
index 4b0b3839..72cdf927 100644
--- a/install/ente-install.sh
+++ b/install/ente-install.sh
@@ -44,8 +44,17 @@ msg_info "Building Museum (server)"
cd /opt/ente/server
$STD corepack enable
$STD go mod tidy
-export CGO_CFLAGS="$(pkg-config --cflags libsodium)"
-export CGO_LDFLAGS="$(pkg-config --libs libsodium)"
+export CGO_ENABLED=1
+CGO_CFLAGS="$(pkg-config --cflags libsodium || true)"
+CGO_LDFLAGS="$(pkg-config --libs libsodium || true)"
+if [ -z "$CGO_CFLAGS" ]; then
+ CGO_CFLAGS="-I/usr/include"
+fi
+if [ -z "$CGO_LDFLAGS" ]; then
+ CGO_LDFLAGS="-lsodium"
+fi
+export CGO_CFLAGS
+export CGO_LDFLAGS
$STD go build cmd/museum/main.go
cp config/example.yaml museum.yaml
msg_ok "Built Museum"
From 6b5f70b6e2590f7af597f2a6714db19f95f43ddf Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 11:54:48 +0200
Subject: [PATCH 056/312] Create copyparty.json
---
frontend/public/json/copyparty.json | 40 +++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 frontend/public/json/copyparty.json
diff --git a/frontend/public/json/copyparty.json b/frontend/public/json/copyparty.json
new file mode 100644
index 00000000..ccc14f4e
--- /dev/null
+++ b/frontend/public/json/copyparty.json
@@ -0,0 +1,40 @@
+{
+ "name": "Copyparty",
+ "slug": "copyparty",
+ "categories": [
+ 1
+ ],
+ "date_created": "2025-08-18",
+ "type": "addon",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": null,
+ "documentation": "https://github.com/9001/copyparty?tab=readme-ov-file#the-browser",
+ "website": "https://github.com/9001/copyparty",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/copyparty.webp",
+ "config_path": "",
+ "description": "This script automatically adds IP address as tags to LXC containers using a Systemd service. The service also updates the tags if a LXC IP address is changed.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "tools/addon/copyparty.sh",
+ "resources": {
+ "cpu": null,
+ "ram": null,
+ "hdd": null,
+ "os": null,
+ "version": null
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "Execute within the Proxmox shell or in LXC",
+ "type": "info"
+ }
+ ]
+}
From 120e5ac5242b82021fd6c8f4a671bd6ed5caaea5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 12:00:20 +0200
Subject: [PATCH 057/312] copyparty
---
frontend/public/json/copyparty.json | 2 +-
tools/addon/copyparty.sh | 41 ++++++++++-------------------
2 files changed, 15 insertions(+), 28 deletions(-)
diff --git a/frontend/public/json/copyparty.json b/frontend/public/json/copyparty.json
index ccc14f4e..bc1fb40c 100644
--- a/frontend/public/json/copyparty.json
+++ b/frontend/public/json/copyparty.json
@@ -13,7 +13,7 @@
"website": "https://github.com/9001/copyparty",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/copyparty.webp",
"config_path": "",
- "description": "This script automatically adds IP address as tags to LXC containers using a Systemd service. The service also updates the tags if a LXC IP address is changed.",
+ "description": "Copyparty is a lightweight, portable HTTP file server with a browser-based interface. It supports drag-and-drop uploads, downloads, deduplication, media playback, and advanced search, making it ideal for quickly sharing and managing files.",
"install_methods": [
{
"type": "default",
diff --git a/tools/addon/copyparty.sh b/tools/addon/copyparty.sh
index 79bd509f..c7bbd32d 100644
--- a/tools/addon/copyparty.sh
+++ b/tools/addon/copyparty.sh
@@ -64,7 +64,8 @@ function setup_user_and_dirs() {
if [[ "$OS" == "Debian" ]]; then
useradd -r -s /sbin/nologin -d "$DATA_PATH" "$SVC_USER"
else
- adduser -D -H -h "$DATA_PATH" -s /sbin/nologin "$SVC_USER"
+ addgroup -S "$SVC_GROUP" 2>/dev/null || true
+ adduser -S -D -H -G "$SVC_GROUP" -h "$DATA_PATH" -s /sbin/nologin "$SVC_USER" 2>/dev/null || true
fi
fi
mkdir -p "$DATA_PATH" "$LOG_PATH"
@@ -190,42 +191,28 @@ msg_ok "Config written"
# --- Systemd/OpenRC Service ---
msg_info "Creating service"
if [[ "$OS" == "Debian" ]]; then
- cat <"$SERVICE_PATH_DEB"
-[Unit]
-Description=CopyParty file server
-
-[Service]
-Type=simple
-User=$SVC_USER
-Group=$SVC_GROUP
-WorkingDirectory=$USER_DATA_PATH
-Environment=PYTHONUNBUFFERED=x
-LogsDirectory=copyparty
-ExecStart=/usr/bin/python3 $BIN_PATH -c $CONF_PATH
-Restart=always
-
-[Install]
-WantedBy=multi-user.target
-EOF
- systemctl daemon-reload
- systemctl enable --now copyparty &>/dev/null
-else
- cat <"$SERVICE_PATH_ALP"
+ cat <<'EOF' >"$SERVICE_PATH_ALP"
#!/sbin/openrc-run
-command="/usr/bin/python3"
-command_args="$BIN_PATH -c $CONF_PATH"
+name="copyparty"
+description="Copyparty file server"
+
+command="$(command -v python3)"
+command_args="/usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf"
command_background=true
-directory="$USER_DATA_PATH"
-pidfile="$USER_DATA_PATH/copyparty.pid"
+directory="/var/lib/copyparty"
+pidfile="/run/copyparty.pid"
+output_log="/var/log/copyparty/copyparty.log"
+error_log="/var/log/copyparty/copyparty.err"
depend() {
need net
}
EOF
+
chmod +x "$SERVICE_PATH_ALP"
rc-update add copyparty default &>/dev/null
- rc-service copyparty start &>/dev/null
+ rc-service copyparty restart &>/dev/null
fi
msg_ok "Service created and started"
From aa413772cd165c2bbfe06b4eafad3a1dc8a4bb76 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 12:01:46 +0200
Subject: [PATCH 058/312] add source
---
tools/addon/copyparty.sh | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/tools/addon/copyparty.sh b/tools/addon/copyparty.sh
index c7bbd32d..78041b97 100644
--- a/tools/addon/copyparty.sh
+++ b/tools/addon/copyparty.sh
@@ -3,6 +3,7 @@
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/9001/copyparty
function header_info() {
clear
@@ -37,7 +38,6 @@ SVC_GROUP="copyparty"
SRC_URL="https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py"
DEFAULT_PORT=3923
-# OS Detection
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
PKG_MANAGER="apk add --no-cache"
@@ -57,7 +57,6 @@ function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
-# User/Group/Dirs
function setup_user_and_dirs() {
msg_info "Creating $SVC_USER user and directories"
if ! id "$SVC_USER" &>/dev/null; then
@@ -97,7 +96,6 @@ function update_copyparty() {
exit 0
}
-# --- Existing Install/Update/Uninstall Check ---
if [[ -f "$BIN_PATH" ]]; then
echo -e "${YW}⚠️ $APP is already installed.${CL}"
echo -n "Uninstall $APP? (y/N): "
@@ -116,7 +114,6 @@ if [[ -f "$BIN_PATH" ]]; then
fi
fi
-# --- Deps ---
msg_info "Installing dependencies"
if [[ "$OS" == "Debian" ]]; then
$PKG_MANAGER python3 curl &>/dev/null
@@ -125,17 +122,14 @@ else
fi
msg_ok "Dependencies installed"
-# --- User/Dirs ---
setup_user_and_dirs
-# --- Download Binary ---
msg_info "Downloading $APP"
curl -fsSL "$SRC_URL" -o "$BIN_PATH"
chmod +x "$BIN_PATH"
chown "$SVC_USER:$SVC_GROUP" "$BIN_PATH"
msg_ok "Downloaded to $BIN_PATH"
-# --- Config: Interaktiv, Auth, Rootdir, Port ---
echo -n "Enter port for $APP (default: $DEFAULT_PORT): "
read -r PORT
PORT=${PORT:-$DEFAULT_PORT}
@@ -163,7 +157,6 @@ else
msg_ok "Configured with admin user: $ADMIN_USER"
fi
-# --- Generate /etc/copyparty.conf ---
msg_info "Writing config to $CONF_PATH"
cat </etc/copyparty.conf
[global]
@@ -188,7 +181,6 @@ chmod 640 "$CONF_PATH"
chown "$SVC_USER:$SVC_GROUP" "$CONF_PATH"
msg_ok "Config written"
-# --- Systemd/OpenRC Service ---
msg_info "Creating service"
if [[ "$OS" == "Debian" ]]; then
cat <<'EOF' >"$SERVICE_PATH_ALP"
@@ -216,7 +208,6 @@ EOF
fi
msg_ok "Service created and started"
-# IP detection (as root, maybe interface up/loopback fallback)
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
From 510829520d7b37aa7958bc4b0e240bd58ef95454 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 12:05:29 +0200
Subject: [PATCH 059/312] Update copyparty.sh
---
tools/addon/copyparty.sh | 49 +++++++++++++++++++++++-----------------
1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/tools/addon/copyparty.sh b/tools/addon/copyparty.sh
index 78041b97..897ad753 100644
--- a/tools/addon/copyparty.sh
+++ b/tools/addon/copyparty.sh
@@ -158,31 +158,38 @@ else
fi
msg_info "Writing config to $CONF_PATH"
-cat </etc/copyparty.conf
-[global]
- p: $PORT
- ansi
- e2dsa
- e2ts
- theme: 2
- grid
-
-[accounts]
- $ADMIN_USER: $ADMIN_PASS
-
-[/]
- $USER_DATA_PATH
- accs:
- rw: *
- rwmda: $ADMIN_USER
-EOF
+msg_info "Writing config to $CONF_PATH"
+{
+ echo "[global]"
+ echo " p: $PORT"
+ echo " ansi"
+ echo " e2dsa"
+ echo " e2ts"
+ echo " theme: 2"
+ echo " grid"
+ echo
+ if [[ -n "$ADMIN_USER" && -n "$ADMIN_PASS" ]]; then
+ echo "[accounts]"
+ echo " $ADMIN_USER: $ADMIN_PASS"
+ echo
+ fi
+ echo "[/]"
+ echo " $USER_DATA_PATH"
+ echo " accs:"
+ if [[ -n "$ADMIN_USER" ]]; then
+ echo " rw: *"
+ echo " rwmda: $ADMIN_USER"
+ else
+ echo " rw: *"
+ fi
+} >"$CONF_PATH"
chmod 640 "$CONF_PATH"
chown "$SVC_USER:$SVC_GROUP" "$CONF_PATH"
msg_ok "Config written"
msg_info "Creating service"
-if [[ "$OS" == "Debian" ]]; then
+if [[ "$OS" == "Alpine" ]]; then
cat <<'EOF' >"$SERVICE_PATH_ALP"
#!/sbin/openrc-run
@@ -203,8 +210,8 @@ depend() {
EOF
chmod +x "$SERVICE_PATH_ALP"
- rc-update add copyparty default &>/dev/null
- rc-service copyparty restart &>/dev/null
+ rc-update add copyparty default >/dev/null 2>&1
+ rc-service copyparty restart >/dev/null 2>&1
fi
msg_ok "Service created and started"
From 54934da806433ca89f80d595a23875acf91dfbea Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 12:06:14 +0200
Subject: [PATCH 060/312] Update copyparty.sh
---
tools/addon/copyparty.sh | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/tools/addon/copyparty.sh b/tools/addon/copyparty.sh
index 897ad753..98f7ad72 100644
--- a/tools/addon/copyparty.sh
+++ b/tools/addon/copyparty.sh
@@ -189,7 +189,28 @@ chown "$SVC_USER:$SVC_GROUP" "$CONF_PATH"
msg_ok "Config written"
msg_info "Creating service"
-if [[ "$OS" == "Alpine" ]]; then
+if [[ "$OS" == "Debian" ]]; then
+ cat <"$SERVICE_PATH_DEB"
+[Unit]
+Description=Copyparty file server
+After=network.target
+
+[Service]
+User=$SVC_USER
+Group=$SVC_GROUP
+WorkingDirectory=$DATA_PATH
+ExecStart=/usr/bin/python3 /usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf
+Restart=always
+StandardOutput=append:/var/log/copyparty/copyparty.log
+StandardError=append:/var/log/copyparty/copyparty.err
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+ systemctl enable -q --now copyparty
+
+elif [[ "$OS" == "Alpine" ]]; then
cat <<'EOF' >"$SERVICE_PATH_ALP"
#!/sbin/openrc-run
From 89e7dd5e519c9cf28505ef898e77800cd3e82e76 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 12:06:50 +0200
Subject: [PATCH 061/312] add gcc
---
install/ente-install.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/install/ente-install.sh b/install/ente-install.sh
index 72cdf927..d24342bf 100644
--- a/install/ente-install.sh
+++ b/install/ente-install.sh
@@ -15,7 +15,11 @@ update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
- libsodium23 libsodium-dev pkg-config caddy
+ libsodium23 \
+ libsodium-dev \
+ pkg-config \
+ caddy \
+ gcc
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
From 7624e540e4c2a11e396602c895e6e7b5f2a67a95 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 13:33:14 +0200
Subject: [PATCH 062/312] Update ente-install.sh
---
install/ente-install.sh | 65 +++++++++++++++++++++++++++++++----------
1 file changed, 49 insertions(+), 16 deletions(-)
diff --git a/install/ente-install.sh b/install/ente-install.sh
index d24342bf..b6527758 100644
--- a/install/ente-install.sh
+++ b/install/ente-install.sh
@@ -60,30 +60,46 @@ fi
export CGO_CFLAGS
export CGO_LDFLAGS
$STD go build cmd/museum/main.go
-cp config/example.yaml museum.yaml
msg_ok "Built Museum"
msg_info "Generating Secrets"
-$STD go run tools/gen-random-keys/main.go >secrets.txt
+SECRET_ENC=$($STD go run tools/gen-random-keys/main.go | grep "encryption" | awk '{print $2}')
+SECRET_HASH=$($STD go run tools/gen-random-keys/main.go | grep "hash" | awk '{print $2}')
+SECRET_JWT=$($STD go run tools/gen-random-keys/main.go | grep "jwt" | awk '{print $2}')
msg_ok "Generated Secrets"
-msg_info "Creating Museum Service"
-cat </etc/systemd/system/ente-museum.service
-[Unit]
-Description=Ente Museum Server
-After=network.target postgresql.service
+msg_info "Creating museum.yaml"
+cat </opt/ente/server/museum.yaml
+db:
+ host: 127.0.0.1
+ port: 5432
+ name: $DB_NAME
+ user: $DB_USER
+ password: $DB_PASS
-[Service]
-WorkingDirectory=/opt/ente/server
-ExecStart=/opt/ente/server/main
-Restart=always
-Environment="DATABASE_URL=postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME"
+s3:
+ are_local_buckets: true
+ use_path_style_urls: true
+ local-dev:
+ key: dummy
+ secret: dummy
+ endpoint: localhost:3200
+ region: eu-central-2
+ bucket: ente-dev
-[Install]
-WantedBy=multi-user.target
+apps:
+ public-albums: http://localhost:3002
+ cast: http://localhost:3004
+ accounts: http://localhost:3001
+
+key:
+ encryption: $SECRET_ENC
+ hash: $SECRET_HASH
+
+jwt:
+ secret: $SECRET_JWT
EOF
-systemctl enable -q --now ente-museum
-msg_ok "Created Museum Service"
+msg_ok "Created museum.yaml"
msg_info "Building Web Applications"
cd /opt/ente/web
@@ -101,6 +117,23 @@ cp -r apps/auth/out /var/www/ente/apps/auth
cp -r apps/cast/out /var/www/ente/apps/cast
msg_ok "Built Web Applications"
+msg_info "Creating Museum Service"
+cat </etc/systemd/system/ente-museum.service
+[Unit]
+Description=Ente Museum Server
+After=network.target postgresql.service
+
+[Service]
+WorkingDirectory=/opt/ente/server
+ExecStart=/opt/ente/server/main -config /opt/ente/server/museum.yaml
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now ente-museum
+msg_ok "Created Museum Service"
+
msg_info "Configuring Caddy"
cat </etc/caddy/Caddyfile
:3000 {
From b2f6b12ccf0bc954b34a1f2896095442f41520da Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 14:33:26 +0200
Subject: [PATCH 063/312] Update litellm.sh
---
ct/litellm.sh | 54 +++++++++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/ct/litellm.sh b/ct/litellm.sh
index 847b7d8b..8d2b7f73 100644
--- a/ct/litellm.sh
+++ b/ct/litellm.sh
@@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/BerriAI/litellm
-APP="litellm"
+APP="LiteLLM"
var_tags="${var_tags:-ai;interface}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
@@ -20,34 +20,34 @@ color
catch_errors
function update_script() {
- header_info
- check_container_storage
- check_container_resources
+ header_info
+ check_container_storage
+ check_container_resources
- if [[ ! -f /etc/systemd/system/litellm.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- msg_info "Stopping ${APP}"
- systemctl stop litellm.service
- msg_ok "Stopped ${APP}"
-
- VENV_PATH="/opt/litellm/.venv"
- PYTHON_VERSION="3.13" setup_uv
-
- msg_info "Updating $APP"
- $STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
-
- msg_info "Updating DB Schema"
- uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
- msg_ok "DB Schema Updated"
-
- msg_info "Starting ${APP}"
- systemctl start litellm.service
- msg_ok "Started ${APP}"
- msg_ok "Updated Successfully"
+ if [[ ! -f /etc/systemd/system/litellm.service ]]; then
+ msg_error "No ${APP} Installation Found!"
exit
+ fi
+
+ msg_info "Stopping ${APP}"
+ systemctl stop litellm
+ msg_ok "Stopped ${APP}"
+
+ VENV_PATH="/opt/litellm/.venv"
+ PYTHON_VERSION="3.13" setup_uv
+
+ msg_info "Updating $APP"
+ $STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
+
+ msg_info "Updating DB Schema"
+ $STD uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
+ msg_ok "DB Schema Updated"
+
+ msg_info "Starting ${APP}"
+ systemctl start litellm
+ msg_ok "Started ${APP}"
+ msg_ok "Updated Successfully"
+ exit
}
start
From 8946dd0c99a60769dc57b8f7cfac2b07a84ee3d2 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 14:39:16 +0200
Subject: [PATCH 064/312] Update frigate-install.sh
---
install/frigate-install.sh | 225 ++++++++++++++++++++++++-------------
1 file changed, 148 insertions(+), 77 deletions(-)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 3d5be25a..08a19b76 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -14,7 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y {git,ffmpeg,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbbmalloc2,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
+$STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
@@ -36,23 +36,32 @@ fetch_and_deploy_gh_release "libusb" "libusb/libusb" "tarball" "v1.0.29" "/opt/f
# fi
# msg_ok "Set Up Hardware Acceleration"
-msg_info "Setting up Python venv"
+msg_info "Setting up Python"
cd /opt/frigate
-python3 -m venv venv
-source venv/bin/activate
-$STD pip install --upgrade pip wheel --break-system-packages
-$STD pip install -r docker/main/requirements.txt --break-system-packages
-$STD pip install -r docker/main/requirements-wheels.txt --break-system-packages
-$STD pip install -r docker/main/requirements-ov.txt --break-system-packages
+$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt
+cp -a /opt/frigate/docker/main/rootfs/. /
+export TARGETARCH="amd64"
+echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections
+$STD apt update
+$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg
+$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
+$STD pip3 install -U /wheels/*.whl
+ldconfig
+$STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt
+$STD /opt/frigate/.devcontainer/initialize.sh
+$STD make version
msg_ok "Python venv ready"
msg_info "Building Web UI"
cd /opt/frigate/web
$STD npm ci
$STD npm run build
+cp -r /opt/frigate/web/dist/* /opt/frigate/web/
+cp -r /opt/frigate/config/. /config
msg_ok "Web UI built"
msg_info "Writing default config"
+sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
mkdir -p /opt/frigate/config
cat </opt/frigate/config/config.yml
mqtt:
@@ -72,16 +81,54 @@ cameras:
fps: 5
EOF
mkdir -p /config
-ln -sf /opt/frigate/config/config.yml /config/config.yml
+ln -sf /config/config.yml /opt/frigate/config/config.yml
+if [[ "$CTTYPE" == "0" ]]; then
+ sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group
+else
+ sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group
+fi
+echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
mkdir -p /media/frigate
wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4
cat <<'EOF' >/opt/frigate/frigate/version.py
VERSION = "0.16.0"
EOF
-ln -sf /usr/lib/ffmpeg/7.0/bin/ffmpeg /usr/bin/ffmpeg
-ln -sf /usr/lib/ffmpeg/7.0/bin/ffprobe /usr/bin/ffprobe
msg_ok "Config ready"
+if grep -q -o -m1 -E 'avx[^ ]*' /proc/cpuinfo; then
+ msg_ok "AVX Support Detected"
+ msg_info "Installing Openvino Object Detection Model (Resilience)"
+ $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt
+ cd /opt/frigate/models
+ export ENABLE_ANALYTICS=NO
+ $STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2
+ $STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo
+ cd /
+ cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model
+ curl -fsSL "https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt" -o "openvino-model/coco_91cl_bkgr.txt"
+ sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt
+ cat <>/config/config.yml
+detectors:
+ ov:
+ type: openvino
+ device: CPU
+ model:
+ path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml
+model:
+ width: 300
+ height: 300
+ input_tensor: nhwc
+ input_pixel_format: bgr
+ labelmap_path: /openvino-model/coco_91cl_bkgr.txt
+EOF
+ msg_ok "Installed Openvino Object Detection Model"
+else
+ cat <>/config/config.yml
+model:
+ path: /cpu_model.tflite
+EOF
+fi
+
msg_info "Building and Installing libUSB without udev"
wget -qO /tmp/libusb.zip https://github.com/libusb/libusb/archive/v1.0.29.zip
unzip -q /tmp/libusb.zip -d /tmp/
@@ -94,24 +141,35 @@ ldconfig
rm -rf /tmp/libusb.zip /tmp/libusb-1.0.29
msg_ok "Installed libUSB without udev"
-# Coral Object Detection Models
-msg_info "Installing Coral Object Detection Models"
+msg_info "Installing Coral Object Detection Model (Patience)"
cd /opt/frigate
export CCACHE_DIR=/root/.ccache
export CCACHE_MAXSIZE=2G
-
-# edgetpu / cpu Modelle
-wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite
-wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite
+curl -fsSL "https://github.com/libusb/libusb/archive/v1.0.26.zip" -o "v1.0.26.zip"
+$STD unzip v1.0.26.zip
+rm v1.0.26.zip
+cd libusb-1.0.26
+$STD ./bootstrap.sh
+$STD ./configure --disable-udev --enable-shared
+$STD make -j $(nproc --all)
+cd /opt/frigate/libusb-1.0.26/libusb
+mkdir -p /usr/local/lib
+$STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib'
+mkdir -p /usr/local/include/libusb-1.0
+$STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'
+ldconfig
+cd /
+curl -fsSL "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite" -o "edgetpu_model.tflite"
+curl -fsSL "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite" -o "cpu_model.tflite"
cp /opt/frigate/labelmap.txt /labelmap.txt
-
-# Audio-Modelle
-wget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download
+curl -fsSL "https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download" -o "yamnet-tflite-classification-tflite-v1.tar.gz"
tar xzf yamnet-tflite-classification-tflite-v1.tar.gz
rm -rf yamnet-tflite-classification-tflite-v1.tar.gz
mv 1.tflite cpu_audio_model.tflite
cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt
-msg_ok "Installed Coral Object Detection Models"
+mkdir -p /media/frigate
+curl -fsSL "https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4" -o "/media/frigate/person-bicycle-car-detection.mp4"
+msg_ok "Installed Coral Object Detection Model"
# ------------------------------------------------------------
# Tempio installieren
@@ -121,7 +179,7 @@ export TARGETARCH="amd64"
export DEBIAN_FRONTEND=noninteractive
echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
echo "libedgetpu1-max libedgetpu/install-confirm-max select true" | debconf-set-selections
-/opt/frigate/docker/main/install_tempio.sh
+$STD /opt/frigate/docker/main/install_tempio.sh
chmod +x /usr/local/tempio/bin/tempio
ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
msg_ok "Installed Tempio"
@@ -133,82 +191,95 @@ cp /opt/frigate/audio-labelmap.txt /
cp /opt/frigate/labelmap.txt /
msg_ok "Copied model files"
-# ------------------------------------------------------------
-# systemd Units
-msg_info "Creating systemd service for go2rtc"
-cat </etc/systemd/system/go2rtc.service
+msg_info "Building Nginx with Custom Modules"
+sed -i 's/if \[\[ "$VERSION_ID" == "12" \]\]; then/if [[ -f \/etc\/apt\/sources.list.d\/debian.sources ]]; then/' /opt/frigate/docker/main/build_nginx.sh
+$STD /opt/frigate/docker/main/build_nginx.sh
+sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
+ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
+msg_ok "Built Nginx"
+
+msg_info "Creating Services"
+cat </etc/systemd/system/create_directories.service
[Unit]
-Description=go2rtc
-After=network.target
+Description=Create necessary directories for logs
[Service]
-ExecStart=/usr/local/bin/go2rtc
+Type=oneshot
+ExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs'
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now create_directories
+sleep 3
+cat </etc/systemd/system/go2rtc.service
+[Unit]
+Description=go2rtc service
+After=network.target
+After=create_directories.service
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
Restart=always
-RestartSec=2
+RestartSec=1
User=root
-StandardOutput=journal
-StandardError=journal
+Environment=DEFAULT_FFMPEG_VERSION=7.0
+Environment=INCLUDED_FFMPEG_VERSIONS=5.0
+ExecStartPre=+rm /dev/shm/logs/go2rtc/current
+ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
+StandardOutput=file:/dev/shm/logs/go2rtc/current
+StandardError=file:/dev/shm/logs/go2rtc/current
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now go2rtc
-msg_ok "go2rtc service enabled"
-
-msg_info "Creating systemd service for Frigate"
+sleep 3
cat </etc/systemd/system/frigate.service
[Unit]
Description=Frigate service
-After=go2rtc.service network.target
+After=go2rtc.service
+After=create_directories.service
+StartLimitIntervalSec=0
[Service]
-WorkingDirectory=/opt/frigate
-Environment="PATH=/opt/frigate/venv/bin"
-Environment="PYTHONPATH=/opt/frigate"
-ExecStartPre=/bin/mkdir -p /media/frigate/recordings /media/frigate/clips /media/frigate/snapshots
-ExecStart=/opt/frigate/venv/bin/python3 -u -m frigate
+Type=simple
Restart=always
-RestartSec=5
+RestartSec=1
User=root
-StandardOutput=journal
-StandardError=journal
+# Environment=PLUS_API_KEY=
+Environment=DEFAULT_FFMPEG_VERSION=7.0
+Environment=INCLUDED_FFMPEG_VERSIONS=5.0
+ExecStartPre=+rm /dev/shm/logs/frigate/current
+ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
+StandardOutput=file:/dev/shm/logs/frigate/current
+StandardError=file:/dev/shm/logs/frigate/current
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now frigate
-msg_ok "Frigate service enabled"
+sleep 3
+cat </etc/systemd/system/nginx.service
+[Unit]
+Description=Nginx service
+After=frigate.service
+After=create_directories.service
+StartLimitIntervalSec=0
-msg_info "Setting environmental variables"
-cat <>/root/.bashrc
-export TERM='xterm-256color'
-export DEFAULT_FFMPEG_VERSION='7.0'
-export NVIDIA_VISIBLE_DEVICES='all'
-export ENV NVIDIA_DRIVER_CAPABILITIES='compute,video,utility'
-export PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
-export TOKENIZERS_PARALLELISM=true
-export TRANSFORMERS_NO_ADVISORY_WARNINGS=1
-export OPENCV_FFMPEG_LOGLEVEL=8
-export HAILORT_LOGGER_PATH=NONE
-export INCLUDED_FFMPEG_VERSIONS="7.0:5.0"
-export S6_LOGGING_SCRIPT="T 1 n0 s10000000 T"
-export S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0
-export CCACHE_DIR=/root/.ccache
-export CCACHE_MAXSIZE=2G
+[Service]
+Type=simple
+Restart=always
+RestartSec=1
+User=root
+ExecStartPre=+rm /dev/shm/logs/nginx/current
+ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
+StandardOutput=file:/dev/shm/logs/nginx/current
+StandardError=file:/dev/shm/logs/nginx/current
+
+[Install]
+WantedBy=multi-user.target
EOF
-msg_ok "Environment set"
-
-msg_info "Building Nginx with Custom Modules"
-sed -i 's/if \[\[ "\$VERSION_ID" == "12" \]\]; then/if \[\[ "\$VERSION_ID" == "13" \]\]; then/' /opt/frigate/docker/main/build_nginx.sh
-$STD bash /opt/frigate/docker/main/build_nginx.sh
-sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
-ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
-msg_ok "Built Nginx"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
+systemctl enable -q --now nginx
+msg_ok "Configured Services"
From 8fed150591b1bcfc19f88ddd56cc113726f59d01 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 14:51:51 +0200
Subject: [PATCH 065/312] Update frigate-install.sh
---
install/frigate-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 08a19b76..76f65c88 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -38,6 +38,7 @@ fetch_and_deploy_gh_release "libusb" "libusb/libusb" "tarball" "v1.0.29" "/opt/f
msg_info "Setting up Python"
cd /opt/frigate
+mkdir -p /opt/frigate/models
$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt
cp -a /opt/frigate/docker/main/rootfs/. /
export TARGETARCH="amd64"
From 26155629630ecf873ca7f4708c9ee756d71ab9f0 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:06:07 +0200
Subject: [PATCH 066/312] refactor: paperless
---
ct/paperless-ngx.sh | 96 +++++++++++++++
install/paperless-ngx-install.sh | 199 +++++++++++++++++++++++++++++++
2 files changed, 295 insertions(+)
create mode 100644 ct/paperless-ngx.sh
create mode 100644 install/paperless-ngx-install.sh
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
new file mode 100644
index 00000000..d3904274
--- /dev/null
+++ b/ct/paperless-ngx.sh
@@ -0,0 +1,96 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://docs.paperless-ngx.com/
+
+APP="Paperless-ngx"
+var_tags="${var_tags:-document;management}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-10}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ if [[ ! -d /opt/paperless ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+
+ UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \
+ "1" "Update Paperless-ngx to $RELEASE" ON \
+ "2" "Paperless-ngx Credentials" OFF \
+ 3>&1 1>&2 2>&3)
+ header_info
+ check_container_storage
+ check_container_resources
+ if [ "$UPD" == "1" ]; then
+ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ if [[ "$(gs --version 2>/dev/null)" != "10.04.0" ]]; then
+ msg_info "Updating Ghostscript (Patience)"
+ cd /tmp
+ curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz" -o $(basename "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz")
+ tar -xzf ghostscript-10.04.0.tar.gz
+ cd ghostscript-10.04.0
+ $STD ./configure
+ $STD make
+ $STD sudo make install
+ rm -rf /tmp/ghostscript*
+ msg_ok "Ghostscript updated to 10.04.0"
+ fi
+ msg_info "Stopping all Paperless-ngx Services"
+ systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ msg_ok "Stopped all Paperless-ngx Services"
+
+ msg_info "Updating to ${RELEASE}"
+ cd ~
+ curl -fsSL "https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz" -o $(basename "https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz")
+ tar -xf paperless-ngx-$RELEASE.tar.xz
+ cp -r /opt/paperless/paperless.conf paperless-ngx/
+ cp -r paperless-ngx/* /opt/paperless/
+ cd /opt/paperless
+ $STD pip install -r requirements.txt
+ cd /opt/paperless/src
+ $STD /usr/bin/python3 manage.py migrate
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Updated to ${RELEASE}"
+
+ msg_info "Cleaning up"
+ cd ~
+ rm paperless-ngx-$RELEASE.tar.xz
+ rm -rf paperless-ngx
+ msg_ok "Cleaned"
+
+ msg_info "Starting all Paperless-ngx Services"
+ systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ sleep 1
+ msg_ok "Started all Paperless-ngx Services"
+ msg_ok "Updated Successfully!\n"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ fi
+ exit
+ fi
+ if [ "$UPD" == "2" ]; then
+ cat paperless.creds
+ exit
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh
new file mode 100644
index 00000000..c8e89c4a
--- /dev/null
+++ b/install/paperless-ngx-install.sh
@@ -0,0 +1,199 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://docs.paperless-ngx.com/
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies (Patience)"
+$STD apt-get install -y \
+ redis \
+ build-essential \
+ imagemagick \
+ fonts-liberation \
+ optipng \
+ libpq-dev \
+ libmagic-dev \
+ mime-support \
+ libzbar0 \
+ poppler-utils \
+ default-libmysqlclient-dev \
+ automake \
+ libtool \
+ pkg-config \
+ libtiff-dev \
+ libpng-dev \
+ libleptonica-dev
+msg_ok "Installed Dependencies"
+
+PG_VERSION="16" setup_postgresql
+PYTHON_VERSION="3.13" setup_uv
+fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
+fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
+setup_gs
+
+msg_info "Installing OCR Dependencies (Patience)"
+$STD apt-get install -y \
+ unpaper \
+ icc-profiles-free \
+ qpdf \
+ liblept5 \
+ libxml2 \
+ pngquant \
+ zlib1g \
+ tesseract-ocr \
+ tesseract-ocr-eng
+$STD sudo make install
+msg_ok "Installed OCR Dependencies"
+
+msg_info "Setup JBIG2"
+cd /opt/jbig2enc
+$STD bash ./autogen.sh
+$STD bash ./configure
+$STD make
+$STD make install
+rm -rf /opt/jbig2enc
+msg_ok "Installed JBIG2"
+
+msg_info "Setting up PostgreSQL database"
+DB_NAME=paperlessdb
+DB_USER=paperless
+DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
+SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
+echo "" >>~/paperless.creds
+echo -e "Paperless-ngx Database User: \e[32m$DB_USER\e[0m" >>~/paperless.creds
+echo -e "Paperless-ngx Database Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds
+echo -e "Paperless-ngx Database Name: \e[32m$DB_NAME\e[0m" >>~/paperless.creds
+
+msg_info "Installing Natural Language Toolkit (Patience)"
+$STD uv run -- python -m nltk.downloader -d /usr/share/nltk_data all
+sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml
+msg_ok "Installed Natural Language Toolkit"
+
+msg_info "Setup Paperless-ngx"
+cd /opt/paperless
+$STD uv sync --all-extras
+curl -fsSL "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example" -o /opt/paperless/paperless.conf
+mkdir -p {consume,data,media,static}
+sed -i \
+ -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' \
+ -e "s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/opt/paperless/consume|" \
+ -e "s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless/data|" \
+ -e "s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless/media|" \
+ -e "s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|" \
+ -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' \
+ -e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' \
+ -e "s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$DB_NAME|" \
+ -e "s|#PAPERLESS_DBUSER=paperless|PAPERLESS_DBUSER=$DB_USER|" \
+ -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" \
+ -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" \
+ /opt/paperless/paperless.conf
+cd /opt/paperless/src
+$STD uv run -- python manage.py migrate
+msg_ok "Setup Paperless-ngx"
+
+msg_info "Setting up admin Paperless-ngx User & Password"
+cat <>~/paperless.creds
+echo -e "Paperless-ngx WebUI User: \e[32madmin\e[0m" >>~/paperless.creds
+echo -e "Paperless-ngx WebUI Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds
+echo "" >>~/paperless.creds
+msg_ok "Set up admin Paperless-ngx User & Password"
+
+msg_info "Creating Services"
+cat </etc/systemd/system/paperless-scheduler.service
+[Unit]
+Description=Paperless Celery beat
+Requires=redis.service
+
+[Service]
+WorkingDirectory=/opt/paperless/src
+ExecStart=uv run -- celery --app paperless beat --loglevel INFO
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/paperless-task-queue.service
+[Unit]
+Description=Paperless Celery Workers
+Requires=redis.service
+After=postgresql.service
+
+[Service]
+WorkingDirectory=/opt/paperless/src
+ExecStart=uv run -- celery --app paperless worker --loglevel INFO
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/paperless-consumer.service
+[Unit]
+Description=Paperless consumer
+Requires=redis.service
+
+[Service]
+WorkingDirectory=/opt/paperless/src
+ExecStartPre=/bin/sleep 2
+ExecStart=uv run -- python manage.py document_consumer
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/paperless-webserver.service
+[Unit]
+Description=Paperless webserver
+After=network.target
+Wants=network.target
+Requires=redis.service
+
+[Service]
+WorkingDirectory=/opt/paperless/src
+ExecStart=uv run -- granian --interface asginl --ws "paperless.asgi:application"
+Environment=GRANIAN_HOST=::
+Environment=GRANIAN_PORT=8000
+Environment=GRANIAN_WORKERS=1
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now paperless-webserver paperless-scheduler paperless-task-queue paperless-consumer
+msg_ok "Created Services"
+
+read -r -p "${TAB3}Would you like to add Adminer? " prompt
+if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
+ setup_adminer
+fi
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -rf /opt/paperless/docker
+rm -rf /tmp/ghostscript*
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 596da1450e833103279a2687ec161cdd09c90561 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:08:02 +0200
Subject: [PATCH 067/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index d3904274..201bb9d1 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
From 9077f611021600045cccdc1bcaec65c2ef43b9e9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:17:05 +0200
Subject: [PATCH 068/312] refd
---
ct/paperless-ngx.sh | 93 +++++++++++++++++---------------------
install/frigate-install.sh | 12 ++---
2 files changed, 48 insertions(+), 57 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 201bb9d1..0d51673d 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -20,70 +20,61 @@ color
catch_errors
function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
if [[ ! -d /opt/paperless ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
- RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+ RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | jq -r .tag_name | sed 's/^v//')
+ if [[ "${RELEASE}" != "$(cat ~/.paperless 2>/dev/null)" ]] || [[ ! -f ~/.paperless ]]; then
+ PYTHON_VERSION="3.13" setup_uv
+ fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
+ fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
+ setup_gs
- UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \
- "1" "Update Paperless-ngx to $RELEASE" ON \
- "2" "Paperless-ngx Credentials" OFF \
- 3>&1 1>&2 2>&3)
- header_info
- check_container_storage
- check_container_resources
- if [ "$UPD" == "1" ]; then
- if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
- if [[ "$(gs --version 2>/dev/null)" != "10.04.0" ]]; then
- msg_info "Updating Ghostscript (Patience)"
- cd /tmp
- curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz" -o $(basename "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs10040/ghostscript-10.04.0.tar.gz")
- tar -xzf ghostscript-10.04.0.tar.gz
- cd ghostscript-10.04.0
- $STD ./configure
- $STD make
- $STD sudo make install
- rm -rf /tmp/ghostscript*
- msg_ok "Ghostscript updated to 10.04.0"
- fi
- msg_info "Stopping all Paperless-ngx Services"
- systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
- msg_ok "Stopped all Paperless-ngx Services"
+ msg_info "Stopping all Paperless-ngx Services"
+ systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ msg_ok "Stopped all Paperless-ngx Services"
+ if grep -q "uv run" /etc/systemd/system/paperless-webserver.service; then
msg_info "Updating to ${RELEASE}"
- cd ~
- curl -fsSL "https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz" -o $(basename "https://github.com/paperless-ngx/paperless-ngx/releases/download/$RELEASE/paperless-ngx-$RELEASE.tar.xz")
- tar -xf paperless-ngx-$RELEASE.tar.xz
- cp -r /opt/paperless/paperless.conf paperless-ngx/
- cp -r paperless-ngx/* /opt/paperless/
cd /opt/paperless
- $STD pip install -r requirements.txt
+ $STD uv sync --all-extras
cd /opt/paperless/src
- $STD /usr/bin/python3 manage.py migrate
- echo "${RELEASE}" >/opt/${APP}_version.txt
+ $STD uv run -- python manage.py migrate
msg_ok "Updated to ${RELEASE}"
-
- msg_info "Cleaning up"
- cd ~
- rm paperless-ngx-$RELEASE.tar.xz
- rm -rf paperless-ngx
- msg_ok "Cleaned"
-
- msg_info "Starting all Paperless-ngx Services"
- systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
- sleep 1
- msg_ok "Started all Paperless-ngx Services"
- msg_ok "Updated Successfully!\n"
else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ msg_info "Migrating old Paperless-ngx installation to uv"
+ rm -rf /opt/paperless/venv
+ find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
+ sed -i 's|ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer|' /etc/systemd/system/paperless-consumer.service
+ sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-scheduler.service
+ sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-task-queue.service
+ sed -i 's|ExecStart=granian|ExecStart=uv run -- granian|' /etc/systemd/system/paperless-webserver.service
+ $STD systemctl daemon-reexec
+ $STD systemctl daemon-reload
+ cd /opt/paperless
+ $STD uv sync --all-extras
+ cd /opt/paperless/src
+ $STD uv run -- python manage.py migrate
+ msg_ok "Paperless-ngx migration and update to ${RELEASE} completed"
fi
- exit
- fi
- if [ "$UPD" == "2" ]; then
- cat paperless.creds
- exit
+
+ msg_info "Cleaning up"
+ cd ~
+ msg_ok "Cleaned"
+
+ msg_info "Starting all Paperless-ngx Services"
+ systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ sleep 1
+ msg_ok "Started all Paperless-ngx Services"
+ msg_ok "Updated Successfully!\n"
+ else
+ msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi
+ exit
}
start
diff --git a/install/frigate-install.sh b/install/frigate-install.sh
index 76f65c88..cbd8357c 100644
--- a/install/frigate-install.sh
+++ b/install/frigate-install.sh
@@ -185,12 +185,12 @@ chmod +x /usr/local/tempio/bin/tempio
ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
msg_ok "Installed Tempio"
-msg_info "Copying model files"
-cp /opt/frigate/cpu_model.tflite /
-cp /opt/frigate/edgetpu_model.tflite /
-cp /opt/frigate/audio-labelmap.txt /
-cp /opt/frigate/labelmap.txt /
-msg_ok "Copied model files"
+# msg_info "Copying model files"
+# cp /opt/frigate/cpu_model.tflite /
+# cp /opt/frigate/edgetpu_model.tflite /
+# cp /opt/frigate/audio-labelmap.txt /
+# cp /opt/frigate/labelmap.txt /
+# msg_ok "Copied model files"
msg_info "Building Nginx with Custom Modules"
sed -i 's/if \[\[ "$VERSION_ID" == "12" \]\]; then/if [[ -f \/etc\/apt\/sources.list.d\/debian.sources ]]; then/' /opt/frigate/docker/main/build_nginx.sh
From 1d42004d887c954344a18796f3e0855e9a94220f Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Mon, 18 Aug 2025 13:17:28 +0000
Subject: [PATCH 069/312] Update .app files
---
ct/headers/ente | 6 ++++++
ct/headers/litellm | 12 ++++++------
ct/headers/paperless-ngx | 6 ++++++
3 files changed, 18 insertions(+), 6 deletions(-)
create mode 100644 ct/headers/ente
create mode 100644 ct/headers/paperless-ngx
diff --git a/ct/headers/ente b/ct/headers/ente
new file mode 100644
index 00000000..f700a1f5
--- /dev/null
+++ b/ct/headers/ente
@@ -0,0 +1,6 @@
+ ______ __
+ / ____/___ / /____
+ / __/ / __ \/ __/ _ \
+ / /___/ / / / /_/ __/
+/_____/_/ /_/\__/\___/
+
diff --git a/ct/headers/litellm b/ct/headers/litellm
index 0b7dba63..1360a8ff 100644
--- a/ct/headers/litellm
+++ b/ct/headers/litellm
@@ -1,6 +1,6 @@
- ___ __ ____
- / (_) /____ / / /___ ___
- / / / __/ _ \/ / / __ `__ \
- / / / /_/ __/ / / / / / / /
-/_/_/\__/\___/_/_/_/ /_/ /_/
-
+ __ _ __ __ __ __ ___
+ / / (_) /____ / / / / / |/ /
+ / / / / __/ _ \/ / / / / /|_/ /
+ / /___/ / /_/ __/ /___/ /___/ / / /
+/_____/_/\__/\___/_____/_____/_/ /_/
+
diff --git a/ct/headers/paperless-ngx b/ct/headers/paperless-ngx
new file mode 100644
index 00000000..177cf574
--- /dev/null
+++ b/ct/headers/paperless-ngx
@@ -0,0 +1,6 @@
+ ____ __
+ / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __
+ / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/_____/ __ \/ __ `/ |/_/
+ / ____/ /_/ / /_/ / __/ / / / __(__ |__ )_____/ / / / /_/ /> <
+/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_|
+ /_/ /____/
From d9b0104f8841c8b3cdc4018da453fbbdcf8718c3 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:55:43 +0200
Subject: [PATCH 070/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 0d51673d..4ba8a9f0 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -49,10 +49,21 @@ function update_script() {
msg_info "Migrating old Paperless-ngx installation to uv"
rm -rf /opt/paperless/venv
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
- sed -i 's|ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer|' /etc/systemd/system/paperless-consumer.service
- sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-scheduler.service
- sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-task-queue.service
- sed -i 's|ExecStart=granian|ExecStart=uv run -- granian|' /etc/systemd/system/paperless-webserver.service
+ declare -A PATCHES=(
+ ["paperless-consumer.service"]="ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer"
+ ["paperless-scheduler.service"]="ExecStart=celery|ExecStart=uv run -- celery"
+ ["paperless-task-queue.service"]="ExecStart=celery|ExecStart=uv run -- celery"
+ ["paperless-webserver.service"]="ExecStart=.*|ExecStart=uv run -- granian --interface asginl --ws \"paperless.asgi:application\""
+ )
+ for svc in "${!PATCHES[@]}"; do
+ path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
+ if [[ -n "$path" && -f "$path" ]]; then
+ sed -i "s|${PATCHES[$svc]%|*}|${PATCHES[$svc]#*|}|" "$path"
+ msg_ok "Patched $svc"
+ else
+ msg_error "Service file for $svc not found!"
+ fi
+ done
$STD systemctl daemon-reexec
$STD systemctl daemon-reload
cd /opt/paperless
From a61c0e9cc4b6a93a76b01009fcc3d4c96623ecb7 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:55:43 +0200
Subject: [PATCH 071/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 0d51673d..4ba8a9f0 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -49,10 +49,21 @@ function update_script() {
msg_info "Migrating old Paperless-ngx installation to uv"
rm -rf /opt/paperless/venv
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
- sed -i 's|ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer|' /etc/systemd/system/paperless-consumer.service
- sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-scheduler.service
- sed -i 's|ExecStart=celery|ExecStart=uv run -- celery|' /etc/systemd/system/paperless-task-queue.service
- sed -i 's|ExecStart=granian|ExecStart=uv run -- granian|' /etc/systemd/system/paperless-webserver.service
+ declare -A PATCHES=(
+ ["paperless-consumer.service"]="ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer"
+ ["paperless-scheduler.service"]="ExecStart=celery|ExecStart=uv run -- celery"
+ ["paperless-task-queue.service"]="ExecStart=celery|ExecStart=uv run -- celery"
+ ["paperless-webserver.service"]="ExecStart=.*|ExecStart=uv run -- granian --interface asginl --ws \"paperless.asgi:application\""
+ )
+ for svc in "${!PATCHES[@]}"; do
+ path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
+ if [[ -n "$path" && -f "$path" ]]; then
+ sed -i "s|${PATCHES[$svc]%|*}|${PATCHES[$svc]#*|}|" "$path"
+ msg_ok "Patched $svc"
+ else
+ msg_error "Service file for $svc not found!"
+ fi
+ done
$STD systemctl daemon-reexec
$STD systemctl daemon-reload
cd /opt/paperless
From dd08bca358c0992b2adba9026debeaf0fa6f539c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:57:03 +0200
Subject: [PATCH 072/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 4ba8a9f0..e3bea2fe 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -32,7 +32,7 @@ function update_script() {
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- setup_gs
+ #setup_gs
msg_info "Stopping all Paperless-ngx Services"
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
From 5eb747aafb7b1a694ee90f4e0a2cddd91dbe05cb Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 15:57:03 +0200
Subject: [PATCH 073/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 4ba8a9f0..e3bea2fe 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -32,7 +32,7 @@ function update_script() {
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- setup_gs
+ #setup_gs
msg_info "Stopping all Paperless-ngx Services"
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
From a51695e3008cc5739b0fe580c82e28bf50d38019 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:22:51 +0200
Subject: [PATCH 074/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index e3bea2fe..c462c67e 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -49,12 +49,14 @@ function update_script() {
msg_info "Migrating old Paperless-ngx installation to uv"
rm -rf /opt/paperless/venv
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
+
declare -A PATCHES=(
["paperless-consumer.service"]="ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer"
["paperless-scheduler.service"]="ExecStart=celery|ExecStart=uv run -- celery"
["paperless-task-queue.service"]="ExecStart=celery|ExecStart=uv run -- celery"
- ["paperless-webserver.service"]="ExecStart=.*|ExecStart=uv run -- granian --interface asginl --ws \"paperless.asgi:application\""
+ ["paperless-webserver.service"]="ExecStart=.*granian.*|ExecStart=uv run -- granian --interface asgi --host 0.0.0.0 --port 8000 --ws paperless.asgi:application"
)
+
for svc in "${!PATCHES[@]}"; do
path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
if [[ -n "$path" && -f "$path" ]]; then
@@ -64,13 +66,18 @@ function update_script() {
msg_error "Service file for $svc not found!"
fi
done
- $STD systemctl daemon-reexec
+
$STD systemctl daemon-reload
cd /opt/paperless
$STD uv sync --all-extras
cd /opt/paperless/src
$STD uv run -- python manage.py migrate
+
msg_ok "Paperless-ngx migration and update to ${RELEASE} completed"
+
+ # msg_info "Collecting static files (Patience)"
+ # $STD uv run -- python manage.py collectstatic --noinput --clear --link
+ # msg_ok "Collected static files"
fi
msg_info "Cleaning up"
From b1a3b4d3cf4aa258df2a2ce81dba05de0239066e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:22:51 +0200
Subject: [PATCH 075/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index e3bea2fe..c462c67e 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -49,12 +49,14 @@ function update_script() {
msg_info "Migrating old Paperless-ngx installation to uv"
rm -rf /opt/paperless/venv
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
+
declare -A PATCHES=(
["paperless-consumer.service"]="ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer"
["paperless-scheduler.service"]="ExecStart=celery|ExecStart=uv run -- celery"
["paperless-task-queue.service"]="ExecStart=celery|ExecStart=uv run -- celery"
- ["paperless-webserver.service"]="ExecStart=.*|ExecStart=uv run -- granian --interface asginl --ws \"paperless.asgi:application\""
+ ["paperless-webserver.service"]="ExecStart=.*granian.*|ExecStart=uv run -- granian --interface asgi --host 0.0.0.0 --port 8000 --ws paperless.asgi:application"
)
+
for svc in "${!PATCHES[@]}"; do
path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
if [[ -n "$path" && -f "$path" ]]; then
@@ -64,13 +66,18 @@ function update_script() {
msg_error "Service file for $svc not found!"
fi
done
- $STD systemctl daemon-reexec
+
$STD systemctl daemon-reload
cd /opt/paperless
$STD uv sync --all-extras
cd /opt/paperless/src
$STD uv run -- python manage.py migrate
+
msg_ok "Paperless-ngx migration and update to ${RELEASE} completed"
+
+ # msg_info "Collecting static files (Patience)"
+ # $STD uv run -- python manage.py collectstatic --noinput --clear --link
+ # msg_ok "Collected static files"
fi
msg_info "Cleaning up"
From 70f76ddbef01854a7d0d251c70f2f9fa7aff53dd Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:25:43 +0200
Subject: [PATCH 076/312] jq
---
ct/paperless-ngx.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index c462c67e..8c8eee0e 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -27,6 +27,9 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
+ if ! command -v jq &>/dev/null; then
+ $STD apt-get install -y jq
+ fi
RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | jq -r .tag_name | sed 's/^v//')
if [[ "${RELEASE}" != "$(cat ~/.paperless 2>/dev/null)" ]] || [[ ! -f ~/.paperless ]]; then
PYTHON_VERSION="3.13" setup_uv
From 28411398a7e34a420d27b17428799244478338e1 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:35:19 +0200
Subject: [PATCH 077/312] fixes
---
ct/paperless-ngx.sh | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 8c8eee0e..dbed4c25 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -54,16 +54,16 @@ function update_script() {
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
declare -A PATCHES=(
- ["paperless-consumer.service"]="ExecStart=.*manage.py document_consumer|ExecStart=uv run -- python manage.py document_consumer"
- ["paperless-scheduler.service"]="ExecStart=celery|ExecStart=uv run -- celery"
- ["paperless-task-queue.service"]="ExecStart=celery|ExecStart=uv run -- celery"
- ["paperless-webserver.service"]="ExecStart=.*granian.*|ExecStart=uv run -- granian --interface asgi --host 0.0.0.0 --port 8000 --ws paperless.asgi:application"
+ ["paperless-consumer.service"]="ExecStart=uv run -- python manage.py document_consumer"
+ ["paperless-scheduler.service"]="ExecStart=uv run -- celery beat --loglevel INFO"
+ ["paperless-task-queue.service"]="ExecStart=uv run -- celery worker --loglevel INFO"
+ ["paperless-webserver.service"]="ExecStart=uv run -- granian --interface asgi --host 0.0.0.0 --port 8000 --ws paperless.asgi:application"
)
for svc in "${!PATCHES[@]}"; do
path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
if [[ -n "$path" && -f "$path" ]]; then
- sed -i "s|${PATCHES[$svc]%|*}|${PATCHES[$svc]#*|}|" "$path"
+ sed -i "s|^ExecStart=.*|${PATCHES[$svc]}|" "$path"
msg_ok "Patched $svc"
else
msg_error "Service file for $svc not found!"
@@ -88,7 +88,7 @@ function update_script() {
msg_ok "Cleaned"
msg_info "Starting all Paperless-ngx Services"
- systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
sleep 1
msg_ok "Started all Paperless-ngx Services"
msg_ok "Updated Successfully!\n"
From 5c36039c90d1bbfee8cfc066ae1d97d0f0704e42 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:48:16 +0200
Subject: [PATCH 078/312] hint for rollback
---
ct/paperless-ngx.sh | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index dbed4c25..7ef0698f 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -35,10 +35,10 @@ function update_script() {
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- #setup_gs
+ setup_gs
msg_info "Stopping all Paperless-ngx Services"
- systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue.service
+ systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
msg_ok "Stopped all Paperless-ngx Services"
if grep -q "uv run" /etc/systemd/system/paperless-webserver.service; then
@@ -49,6 +49,17 @@ function update_script() {
$STD uv run -- python manage.py migrate
msg_ok "Updated to ${RELEASE}"
else
+ msg_warn "You are about to migrate your Paperless-ngx installation to uv!"
+ msg_custom "🔒" "It is strongly recommended to take a Proxmox snapshot first:"
+ echo -e " 1. Stop the container: pct stop "
+ echo -e " 2. Create a snapshot: pct snapshot pre-paperless-uv-migration"
+ echo -e " 3. Start the container again\n"
+
+ read -rp "Have you created a snapshot? [y/N]: " confirm
+ if [[ ! "$confirm" =~ ^([yY]|[yY][eE][sS])$ ]]; then
+ msg_error "Migration aborted. Please create a snapshot first."
+ exit 1
+ fi
msg_info "Migrating old Paperless-ngx installation to uv"
rm -rf /opt/paperless/venv
find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
@@ -72,21 +83,13 @@ function update_script() {
$STD systemctl daemon-reload
cd /opt/paperless
+ msg_info "Running Paperless-ngx UV sync"
$STD uv sync --all-extras
cd /opt/paperless/src
$STD uv run -- python manage.py migrate
-
msg_ok "Paperless-ngx migration and update to ${RELEASE} completed"
-
- # msg_info "Collecting static files (Patience)"
- # $STD uv run -- python manage.py collectstatic --noinput --clear --link
- # msg_ok "Collected static files"
fi
- msg_info "Cleaning up"
- cd ~
- msg_ok "Cleaned"
-
msg_info "Starting all Paperless-ngx Services"
systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
sleep 1
From db57a7290a6e96f16e838ac95f57854707524271 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 18 Aug 2025 16:52:08 +0200
Subject: [PATCH 079/312] silent setup_gs
---
misc/tools.func | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/tools.func b/misc/tools.func
index 88a4faa7..f8797426 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -1422,7 +1422,7 @@ function setup_gs() {
rm -rf "$TMP_DIR"
}
$STD apt-get install -y build-essential libpng-dev zlib1g-dev
- ./configure >/dev/null && make && sudo make install >/dev/null
+ $STD ./configure >/dev/null && $STD make && $STD sudo make install
local EXIT_CODE=$?
hash -r
if [[ ! -x "$(command -v gs)" ]]; then
From 4db639458d2918b95098ec2c5e44ee2d8c91a1c0 Mon Sep 17 00:00:00 2001
From: Frederik Botha
Date: Mon, 21 Jul 2025 17:16:08 +0100
Subject: [PATCH 080/312] Dispatcharr install files
---
ct/dispatcharr.sh | 120 +++++++++++
frontend/public/json/dispatcharr.json | 34 ++++
install/dispatcharr-install.sh | 275 ++++++++++++++++++++++++++
3 files changed, 429 insertions(+)
create mode 100644 ct/dispatcharr.sh
create mode 100644 frontend/public/json/dispatcharr.json
create mode 100644 install/dispatcharr-install.sh
diff --git a/ct/dispatcharr.sh b/ct/dispatcharr.sh
new file mode 100644
index 00000000..cc75af51
--- /dev/null
+++ b/ct/dispatcharr.sh
@@ -0,0 +1,120 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/ekke85/ProxmoxVED/refs/heads/dispatcharr/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: ekke85
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/Dispatcharr/Dispatcharr
+
+APP="Dispatcharr"
+APP_NAME=${APP,,}
+var_tags="${var_tags:-media;arr}"
+var_cpu="${var_cpu:-1}"
+var_ram="${var_ram:-1024}"
+var_disk="${var_disk:-8}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+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/dispatcharr" ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ RELEASE=$(curl -fsSL https://api.github.com/repos/Dispatcharr/Dispatcharr/releases/latest | jq -r '.tag_name' | sed 's/^v//')
+ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ msg_ok "Starting update"
+ APP_DIR="/opt/dispatcharr"
+ APP_USER="dispatcharr"
+ APP_GROUP="dispatcharr"
+
+
+
+ msg_info "Stopping $APP"
+ systemctl stop dispatcharr-celery
+ systemctl stop dispatcharr-celerybeat
+ systemctl stop dispatcharr-daphne
+ systemctl stop dispatcharr
+ msg_ok "Stopped $APP"
+
+ msg_info "Creating Backup"
+ BACKUP_FILE="/opt/dispatcharr_$(date +%F).tar.gz"
+ msg_info "Source and Database backup"
+ set -o allexport
+ source /etc/$APP_NAME/$APP_NAME.env
+ set +o allexport
+ PGPASSWORD=$POSTGRES_PASSWORD pg_dump -U $POSTGRES_USER -h $POSTGRES_HOST $POSTGRES_DB > /opt/$POSTGRES_DB-`date +%F`.sql
+ $STD tar -czf "$BACKUP_FILE" /opt/dispatcharr /opt/Dispatcharr_version.txt /opt/$POSTGRES_DB-`date +%F`.sql &>/dev/null
+ msg_ok "Backup Created"
+
+ msg_info "Updating $APP to v${RELEASE}"
+ rm -rf /opt/dispatcharr
+ fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
+ chown -R "$APP_USER:$APP_GROUP" "$APP_DIR"
+ sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "${APP_DIR}/apps/output/views.py"
+
+ msg_ok "Dispatcharr Updated to $RELEASE"
+
+ msg_info "Creating Python Virtual Environment"
+ cd $APP_DIR
+ python3 -m venv env
+ source env/bin/activate
+ $STD pip install --upgrade pip
+ $STD pip install -r requirements.txt
+ $STD pip install gunicorn
+ ln -sf /usr/bin/ffmpeg $APP_DIR/env/bin/ffmpeg
+ msg_ok "Python Environment Setup"
+
+ msg_info "Building Frontend"
+ cd $APP_DIR/frontend
+ $STD npm install --legacy-peer-deps
+ $STD npm run build
+ msg_ok "Built Frontend"
+
+ msg_info "Running Django Migrations"
+ cd $APP_DIR
+ source env/bin/activate
+ set -o allexport
+ source /etc/$APP_NAME/$APP_NAME.env
+ set +o allexport
+ $STD python manage.py migrate --noinput
+ $STD python manage.py collectstatic --noinput
+ msg_ok "Migrations Complete"
+
+ msg_info "Starting $APP"
+ systemctl start dispatcharr-celery
+ systemctl start dispatcharr-celerybeat
+ systemctl start dispatcharr-daphne
+ systemctl start dispatcharr
+ msg_ok "Started $APP"
+ echo "${RELEASE}" > "/opt/${APP}_version.txt"
+
+ msg_info "Cleaning Up"
+ rm -rf /opt/$POSTGRES_DB-`date +%F`.sql
+ msg_ok "Cleanup Completed"
+
+ msg_ok "Update Successful, Backup saved to $BACKUP_FILE"
+
+ else
+ msg_ok "No update required. ${APP} is already at v${RELEASE}"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:9191${CL}"
diff --git a/frontend/public/json/dispatcharr.json b/frontend/public/json/dispatcharr.json
new file mode 100644
index 00000000..03cd36bb
--- /dev/null
+++ b/frontend/public/json/dispatcharr.json
@@ -0,0 +1,34 @@
+{
+ "name": "Dispatcharr",
+ "slug": "dispatcharr",
+ "categories": [
+ 14
+ ],
+ "date_created": "2025-07-01",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 9191,
+ "documentation": "https://dispatcharr.github.io/Dispatcharr-Docs/",
+ "website": "https://dispatcharr.github.io/Dispatcharr-Docs/",
+ "logo": "https://raw.githubusercontent.com/Dispatcharr/Dispatcharr/refs/heads/main/frontend/src/images/logo.png",
+ "description": "Dispatcharr is an open-source powerhouse for managing IPTV streams and EPG data with elegance and control. Born from necessity and built with passion, it started as a personal project by OkinawaBoss and evolved with contributions from legends like dekzter, SergeantPanda and Bucatini.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/dispatcharr.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 1024,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+
diff --git a/install/dispatcharr-install.sh b/install/dispatcharr-install.sh
new file mode 100644
index 00000000..7174b4ac
--- /dev/null
+++ b/install/dispatcharr-install.sh
@@ -0,0 +1,275 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: ekke85
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/Dispatcharr/Dispatcharr
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+
+APPLICATION="Dispatcharr"
+APP_NAME="dispatcharr"
+APP_USER="dispatcharr"
+APP_GROUP="dispatcharr"
+APP_DIR="/opt/dispatcharr"
+GUNICORN_RUNTIME_DIR="dispatcharr"
+GUNICORN_PORT="5656"
+NGINX_HTTP_PORT="9191"
+WEBSOCKET_PORT="8001"
+
+msg_info "Creating ${APP_USER} user"
+groupadd -f $APP_GROUP
+useradd -M -s /usr/sbin/nologin -g $APP_GROUP $APP_USER || true
+msg_ok "Created ${APP_USER} user"
+
+setup_uv
+NODE_VERSION="22" setup_nodejs
+PG_VERSION="16" setup_postgresql
+
+msg_info "Installing Dependencies"
+$STD apt-get install -y \
+ git \
+ curl \
+ wget \
+ build-essential \
+ gcc \
+ libpcre3-dev \
+ libpq-dev \
+ python3-dev \
+ python3-venv \
+ python3-pip \
+ nginx \
+ redis-server \
+ ffmpeg \
+ procps \
+ streamlink
+msg_ok "Installed Dependencies"
+
+msg_info "Configuring PostgreSQL"
+
+POSTGRES_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
+
+{
+ echo "POSTGRES_DB=dispatcharr"
+ echo "POSTGRES_USER=dispatch"
+ echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD"
+ echo "POSTGRES_HOST=localhost"
+} >> ~/.$APP_NAME.creds
+
+source ~/.$APP_NAME.creds
+
+su - postgres -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='${POSTGRES_USER}'\"" | grep -q 1 || \
+ su - postgres -c "psql -c \"CREATE USER ${POSTGRES_USER} WITH PASSWORD '${POSTGRES_PASSWORD}';\""
+
+su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB}'\"" | grep -q 1 || \
+ su - postgres -c "psql -c \"CREATE DATABASE ${POSTGRES_DB} OWNER ${POSTGRES_USER};\""
+
+su - postgres -c "psql -d ${POSTGRES_DB} -c \"ALTER SCHEMA public OWNER TO ${POSTGRES_USER};\""
+
+
+
+msg_ok "Configured PostgreSQL"
+
+msg_info "Fetching latest Dispatcharr release version"
+LATEST_VERSION=$(curl -fsSL https://api.github.com/repos/Dispatcharr/Dispatcharr/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
+
+if [[ -z "$LATEST_VERSION" ]]; then
+ msg_error "Failed to fetch latest release version from GitHub."
+ exit 1
+fi
+
+msg_info "Downloading Dispatcharr $LATEST_VERSION"
+fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
+echo "$LATEST_VERSION" > "/opt/${APPLICATION}_version.txt"
+mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
+mkdir -p /etc/$APP_NAME
+cp ~/.$APP_NAME.creds /etc/$APP_NAME/$APP_NAME.env
+chown -R "$APP_USER:$APP_GROUP" {/etc/$APP_NAME,$APP_DIR,/data}
+
+
+sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "${APP_DIR}/apps/output/views.py"
+
+msg_ok "Downloaded Dispatcharr $LATEST_VERSION"
+
+msg_info "Install Python Requirements"
+cd $APP_DIR
+python3 -m venv env
+source env/bin/activate
+
+$STD pip install --upgrade pip
+$STD pip install -r requirements.txt
+$STD pip install gunicorn
+ln -sf /usr/bin/ffmpeg $APP_DIR/env/bin/ffmpeg
+msg_ok "Python Requirements Installed"
+
+msg_info "Building Frontend"
+cd $APP_DIR/frontend
+$STD npm install --legacy-peer-deps
+$STD npm run build
+msg_ok "Built Frontend"
+
+msg_info "Running Django Migrations"
+cd $APP_DIR
+source env/bin/activate
+set -o allexport
+source /etc/$APP_NAME/$APP_NAME.env
+set +o allexport
+
+$STD python manage.py migrate --noinput
+$STD python manage.py collectstatic --noinput
+msg_ok "Migrations Complete"
+
+msg_info "Configuring Nginx"
+cat </etc/nginx/sites-available/dispatcharr.conf
+server {
+ listen $NGINX_HTTP_PORT;
+
+ location / {
+ include proxy_params;
+ proxy_pass http://127.0.0.1:$GUNICORN_PORT;
+ }
+
+ location /static/ {
+ alias $APP_DIR/static/;
+ }
+
+ location /assets/ {
+ alias $APP_DIR/frontend/dist/assets/;
+ }
+
+ location /media/ {
+ alias $APP_DIR/media/;
+ }
+
+ location /ws/ {
+ proxy_pass http://127.0.0.1:$WEBSOCKET_PORT;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade \$http_upgrade;
+ proxy_set_header Connection "Upgrade";
+ proxy_set_header Host \$host;
+ }
+}
+EOF
+
+ln -sf /etc/nginx/sites-available/dispatcharr.conf /etc/nginx/sites-enabled/dispatcharr.conf
+rm -f /etc/nginx/sites-enabled/default
+nginx -t
+systemctl restart nginx
+systemctl enable nginx
+msg_ok "Configured Nginx"
+
+msg_info "Creating systemd services"
+
+cat </etc/systemd/system/dispatcharr.service
+[Unit]
+Description=Gunicorn for Dispatcharr
+After=network.target postgresql.service redis-server.service
+
+[Service]
+User=$APP_USER
+Group=$APP_GROUP
+WorkingDirectory=$APP_DIR
+RuntimeDirectory=$GUNICORN_RUNTIME_DIR
+RuntimeDirectoryMode=0775
+Environment="PATH=$APP_DIR/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
+EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+ExecStart=$APP_DIR/env/bin/gunicorn \\
+ --workers=4 \\
+ --worker-class=gevent \\
+ --timeout=300 \\
+ --bind 0.0.0.0:$GUNICORN_PORT \
+ dispatcharr.wsgi:application
+Restart=always
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/dispatcharr-celery.service
+[Unit]
+Description=Celery Worker for Dispatcharr
+After=network.target redis-server.service
+Requires=dispatcharr.service
+
+[Service]
+User=$APP_USER
+Group=$APP_GROUP
+WorkingDirectory=$APP_DIR
+Environment="PATH=$APP_DIR/env/bin"
+EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
+ExecStart=$APP_DIR/env/bin/celery -A dispatcharr worker -l info -c 4
+Restart=always
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/dispatcharr-celerybeat.service
+[Unit]
+Description=Celery Beat Scheduler for Dispatcharr
+After=network.target redis-server.service
+Requires=dispatcharr.service
+
+[Service]
+User=$APP_USER
+Group=$APP_GROUP
+WorkingDirectory=$APP_DIR
+Environment="PATH=$APP_DIR/env/bin"
+EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
+ExecStart=$APP_DIR/env/bin/celery -A dispatcharr beat -l info
+Restart=always
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat </etc/systemd/system/dispatcharr-daphne.service
+[Unit]
+Description=Daphne for Dispatcharr (ASGI)
+After=network.target
+Requires=dispatcharr.service
+
+[Service]
+User=$APP_USER
+Group=$APP_GROUP
+WorkingDirectory=$APP_DIR
+Environment="PATH=$APP_DIR/env/bin"
+EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+ExecStart=$APP_DIR/env/bin/daphne -b 0.0.0.0 -p $WEBSOCKET_PORT dispatcharr.asgi:application
+Restart=always
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+msg_ok "Created systemd services"
+
+
+msg_info "Starting Dispatcharr Services"
+systemctl daemon-reexec
+systemctl daemon-reload
+systemctl enable dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
+systemctl restart dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
+msg_ok "Started Dispatcharr Services"
+
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 804dc8900e7a4bd59fb7021b1247644f756f178f Mon Sep 17 00:00:00 2001
From: Frederik Botha
Date: Mon, 21 Jul 2025 18:07:01 +0100
Subject: [PATCH 081/312] Updated the build.func location in the ct file
---
ct/dispatcharr.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/dispatcharr.sh b/ct/dispatcharr.sh
index cc75af51..49285859 100644
--- a/ct/dispatcharr.sh
+++ b/ct/dispatcharr.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/ekke85/ProxmoxVED/refs/heads/dispatcharr/misc/build.func)
+source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: ekke85
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
From 6aac6df21b762ce34c69faac3935470fae71dc9d Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Tue, 19 Aug 2025 06:05:26 +0000
Subject: [PATCH 082/312] Update .app files
---
ct/headers/dispatcharr | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 ct/headers/dispatcharr
diff --git a/ct/headers/dispatcharr b/ct/headers/dispatcharr
new file mode 100644
index 00000000..a8ad5396
--- /dev/null
+++ b/ct/headers/dispatcharr
@@ -0,0 +1,6 @@
+ ____ _ __ __
+ / __ \(_)________ ____ _/ /______/ /_ ____ ___________
+ / / / / / ___/ __ \/ __ `/ __/ ___/ __ \/ __ `/ ___/ ___/
+ / /_/ / (__ ) /_/ / /_/ / /_/ /__/ / / / /_/ / / / /
+/_____/_/____/ .___/\__,_/\__/\___/_/ /_/\__,_/_/ /_/
+ /_/
From bb9656b8ea6e644c9612daeebb70f085f5d27bee Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Tue, 19 Aug 2025 06:08:45 +0000
Subject: [PATCH 083/312] Update .app files
---
ct/headers/freepbx | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 ct/headers/freepbx
diff --git a/ct/headers/freepbx b/ct/headers/freepbx
new file mode 100644
index 00000000..25541c2e
--- /dev/null
+++ b/ct/headers/freepbx
@@ -0,0 +1,6 @@
+ ______ ____ ____ _ __
+ / ____/_______ ___ / __ \/ __ ) |/ /
+ / /_ / ___/ _ \/ _ \/ /_/ / __ | /
+ / __/ / / / __/ __/ ____/ /_/ / |
+/_/ /_/ \___/\___/_/ /_____/_/|_|
+
From be4c31bb2e489f9f66009353ca089727fc864b0b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 09:00:19 +0200
Subject: [PATCH 084/312] cleanup dispatcharr
---
install/dispatcharr-install.sh | 165 ++++++++++++---------------------
1 file changed, 57 insertions(+), 108 deletions(-)
diff --git a/install/dispatcharr-install.sh b/install/dispatcharr-install.sh
index 7174b4ac..79546a2e 100644
--- a/install/dispatcharr-install.sh
+++ b/install/dispatcharr-install.sh
@@ -13,38 +13,17 @@ setting_up_container
network_check
update_os
-
-APPLICATION="Dispatcharr"
-APP_NAME="dispatcharr"
-APP_USER="dispatcharr"
-APP_GROUP="dispatcharr"
-APP_DIR="/opt/dispatcharr"
-GUNICORN_RUNTIME_DIR="dispatcharr"
-GUNICORN_PORT="5656"
-NGINX_HTTP_PORT="9191"
-WEBSOCKET_PORT="8001"
-
-msg_info "Creating ${APP_USER} user"
-groupadd -f $APP_GROUP
-useradd -M -s /usr/sbin/nologin -g $APP_GROUP $APP_USER || true
-msg_ok "Created ${APP_USER} user"
-
-setup_uv
-NODE_VERSION="22" setup_nodejs
-PG_VERSION="16" setup_postgresql
+# msg_info "Creating ${APP_USER} user"
+# groupadd -f $APP_GROUP
+# useradd -M -s /usr/sbin/nologin -g $APP_GROUP $APP_USER || true
+# msg_ok "Created ${APP_USER} user"
msg_info "Installing Dependencies"
$STD apt-get install -y \
- git \
- curl \
- wget \
build-essential \
gcc \
libpcre3-dev \
libpq-dev \
- python3-dev \
- python3-venv \
- python3-pip \
nginx \
redis-server \
ffmpeg \
@@ -52,74 +31,61 @@ $STD apt-get install -y \
streamlink
msg_ok "Installed Dependencies"
-msg_info "Configuring PostgreSQL"
-
-POSTGRES_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
+setup_uv
+NODE_VERSION="22" setup_nodejs
+PG_VERSION="16" setup_postgresql
+msg_info "Set up PostgreSQL Database"
+DB_NAME=dispatcharr_db
+DB_USER=dispatcharr_usr
+DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
+DB_URL="postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}"
+$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
+$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
- echo "POSTGRES_DB=dispatcharr"
- echo "POSTGRES_USER=dispatch"
- echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD"
- echo "POSTGRES_HOST=localhost"
-} >> ~/.$APP_NAME.creds
+ echo "Dispatcharr-Credentials"
+ echo "Dispatcharr Database Name: $DB_NAME"
+ echo "Dispatcharr Database User: $DB_USER"
+ echo "Dispatcharr Database Password: $DB_PASS"
+} >>~/dispatcharr.creds
+msg_ok "Set up PostgreSQL Database"
-source ~/.$APP_NAME.creds
-
-su - postgres -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='${POSTGRES_USER}'\"" | grep -q 1 || \
- su - postgres -c "psql -c \"CREATE USER ${POSTGRES_USER} WITH PASSWORD '${POSTGRES_PASSWORD}';\""
-
-su - postgres -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB}'\"" | grep -q 1 || \
- su - postgres -c "psql -c \"CREATE DATABASE ${POSTGRES_DB} OWNER ${POSTGRES_USER};\""
-
-su - postgres -c "psql -d ${POSTGRES_DB} -c \"ALTER SCHEMA public OWNER TO ${POSTGRES_USER};\""
-
-
-
-msg_ok "Configured PostgreSQL"
-
-msg_info "Fetching latest Dispatcharr release version"
-LATEST_VERSION=$(curl -fsSL https://api.github.com/repos/Dispatcharr/Dispatcharr/releases/latest | grep '"tag_name":' | cut -d '"' -f4)
-
-if [[ -z "$LATEST_VERSION" ]]; then
- msg_error "Failed to fetch latest release version from GitHub."
- exit 1
-fi
-
-msg_info "Downloading Dispatcharr $LATEST_VERSION"
fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
-echo "$LATEST_VERSION" > "/opt/${APPLICATION}_version.txt"
-mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
-mkdir -p /etc/$APP_NAME
-cp ~/.$APP_NAME.creds /etc/$APP_NAME/$APP_NAME.env
-chown -R "$APP_USER:$APP_GROUP" {/etc/$APP_NAME,$APP_DIR,/data}
+mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
+mkdir -p /etc/dispatcharr
+cp ~/.dispatcharr.creds /etc/dispatcharr/dispatcharr.env
+chown -R "$APP_USER:$APP_GROUP" {/etc/dispatcharr,/opt/dispatcharr,/data}
sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "${APP_DIR}/apps/output/views.py"
msg_ok "Downloaded Dispatcharr $LATEST_VERSION"
msg_info "Install Python Requirements"
-cd $APP_DIR
+cd /opt/dispatcharr
python3 -m venv env
source env/bin/activate
$STD pip install --upgrade pip
$STD pip install -r requirements.txt
$STD pip install gunicorn
-ln -sf /usr/bin/ffmpeg $APP_DIR/env/bin/ffmpeg
+ln -sf /usr/bin/ffmpeg /opt/dispatcharr/env/bin/ffmpeg
msg_ok "Python Requirements Installed"
msg_info "Building Frontend"
-cd $APP_DIR/frontend
+cd /opt/dispatcharr/frontend
$STD npm install --legacy-peer-deps
$STD npm run build
msg_ok "Built Frontend"
msg_info "Running Django Migrations"
-cd $APP_DIR
+cd /opt/dispatcharr
source env/bin/activate
set -o allexport
-source /etc/$APP_NAME/$APP_NAME.env
+source /etc/dispatcharr/dispatcharr.env
set +o allexport
$STD python manage.py migrate --noinput
@@ -129,27 +95,27 @@ msg_ok "Migrations Complete"
msg_info "Configuring Nginx"
cat </etc/nginx/sites-available/dispatcharr.conf
server {
- listen $NGINX_HTTP_PORT;
+ listen 9191;
location / {
include proxy_params;
- proxy_pass http://127.0.0.1:$GUNICORN_PORT;
+ proxy_pass http://127.0.0.1:5656;
}
location /static/ {
- alias $APP_DIR/static/;
+ alias /opt/dispatcharr/static/;
}
location /assets/ {
- alias $APP_DIR/frontend/dist/assets/;
+ alias /opt/dispatcharr/frontend/dist/assets/;
}
location /media/ {
- alias $APP_DIR/media/;
+ alias /opt/dispatcharr/media/;
}
location /ws/ {
- proxy_pass http://127.0.0.1:$WEBSOCKET_PORT;
+ proxy_pass http://127.0.0.1:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
@@ -173,18 +139,16 @@ Description=Gunicorn for Dispatcharr
After=network.target postgresql.service redis-server.service
[Service]
-User=$APP_USER
-Group=$APP_GROUP
-WorkingDirectory=$APP_DIR
-RuntimeDirectory=$GUNICORN_RUNTIME_DIR
+WorkingDirectory=/opt/dispatcharr
+RuntimeDirectory=dispatcharr
RuntimeDirectoryMode=0775
-Environment="PATH=$APP_DIR/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
-EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
-ExecStart=$APP_DIR/env/bin/gunicorn \\
+Environment="PATH=/opt/dispatcharr/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
+EnvironmentFile=/etc/dispatcharr/dispatcharr.env
+ExecStart=/opt/dispatcharr/env/bin/gunicorn \\
--workers=4 \\
--worker-class=gevent \\
--timeout=300 \\
- --bind 0.0.0.0:$GUNICORN_PORT \
+ --bind 0.0.0.0:5656 \
dispatcharr.wsgi:application
Restart=always
KillMode=mixed
@@ -200,13 +164,11 @@ After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
-User=$APP_USER
-Group=$APP_GROUP
-WorkingDirectory=$APP_DIR
-Environment="PATH=$APP_DIR/env/bin"
-EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+WorkingDirectory=/opt/dispatcharr
+Environment="PATH=/opt/dispatcharr/env/bin"
+EnvironmentFile=/etc/dispatcharr/dispatcharr.env
Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
-ExecStart=$APP_DIR/env/bin/celery -A dispatcharr worker -l info -c 4
+ExecStart=/opt/dispatcharr/env/bin/celery -A dispatcharr worker -l info -c 4
Restart=always
KillMode=mixed
@@ -221,13 +183,11 @@ After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
-User=$APP_USER
-Group=$APP_GROUP
-WorkingDirectory=$APP_DIR
-Environment="PATH=$APP_DIR/env/bin"
-EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
+WorkingDirectory=/opt/dispatcharr
+Environment="PATH=/opt/dispatcharr/env/bin"
+EnvironmentFile=/etc/dispatcharr/dispatcharr.env
Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
-ExecStart=$APP_DIR/env/bin/celery -A dispatcharr beat -l info
+ExecStart=/opt/dispatcharr/env/bin/celery -A dispatcharr beat -l info
Restart=always
KillMode=mixed
@@ -242,30 +202,19 @@ After=network.target
Requires=dispatcharr.service
[Service]
-User=$APP_USER
-Group=$APP_GROUP
-WorkingDirectory=$APP_DIR
-Environment="PATH=$APP_DIR/env/bin"
-EnvironmentFile=/etc/$APP_NAME/$APP_NAME.env
-ExecStart=$APP_DIR/env/bin/daphne -b 0.0.0.0 -p $WEBSOCKET_PORT dispatcharr.asgi:application
+WorkingDirectory=/opt/dispatcharr
+Environment="PATH=/opt/dispatcharr/env/bin"
+EnvironmentFile=/etc/dispatcharr/dispatcharr.env
+ExecStart=/opt/dispatcharr/env/bin/daphne -b 0.0.0.0 -p 8001 dispatcharr.asgi:application
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
-
-msg_ok "Created systemd services"
-
-
-msg_info "Starting Dispatcharr Services"
-systemctl daemon-reexec
-systemctl daemon-reload
-systemctl enable dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
-systemctl restart dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
+systemctl enable -q --now dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
msg_ok "Started Dispatcharr Services"
-
motd_ssh
customize
From 086b24bbf10d99768b9e7b1303d6611bacf69a1c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 09:02:24 +0200
Subject: [PATCH 085/312] cl
---
ct/twingate-connector.sh | 44 --------------
frontend/public/json/twingate-connector.json | 44 --------------
install/twingate-connector-install.sh | 63 --------------------
3 files changed, 151 deletions(-)
delete mode 100644 ct/twingate-connector.sh
delete mode 100644 frontend/public/json/twingate-connector.json
delete mode 100644 install/twingate-connector-install.sh
diff --git a/ct/twingate-connector.sh b/ct/twingate-connector.sh
deleted file mode 100644
index f1a05c9a..00000000
--- a/ct/twingate-connector.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: twingate-andrewb
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.twingate.com/docs/
-
-APP="twingate-connector"
-var_tags="${var_tags:-network;connector;twingate}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-1024}"
-var_disk="${var_disk:-3}"
-var_os="${var_os:-ubuntu}"
-var_version="${var_version:-24.04}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -f /lib/systemd/system/twingate-connector.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- msg_info "Updating ${APP}"
- $STD apt update
- $STD apt install -yq twingate-connector
- $STD systemctl restart twingate-connector
- msg_ok "Updated Successfully"
- exit
-}
-
-start
-build_container
-description
-
-msg_ok "All Finished! If you need to update your access or refresh tokens, they can be found in /etc/twingate/connector.conf"
diff --git a/frontend/public/json/twingate-connector.json b/frontend/public/json/twingate-connector.json
deleted file mode 100644
index e9aa195e..00000000
--- a/frontend/public/json/twingate-connector.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "name": "twingate-connector",
- "slug": "twingate-connector",
- "categories": [
- 4
- ],
- "date_created": "2025-07-17",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": null,
- "documentation": "https://www.twingate.com/docs/",
- "config_path": "/etc/twingate/connector.conf",
- "website": "https://www.twingate.com",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/twingate.webp",
- "description": "Twingate Connectors are lightweight software components that establish secure, least-privileged access between private network resources and authorized users without exposing the network to the internet. They act as outbound-only bridges between your protected resources and the Twingate infrastructure, ensuring zero-trust access without the need for a VPN.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/twingate-connector.sh",
- "resources": {
- "cpu": 1,
- "ram": 1024,
- "hdd": 3,
- "os": "Ubuntu",
- "version": "24.04"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "You can get your Twingate access or refresh tokens from the Twingate Admin Console. `https://auth.twingate.com/signup-v2`",
- "type": "info"
- },
- {
- "text": "If you need to update your access or refresh tokens, they can be found in /etc/twingate/connector.conf",
- "type": "info"
- }
- ]
-}
diff --git a/install/twingate-connector-install.sh b/install/twingate-connector-install.sh
deleted file mode 100644
index c6027854..00000000
--- a/install/twingate-connector-install.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: MickLesk (CanbiZ), twingate-andrewb
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.twingate.com/docs/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-install -d -m 0700 /etc/twingate
-
-access_token=""
-refresh_token=""
-network=""
-
-while [[ -z "$access_token" ]]; do
- read -rp "${TAB3}Please enter your access token: " access_token
-done
-while [[ -z "$refresh_token" ]]; do
- read -rp "${TAB3}Please enter your refresh token: " refresh_token
-done
-while [[ -z "$network" ]]; do
- read -rp "${TAB3}Please enter your network name: " network
-done
-
-msg_info "Setup Twingate Repository"
-curl -fsSL "https://packages.twingate.com/apt/gpg.key" | gpg --dearmor -o /usr/share/keyrings/twingate-connector-keyring.gpg
-echo "deb [signed-by=/usr/share/keyrings/twingate-connector-keyring.gpg] https://packages.twingate.com/apt/ /" > /etc/apt/sources.list.d/twingate.list
-$STD apt-get update
-msg_ok "Setup Twingate Repository"
-
-msg_info "Setup Twingate Connector"
-$STD apt-get install -y twingate-connector
-msg_ok "Setup Twingate Connector"
-
-msg_info "Writing config"
-{
- echo "TWINGATE_NETWORK=${network}"
- echo "TWINGATE_ACCESS_TOKEN=${access_token}"
- echo "TWINGATE_REFRESH_TOKEN=${refresh_token}"
- echo "TWINGATE_LABEL_HOSTNAME=$(hostname)"
- echo "TWINGATE_LABEL_DEPLOYED_BY=proxmox"
-} > /etc/twingate/connector.conf
-chmod 600 /etc/twingate/connector.conf
-msg_ok "Config written"
-
-msg_info "Starting Service"
-systemctl enable -q --now twingate-connector
-msg_ok "Service started"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Done cleaning up"
From c528bf6e8f00799cc743c8c504891daf76d6f2a3 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 09:48:42 +0200
Subject: [PATCH 086/312] removed
---
ct/swizzin.sh | 43 -----------------
frontend/public/json/dispatcharr.json | 66 +++++++++++++--------------
frontend/public/json/swizzin.json | 48 -------------------
install/swizzin-install.sh | 34 --------------
4 files changed, 33 insertions(+), 158 deletions(-)
delete mode 100644 ct/swizzin.sh
delete mode 100644 frontend/public/json/swizzin.json
delete mode 100644 install/swizzin-install.sh
diff --git a/ct/swizzin.sh b/ct/swizzin.sh
deleted file mode 100644
index de10cb1b..00000000
--- a/ct/swizzin.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: EEJoshua
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://swizzin.ltd/
-
-APP="Swizzin"
-var_tags="${var_tags:-seedbox}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-4096}"
-var_disk="${var_disk:-20}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if ! command -v sudo box >/dev/null 2>&1; then
- msg_error "No ${APP} installation found!\n"
- exit
- fi
- msg_info "Running 'sudo box update' inside the container\n"
- $STD sudo box update
- msg_ok "Update finished\n"
- 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}If installed panel, access through the following URL:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/frontend/public/json/dispatcharr.json b/frontend/public/json/dispatcharr.json
index 03cd36bb..b833cde6 100644
--- a/frontend/public/json/dispatcharr.json
+++ b/frontend/public/json/dispatcharr.json
@@ -1,34 +1,34 @@
{
- "name": "Dispatcharr",
- "slug": "dispatcharr",
- "categories": [
- 14
- ],
- "date_created": "2025-07-01",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 9191,
- "documentation": "https://dispatcharr.github.io/Dispatcharr-Docs/",
- "website": "https://dispatcharr.github.io/Dispatcharr-Docs/",
- "logo": "https://raw.githubusercontent.com/Dispatcharr/Dispatcharr/refs/heads/main/frontend/src/images/logo.png",
- "description": "Dispatcharr is an open-source powerhouse for managing IPTV streams and EPG data with elegance and control. Born from necessity and built with passion, it started as a personal project by OkinawaBoss and evolved with contributions from legends like dekzter, SergeantPanda and Bucatini.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/dispatcharr.sh",
- "resources": {
- "cpu": 1,
- "ram": 1024,
- "hdd": 8,
- "os": "debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": []
-
+ "name": "Dispatcharr",
+ "slug": "dispatcharr",
+ "categories": [
+ 14
+ ],
+ "date_created": "2025-07-01",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 9191,
+ "documentation": "https://dispatcharr.github.io/Dispatcharr-Docs/",
+ "website": "https://dispatcharr.github.io/Dispatcharr-Docs/",
+ "logo": "https://raw.githubusercontent.com/Dispatcharr/Dispatcharr/refs/heads/main/frontend/src/images/logo.png",
+ "description": "Dispatcharr is an open-source powerhouse for managing IPTV streams and EPG data with elegance and control. Born from necessity and built with passion, it started as a personal project by OkinawaBoss and evolved with contributions from legends like dekzter, SergeantPanda and Bucatini.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/dispatcharr.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 1024,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/frontend/public/json/swizzin.json b/frontend/public/json/swizzin.json
deleted file mode 100644
index 2f08f31f..00000000
--- a/frontend/public/json/swizzin.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "name": "Swizzin",
- "slug": "swizzin",
- "categories": [
- 15
- ],
- "date_created": "2025-08-01",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 80,
- "documentation": "https://swizzin.ltd/getting-started",
- "config_path": "/etc/swizzin/",
- "website": "https://swizzin.ltd/",
- "logo": "https://swizzin.ltd/img/logo-sm.png",
- "description": "Swizzin is a light-weight, modular, and user-friendly seedbox solution for Debian-based servers. It allows for the easy installation and management of a wide variety of applications commonly used for torrenting and media management, such as rTorrent, Sonarr, Radarr, and Plex, all accessible through a command-line utility or a web-based dashboard.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/swizzin.sh",
- "resources": {
- "cpu": 2,
- "ram": 4096,
- "hdd": 20,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "It is very recommended to install at least the 'panel' for web access, and 'nginx' for easy access to other apps.",
- "type": "warning"
- },
- {
- "text": "Installation might take a long time if choosing to install many apps. Be patient.",
- "type": "warning"
- },
- {
- "text": "Swizzin is a management suite, not a single application. Use the 'box' command inside the container to install/manage individual apps like rTorrent, Sonarr, etc. A full list can be found in documentation.",
- "type": "info"
- }
- ]
-}
\ No newline at end of file
diff --git a/install/swizzin-install.sh b/install/swizzin-install.sh
deleted file mode 100644
index aff5c85d..00000000
--- a/install/swizzin-install.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: EEJoshua
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://swizzin.ltd/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_warn "WARNING: This script will run an external installer from a third-party source (https://swizzin.ltd/)."
-msg_warn "The following code is NOT maintained or audited by our repository."
-msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
-msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://s5n.sh"
-echo
-read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
-if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
- msg_error "Aborted by user. No changes have been made."
- exit 10
-fi
-bash <(curl -sL s5n.sh)
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
From 3c6f697ba5a29170f54f6d0bc3a9171b880b0e3e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:08:55 +0200
Subject: [PATCH 087/312] Update dispatcharr.json
---
frontend/public/json/dispatcharr.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/frontend/public/json/dispatcharr.json b/frontend/public/json/dispatcharr.json
index b833cde6..46abd555 100644
--- a/frontend/public/json/dispatcharr.json
+++ b/frontend/public/json/dispatcharr.json
@@ -12,6 +12,7 @@
"documentation": "https://dispatcharr.github.io/Dispatcharr-Docs/",
"website": "https://dispatcharr.github.io/Dispatcharr-Docs/",
"logo": "https://raw.githubusercontent.com/Dispatcharr/Dispatcharr/refs/heads/main/frontend/src/images/logo.png",
+ "config_path": "",
"description": "Dispatcharr is an open-source powerhouse for managing IPTV streams and EPG data with elegance and control. Born from necessity and built with passion, it started as a personal project by OkinawaBoss and evolved with contributions from legends like dekzter, SergeantPanda and Bucatini.",
"install_methods": [
{
From 7a0a12bb876a8dbe0409381048e46750c2616040 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:45:29 +0200
Subject: [PATCH 088/312] fix service update paperless
---
ct/paperless-ngx.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 7ef0698f..21d11e9a 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -66,9 +66,9 @@ function update_script() {
declare -A PATCHES=(
["paperless-consumer.service"]="ExecStart=uv run -- python manage.py document_consumer"
- ["paperless-scheduler.service"]="ExecStart=uv run -- celery beat --loglevel INFO"
- ["paperless-task-queue.service"]="ExecStart=uv run -- celery worker --loglevel INFO"
- ["paperless-webserver.service"]="ExecStart=uv run -- granian --interface asgi --host 0.0.0.0 --port 8000 --ws paperless.asgi:application"
+ ["paperless-scheduler.service"]="ExecStart=uv run -- celery --app paperless beat --loglevel INFO"
+ ["paperless-task-queue.service"]="ExecStart=uv run -- celery --app paperless worker --loglevel INFO"
+ ["paperless-webserver.service"]="ExecStart=uv run -- granian --interface asgi --ws \"paperless.asgi:application\""
)
for svc in "${!PATCHES[@]}"; do
From df29d2d2965087e00a2d287737f227e72eaa28b2 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Tue, 19 Aug 2025 08:45:45 +0000
Subject: [PATCH 089/312] Update .app files
---
ct/headers/swizzin | 6 ------
ct/headers/twingate-connector | 6 ------
2 files changed, 12 deletions(-)
delete mode 100644 ct/headers/swizzin
delete mode 100644 ct/headers/twingate-connector
diff --git a/ct/headers/swizzin b/ct/headers/swizzin
deleted file mode 100644
index 473b027e..00000000
--- a/ct/headers/swizzin
+++ /dev/null
@@ -1,6 +0,0 @@
- _____ _ _
- / ___/ __(_)_______ (_)___
- \__ \ | /| / / /_ /_ / / / __ \
- ___/ / |/ |/ / / / /_/ /_/ / / / /
-/____/|__/|__/_/ /___/___/_/_/ /_/
-
diff --git a/ct/headers/twingate-connector b/ct/headers/twingate-connector
deleted file mode 100644
index bca28370..00000000
--- a/ct/headers/twingate-connector
+++ /dev/null
@@ -1,6 +0,0 @@
- __ _ __ __
- / /__ __(_)___ ____ _____ _/ /____ _________ ____ ____ ___ _____/ /_____ _____
- / __/ | /| / / / __ \/ __ `/ __ `/ __/ _ \______/ ___/ __ \/ __ \/ __ \/ _ \/ ___/ __/ __ \/ ___/
-/ /_ | |/ |/ / / / / / /_/ / /_/ / /_/ __/_____/ /__/ /_/ / / / / / / / __/ /__/ /_/ /_/ / /
-\__/ |__/|__/_/_/ /_/\__, /\__,_/\__/\___/ \___/\____/_/ /_/_/ /_/\___/\___/\__/\____/_/
- /____/
From 058f01471036436e10ca9e7d6966940a14571e9c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:47:34 +0200
Subject: [PATCH 090/312] Update create_lxc.sh
---
misc/create_lxc.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 03de6aaa..ea1749d2 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -389,8 +389,9 @@ if [[ "${PCT_RAM_SIZE:-2048}" -lt 1024 ]]; then
msg_warn "Configured RAM (${PCT_RAM_SIZE}MB) is below 1024MB – some apps may not work properly."
fi
-if [[ "${PCT_UNPRIVILEGED:-1}" == "1" && " ${PCT_OPTIONS[*]} " == *"fuse=1"* ]]; then
- msg_warn "Unprivileged container with FUSE may fail unless extra device mappings are configured."
-fi
+# comment out 19.08.2025 - PCT Options not correct, message every new lxc (without fuse too)
+# if [[ "${PCT_UNPRIVILEGED:-1}" == "1" && " ${PCT_OPTIONS[*]} " == *"fuse=1"* ]]; then
+# msg_warn "Unprivileged container with FUSE may fail unless extra device mappings are configured."
+# fi
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
From 9414137350ddf8218ad2941a43bd02d29967c3b2 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:49:18 +0200
Subject: [PATCH 091/312] Update push-to-gitea.yml
---
.github/workflows/push-to-gitea.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/push-to-gitea.yml b/.github/workflows/push-to-gitea.yml
index 73d9a72b..163ea035 100644
--- a/.github/workflows/push-to-gitea.yml
+++ b/.github/workflows/push-to-gitea.yml
@@ -33,7 +33,7 @@ jobs:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
- name: Push to Gitea
- run: git push gitea --all
+ run: git push gitea main --force
env:
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
From 563130ea85e552775459fa8b28bfc298059f400a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:51:41 +0200
Subject: [PATCH 092/312] Update paperless-ngx-install.sh
---
install/paperless-ngx-install.sh | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh
index c8e89c4a..92957802 100644
--- a/install/paperless-ngx-install.sh
+++ b/install/paperless-ngx-install.sh
@@ -114,11 +114,15 @@ user.is_superuser = True
user.is_staff = True
user.save()
EOF
-
-echo "" >>~/paperless.creds
-echo -e "Paperless-ngx WebUI User: \e[32madmin\e[0m" >>~/paperless.creds
-echo -e "Paperless-ngx WebUI Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds
-echo "" >>~/paperless.creds
+{
+ echo "Paperless-ngx-Credentials"
+ echo "Paperless-ngx Database Name: $DB_NAME"
+ echo "Paperless-ngx Database User: $DB_USER"
+ echo "Paperless-ngx Database Password: $DB_PASS"
+ echo "Paperless-ngx Secret Key: $SECRET_KEY\n"
+ echo "Paperless-ngx WebUI User: admin"
+ echo "Paperless-ngx WebUI Password: $DB_PASS"
+} >>~/paperless-ngx.creds
msg_ok "Set up admin Paperless-ngx User & Password"
msg_info "Creating Services"
From a3efa4e350df5f9e5f9ce735d0e1a95c4b71ba69 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:54:10 +0200
Subject: [PATCH 093/312] Update push-to-gitea.yml
---
.github/workflows/push-to-gitea.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/push-to-gitea.yml b/.github/workflows/push-to-gitea.yml
index 163ea035..c1fb72d5 100644
--- a/.github/workflows/push-to-gitea.yml
+++ b/.github/workflows/push-to-gitea.yml
@@ -27,7 +27,7 @@ jobs:
- name: Pull Gitea changes
run: |
git fetch gitea
- git rebase gitea/main
+ git merge --strategy=ours gitea/main
env:
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
From fef85f7064db80c73e6a696dab843f9eedacf123 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:55:20 +0200
Subject: [PATCH 094/312] Update paperless-ngx-install.sh
---
install/paperless-ngx-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh
index 92957802..4ddc0fc8 100644
--- a/install/paperless-ngx-install.sh
+++ b/install/paperless-ngx-install.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
+# Author: tteck (tteckster) | MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://docs.paperless-ngx.com/
From 507e732ca9dcc4e3bb770b9f7fdca2a45ad25730 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 10:57:57 +0200
Subject: [PATCH 095/312] Update dispatcharr-install.sh
---
install/dispatcharr-install.sh | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/install/dispatcharr-install.sh b/install/dispatcharr-install.sh
index 79546a2e..29e9457c 100644
--- a/install/dispatcharr-install.sh
+++ b/install/dispatcharr-install.sh
@@ -55,16 +55,12 @@ msg_ok "Set up PostgreSQL Database"
fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
-mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
-mkdir -p /etc/dispatcharr
-cp ~/.dispatcharr.creds /etc/dispatcharr/dispatcharr.env
-chown -R "$APP_USER:$APP_GROUP" {/etc/dispatcharr,/opt/dispatcharr,/data}
-
-sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "${APP_DIR}/apps/output/views.py"
-
-msg_ok "Downloaded Dispatcharr $LATEST_VERSION"
+#chown -R "$APP_USER:$APP_GROUP" {/etc/dispatcharr,/opt/dispatcharr,/data}
msg_info "Install Python Requirements"
+mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
+mkdir -p /etc/dispatcharr
+sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "/opt/dispatcharr/apps/output/views.py"
cd /opt/dispatcharr
python3 -m venv env
source env/bin/activate
From b342474da89fa7bf89faf443e25ac6835ff87cac Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:14:37 +0200
Subject: [PATCH 096/312] patch granian host
---
ct/paperless-ngx.sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 21d11e9a..997e7b16 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -75,6 +75,11 @@ function update_script() {
path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
if [[ -n "$path" && -f "$path" ]]; then
sed -i "s|^ExecStart=.*|${PATCHES[$svc]}|" "$path"
+ if [[ "$svc" == "paperless-webserver.service" ]]; then
+ grep -q "^Environment=GRANIAN_HOST=" "$path" || echo 'Environment=GRANIAN_HOST=::' >>"$path"
+ grep -q "^Environment=GRANIAN_PORT=" "$path" || echo 'Environment=GRANIAN_PORT=8000' >>"$path"
+ grep -q "^Environment=GRANIAN_WORKERS=" "$path" || echo 'Environment=GRANIAN_WORKERS=1' >>"$path"
+ fi
msg_ok "Patched $svc"
else
msg_error "Service file for $svc not found!"
From 3fd51d7a40248e5889f571c9ad79475348b27d1b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:32:44 +0200
Subject: [PATCH 097/312] fetch local templates
---
misc/create_lxc.sh | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index ea1749d2..72e0583a 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -258,34 +258,38 @@ fi
# Update LXC template list
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
-msg_info "Updating LXC Template List"
-if ! pveam update >/dev/null 2>&1; then
- TEMPLATE_FALLBACK=$(pveam list "$TEMPLATE_STORAGE" | awk "/$TEMPLATE_SEARCH/ {print \$2}" | sort -t - -k 2 -V | tail -n1)
- if [[ -z "$TEMPLATE_FALLBACK" ]]; then
- msg_error "Failed to update LXC template list and no local template matching '$TEMPLATE_SEARCH' found."
- exit 201
- fi
- msg_info "Skipping template update – using local fallback: $TEMPLATE_FALLBACK"
-else
- msg_ok "LXC Template List Updated"
-fi
-
-# Get LXC template string
-TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
-mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V)
+msg_info "Searching for online LXC template for '$TEMPLATE_SEARCH'..."
+mapfile -t TEMPLATES < <(
+ pveam update >/dev/null 2>&1 &&
+ pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
+)
+# If nothing found online, search local templates
if [ ${#TEMPLATES[@]} -eq 0 ]; then
- msg_error "No matching LXC template found for '${TEMPLATE_SEARCH}'. Make sure your host can reach the Proxmox template repository."
- exit 207
+ msg_info "Online search failed or no template found. Checking for local fallbacks..."
+ mapfile -t TEMPLATES < <(
+ pveam list "$TEMPLATE_STORAGE" | awk "/$TEMPLATE_SEARCH/ {print \$2}" | sort -t - -k 2 -V
+ )
+
+ if [ ${#TEMPLATES[@]} -eq 0 ]; then
+ msg_error "No online or local LXC template found for '${TEMPLATE_SEARCH}'. Please check network or install a template manually."
+ exit 207
+ fi
+ msg_ok "Found local fallback template."
+else
+ msg_ok "Found online template."
fi
+# Use the newest available template (last in sorted list)
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")"
+
msg_debug "TEMPLATE_SEARCH=$TEMPLATE_SEARCH"
msg_debug "TEMPLATES=(${TEMPLATES[*]})"
msg_debug "Selected TEMPLATE=$TEMPLATE"
msg_debug "TEMPLATE_PATH=$TEMPLATE_PATH"
+# Validate that template file exists and is not corrupted
TEMPLATE_VALID=1
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
TEMPLATE_VALID=0
From b3a6a0daefeaf02f6be8a6879e681e2c1cd83166 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:33:19 +0200
Subject: [PATCH 098/312] Update debian.sh
---
ct/debian.sh | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/ct/debian.sh b/ct/debian.sh
index 4bcf91d6..b7efad6c 100644
--- a/ct/debian.sh
+++ b/ct/debian.sh
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
+var_version="${var_version:-11}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-no}"
var_tun="${var_tun:-no}"
@@ -22,18 +22,18 @@ color
catch_errors
function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -d /var ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- msg_info "Updating $APP LXC"
- $STD apt-get update
- $STD apt-get -y upgrade
- msg_ok "Updated $APP LXC"
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /var ]]; then
+ msg_error "No ${APP} Installation Found!"
exit
+ fi
+ msg_info "Updating $APP LXC"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ msg_ok "Updated $APP LXC"
+ exit
}
start
From cd1e08b669812965be9d3d52dafa1c49b08beb05 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:35:08 +0200
Subject: [PATCH 099/312] Update create_lxc.sh
---
misc/create_lxc.sh | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 72e0583a..f54016af 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -264,11 +264,11 @@ mapfile -t TEMPLATES < <(
pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
)
-# If nothing found online, search local templates
+# If nothing found online, search local templates (file names only)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
msg_info "Online search failed or no template found. Checking for local fallbacks..."
mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" | awk "/$TEMPLATE_SEARCH/ {print \$2}" | sort -t - -k 2 -V
+ pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$2 ~ s {print $2}' | sort -t - -k 2 -V
)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
@@ -289,17 +289,15 @@ msg_debug "TEMPLATES=(${TEMPLATES[*]})"
msg_debug "Selected TEMPLATE=$TEMPLATE"
msg_debug "TEMPLATE_PATH=$TEMPLATE_PATH"
-# Validate that template file exists and is not corrupted
+# Validation: only run download logic if template came from online list
TEMPLATE_VALID=1
-if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
- TEMPLATE_VALID=0
-elif [ ! -s "$TEMPLATE_PATH" ]; then
+if [ ! -s "$TEMPLATE_PATH" ]; then
TEMPLATE_VALID=0
elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then
TEMPLATE_VALID=0
fi
-if [ "$TEMPLATE_VALID" -eq 0 ]; then
+if [ "$TEMPLATE_VALID" -eq 0 ] && [[ " ${TEMPLATES[*]} " =~ ".tar." ]]; then
msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading."
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
for attempt in {1..3}; do
From 454d95bd39e465417f8d1ad8e7e38d85e762bddb Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:37:52 +0200
Subject: [PATCH 100/312] Update create_lxc.sh
---
misc/create_lxc.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index f54016af..e171edb5 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -265,10 +265,11 @@ mapfile -t TEMPLATES < <(
)
# If nothing found online, search local templates (file names only)
+# If nothing found online, search local templates (extract filename from volume ID)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
msg_info "Online search failed or no template found. Checking for local fallbacks..."
mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$2 ~ s {print $2}' | sort -t - -k 2 -V
+ pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' | sed 's/.*\///' | sort -t - -k 2 -V
)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
From f37ff17081d116dd77f3cf6f8032ff9d835689f6 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:37:57 +0200
Subject: [PATCH 101/312] Update create_lxc.sh
---
misc/create_lxc.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index e171edb5..be70a487 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -264,7 +264,6 @@ mapfile -t TEMPLATES < <(
pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
)
-# If nothing found online, search local templates (file names only)
# If nothing found online, search local templates (extract filename from volume ID)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
msg_info "Online search failed or no template found. Checking for local fallbacks..."
From 2564c1c0df057b6c80873a48ddd048bd83ca0393 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:39:30 +0200
Subject: [PATCH 102/312] Update create_lxc.sh
---
misc/create_lxc.sh | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index be70a487..3b51e541 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -258,29 +258,30 @@ fi
# Update LXC template list
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
-msg_info "Searching for online LXC template for '$TEMPLATE_SEARCH'..."
+# 1. Check local templates first
+msg_info "Checking for local template for '$TEMPLATE_SEARCH'..."
mapfile -t TEMPLATES < <(
- pveam update >/dev/null 2>&1 &&
- pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
+ pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' | sed 's/.*\///' | sort -t - -k 2 -V
)
-# If nothing found online, search local templates (extract filename from volume ID)
-if [ ${#TEMPLATES[@]} -eq 0 ]; then
- msg_info "Online search failed or no template found. Checking for local fallbacks..."
+if [ ${#TEMPLATES[@]} -gt 0 ]; then
+ msg_ok "Found local template."
+else
+ # 2. If no local match, try online
+ msg_info "No local template found. Searching online..."
mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' | sed 's/.*\///' | sort -t - -k 2 -V
+ pveam update >/dev/null 2>&1 &&
+ pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
)
if [ ${#TEMPLATES[@]} -eq 0 ]; then
msg_error "No online or local LXC template found for '${TEMPLATE_SEARCH}'. Please check network or install a template manually."
exit 207
fi
- msg_ok "Found local fallback template."
-else
msg_ok "Found online template."
fi
-# Use the newest available template (last in sorted list)
+# 3. Use the newest template (last in sorted list)
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")"
@@ -289,7 +290,7 @@ msg_debug "TEMPLATES=(${TEMPLATES[*]})"
msg_debug "Selected TEMPLATE=$TEMPLATE"
msg_debug "TEMPLATE_PATH=$TEMPLATE_PATH"
-# Validation: only run download logic if template came from online list
+# 4. Validate template (exists & not corrupted)
TEMPLATE_VALID=1
if [ ! -s "$TEMPLATE_PATH" ]; then
TEMPLATE_VALID=0
@@ -297,8 +298,8 @@ elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1;
TEMPLATE_VALID=0
fi
-if [ "$TEMPLATE_VALID" -eq 0 ] && [[ " ${TEMPLATES[*]} " =~ ".tar." ]]; then
- msg_warn "Template $TEMPLATE not found or appears to be corrupted. Re-downloading."
+if [ "$TEMPLATE_VALID" -eq 0 ]; then
+ msg_warn "Template $TEMPLATE is missing or corrupted. Re-downloading."
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
for attempt in {1..3}; do
msg_info "Attempt $attempt: Downloading LXC template..."
From dc13b2e2855b7b04961c1cb68323a3fad1797cc7 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:40:06 +0200
Subject: [PATCH 103/312] Update create_lxc.sh
---
misc/create_lxc.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 3b51e541..98cc7016 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -6,7 +6,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# This sets verbose mode if the global variable is set to "yes"
-# if [ "$VERBOSE" == "yes" ]; then set -x; fi
+if [ "$CREATE_LXC_VERBOSE" == "yes" ]; then set -x; fi
if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
From 08ab05e07ebc5b47e62aebdbbc3cafb055b273ff Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:45:52 +0200
Subject: [PATCH 104/312] -
---
vm/debian-13-vm.sh | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/vm/debian-13-vm.sh b/vm/debian-13-vm.sh
index eeb0d106..b222ff90 100644
--- a/vm/debian-13-vm.sh
+++ b/vm/debian-13-vm.sh
@@ -11,9 +11,9 @@ function header_info {
cat <<"EOF"
____ __ _ ________
/ __ \___ / /_ (_)___ _____ < /__ /
- / / / / _ \/ __ \/ / __ `/ __ \ / / /_ <
- / /_/ / __/ /_/ / / /_/ / / / / / /___/ /
-/_____/\___/_.___/_/\__,_/_/ /_/ /_//____/
+ / / / / _ \/ __ \/ / __ `/ __ \ / / /_ <
+ / /_/ / __/ /_/ / / /_/ / / / / / /___/ /
+/_____/\___/_.___/_/\__,_/_/ /_/ /_//____/
(Trixie)
EOF
}
@@ -474,9 +474,9 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
msg_info "Retrieving the URL for the Debian 13 Qcow2 Disk Image"
if [ "$CLOUD_INIT" == "yes" ]; then
- URL=https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-genericcloud-amd64-daily.qcow2
+ URL=https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2
else
- URL=https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-nocloud-amd64-daily.qcow2
+ URL=https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-amd64.qcow2
fi
sleep 2
msg_ok "${CL}${BL}${URL}${CL}"
@@ -540,7 +540,7 @@ DESCRIPTION=$(
-
+
GitHub
From 18a88c362d1914c4343cd38733f7a8c089863b0c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 11:46:33 +0200
Subject: [PATCH 105/312] Update debian-13-vm.sh
---
vm/debian-13-vm.sh | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/vm/debian-13-vm.sh b/vm/debian-13-vm.sh
index b222ff90..05aa50bc 100644
--- a/vm/debian-13-vm.sh
+++ b/vm/debian-13-vm.sh
@@ -138,36 +138,37 @@ function check_root() {
fi
}
+# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
+# Supported: Proxmox VE 8.0.x – 8.9.x and 9.0 (NOT 9.1+)
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
- # Check for Proxmox VE 8.x
+ # Check for Proxmox VE 8.x: allow 8.0–8.9
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
- if ((MINOR < 1 || MINOR > 4)); then
+ if ((MINOR < 0 || MINOR > 9)); then
msg_error "This version of Proxmox VE is not supported."
- echo -e "Required: Proxmox VE version 8.1 – 8.4"
+ msg_error "Supported: Proxmox VE version 8.0 – 8.9"
exit 1
fi
return 0
fi
- # Check for Proxmox VE 9.x (Beta) — require confirmation
+ # Check for Proxmox VE 9.x: allow ONLY 9.0
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
- if whiptail --title "Proxmox 9.x Detected (Beta)" \
- --yesno "You are using Proxmox VE $PVE_VER, which is currently in Beta state.\n\nThis version is experimentally supported.\n\nDo you want to proceed anyway?" 12 70; then
- msg_ok "Confirmed: Continuing with Proxmox VE $PVE_VER"
- return 0
- else
- msg_error "Aborted by user: Proxmox VE 9.x was not confirmed."
+ local MINOR="${BASH_REMATCH[1]}"
+ if ((MINOR != 0)); then
+ msg_error "This version of Proxmox VE is not yet supported."
+ msg_error "Supported: Proxmox VE version 9.0"
exit 1
fi
+ return 0
fi
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
- echo -e "Supported versions: Proxmox VE 8.1 – 8.4 or 9.x (Beta, with confirmation)"
+ msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0"
exit 1
}
From b421208a02a8706dda9b2485a625a8a8098d291f Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:37:16 +0200
Subject: [PATCH 106/312] glances
---
tools/addon/glances.sh | 125 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 125 insertions(+)
create mode 100644 tools/addon/glances.sh
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
new file mode 100644
index 00000000..90012a9d
--- /dev/null
+++ b/tools/addon/glances.sh
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# License: MIT
+# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+
+function header_info {
+ clear
+ cat <<"EOF"
+ ________
+ / ____/ /___ _____ ________ _____
+ / / __/ / __ `/ __ \/ ___/ _ \/ ___/
+/ /_/ / / /_/ / / / / /__/ __(__ )
+\____/_/\__,_/_/ /_/\___/\___/____/
+
+EOF
+}
+IP=$(hostname -I | awk '{print $1}')
+YW=$(echo "\033[33m")
+BL=$(echo "\033[36m")
+RD=$(echo "\033[01;31m")
+BGN=$(echo "\033[4;92m")
+GN=$(echo "\033[1;92m")
+DGN=$(echo "\033[32m")
+CL=$(echo "\033[m")
+BFR="\\r\\033[K"
+HOLD=" "
+CM="${GN}✓${CL}"
+APP="Glances"
+hostname="$(hostname)"
+silent() { "$@" >/dev/null 2>&1; }
+set -e
+spinner() {
+ local chars="/-\|"
+ local spin_i=0
+ printf "\e[?25l"
+ while true; do
+ printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}"
+ sleep 0.1
+ done
+}
+
+msg_info() {
+ local msg="$1"
+ echo -ne " ${HOLD} ${YW}${msg} "
+ spinner &
+ SPINNER_PID=$!
+}
+
+msg_ok() {
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
+ printf "\e[?25h"
+ local msg="$1"
+ echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
+}
+
+install() {
+ header_info
+ while true; do
+ read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
+ case $yn in
+ [Yy]*) break ;;
+ [Nn]*) exit ;;
+ *) echo "Please answer yes or no." ;;
+ esac
+ done
+ header_info
+ read -r -p "Verbose mode? " prompt
+ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
+ STD=""
+ else
+ STD="silent"
+ fi
+ msg_info "Installing $APP"
+ rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
+ $STD bash -c "$(curl -fsSL https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)"
+ cat </etc/systemd/system/glances.service
+[Unit]
+Description=Glances - An eye on your system
+After=network.target
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/glances -w
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+EOF
+ systemctl enable -q --now glances.service
+ msg_ok "Installed $APP on $hostname"
+
+ echo -e "${APP} should be reachable by going to the following URL.
+ ${BL}http://$IP:61208${CL} \n"
+}
+uninstall() {
+ header_info
+ msg_info "Uninstalling $APP"
+ if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
+ systemctl disable -q --now glances
+ bash -c "$(curl -fsSL https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/uninstall.sh)"
+ rm -rf /etc/systemd/system/glances.service
+ msg_ok "Uninstalled $APP"
+ msg_ok "Completed Successfully!\n"
+}
+
+OPTIONS=(Install "Install $APP"
+ Uninstall "Uninstall $APP")
+
+CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$APP" --menu "Select an option:" 10 58 2 \
+ "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
+
+case $CHOICE in
+"Install")
+ install
+ ;;
+"Uninstall")
+ uninstall
+ ;;
+*)
+ echo "Exiting..."
+ exit 0
+ ;;
+esac
From 28441cbcd58bff1460bb4f5052dc4ec6650128ba Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:42:00 +0200
Subject: [PATCH 107/312] refactor: glances
---
tools/addon/glances.sh | 195 ++++++++++++++++++++++-------------------
1 file changed, 105 insertions(+), 90 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 90012a9d..9ae6b3cc 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -5,76 +5,39 @@
# License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-function header_info {
- clear
- cat <<"EOF"
- ________
- / ____/ /___ _____ ________ _____
- / / __/ / __ `/ __ \/ ___/ _ \/ ___/
-/ /_/ / / /_/ / / / / /__/ __(__ )
-\____/_/\__,_/_/ /_/\___/\___/____/
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func)
-EOF
-}
-IP=$(hostname -I | awk '{print $1}')
-YW=$(echo "\033[33m")
-BL=$(echo "\033[36m")
-RD=$(echo "\033[01;31m")
-BGN=$(echo "\033[4;92m")
-GN=$(echo "\033[1;92m")
-DGN=$(echo "\033[32m")
-CL=$(echo "\033[m")
-BFR="\\r\\033[K"
-HOLD=" "
-CM="${GN}✓${CL}"
APP="Glances"
+IP=$(hostname -I | awk '{print $1}')
hostname="$(hostname)"
-silent() { "$@" >/dev/null 2>&1; }
-set -e
-spinner() {
- local chars="/-\|"
- local spin_i=0
- printf "\e[?25l"
- while true; do
- printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}"
- sleep 0.1
- done
-}
-msg_info() {
- local msg="$1"
- echo -ne " ${HOLD} ${YW}${msg} "
- spinner &
- SPINNER_PID=$!
-}
+header_info "$APP"
+catch_errors
-msg_ok() {
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
- printf "\e[?25h"
- local msg="$1"
- echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
-}
+# install on Debian/Ubuntu
+install_glances_debian() {
+ msg_info "Installing dependencies"
+ $STD apt-get update
+ $STD apt-get install -y gcc lm-sensors wireless-tools
+ msg_ok "Installed dependencies"
-install() {
- header_info
- while true; do
- read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
- case $yn in
- [Yy]*) break ;;
- [Nn]*) exit ;;
- *) echo "Please answer yes or no." ;;
- esac
- done
- header_info
- read -r -p "Verbose mode? " prompt
- if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
- STD=""
- else
- STD="silent"
- fi
- msg_info "Installing $APP"
- rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
- $STD bash -c "$(curl -fsSL https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/install.sh)"
+ msg_info "Setting up Python + uv"
+ setup_uv PYTHON_VERSION="3.12"
+ msg_ok "Setup Python + uv"
+
+ msg_info "Installing $APP (with web UI)"
+ cd /opt
+ mkdir -p glances
+ cd glances
+ uv venv
+ source .venv/bin/activate
+ uv pip install --upgrade pip wheel setuptools
+ uv pip install "glances[web]"
+ deactivate
+ msg_ok "Installed $APP"
+
+ msg_info "Creating systemd service"
cat </etc/systemd/system/glances.service
[Unit]
Description=Glances - An eye on your system
@@ -82,44 +45,96 @@ After=network.target
[Service]
Type=simple
-ExecStart=/usr/local/bin/glances -w
+ExecStart=/opt/glances/.venv/bin/glances -w
Restart=on-failure
+WorkingDirectory=/opt/glances
[Install]
WantedBy=multi-user.target
EOF
- systemctl enable -q --now glances.service
- msg_ok "Installed $APP on $hostname"
+ systemctl enable -q --now glances
+ msg_ok "Created systemd service"
- echo -e "${APP} should be reachable by going to the following URL.
- ${BL}http://$IP:61208${CL} \n"
+ echo -e "\n$APP is now running at: http://$IP:61208\n"
}
-uninstall() {
- header_info
+
+# uninstall on Debian/Ubuntu
+uninstall_glances_debian() {
msg_info "Uninstalling $APP"
- if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
- systemctl disable -q --now glances
- bash -c "$(curl -fsSL https://raw.githubusercontent.com/nicolargo/glancesautoinstall/master/uninstall.sh)"
- rm -rf /etc/systemd/system/glances.service
- msg_ok "Uninstalled $APP"
- msg_ok "Completed Successfully!\n"
+ systemctl disable -q --now glances || true
+ rm -f /etc/systemd/system/glances.service
+ rm -rf /opt/glances
+ msg_ok "Removed $APP"
}
+# install on Alpine
+install_glances_alpine() {
+ msg_info "Installing dependencies"
+ $STD apk update
+ $STD apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools
+ msg_ok "Installed dependencies"
+
+ msg_info "Setting up Python + uv"
+ setup_uv PYTHON_VERSION="3.12"
+ msg_ok "Setup Python + uv"
+
+ msg_info "Installing $APP (with web UI)"
+ cd /opt
+ mkdir -p glances
+ cd glances
+ uv venv
+ source .venv/bin/activate
+ uv pip install --upgrade pip wheel setuptools
+ uv pip install "glances[web]"
+ deactivate
+ msg_ok "Installed $APP"
+
+ msg_info "Creating OpenRC service"
+ cat <<'EOF' >/etc/init.d/glances
+#!/sbin/openrc-run
+command="/opt/glances/.venv/bin/glances"
+command_args="-w"
+command_background="yes"
+pidfile="/run/glances.pid"
+name="glances"
+description="Glances monitoring tool"
+EOF
+ chmod +x /etc/init.d/glances
+ rc-update add glances default
+ rc-service glances start
+ msg_ok "Created OpenRC service"
+
+ echo -e "\n$APP is now running at: http://$IP:61208\n"
+}
+
+# uninstall on Alpine
+uninstall_glances_alpine() {
+ msg_info "Uninstalling $APP"
+ rc-service glances stop || true
+ rc-update del glances || true
+ rm -f /etc/init.d/glances
+ rm -rf /opt/glances
+ msg_ok "Removed $APP"
+}
+
+# options menu
OPTIONS=(Install "Install $APP"
Uninstall "Uninstall $APP")
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$APP" --menu "Select an option:" 10 58 2 \
- "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
+ "${OPTIONS[@]}" 3>&1 1>&2 2>&3 || true)
-case $CHOICE in
-"Install")
- install
- ;;
-"Uninstall")
- uninstall
- ;;
-*)
- echo "Exiting..."
- exit 0
- ;;
-esac
+# OS detection
+if grep -qi "alpine" /etc/os-release; then
+ case "$CHOICE" in
+ Install) install_glances_alpine ;;
+ Uninstall) uninstall_glances_alpine ;;
+ *) exit 0 ;;
+ esac
+else
+ case "$CHOICE" in
+ Install) install_glances_debian ;;
+ Uninstall) uninstall_glances_debian ;;
+ *) exit 0 ;;
+ esac
+fi
From e1937486577e91c8899be32a67d1164014ed37f5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:44:16 +0200
Subject: [PATCH 108/312] Update glances.sh
---
tools/addon/glances.sh | 36 ++++++++++++++++++++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 9ae6b3cc..adee17b5 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -15,7 +15,6 @@ hostname="$(hostname)"
header_info "$APP"
catch_errors
-# install on Debian/Ubuntu
install_glances_debian() {
msg_info "Installing dependencies"
$STD apt-get update
@@ -58,6 +57,21 @@ EOF
echo -e "\n$APP is now running at: http://$IP:61208\n"
}
+# update on Debian/Ubuntu
+update_glances_debian() {
+ if [[ ! -d /opt/glances/.venv ]]; then
+ msg_error "$APP is not installed"
+ exit 1
+ fi
+ msg_info "Updating $APP"
+ cd /opt/glances
+ source .venv/bin/activate
+ uv pip install --upgrade "glances[web]"
+ deactivate
+ systemctl restart glances
+ msg_ok "Updated $APP"
+}
+
# uninstall on Debian/Ubuntu
uninstall_glances_debian() {
msg_info "Uninstalling $APP"
@@ -107,6 +121,21 @@ EOF
echo -e "\n$APP is now running at: http://$IP:61208\n"
}
+# update on Alpine
+update_glances_alpine() {
+ if [[ ! -d /opt/glances/.venv ]]; then
+ msg_error "$APP is not installed"
+ exit 1
+ fi
+ msg_info "Updating $APP"
+ cd /opt/glances
+ source .venv/bin/activate
+ uv pip install --upgrade "glances[web]"
+ deactivate
+ rc-service glances restart
+ msg_ok "Updated $APP"
+}
+
# uninstall on Alpine
uninstall_glances_alpine() {
msg_info "Uninstalling $APP"
@@ -119,21 +148,24 @@ uninstall_glances_alpine() {
# options menu
OPTIONS=(Install "Install $APP"
+ Update "Update $APP"
Uninstall "Uninstall $APP")
-CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$APP" --menu "Select an option:" 10 58 2 \
+CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "$APP" --menu "Select an option:" 12 58 3 \
"${OPTIONS[@]}" 3>&1 1>&2 2>&3 || true)
# OS detection
if grep -qi "alpine" /etc/os-release; then
case "$CHOICE" in
Install) install_glances_alpine ;;
+ Update) update_glances_alpine ;;
Uninstall) uninstall_glances_alpine ;;
*) exit 0 ;;
esac
else
case "$CHOICE" in
Install) install_glances_debian ;;
+ Update) update_glances_debian ;;
Uninstall) uninstall_glances_debian ;;
*) exit 0 ;;
esac
From 7fd2744efa7ae2aa87945583e7c1bc9ba7f385ac Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:45:09 +0200
Subject: [PATCH 109/312] Update glances.sh
---
tools/addon/glances.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index adee17b5..15a594ee 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -13,7 +13,6 @@ IP=$(hostname -I | awk '{print $1}')
hostname="$(hostname)"
header_info "$APP"
-catch_errors
install_glances_debian() {
msg_info "Installing dependencies"
From 5ff16518d26b11fe74d845052f2a19983d260bf7 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:46:15 +0200
Subject: [PATCH 110/312] Update glances.sh
---
tools/addon/glances.sh | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 15a594ee..50eb7871 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -1,18 +1,36 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT
-# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Author: tteck (tteckster) | MickLesk (CanbiZ)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/core.func)
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func)
+function header_info {
+ clear
+ cat <<"EOF"
+ ________
+ / ____/ /___ _____ ________ _____
+ / / __/ / __ `/ __ \/ ___/ _ \/ ___/
+/ /_/ / / /_/ / / / / /__/ __(__ )
+\____/_/\__,_/_/ /_/\___/\___/____/
+
+EOF
+}
APP="Glances"
IP=$(hostname -I | awk '{print $1}')
hostname="$(hostname)"
+YW=$(echo "\033[33m")
+GN=$(echo "\033[1;92m")
+RD=$(echo "\033[01;31m")
+BL=$(echo "\033[36m")
+CL=$(echo "\033[m")
+CM="${GN}✔️${CL}"
+CROSS="${RD}✖️${CL}"
+INFO="${BL}ℹ️${CL}"
-header_info "$APP"
+function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
+function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
+function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
install_glances_debian() {
msg_info "Installing dependencies"
From 47cbeed528a1d566fb1b39fb85fae9cf0eb8cbec Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:48:40 +0200
Subject: [PATCH 111/312] Update glances.sh
---
tools/addon/glances.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 50eb7871..1bd6e4da 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -39,6 +39,7 @@ install_glances_debian() {
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
+ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv"
From 5c41d05c5ac5315fa17e781ab7da41274ef2bb27 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:49:37 +0200
Subject: [PATCH 112/312] Update glances.sh
---
tools/addon/glances.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 1bd6e4da..67bbfc54 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -34,8 +34,8 @@ function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
install_glances_debian() {
msg_info "Installing dependencies"
- $STD apt-get update
- $STD apt-get install -y gcc lm-sensors wireless-tools
+ apt-get update
+ apt-get install -y gcc lm-sensors wireless-tools
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
@@ -102,8 +102,8 @@ uninstall_glances_debian() {
# install on Alpine
install_glances_alpine() {
msg_info "Installing dependencies"
- $STD apk update
- $STD apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools
+ apk update
+ apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
From 10775c356c0bc8c082fdb218edd2fc1ccf32264d Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:53:09 +0200
Subject: [PATCH 113/312] Update glances.sh
---
tools/addon/glances.sh | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 67bbfc54..0e5999e3 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -34,8 +34,8 @@ function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
install_glances_debian() {
msg_info "Installing dependencies"
- apt-get update
- apt-get install -y gcc lm-sensors wireless-tools
+ apt-get update >/dev/null 2>&1
+ apt-get install -y gcc lm-sensors wireless-tools >/dev/null 2>&1
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
@@ -48,9 +48,9 @@ install_glances_debian() {
mkdir -p glances
cd glances
uv venv
- source .venv/bin/activate
- uv pip install --upgrade pip wheel setuptools
- uv pip install "glances[web]"
+ source .venv/bin/activate >/dev/null 2>&1
+ uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
+ uv pip install "glances[web]" >/dev/null 2>&1
deactivate
msg_ok "Installed $APP"
@@ -84,7 +84,7 @@ update_glances_debian() {
msg_info "Updating $APP"
cd /opt/glances
source .venv/bin/activate
- uv pip install --upgrade "glances[web]"
+ uv pip install --upgrade "glances[web]" >/dev/null 2>&1
deactivate
systemctl restart glances
msg_ok "Updated $APP"
@@ -102,8 +102,8 @@ uninstall_glances_debian() {
# install on Alpine
install_glances_alpine() {
msg_info "Installing dependencies"
- apk update
- apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools
+ apk update >/dev/null 2>&1
+ apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools >/dev/null 2>&1
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
@@ -116,8 +116,8 @@ install_glances_alpine() {
cd glances
uv venv
source .venv/bin/activate
- uv pip install --upgrade pip wheel setuptools
- uv pip install "glances[web]"
+ uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
+ uv pip install "glances[web]" >/dev/null 2>&1
deactivate
msg_ok "Installed $APP"
@@ -148,7 +148,7 @@ update_glances_alpine() {
msg_info "Updating $APP"
cd /opt/glances
source .venv/bin/activate
- uv pip install --upgrade "glances[web]"
+ uv pip install --upgrade "glances[web]" >/dev/null 2>&1
deactivate
rc-service glances restart
msg_ok "Updated $APP"
From 6dee16a15dee2b42a1ee6b1a4c684ab3392f2722 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 12:54:20 +0200
Subject: [PATCH 114/312] Update glances.sh
---
tools/addon/glances.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index 0e5999e3..bd735e34 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -107,6 +107,7 @@ install_glances_alpine() {
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
+ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv"
From ed15393554209ab1b81006a1889fe4b09f2120d9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:06:00 +0200
Subject: [PATCH 115/312] extend setup_uv
---
misc/tools.func | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index f8797426..6014c0d5 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -1283,8 +1283,20 @@ function setup_uv() {
local UV_TAR
case "$ARCH" in
- x86_64) UV_TAR="uv-x86_64-unknown-linux-gnu.tar.gz" ;;
- aarch64) UV_TAR="uv-aarch64-unknown-linux-gnu.tar.gz" ;;
+ x86_64)
+ if grep -qi "alpine" /etc/os-release; then
+ UV_TAR="uv-x86_64-unknown-linux-musl.tar.gz"
+ else
+ UV_TAR="uv-x86_64-unknown-linux-gnu.tar.gz"
+ fi
+ ;;
+ aarch64)
+ if grep -qi "alpine" /etc/os-release; then
+ UV_TAR="uv-aarch64-unknown-linux-musl.tar.gz"
+ else
+ UV_TAR="uv-aarch64-unknown-linux-gnu.tar.gz"
+ fi
+ ;;
*)
msg_error "Unsupported architecture: $ARCH"
rm -rf "$TMP_DIR"
From c486b7b0354ab971fd84c039f615cbe513d9d1a5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:18:21 +0200
Subject: [PATCH 116/312] Update glances.sh
---
tools/addon/glances.sh | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/tools/addon/glances.sh b/tools/addon/glances.sh
index bd735e34..0f1b76f1 100644
--- a/tools/addon/glances.sh
+++ b/tools/addon/glances.sh
@@ -17,8 +17,6 @@ EOF
}
APP="Glances"
-IP=$(hostname -I | awk '{print $1}')
-hostname="$(hostname)"
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
@@ -32,6 +30,17 @@ function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
+get_local_ip() {
+ if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
+ hostname -I | awk '{print $1}'
+ elif command -v ip >/dev/null 2>&1; then
+ ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1
+ else
+ echo "127.0.0.1"
+ fi
+}
+IP=$(get_local_ip)
+
install_glances_debian() {
msg_info "Installing dependencies"
apt-get update >/dev/null 2>&1
@@ -103,7 +112,9 @@ uninstall_glances_debian() {
install_glances_alpine() {
msg_info "Installing dependencies"
apk update >/dev/null 2>&1
- apk add --no-cache gcc musl-dev python3 py3-pip py3-virtualenv lm-sensors wireless-tools >/dev/null 2>&1
+ $STD apk add --no-cache \
+ gcc musl-dev linux-headers python3-dev \
+ python3 py3-pip py3-virtualenv lm-sensors wireless-tools >/dev/null 2>&1
msg_ok "Installed dependencies"
msg_info "Setting up Python + uv"
From 6468f332e8f7d06bad84c8265b28387b60a21ab1 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:20:04 +0200
Subject: [PATCH 117/312] Update build.func
---
misc/build.func | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/build.func b/misc/build.func
index c40a57bd..8a58664f 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1219,7 +1219,7 @@ EOF
if [[ "${#combo_devices[@]}" -eq 1 && -e /dev/dri/card0 ]]; then
combo_devices+=("/dev/dri/card0")
fi
- echo "combo_devices=${combo_devices[*]}"
+ #echo "combo_devices=${combo_devices[*]}"
pci_addr=$(basename "$bypath" | cut -d- -f1 --complement | sed 's/-render//' || true)
pci_info=$(lspci -nn | grep "${pci_addr#0000:}" || true)
From 2587aa41451d5fdb7deb2518d27c832cae96440b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:22:19 +0200
Subject: [PATCH 118/312] feat: use storage as name
---
misc/create_lxc.sh | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 98cc7016..7ca7e40a 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -63,9 +63,10 @@ function check_storage_support() {
local -a VALID_STORAGES=()
while IFS= read -r line; do
- local STORAGE=$(awk '{print $1}' <<<"$line")
- [[ "$STORAGE" == "storage" || -z "$STORAGE" ]] && continue
- VALID_STORAGES+=("$STORAGE")
+ local STORAGE_NAME
+ STORAGE_NAME=$(awk '{print $1}' <<<"$line")
+ [[ -z "$STORAGE_NAME" ]] && continue
+ VALID_STORAGES+=("$STORAGE_NAME")
done < <(pvesm status -content "$CONTENT" 2>/dev/null | awk 'NR>1')
[[ ${#VALID_STORAGES[@]} -gt 0 ]]
@@ -124,11 +125,12 @@ function select_storage() {
while read -r TAG TYPE _ TOTAL USED FREE _; do
[[ -n "$TAG" && -n "$TYPE" ]] || continue
- local DISPLAY="${TAG} (${TYPE})"
+ local STORAGE_NAME="$TAG"
+ local DISPLAY="${STORAGE_NAME} (${TYPE})"
local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED")
local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE")
local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B"
- STORAGE_MAP["$DISPLAY"]="$TAG"
+ STORAGE_MAP["$DISPLAY"]="$STORAGE_NAME"
MENU+=("$DISPLAY" "$INFO" "OFF")
((${#DISPLAY} > COL_WIDTH)) && COL_WIDTH=${#DISPLAY}
done < <(pvesm status -content "$CONTENT" | awk 'NR>1')
From b9c7b658e535aacc7e6eef658a266037b92a7c4e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:39:25 +0200
Subject: [PATCH 119/312] better msg's
---
misc/create_lxc.sh | 49 ++++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 7ca7e40a..6cdfed5c 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -205,39 +205,35 @@ if qm status "$CTID" &>/dev/null || pct status "$CTID" &>/dev/null; then
fi
# This checks for the presence of valid Container Storage and Template Storage locations
-msg_info "Validating Storage"
+msg_info "Validating storage"
if ! check_storage_support "rootdir"; then
- msg_error "No valid storage found for 'rootdir' (Container)."
- msg_debug "check_storage_support('rootdir') → success"
+ msg_error "No valid storage found for 'rootdir' [Container]"
exit 1
fi
if ! check_storage_support "vztmpl"; then
- msg_error "No valid storage found for 'vztmpl' (Template)."
- msg_debug "check_storage_support('vztmpl') → success"
+ msg_error "No valid storage found for 'vztmpl' [Template]"
exit 1
fi
-msg_ok "Valid Storage Found"
+msg_info "Checking template storage"
while true; do
if select_storage template; then
TEMPLATE_STORAGE="$STORAGE_RESULT"
TEMPLATE_STORAGE_INFO="$STORAGE_INFO"
- msg_debug "TEMPLATE_STORAGE=$TEMPLATE_STORAGE"
- msg_debug "TEMPLATE_STORAGE_INFO=$TEMPLATE_STORAGE_INFO"
+ msg_ok "Storage ${BL}$TEMPLATE_STORAGE${CL} ($TEMPLATE_STORAGE_INFO) [Template]"
break
fi
done
+msg_info "Checking container storage"
while true; do
if select_storage container; then
CONTAINER_STORAGE="$STORAGE_RESULT"
CONTAINER_STORAGE_INFO="$STORAGE_INFO"
- msg_debug "CONTAINER_STORAGE=$CONTAINER_STORAGE"
- msg_debug "CONTAINER_STORAGE_INFO=$CONTAINER_STORAGE_INFO"
+ msg_ok "Storage ${BL}$CONTAINER_STORAGE${CL} ($CONTAINER_STORAGE_INFO) [Container]"
break
fi
done
-msg_ok "Validated Storage | Container: ${BL}$CONTAINER_STORAGE${CL} ($CONTAINER_STORAGE_INFO)"
# Check free space on selected container storage
STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }')
@@ -246,11 +242,11 @@ if [ "$STORAGE_FREE" -lt "$REQUIRED_KB" ]; then
msg_error "Not enough space on '$CONTAINER_STORAGE'. Needed: ${PCT_DISK_SIZE:-8}G."
exit 214
fi
+
# Check Cluster Quorum if in Cluster
if [ -f /etc/pve/corosync.conf ]; then
- msg_info "Checking Proxmox cluster quorum status"
+ msg_info "Checking cluster quorum"
if ! pvecm status | awk -F':' '/^Quorate/ { exit ($2 ~ /Yes/) ? 0 : 1 }'; then
- printf "\e[?25h"
msg_error "Cluster is not quorate. Start all nodes or configure quorum device (QDevice)."
exit 210
fi
@@ -261,31 +257,28 @@ fi
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
# 1. Check local templates first
-msg_info "Checking for local template for '$TEMPLATE_SEARCH'..."
+msg_info "Searching for template '$TEMPLATE_SEARCH'"
mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' | sed 's/.*\///' | sort -t - -k 2 -V
+ pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' |
+ sed 's/.*\///' | sort -t - -k 2 -V
)
if [ ${#TEMPLATES[@]} -gt 0 ]; then
- msg_ok "Found local template."
+ TEMPLATE_SOURCE="local"
else
- # 2. If no local match, try online
- msg_info "No local template found. Searching online..."
+ msg_info "No local template found, checking online repository"
+ pveam update >/dev/null 2>&1
mapfile -t TEMPLATES < <(
- pveam update >/dev/null 2>&1 &&
- pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V
+ pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" |
+ sort -t - -k 2 -V
)
-
- if [ ${#TEMPLATES[@]} -eq 0 ]; then
- msg_error "No online or local LXC template found for '${TEMPLATE_SEARCH}'. Please check network or install a template manually."
- exit 207
- fi
- msg_ok "Found online template."
+ TEMPLATE_SOURCE="online"
fi
-# 3. Use the newest template (last in sorted list)
TEMPLATE="${TEMPLATES[-1]}"
-TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || echo "/var/lib/vz/template/cache/$TEMPLATE")"
+TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null ||
+ echo "/var/lib/vz/template/cache/$TEMPLATE")"
+msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
msg_debug "TEMPLATE_SEARCH=$TEMPLATE_SEARCH"
msg_debug "TEMPLATES=(${TEMPLATES[*]})"
From 3a20ca1f9b70be723fc060e704bc3e3c5f63e8d0 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 13:39:29 +0200
Subject: [PATCH 120/312] Traefik fixes
---
install/traefik-install.sh | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index 7507a8a8..0e3a4db2 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -110,7 +110,7 @@ EOF
msg_ok "Created Traefik configuration"
msg_info "Creating Service"
-cat </etc/systemd/system/traefik.service
+cat <<'EOF' >/etc/systemd/system/traefik.service
[Unit]
Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience
@@ -128,7 +128,7 @@ systemctl enable -q --now traefik
msg_ok "Created Service"
msg_info "Creating site templates"
-cat </etc/traefik/template.yaml.tpl
+cat <<'EOF' >/etc/traefik/template.yaml.tpl
http:
routers:
${hostname}:
@@ -142,9 +142,10 @@ http:
servers:
- url: "${URL}"
EOF
-msg_ok: "Template Created"
-msg_info: "Creating Helper Scripts"
-cat </usr/bin/addsite
+msg_ok "Template Created"
+
+msg_info "Creating Helper Scripts"
+cat <<'EOF' >/usr/bin/addsite
#!/bin/bash
function setup_site() {
@@ -164,7 +165,7 @@ function setup_site() {
setup_site
EOF
-cat </usr/bin/ensite
+cat <<'EOF' >/usr/bin/ensite
#!/bin/bash
function ensite() {
@@ -193,7 +194,7 @@ function ensite() {
ensite
EOF
-cat </usr/bin/dissite
+cat <<'EOF' >/usr/bin/dissite
#!/bin/bash
function dissite() {
@@ -223,7 +224,7 @@ function dissite() {
dissite
EOF
-cat </usr/bin/editsite
+cat <<'EOF' >/usr/bin/editsite
#!/bin/bash
function edit_site() {
From eaebea6c35f649e85902bb64f21d956dd8fda483 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 13:40:36 +0200
Subject: [PATCH 121/312] Traefik fixes
---
install/traefik-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index 0e3a4db2..eb2fcb24 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -28,7 +28,7 @@ echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
msg_ok "Installed Traefik v${RELEASE}"
msg_info "Creating Traefik configuration"
-cat </etc/traefik/traefik.yaml
+cat <<'EOF' >/etc/traefik/traefik.yaml
providers:
file:
directory: /etc/traefik/conf.d/
From 429a50d498c673286fba489764d7b1be95a3758f Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 19 Aug 2025 13:45:05 +0200
Subject: [PATCH 122/312] better msgs
---
misc/create_lxc.sh | 3 ---
1 file changed, 3 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 6cdfed5c..db73f0a3 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -225,7 +225,6 @@ while true; do
fi
done
-msg_info "Checking container storage"
while true; do
if select_storage container; then
CONTAINER_STORAGE="$STORAGE_RESULT"
@@ -310,8 +309,6 @@ if [ "$TEMPLATE_VALID" -eq 0 ]; then
done
fi
-msg_ok "LXC Template '$TEMPLATE' is ready to use."
-
msg_info "Creating LXC Container"
# Check and fix subuid/subgid
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
From 9e23e43fc8022084647e5f43d4021eca46598ee1 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 13:55:06 +0200
Subject: [PATCH 123/312] Traefik fixes
---
install/traefik-install.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index eb2fcb24..3f3dc2fb 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -165,6 +165,7 @@ function setup_site() {
setup_site
EOF
+
cat <<'EOF' >/usr/bin/ensite
#!/bin/bash
@@ -194,6 +195,7 @@ function ensite() {
ensite
EOF
+
cat <<'EOF' >/usr/bin/dissite
#!/bin/bash
From 587cfd883a6cddf27e1b6dab540afd50cc34d323 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 15:25:26 +0200
Subject: [PATCH 124/312] Traefik fixes
---
install/traefik-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index 3f3dc2fb..9191d6c6 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -149,6 +149,7 @@ cat <<'EOF' >/usr/bin/addsite
#!/bin/bash
function setup_site() {
+ set -e
hostname="$(whiptail --inputbox "Enter the hostname of the Site" 8 78 --title "Hostname" 3>&1 1>&2 2>&3)"
exitstatus=$?
[[ "$exitstatus" = 1 ]] && return;
From 43a2047e1199466161dd0f033572088a9faee5bc Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 15:32:17 +0200
Subject: [PATCH 125/312] Traefik fixes
---
install/traefik-install.sh | 30 +++++++++++-------------------
1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index 9191d6c6..e65811ed 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -145,26 +145,18 @@ EOF
msg_ok "Template Created"
msg_info "Creating Helper Scripts"
-cat <<'EOF' >/usr/bin/addsite
-#!/bin/bash
+install -Dm0755 /dev/stdin /usr/local/bin/addsite <<'EOF'
+#!/usr/bin/env bash
-function setup_site() {
- set -e
- hostname="$(whiptail --inputbox "Enter the hostname of the Site" 8 78 --title "Hostname" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- FQDN="$(whiptail --inputbox "Enter the FQDN of the Site" 8 78 --title "FQDN" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- URL="$(whiptail --inputbox "Enter the URL of the Site (For example http://192.168.x.x:8080)" 8 78 --title "URL" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- filename="/etc/traefik/sites-available/${hostname}.yaml"
- export hostname FQDN URL
- envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > ${filename}
-}
-
-setup_site
+set -e
+hostname="$(whiptail --inputbox 'Enter the hostname of the Site' 8 78 --title 'Hostname' 3>&1 1>&2 2>&3)" || exit 0
+FQDN="$(whiptail --inputbox 'Enter the FQDN of the Site' 8 78 --title 'FQDN' 3>&1 1>&2 2>&3)" || exit 0
+URL="$(whiptail --inputbox 'Enter the URL of the Site (e.g. http://192.168.x.x:8080)' 8 78 --title 'URL' 3>&1 1>&2 2>&3)" || exit 0
+mkdir -p /etc/traefik/sites-available
+filename="/etc/traefik/sites-available/${hostname}.yaml"
+export hostname FQDN URL
+envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > "$filename"
+echo "Wrote $filename"
EOF
cat <<'EOF' >/usr/bin/ensite
From 320d4e7eb21dda2b88ecbd878716f780246a112b Mon Sep 17 00:00:00 2001
From: tremor021
Date: Tue, 19 Aug 2025 15:36:28 +0200
Subject: [PATCH 126/312] Traefik fixes
---
install/traefik-install.sh | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
index e65811ed..3f3dc2fb 100644
--- a/install/traefik-install.sh
+++ b/install/traefik-install.sh
@@ -145,18 +145,25 @@ EOF
msg_ok "Template Created"
msg_info "Creating Helper Scripts"
-install -Dm0755 /dev/stdin /usr/local/bin/addsite <<'EOF'
-#!/usr/bin/env bash
+cat <<'EOF' >/usr/bin/addsite
+#!/bin/bash
-set -e
-hostname="$(whiptail --inputbox 'Enter the hostname of the Site' 8 78 --title 'Hostname' 3>&1 1>&2 2>&3)" || exit 0
-FQDN="$(whiptail --inputbox 'Enter the FQDN of the Site' 8 78 --title 'FQDN' 3>&1 1>&2 2>&3)" || exit 0
-URL="$(whiptail --inputbox 'Enter the URL of the Site (e.g. http://192.168.x.x:8080)' 8 78 --title 'URL' 3>&1 1>&2 2>&3)" || exit 0
-mkdir -p /etc/traefik/sites-available
-filename="/etc/traefik/sites-available/${hostname}.yaml"
-export hostname FQDN URL
-envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > "$filename"
-echo "Wrote $filename"
+function setup_site() {
+ hostname="$(whiptail --inputbox "Enter the hostname of the Site" 8 78 --title "Hostname" 3>&1 1>&2 2>&3)"
+ exitstatus=$?
+ [[ "$exitstatus" = 1 ]] && return;
+ FQDN="$(whiptail --inputbox "Enter the FQDN of the Site" 8 78 --title "FQDN" 3>&1 1>&2 2>&3)"
+ exitstatus=$?
+ [[ "$exitstatus" = 1 ]] && return;
+ URL="$(whiptail --inputbox "Enter the URL of the Site (For example http://192.168.x.x:8080)" 8 78 --title "URL" 3>&1 1>&2 2>&3)"
+ exitstatus=$?
+ [[ "$exitstatus" = 1 ]] && return;
+ filename="/etc/traefik/sites-available/${hostname}.yaml"
+ export hostname FQDN URL
+ envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > ${filename}
+}
+
+setup_site
EOF
cat <<'EOF' >/usr/bin/ensite
From c2cdecbe19877ba0fef851d94974f1308e7456dd Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 08:24:06 +0200
Subject: [PATCH 127/312] debug output
---
misc/create_lxc.sh | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index db73f0a3..c986bd7b 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -6,7 +6,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# This sets verbose mode if the global variable is set to "yes"
-if [ "$CREATE_LXC_VERBOSE" == "yes" ]; then set -x; fi
+if [ "$VERBOSE" == "yes" ]; then set -x; fi
if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
@@ -254,11 +254,24 @@ fi
# Update LXC template list
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
+case "$PCT_OSTYPE" in
+ debian|ubuntu)
+ TEMPLATE_PATTERN="-standard_"
+ ;;
+ alpine|fedora|rocky|centos)
+ TEMPLATE_PATTERN="-default_"
+ ;;
+ *)
+ TEMPLATE_PATTERN=""
+ ;;
+esac
+
# 1. Check local templates first
msg_info "Searching for template '$TEMPLATE_SEARCH'"
mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" | awk -v s="$TEMPLATE_SEARCH" '$1 ~ s {print $1}' |
+ pveam list "$TEMPLATE_STORAGE" |
+ awk -v s="$TEMPLATE_SEARCH" -v p="$TEMPLATE_PATTERN" '$1 ~ s && $1 ~ p {print $1}' |
sed 's/.*\///' | sort -t - -k 2 -V
)
@@ -268,12 +281,15 @@ else
msg_info "No local template found, checking online repository"
pveam update >/dev/null 2>&1
mapfile -t TEMPLATES < <(
- pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" |
+ pveam update >/dev/null 2>&1 &&
+ pveam available -section system |
+ sed -n "s/.*\($TEMPLATE_SEARCH.*$TEMPLATE_PATTERN.*\)/\1/p" |
sort -t - -k 2 -V
)
TEMPLATE_SOURCE="online"
fi
+
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null ||
echo "/var/lib/vz/template/cache/$TEMPLATE")"
From c1265d940c31aaf190018c1cc682efb1b0d30d0c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 10:56:17 +0200
Subject: [PATCH 128/312] test
---
ct/debian.sh | 2 +-
install/debian-install.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ct/debian.sh b/ct/debian.sh
index b7efad6c..a21a5e3f 100644
--- a/ct/debian.sh
+++ b/ct/debian.sh
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
-var_version="${var_version:-11}"
+var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-no}"
var_tun="${var_tun:-no}"
diff --git a/install/debian-install.sh b/install/debian-install.sh
index fcca74fc..ca9567b9 100644
--- a/install/debian-install.sh
+++ b/install/debian-install.sh
@@ -35,7 +35,7 @@ setup_mariadb
#msg_ok "Get Release $RELEASE"
#NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
-#PG_VERSION="16" setup_postgresql
+PG_VERSION="16" setup_postgresql
motd_ssh
customize
From afb98a7e4aa885d0fc4af8214befc0947ee557c4 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 10:57:13 +0200
Subject: [PATCH 129/312] Update debian.sh
---
ct/debian.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ct/debian.sh b/ct/debian.sh
index a21a5e3f..3cc0b73d 100644
--- a/ct/debian.sh
+++ b/ct/debian.sh
@@ -7,9 +7,9 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV
APP="Debian"
var_tags="${var_tags:-os}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-512}"
-var_disk="${var_disk:-2}"
+var_cpu="${var_cpu:-4}"
+var_ram="${var_ram:-4096}"
+var_disk="${var_disk:-15}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
From b7b0da453379e7f182bbc6be54bae4138f92eb89 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 11:29:33 +0200
Subject: [PATCH 130/312] add netdata for ref
---
tools/addon/netdata.sh | 123 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
create mode 100644 tools/addon/netdata.sh
diff --git a/tools/addon/netdata.sh b/tools/addon/netdata.sh
new file mode 100644
index 00000000..250b8f1c
--- /dev/null
+++ b/tools/addon/netdata.sh
@@ -0,0 +1,123 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# License: MIT
+# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+
+function header_info {
+ clear
+ cat <<"EOF"
+ _ __ __ ____ __
+ / | / /__ / /_/ __ \____ _/ /_____ _
+ / |/ / _ \/ __/ / / / __ `/ __/ __ `/
+ / /| / __/ /_/ /_/ / /_/ / /_/ /_/ /
+/_/ |_/\___/\__/_____/\__,_/\__/\__,_/
+
+EOF
+}
+
+YW=$(echo "\033[33m")
+BL=$(echo "\033[36m")
+RD=$(echo "\033[01;31m")
+GN=$(echo "\033[1;92m")
+CL=$(echo "\033[m")
+BFR="\\r\\033[K"
+HOLD="-"
+CM="${GN}✓${CL}"
+silent() { "$@" >/dev/null 2>&1; }
+set -e
+header_info
+echo "Loading..."
+function msg_info() {
+ local msg="$1"
+ echo -ne " ${HOLD} ${YW}${msg}..."
+}
+
+function msg_ok() {
+ local msg="$1"
+ echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
+}
+
+install() {
+ header_info
+ while true; do
+ read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?" yn
+ case $yn in
+ [Yy]*) break ;;
+ [Nn]*) exit ;;
+ *) echo "Please answer yes or no." ;;
+ esac
+ done
+ header_info
+ read -r -p "Verbose mode? " prompt
+ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
+ STD=""
+ else
+ STD="silent"
+ fi
+ header_info
+
+ msg_info "Setting up repository"
+ $STD apt-get install -y debian-keyring
+ curl -fsSL "https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_5-1+debian12_all.deb" -o $(basename "https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_5-1+debian12_all.deb")
+ $STD dpkg -i netdata-repo_5-1+debian12_all.deb
+ rm -rf netdata-repo_5-1+debian12_all.deb
+ msg_ok "Set up repository"
+
+ msg_info "Installing Netdata"
+ $STD apt-get update
+ $STD apt-get install -y netdata
+ msg_ok "Installed Netdata"
+ msg_ok "Completed Successfully!\n"
+ echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n"
+}
+
+uninstall() {
+ header_info
+ read -r -p "Verbose mode? " prompt
+ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
+ STD=""
+ else
+ STD="silent"
+ fi
+ header_info
+
+ msg_info "Uninstalling Netdata"
+ systemctl stop netdata
+ rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
+ rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
+ $STD apt-get remove --purge -y netdata netdata-repo
+ systemctl daemon-reload
+ $STD apt autoremove -y
+ $STD userdel netdata
+ msg_ok "Uninstalled Netdata"
+ msg_ok "Completed Successfully!\n"
+}
+
+if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then
+ echo -e "This version of Proxmox Virtual Environment is not supported"
+ echo -e "Requires PVE Version 8.0 or higher"
+ echo -e "Exiting..."
+ sleep 2
+ exit
+fi
+
+OPTIONS=(Install "Install NetData on Proxmox VE"
+ Uninstall "Uninstall NetData from Proxmox VE")
+
+CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \
+ "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
+
+case $CHOICE in
+"Install")
+ install
+ ;;
+"Uninstall")
+ uninstall
+ ;;
+*)
+ echo "Exiting..."
+ exit 0
+ ;;
+esac
From 30d6cf8b4a86f35f0d9ad9eda797d7bcc34b8070 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 11:36:41 +0200
Subject: [PATCH 131/312] Update netdata.sh
---
tools/addon/netdata.sh | 115 +++++++++++++++++++++++++++++------------
1 file changed, 81 insertions(+), 34 deletions(-)
diff --git a/tools/addon/netdata.sh b/tools/addon/netdata.sh
index 250b8f1c..5e9b6326 100644
--- a/tools/addon/netdata.sh
+++ b/tools/addon/netdata.sh
@@ -39,30 +39,91 @@ function msg_ok() {
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
+pve_check() {
+ if ! command -v pveversion >/dev/null 2>&1; then
+ msg_error "This script can only be run on a Proxmox VE host."
+ exit 1
+ fi
+
+ local PVE_VER
+ PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
+
+ # Proxmox VE 8.x: allow 8.0 – 8.9
+ if [[ "$PVE_VER" =~ ^8\.([0-9]+)$ ]]; then
+ local MINOR="${BASH_REMATCH[1]}"
+ if ((MINOR < 0 || MINOR > 9)); then
+ msg_error "Unsupported Proxmox VE version: $PVE_VER"
+ msg_error "Supported versions: 8.0 – 8.9 or 9.0"
+ exit 1
+ fi
+ return 0
+ fi
+
+ # Proxmox VE 9.x: allow only 9.0
+ if [[ "$PVE_VER" =~ ^9\.([0-9]+)$ ]]; then
+ local MINOR="${BASH_REMATCH[1]}"
+ if ((MINOR != 0)); then
+ msg_error "Unsupported Proxmox VE version: $PVE_VER"
+ msg_error "Supported versions: 8.0 – 8.9 or 9.0"
+ exit 1
+ fi
+ return 0
+ fi
+
+ msg_error "Unsupported Proxmox VE version: $PVE_VER"
+ msg_error "Supported versions: 8.0 – 8.9 or 9.0"
+ exit 1
+}
+
+detect_codename() {
+ source /etc/os-release
+ if [[ "$ID" != "debian" ]]; then
+ msg_error "Unsupported base OS: $ID (only Proxmox VE / Debian supported)."
+ exit 1
+ fi
+ CODENAME="${VERSION_CODENAME:-}"
+ if [[ -z "$CODENAME" ]]; then
+ msg_error "Could not detect Debian codename."
+ exit 1
+ fi
+ echo "$CODENAME"
+}
+
+get_latest_repo_pkg() {
+ local REPO_URL=$1
+ curl -fsSL "$REPO_URL" |
+ grep -oP 'netdata-repo_[^"]+all\.deb' |
+ sort -V |
+ tail -n1
+}
+
install() {
header_info
while true; do
- read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)?" yn
+ read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)? " yn
case $yn in
[Yy]*) break ;;
[Nn]*) exit ;;
*) echo "Please answer yes or no." ;;
esac
done
- header_info
+
read -r -p "Verbose mode? " prompt
- if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
- STD=""
- else
- STD="silent"
- fi
- header_info
+ [[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
+
+ CODENAME=$(detect_codename)
+ REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/"
msg_info "Setting up repository"
$STD apt-get install -y debian-keyring
- curl -fsSL "https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_5-1+debian12_all.deb" -o $(basename "https://repo.netdata.cloud/repos/repoconfig/debian/bookworm/netdata-repo_5-1+debian12_all.deb")
- $STD dpkg -i netdata-repo_5-1+debian12_all.deb
- rm -rf netdata-repo_5-1+debian12_all.deb
+ PKG=$(get_latest_repo_pkg "$REPO_URL")
+ if [[ -z "$PKG" ]]; then
+ msg_error "Could not find netdata-repo package for Debian $CODENAME"
+ exit 1
+ fi
+ curl -fsSL "${REPO_URL}${PKG}" -o "$PKG"
+ $STD dpkg -i "$PKG"
+ rm -f "$PKG"
msg_ok "Set up repository"
msg_info "Installing Netdata"
@@ -76,46 +137,32 @@ install() {
uninstall() {
header_info
read -r -p "Verbose mode? " prompt
- if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
- STD=""
- else
- STD="silent"
- fi
- header_info
+ [[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
msg_info "Uninstalling Netdata"
- systemctl stop netdata
+ systemctl stop netdata || true
rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
$STD apt-get remove --purge -y netdata netdata-repo
systemctl daemon-reload
$STD apt autoremove -y
- $STD userdel netdata
+ $STD userdel netdata || true
msg_ok "Uninstalled Netdata"
msg_ok "Completed Successfully!\n"
}
-if ! pveversion | grep -Eq "pve-manager/8\.[0-4](\.[0-9]+)*"; then
- echo -e "This version of Proxmox Virtual Environment is not supported"
- echo -e "Requires PVE Version 8.0 or higher"
- echo -e "Exiting..."
- sleep 2
- exit
-fi
+header_info
+pve_check
OPTIONS=(Install "Install NetData on Proxmox VE"
Uninstall "Uninstall NetData from Proxmox VE")
-CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" --menu "Select an option:" 10 58 2 \
- "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
+CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" \
+ --menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
case $CHOICE in
-"Install")
- install
- ;;
-"Uninstall")
- uninstall
- ;;
+"Install") install ;;
+"Uninstall") uninstall ;;
*)
echo "Exiting..."
exit 0
From d5f620bfe63dbd3cd65419f5cc6790959501e03b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 11:38:22 +0200
Subject: [PATCH 132/312] Update netdata.sh
---
tools/addon/netdata.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/addon/netdata.sh b/tools/addon/netdata.sh
index 5e9b6326..f3e54ff6 100644
--- a/tools/addon/netdata.sh
+++ b/tools/addon/netdata.sh
@@ -39,6 +39,8 @@ function msg_ok() {
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
+function msg_error() { echo -e "${RD}✗ $1${CL}"; }
+
pve_check() {
if ! command -v pveversion >/dev/null 2>&1; then
msg_error "This script can only be run on a Proxmox VE host."
From c74b2d58da6fa25c224576fa7e8b933fbff5e160 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 11:44:20 +0200
Subject: [PATCH 133/312] Update netdata.sh
---
tools/addon/netdata.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/addon/netdata.sh b/tools/addon/netdata.sh
index f3e54ff6..1f2d598f 100644
--- a/tools/addon/netdata.sh
+++ b/tools/addon/netdata.sh
@@ -51,11 +51,11 @@ pve_check() {
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
# Proxmox VE 8.x: allow 8.0 – 8.9
- if [[ "$PVE_VER" =~ ^8\.([0-9]+)$ ]]; then
+ if [[ "$PVE_VER" =~ ^9\.([0-9]+)(\.[0-9]+)?$ ]]; then
local MINOR="${BASH_REMATCH[1]}"
- if ((MINOR < 0 || MINOR > 9)); then
+ if ((MINOR != 0)); then
msg_error "Unsupported Proxmox VE version: $PVE_VER"
- msg_error "Supported versions: 8.0 – 8.9 or 9.0"
+ msg_error "Supported versions: 8.0 – 8.9 or 9.0.x"
exit 1
fi
return 0
From fb3f4f4eb4eea902fe887d834addf317847cb1b5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 12:30:28 +0200
Subject: [PATCH 134/312] paperless prebuild
---
ct/paperless-ngx.sh | 2 +-
install/paperless-ngx-install.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 997e7b16..849cffde 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -33,7 +33,7 @@ function update_script() {
RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | jq -r .tag_name | sed 's/^v//')
if [[ "${RELEASE}" != "$(cat ~/.paperless 2>/dev/null)" ]] || [[ ! -f ~/.paperless ]]; then
PYTHON_VERSION="3.13" setup_uv
- fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
+ fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
setup_gs
diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh
index 4ddc0fc8..d668909f 100644
--- a/install/paperless-ngx-install.sh
+++ b/install/paperless-ngx-install.sh
@@ -36,7 +36,7 @@ msg_ok "Installed Dependencies"
PG_VERSION="16" setup_postgresql
PYTHON_VERSION="3.13" setup_uv
-fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "tarball" "latest" "/opt/paperless"
+fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
setup_gs
From 70f72e3432a21e40856a37bf6b1d3502d705a7a6 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 12:34:21 +0200
Subject: [PATCH 135/312] Update tools.func
---
misc/tools.func | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/misc/tools.func b/misc/tools.func
index 6014c0d5..7c7e5492 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -1434,7 +1434,9 @@ function setup_gs() {
rm -rf "$TMP_DIR"
}
$STD apt-get install -y build-essential libpng-dev zlib1g-dev
- $STD ./configure >/dev/null && $STD make && $STD sudo make install
+ $STD ./configure >/dev/null
+ $STD make
+ $STD sudo make install
local EXIT_CODE=$?
hash -r
if [[ ! -x "$(command -v gs)" ]]; then
From f9bb13d36c4cb73ed10bdbf5753ac23fe79b36ea Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 13:18:45 +0200
Subject: [PATCH 136/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index 849cffde..b698a581 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -32,17 +32,26 @@ function update_script() {
fi
RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | jq -r .tag_name | sed 's/^v//')
if [[ "${RELEASE}" != "$(cat ~/.paperless 2>/dev/null)" ]] || [[ ! -f ~/.paperless ]]; then
- PYTHON_VERSION="3.13" setup_uv
- fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
- fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- setup_gs
-
msg_info "Stopping all Paperless-ngx Services"
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
msg_ok "Stopped all Paperless-ngx Services"
if grep -q "uv run" /etc/systemd/system/paperless-webserver.service; then
+
+ msg_info "backing up data"
+ mkdir -p /opt/paperless/backup
+ cp -r /opt/paperless/data /opt/paperless/backup/
+ cp -r /opt/paperless/media /opt/paperless/backup/
+ cp -r /opt/paperless/paperless.conf /opt/paperless/backup/
+ msg_ok "Backup completed"
+
+ PYTHON_VERSION="3.13" setup_uv
+ fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
+ fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
+ setup_gs
+
msg_info "Updating to ${RELEASE}"
+ cp -r /opt/paperless/backup/* /opt/paperless/
cd /opt/paperless
$STD uv sync --all-extras
cd /opt/paperless/src
@@ -87,8 +96,21 @@ function update_script() {
done
$STD systemctl daemon-reload
+ msg_info "backing up data"
+ mkdir -p /opt/paperless/backup
+ cp -r /opt/paperless/data /opt/paperless/backup/
+ cp -r /opt/paperless/media /opt/paperless/backup/
+ cp -r /opt/paperless/paperless.conf /opt/paperless/backup/
+ msg_ok "Backup completed"
+
+ PYTHON_VERSION="3.13" setup_uv
+ fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
+ fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
+ setup_gs
+
+ msg_info "Updating Paperless-ngx"
+ cp -r /opt/paperless/backup/* /opt/paperless/
cd /opt/paperless
- msg_info "Running Paperless-ngx UV sync"
$STD uv sync --all-extras
cd /opt/paperless/src
$STD uv run -- python manage.py migrate
From 6e1c22246718f8888eeaf7f703432c54ebf7c6f6 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 20 Aug 2025 13:45:40 +0200
Subject: [PATCH 137/312] Update paperless-ngx.sh
---
ct/paperless-ngx.sh | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
index b698a581..8c0b38e8 100644
--- a/ct/paperless-ngx.sh
+++ b/ct/paperless-ngx.sh
@@ -85,9 +85,12 @@ function update_script() {
if [[ -n "$path" && -f "$path" ]]; then
sed -i "s|^ExecStart=.*|${PATCHES[$svc]}|" "$path"
if [[ "$svc" == "paperless-webserver.service" ]]; then
- grep -q "^Environment=GRANIAN_HOST=" "$path" || echo 'Environment=GRANIAN_HOST=::' >>"$path"
- grep -q "^Environment=GRANIAN_PORT=" "$path" || echo 'Environment=GRANIAN_PORT=8000' >>"$path"
- grep -q "^Environment=GRANIAN_WORKERS=" "$path" || echo 'Environment=GRANIAN_WORKERS=1' >>"$path"
+ grep -q "^Environment=GRANIAN_HOST=" "$path" ||
+ sed -i '/^\[Service\]/a Environment=GRANIAN_HOST=::' "$path"
+ grep -q "^Environment=GRANIAN_PORT=" "$path" ||
+ sed -i '/^\[Service\]/a Environment=GRANIAN_PORT=8000' "$path"
+ grep -q "^Environment=GRANIAN_WORKERS=" "$path" ||
+ sed -i '/^\[Service\]/a Environment=GRANIAN_WORKERS=1' "$path"
fi
msg_ok "Patched $svc"
else
From 206d919c61ca601d81cccb4fffcc38898ae614ba Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Wed, 20 Aug 2025 11:46:01 +0000
Subject: [PATCH 138/312] Update .app files
---
tools/headers/glances | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 tools/headers/glances
diff --git a/tools/headers/glances b/tools/headers/glances
new file mode 100644
index 00000000..18ac9757
--- /dev/null
+++ b/tools/headers/glances
@@ -0,0 +1,6 @@
+ ________
+ / ____/ /___ _____ ________ _____
+ / / __/ / __ `/ __ \/ ___/ _ \/ ___/
+/ /_/ / / /_/ / / / / /__/ __(__ )
+\____/_/\__,_/_/ /_/\___/\___/____/
+
From 05347048c538b593588a1b3f7a543d6662684a6d Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 13:59:07 +0200
Subject: [PATCH 139/312] Add Alpine RustDesk Server script
---
ct/alpine-rustdeskserver.sh | 62 +++++++++++++
install/alpine-rustdeskserver-install.sh | 111 +++++++++++++++++++++++
2 files changed, 173 insertions(+)
create mode 100644 ct/alpine-rustdeskserver.sh
create mode 100644 install/alpine-rustdeskserver-install.sh
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
new file mode 100644
index 00000000..0cf945f7
--- /dev/null
+++ b/ct/alpine-rustdeskserver.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: Slaviša Arežina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/rustdesk/rustdesk-server
+
+APP="Alpine-RustDesk Server"
+var_tags="${var_tags:-alpine;monitoring}"
+var_cpu="${var_cpu:-1}"
+var_ram="${var_ram:-512}"
+var_disk="${var_disk:-3}"
+var_os="${var_os:-alpine}"
+var_version="${var_version:-3.22}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+
+ if [[ ! -d /opt/rustdesk-server ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit 1
+ fi
+ RELEASE=$(curl -s https://api.github.com/repos/TwiN/RustDesk Server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ if [ "${RELEASE}" != "$(cat /opt/RustDesk Server_version.txt)" ] || [ ! -f /opt/RustDesk Server_version.txt ]; then
+ msg_info "Updating ${APP} LXC"
+ $STD apk -U upgrade
+ $STD service RustDesk Server stop
+ mv /opt/RustDesk Server/config/config.yaml /opt
+ rm -rf /opt/RustDesk Server/*
+ temp_file=$(mktemp)
+ curl -fsSL "https://github.com/TwiN/RustDesk Server/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
+ tar zxf "$temp_file" --strip-components=1 -C /opt/RustDesk Server
+ cd /opt/RustDesk Server
+ $STD go mod tidy
+ CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o RustDesk Server .
+ setcap CAP_NET_RAW+ep RustDesk Server
+ mv /opt/config.yaml config
+ rm -f "$temp_file"
+ echo "${RELEASE}" >/opt/RustDesk Server_version.txt
+ $STD service RustDesk Server start
+ msg_ok "Updated Successfully"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ fi
+
+ exit 0
+}
+
+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 IP:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
new file mode 100644
index 00000000..d6e33d6d
--- /dev/null
+++ b/install/alpine-rustdeskserver-install.sh
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: Slaviša Arežina (tremor021)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/rustdesk/rustdesk-server
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+msg_info "Installing RustDesk Server v${RELEASE}"
+temp_file1=$(mktemp)
+curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file"
+unzip "$temp_file1"
+mv amd64 /opt/rustdesk-server
+mkdir -p /root/.config/rustdesk
+cd /opt/rustdesk-server
+$STD ./rustdesk-utils genkeypair | tee \
+ >(grep "Public Key" | awk '{print $3}' > /root/.config/rustdesk/id_ed25519.pub) \
+ >(grep "Secret Key" | awk '{print $3}' > /root/.config/rustdesk/id_ed25519)
+chmod 600 /root/.config/rustdesk/id_ed25519
+chmod 644 /root/.config/rustdesk/id_ed25519.pub
+echo "${RELEASE}" >~/.rustdesk-server
+msg_ok "Installed RustDesk Server v${RELEASE}"
+
+APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+msg_info "Installing RustDesk API v${APIRELEASE}"
+temp_file2=$(mktemp)
+curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o $temp_file2
+tar zxvf "$temp_file2"
+mv release /opt/rustdesk-api
+msg_ok "Installed RustDesk API v${APIRELEASE}"
+
+msg_info "Enabling RustDesk Server Services"
+cat </etc/init.d/rustdesk-server-hbbs
+#!/sbin/openrc-run
+description="RustDesk HBBS Service"
+directory="/opt/rustdesk-server"
+command="/opt/rustdesk-server/hbbs"
+command_args=""
+command_background="true"
+command_user="root"
+pidfile="/var/run/rustdesk-server-hbbs.pid"
+output_log="/var/log/rustdesk-hbbs.log"
+error_log="/var/log/rustdesk-hbbs.err"
+
+depend() {
+ use net
+}
+EOF
+
+cat </etc/init.d/rustdesk-server-hbbr
+#!/sbin/openrc-run
+description="RustDesk HBBR Service"
+directory="/opt/rustdesk-server"
+command="/opt/rustdesk-server/hbbr"
+command_args=""
+command_background="true"
+command_user="root"
+pidfile="/var/run/rustdesk-server-hbbr.pid"
+output_log="/var/log/rustdesk-hbbr.log"
+error_log="/var/log/rustdesk-hbbr.err"
+
+depend() {
+ use net
+}
+EOF
+
+cat </etc/init.d/rustdesk-api
+#!/sbin/openrc-run
+description="RustDesk API Service"
+directory="/opt/rustdesk-api"
+command="/opt/rustdesk-api/apimain"
+command_args=""
+command_background="true"
+command_user="root"
+pidfile="/var/run/rustdesk-server-hbbr.pid"
+output_log="/var/log/rustdesk-api.log"
+error_log="/var/log/rustdesk-api.err"
+
+depend() {
+ use net
+}
+EOF
+chmod +x /etc/init.d/rustdesk-server-hbbs
+chmod +x /etc/init.d/rustdesk-server-hbbr
+chmod +x /etc/init.d/rustdesk-api
+$STD rc-update add rustdesk-server-hbbs default
+$STD rc-update add rustdesk-server-hbbr default
+$STD rc-update add rustdesk-api default
+msg_ok "Enabled RustDesk Server Services"
+
+msg_info "Starting RustDesk Server"
+$STD service rustdesk-server-hbbs start
+$STD service rustdesk-server-hbbr start
+$STD service rustdesk-api start
+msg_ok "Started RustDesk Server"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+rm -f "$temp_file1" "$temp_file2"
+$STD apk cache clean
+msg_ok "Cleaned"
From 5961178d110e1fbe02f3dc969c3a025ee07470be Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:00:59 +0200
Subject: [PATCH 140/312] Update RustDesk
---
ct/alpine-rustdeskserver.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index 0cf945f7..c8b2c90b 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/rustdesk/rustdesk-server
-APP="Alpine-RustDesk Server"
+APP="Alpine-RustDeskServer"
var_tags="${var_tags:-alpine;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
From 8ac7b7630dfa906eb8353e09e2d7e3dd2bb08a9e Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:12:59 +0200
Subject: [PATCH 141/312] Update
---
ct/alpine-rustdeskserver.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index c8b2c90b..1897d7df 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
From 2fff0d528b59474bb9ad5dcf073166c1c1545784 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:15:07 +0200
Subject: [PATCH 142/312] Update
---
install/alpine-rustdeskserver-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
index d6e33d6d..12edc020 100644
--- a/install/alpine-rustdeskserver-install.sh
+++ b/install/alpine-rustdeskserver-install.sh
@@ -16,7 +16,7 @@ update_os
RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
msg_info "Installing RustDesk Server v${RELEASE}"
temp_file1=$(mktemp)
-curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file"
+curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
unzip "$temp_file1"
mv amd64 /opt/rustdesk-server
mkdir -p /root/.config/rustdesk
@@ -32,7 +32,7 @@ msg_ok "Installed RustDesk Server v${RELEASE}"
APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
msg_info "Installing RustDesk API v${APIRELEASE}"
temp_file2=$(mktemp)
-curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o $temp_file2
+curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
tar zxvf "$temp_file2"
mv release /opt/rustdesk-api
msg_ok "Installed RustDesk API v${APIRELEASE}"
From 24169a9eaba9b97224efe50debbab89362fb7125 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:22:10 +0200
Subject: [PATCH 143/312] Update RustDesk
---
install/alpine-rustdeskserver-install.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
index 12edc020..31628209 100644
--- a/install/alpine-rustdeskserver-install.sh
+++ b/install/alpine-rustdeskserver-install.sh
@@ -21,11 +21,12 @@ unzip "$temp_file1"
mv amd64 /opt/rustdesk-server
mkdir -p /root/.config/rustdesk
cd /opt/rustdesk-server
-$STD ./rustdesk-utils genkeypair | tee \
- >(grep "Public Key" | awk '{print $3}' > /root/.config/rustdesk/id_ed25519.pub) \
- >(grep "Secret Key" | awk '{print $3}' > /root/.config/rustdesk/id_ed25519)
+./rustdesk-utils genkeypair > /tmp/rustdesk_keys.txt
+grep "Public Key" /tmp/rustdesk_keys.txt | awk '{print $3}' > /root/.config/rustdesk/id_ed25519.pub
+grep "Secret Key" /tmp/rustdesk_keys.txt | awk '{print $3}' > /root/.config/rustdesk/id_ed25519
chmod 600 /root/.config/rustdesk/id_ed25519
chmod 644 /root/.config/rustdesk/id_ed25519.pub
+rm /tmp/rustdesk_keys.txt
echo "${RELEASE}" >~/.rustdesk-server
msg_ok "Installed RustDesk Server v${RELEASE}"
From c19bfbe24025a78fb8909e333b246954111f84f9 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:42:31 +0200
Subject: [PATCH 144/312] Update RustDesk
---
install/alpine-rustdeskserver-install.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
index 31628209..c8929335 100644
--- a/install/alpine-rustdeskserver-install.sh
+++ b/install/alpine-rustdeskserver-install.sh
@@ -17,7 +17,7 @@ RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases
msg_info "Installing RustDesk Server v${RELEASE}"
temp_file1=$(mktemp)
curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
-unzip "$temp_file1"
+$STD unzip "$temp_file1"
mv amd64 /opt/rustdesk-server
mkdir -p /root/.config/rustdesk
cd /opt/rustdesk-server
@@ -34,7 +34,7 @@ APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/release
msg_info "Installing RustDesk API v${APIRELEASE}"
temp_file2=$(mktemp)
curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
-tar zxvf "$temp_file2"
+$STD tar zxvf "$temp_file2"
mv release /opt/rustdesk-api
msg_ok "Installed RustDesk API v${APIRELEASE}"
@@ -81,7 +81,7 @@ command="/opt/rustdesk-api/apimain"
command_args=""
command_background="true"
command_user="root"
-pidfile="/var/run/rustdesk-server-hbbr.pid"
+pidfile="/var/run/rustdesk-api.pid"
output_log="/var/log/rustdesk-api.log"
error_log="/var/log/rustdesk-api.err"
From 59a7ddf581e93bee87c4477c1ba0429338b86d46 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 14:53:59 +0200
Subject: [PATCH 145/312] Update RustDesk
---
install/alpine-rustdeskserver-install.sh | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
index c8929335..e60652aa 100644
--- a/install/alpine-rustdeskserver-install.sh
+++ b/install/alpine-rustdeskserver-install.sh
@@ -36,6 +36,15 @@ temp_file2=$(mktemp)
curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
$STD tar zxvf "$temp_file2"
mv release /opt/rustdesk-api
+cd /opt/rustdesk-api
+ADMINPASS=$(head -c 16 /dev/urandom | xxd -p -c 16)
+$STD ./apimain reset-admin-pwd "$ADMINPASS"
+{
+ echo "RustDesk WebUI"
+ echo ""
+ echo "Username: admin"
+ echo "Password: $ADMINPASS"
+} >>~/rustdesk.creds
msg_ok "Installed RustDesk API v${APIRELEASE}"
msg_info "Enabling RustDesk Server Services"
From c668718209ac8707bb296e13bb176d20eeea0705 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 20:48:35 +0200
Subject: [PATCH 146/312] Update RustDesk
---
ct/alpine-rustdeskserver.sh | 56 ++++++++++++++----------
install/alpine-rustdeskserver-install.sh | 1 +
2 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index 1897d7df..333548ed 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -26,29 +26,41 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit 1
fi
- RELEASE=$(curl -s https://api.github.com/repos/TwiN/RustDesk Server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
- if [ "${RELEASE}" != "$(cat /opt/RustDesk Server_version.txt)" ] || [ ! -f /opt/RustDesk Server_version.txt ]; then
- msg_info "Updating ${APP} LXC"
- $STD apk -U upgrade
- $STD service RustDesk Server stop
- mv /opt/RustDesk Server/config/config.yaml /opt
- rm -rf /opt/RustDesk Server/*
- temp_file=$(mktemp)
- curl -fsSL "https://github.com/TwiN/RustDesk Server/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
- tar zxf "$temp_file" --strip-components=1 -C /opt/RustDesk Server
- cd /opt/RustDesk Server
- $STD go mod tidy
- CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o RustDesk Server .
- setcap CAP_NET_RAW+ep RustDesk Server
- mv /opt/config.yaml config
- rm -f "$temp_file"
- echo "${RELEASE}" >/opt/RustDesk Server_version.txt
- $STD service RustDesk Server start
- msg_ok "Updated Successfully"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
- fi
+ APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+ if [ "${RELEASE}" != "$(cat ~/.rustdesk-server 2>/dev/null)" ] || [ ! -f ~/.rustdesk-server ]; then
+ msg_info "Updating RustDesk Server to v${RELEASE}"
+ $STD apk -U upgrade
+ $STD service rustdesk-server-hbbs stop
+ $STD service rustdesk-server-hbbr stop
+ temp_file1=$(mktemp)
+ curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
+ $STD unzip "$temp_file1"
+ cp -r amd64/* /opt/rustdesk-server/
+ echo "${RELEASE}" >~/.rustdesk-server
+ $STD service rustdesk-server-hbbs start
+ $STD service rustdesk-server-hbbr start
+ rm -rf amd64
+ rm -f $temp_file1
+ msg_ok "Updated RustDesk Server successfully"
+ else
+ msg_ok "No update required. ${APP} is already at v${RELEASE}"
+ fi
+ if [ "${APIRELEASE}" != "$(cat ~/.rustdesk-api)" ] || [ ! -f ~/.rustdesk-api ]; then
+ msg_info "Updating RustDesk API to v${APIRELEASE}"
+
+ temp_file2=$(mktemp)
+ curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
+ $STD tar zxvf "$temp_file2"
+ cp -r release/* /opt/rustdesk-api
+ echo "${APIRELEASE}" >~/.rustdesk-api
+ rm -rf release
+ rm -f $temp_file2
+ msg_ok "Updated RustDesk API"
+ else
+ msg_ok "No update required. RustDesk API is already at v${APIRELEASE}"
+ fi
exit 0
}
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
index e60652aa..b26f3134 100644
--- a/install/alpine-rustdeskserver-install.sh
+++ b/install/alpine-rustdeskserver-install.sh
@@ -45,6 +45,7 @@ $STD ./apimain reset-admin-pwd "$ADMINPASS"
echo "Username: admin"
echo "Password: $ADMINPASS"
} >>~/rustdesk.creds
+echo "${APIRELEASE}" >~/.rustdesk-api
msg_ok "Installed RustDesk API v${APIRELEASE}"
msg_info "Enabling RustDesk Server Services"
From 7ec9aa87b8a7f678991999019a4a7f61ba944a3c Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 20:50:50 +0200
Subject: [PATCH 147/312] Update RustDesk
---
ct/alpine-rustdeskserver.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index 333548ed..30fa99ab 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -49,12 +49,13 @@ function update_script() {
fi
if [ "${APIRELEASE}" != "$(cat ~/.rustdesk-api)" ] || [ ! -f ~/.rustdesk-api ]; then
msg_info "Updating RustDesk API to v${APIRELEASE}"
-
+ $STD service rustdesk-api stop
temp_file2=$(mktemp)
curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
$STD tar zxvf "$temp_file2"
cp -r release/* /opt/rustdesk-api
echo "${APIRELEASE}" >~/.rustdesk-api
+ $STD service rustdesk-api start
rm -rf release
rm -f $temp_file2
msg_ok "Updated RustDesk API"
From 806523023e27c696f7b7791a10ff437951d00558 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 20:58:28 +0200
Subject: [PATCH 148/312] Update RustDesk
---
ct/alpine-rustdeskserver.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index 30fa99ab..9f1b1d00 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -72,4 +72,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 IP:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:21114${CL}"
From b6958e6d86b2ec67208ce446904b214933577abe Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 21:01:26 +0200
Subject: [PATCH 149/312] Update RustDesk
---
ct/alpine-rustdeskserver.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
index 9f1b1d00..1494be48 100644
--- a/ct/alpine-rustdeskserver.sh
+++ b/ct/alpine-rustdeskserver.sh
@@ -21,7 +21,6 @@ catch_errors
function update_script() {
header_info
-
if [[ ! -d /opt/rustdesk-server ]]; then
msg_error "No ${APP} Installation Found!"
exit 1
From 327d270294bd9ed0440cfe13e883894490698cd8 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Wed, 20 Aug 2025 21:11:36 +0200
Subject: [PATCH 150/312] Add RustDesk json
---
frontend/public/json/rustdeskserver.json | 55 ++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 frontend/public/json/rustdeskserver.json
diff --git a/frontend/public/json/rustdeskserver.json b/frontend/public/json/rustdeskserver.json
new file mode 100644
index 00000000..7dd43605
--- /dev/null
+++ b/frontend/public/json/rustdeskserver.json
@@ -0,0 +1,55 @@
+{
+ "name": "RustDesk Server",
+ "slug": "rustdeskserver",
+ "categories": [
+ 21
+ ],
+ "date_created": "2025-02-13",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 21114,
+ "documentation": "https://rustdesk.com/docs/en/",
+ "website": "https://rustdesk.com/",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/rustdesk.webp",
+ "config_path": "",
+ "description": "RustDesk is a full-featured open source remote control alternative for self-hosting and security with minimal configuration.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/rustdeskserver.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 512,
+ "hdd": 2,
+ "os": "debian",
+ "version": "12"
+ }
+ },
+ {
+ "type": "alpine",
+ "script": "ct/alpine-rustdeskserver.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 512,
+ "hdd": 2,
+ "os": "alpine",
+ "version": "3.22"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "Check our configuration guide for help: `https://github.com/community-scripts/ProxmoxVE/discussions/2388`",
+ "type": "info"
+ },
+ {
+ "text": "Login credentials: `cat ~/rustdesk.creds`",
+ "type": "info"
+ }
+ ]
+}
From 3f102060c037e6310355190ff205c3408503f2a7 Mon Sep 17 00:00:00 2001
From: Henrique Goncalves
Date: Tue, 12 Aug 2025 07:30:00 -0300
Subject: [PATCH 151/312] feat: add dependency-check
---
frontend/public/json/dependency-check.json | 48 +++
tools/pve/dependency-check.sh | 363 +++++++++++++++++++++
2 files changed, 411 insertions(+)
create mode 100644 frontend/public/json/dependency-check.json
create mode 100644 tools/pve/dependency-check.sh
diff --git a/frontend/public/json/dependency-check.json b/frontend/public/json/dependency-check.json
new file mode 100644
index 00000000..13b31fe1
--- /dev/null
+++ b/frontend/public/json/dependency-check.json
@@ -0,0 +1,48 @@
+{
+ "name": "Proxmox VE VM Startup Dependency Check",
+ "slug": "dependency-check",
+ "categories": [
+ 1
+ ],
+ "date_created": "2025-08-12",
+ "type": "pve",
+ "updateable": false,
+ "privileged": false,
+ "interface_port": null,
+ "documentation": null,
+ "website": null,
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/proxmox.webp",
+ "config_path": "/etc/default/pve-auto-hook",
+ "description": "This script checks for the presence of required dependencies before starting a VM or LXC container in Proxmox. It ensures that all referenced storages are available and, additionally, supports the usage of tags to check for specific dependencies. If any required dependency is missing, the VM or container will not start until the issue is resolved. This script is designed to be used as a Proxmox hookscript, which can be applied to both QEMU VMs and LXC containers.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "tools/pve/dependency-check.sh",
+ "resources": {
+ "cpu": null,
+ "ram": null,
+ "hdd": null,
+ "os": null,
+ "version": null
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "Execute within the Proxmox shell",
+ "type": "info"
+ },
+ {
+ "text": "To wait until a certain host is available, tag the VM or container with `dep_ping_` where `` is the name or IP of the host to ping. The script will wait until the host is reachable before proceeding with the startup.",
+ "type": "info"
+ },
+ {
+ "text": "To wait until a certain TCP port is open, tag the VM or container with `dep_tcp__` where `` is the name or IP of the host and `` is the TCP port number. The script will wait until the port is open before proceeding with the startup.",
+ "type": "info"
+ }
+ ]
+}
diff --git a/tools/pve/dependency-check.sh b/tools/pve/dependency-check.sh
new file mode 100644
index 00000000..b7798d95
--- /dev/null
+++ b/tools/pve/dependency-check.sh
@@ -0,0 +1,363 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2023 community-scripts ORG
+# This script is designed to install the Proxmox Dependency Check Hookscript.
+# It sets up a dependency-checking hookscript and automates its
+# application to all new and existing guests using a systemd watcher.
+# License: MIT
+
+function header_info {
+ clear
+ cat <<"EOF"
+ ____ _ ____ _ _
+ | _ \ ___ _ __ ___ _ __ __| | ___ _ __ ___ _ _ / ___| |__ ___ ___| | __
+ | | | |/ _ \ '_ \ / _ \ '_ \ / _` |/ _ \ '_ \ / __| | | | | | '_ \ / _ \/ __| |/ /
+ | |_| | __/ |_) | __/ | | | (_| | __/ | | | (__| |_| | |___| | | | __/ (__| <
+ |____/ \___| .__/ \___|_| |_|\__,_|\___|_| |_|\___|\__, |\____|_| |_|\___|\___|_|\_\
+ |_| |___/
+EOF
+}
+
+# Color variables
+YW=$(echo "\033[33m")
+GN=$(echo "\033[1;92m")
+RD=$(echo "\033[01;31m")
+CL=$(echo "\033[m")
+BFR="\\r\\033[K"
+HOLD=" "
+CM="${GN}✓${CL}"
+CROSS="${RD}✗${CL}"
+
+# Spinner for progress indication (simplified)
+spinner() {
+ local pid=$!
+ local delay=0.1
+ local spinstr='|/-\'
+ while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
+ local temp=${spinstr#?}
+ printf " [%c] " "$spinstr"
+ local spinstr=$temp${spinstr%"$temp"}
+ sleep $delay
+ printf "\b\b\b\b\b\b"
+ done
+ printf " \b\b\b\b"
+}
+
+# Message functions
+msg_info() {
+ echo -ne " ${YW}›${CL} $1..."
+}
+
+msg_ok() {
+ echo -e "${BFR} ${CM} $1${CL}"
+}
+
+msg_error() {
+ echo -e "${BFR} ${CROSS} $1${CL}"
+}
+# --- End of base script functions ---
+
+
+# --- Installation Functions ---
+
+# Function to create the actual hookscript that runs before guest startup
+create_dependency_hookscript() {
+ msg_info "Creating dependency-check hookscript"
+ mkdir -p /var/lib/vz/snippets
+ cat <<'EOF' > /var/lib/vz/snippets/dependency-check.sh
+#!/bin/bash
+# Proxmox Hookscript for Pre-Start Dependency Checking
+# Works for both QEMU VMs and LXC Containers
+
+# --- Configuration ---
+POLL_INTERVAL=5 # Seconds to wait between checks
+MAX_ATTEMPTS=60 # Max number of attempts before failing (60 * 5s = 5 minutes)
+# --- End Configuration ---
+
+VMID=$1
+PHASE=$2
+
+# Function for logging to syslog with a consistent format
+log() {
+ echo "[hookscript-dep-check] VMID $VMID: $1"
+}
+
+# This script only runs in the 'pre-start' phase
+if [ "$PHASE" != "pre-start" ]; then
+ exit 0
+fi
+
+log "--- Starting Pre-Start Dependency Check ---"
+
+# --- Determine Guest Type (QEMU or LXC) ---
+GUEST_TYPE=""
+CONFIG_CMD=""
+if qm config "$VMID" >/dev/null 2>&1; then
+ GUEST_TYPE="qemu"
+ CONFIG_CMD="qm config"
+ log "Guest type is QEMU (VM)."
+elif pct config "$VMID" >/dev/null 2>&1; then
+ GUEST_TYPE="lxc"
+ CONFIG_CMD="pct config"
+ log "Guest type is LXC (Container)."
+else
+ log "ERROR: Could not determine guest type for $VMID. Aborting."
+ exit 1
+fi
+
+GUEST_CONFIG=$($CONFIG_CMD "$VMID")
+
+# --- 1. Storage Availability Check ---
+log "Checking storage availability..."
+# Grep for all disk definitions (scsi, sata, virtio, ide, rootfs, mp)
+# and extract the storage identifier (the field between the colons).
+# Sort -u gets the unique list of storage pools.
+STORAGE_IDS=$(echo "$GUEST_CONFIG" | grep -E '^(scsi|sata|virtio|ide|rootfs|mp)[0-9]*:' | awk -F'[:]' '{print $2}' | awk '{print$1}' | sort -u)
+
+if [ -z "$STORAGE_IDS" ]; then
+ log "No storage dependencies found to check."
+else
+ for STORAGE_ID in $STORAGE_IDS; do
+ log "Checking status of storage: '$STORAGE_ID'"
+ ATTEMPTS=0
+ while true; do
+ # Grep for the storage ID line in pvesm status and check the 'Active' column (3rd column)
+ STATUS=$(pvesm status | grep "^\s*$STORAGE_ID\s" | awk '{print $3}')
+ if [ "$STATUS" == "active" ]; then
+ log "Storage '$STORAGE_ID' is active."
+ break
+ fi
+
+ ATTEMPTS=$((ATTEMPTS + 1))
+ if [ $ATTEMPTS -ge $MAX_ATTEMPTS ]; then
+ log "ERROR: Timeout waiting for storage '$STORAGE_ID' to become active. Aborting start."
+ exit 1
+ fi
+
+ log "Storage '$STORAGE_ID' is not active (current status: '${STATUS:-inactive/unknown}'). Waiting ${POLL_INTERVAL}s... (Attempt ${ATTEMPTS}/${MAX_ATTEMPTS})"
+ sleep $POLL_INTERVAL
+ done
+ done
+fi
+log "All storage dependencies are met."
+
+
+# --- 2. Custom Tag-Based Dependency Check ---
+log "Checking for custom tag-based dependencies..."
+TAGS=$(echo "$GUEST_CONFIG" | grep '^tags:' | awk '{print $2}')
+
+if [ -z "$TAGS" ]; then
+ log "No tags found. Skipping custom dependency check."
+else
+ # Replace colons with spaces to loop through tags
+ for TAG in ${TAGS//;/ }; do
+ # Check if the tag matches our dependency format 'dep_*'
+ if [[ $TAG == dep_* ]]; then
+ log "Found dependency tag: '$TAG'"
+
+ # Split tag into parts using underscore as delimiter
+ IFS='_' read -ra PARTS <<< "$TAG"
+ DEP_TYPE="${PARTS[1]}"
+
+ ATTEMPTS=0
+ while true; do
+ CHECK_PASSED=false
+ case "$DEP_TYPE" in
+ "tcp")
+ HOST="${PARTS[2]}"
+ PORT="${PARTS[3]}"
+ if [ -z "$HOST" ] || [ -z "$PORT" ]; then
+ log "ERROR: Malformed TCP dependency tag '$TAG'. Skipping."
+ CHECK_PASSED=true # Skip to avoid infinite loop
+ # nc -z is great for this. -w sets a timeout.
+ elif nc -z -w 2 "$HOST" "$PORT"; then
+ log "TCP dependency met: Host $HOST port $PORT is open."
+ CHECK_PASSED=true
+ fi
+ ;;
+
+ "ping")
+ HOST="${PARTS[2]}"
+ if [ -z "$HOST" ]; then
+ log "ERROR: Malformed PING dependency tag '$TAG'. Skipping."
+ CHECK_PASSED=true # Skip to avoid infinite loop
+ # ping -c 1 (one packet) -W 2 (2-second timeout)
+ elif ping -c 1 -W 2 "$HOST" >/dev/null 2>&1; then
+ log "Ping dependency met: Host $HOST is reachable."
+ CHECK_PASSED=true
+ fi
+ ;;
+
+ *)
+ log "WARNING: Unknown dependency type '$DEP_TYPE' in tag '$TAG'. Ignoring."
+ CHECK_PASSED=true # Mark as passed to avoid getting stuck
+ ;;
+ esac
+
+ if $CHECK_PASSED; then
+ break
+ fi
+
+ ATTEMPTS=$((ATTEMPTS + 1))
+ if [ $ATTEMPTS -ge $MAX_ATTEMPTS ]; then
+ log "ERROR: Timeout waiting for dependency '$TAG'. Aborting start."
+ exit 1
+ fi
+
+ log "Dependency '$TAG' not met. Waiting ${POLL_INTERVAL}s... (Attempt ${ATTEMPTS}/${MAX_ATTEMPTS})"
+ sleep $POLL_INTERVAL
+ done
+ fi
+ done
+fi
+
+log "All custom dependencies are met."
+log "--- Dependency Check Complete. Proceeding with start. ---"
+exit 0
+EOF
+ chmod +x /var/lib/vz/snippets/dependency-check.sh
+ msg_ok "Created dependency-check hookscript"
+}
+
+# Function to create the config file for exclusions
+create_exclusion_config() {
+ msg_info "Creating exclusion configuration file"
+ if [ -f /etc/default/pve-auto-hook ]; then
+ msg_ok "Exclusion file already exists, skipping."
+ else
+ cat <<'EOF' > /etc/default/pve-auto-hook
+#
+# Configuration for the Proxmox Automatic Hookscript Applicator
+#
+# Add VM or LXC IDs here to prevent the hookscript from being added.
+# Separate IDs with spaces.
+#
+# Example:
+# IGNORE_IDS="9000 9001 105"
+#
+
+IGNORE_IDS=""
+EOF
+ msg_ok "Created exclusion configuration file"
+ fi
+}
+
+# Function to create the script that applies the hook
+create_applicator_script() {
+ msg_info "Creating the hookscript applicator script"
+ cat <<'EOF' > /usr/local/bin/pve-apply-hookscript.sh
+#!/bin/bash
+HOOKSCRIPT_VOLUME_ID="local:snippets/dependency-check.sh"
+CONFIG_FILE="/etc/default/pve-auto-hook"
+LOG_TAG="pve-auto-hook-list"
+
+log() {
+ systemd-cat -t "$LOG_TAG" <<< "$1"
+}
+
+if [ -f "$CONFIG_FILE" ]; then
+ source "$CONFIG_FILE"
+fi
+
+# Process QEMU VMs
+qm list | awk 'NR>1 {print $1}' | while read -r VMID; do
+ is_ignored=false
+ for id_to_ignore in $IGNORE_IDS; do
+ if [ "$id_to_ignore" == "$VMID" ]; then is_ignored=true; break; fi
+ done
+ if $is_ignored; then continue; fi
+ if qm config "$VMID" | grep -q '^hookscript:'; then continue; fi
+ log "Hookscript not found for VM $VMID. Applying..."
+ qm set "$VMID" --hookscript "$HOOKSCRIPT_VOLUME_ID"
+done
+
+# Process LXC Containers
+pct list | awk 'NR>1 {print $1}' | while read -r VMID; do
+ is_ignored=false
+ for id_to_ignore in $IGNORE_IDS; do
+ if [ "$id_to_ignore" == "$VMID" ]; then is_ignored=true; break; fi
+ done
+ if $is_ignored; then continue; fi
+ if pct config "$VMID" | grep -q '^hookscript:'; then continue; fi
+ log "Hookscript not found for LXC $VMID. Applying..."
+ pct set "$VMID" --hookscript "$HOOKSCRIPT_VOLUME_ID"
+done
+EOF
+ chmod +x /usr/local/bin/pve-apply-hookscript.sh
+ msg_ok "Created applicator script"
+}
+
+# Function to set up the systemd watcher and service
+create_systemd_units() {
+ msg_info "Creating systemd watcher and service units"
+ cat <<'EOF' > /etc/systemd/system/pve-auto-hook.path
+[Unit]
+Description=Watch for new Proxmox guest configs to apply hookscript
+
+[Path]
+PathModified=/etc/pve/qemu-server/
+PathModified=/etc/pve/lxc/
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+ cat <<'EOF' > /etc/systemd/system/pve-auto-hook.service
+[Unit]
+Description=Automatically add hookscript to new Proxmox guests
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/pve-apply-hookscript.sh
+EOF
+ msg_ok "Created systemd units"
+}
+
+
+# --- Main Execution ---
+header_info
+
+if ! command -v pveversion >/dev/null 2>&1; then
+ msg_error "This script must be run on a Proxmox VE host."
+ exit 1
+fi
+
+echo -e "\nThis script will install a service to automatically apply a"
+echo -e "dependency-checking hookscript to all new and existing Proxmox guests."
+echo -e "${YW}This includes creating files in:${CL}"
+echo -e " - /var/lib/vz/snippets/"
+echo -e " - /usr/local/bin/"
+echo -e " - /etc/default/"
+echo -e " - /etc/systemd/system/\n"
+
+read -p "Do you want to proceed with the installation? (y/n): " -n 1 -r
+echo
+if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ msg_error "Installation cancelled."
+ exit 1
+fi
+
+echo -e "\n"
+create_dependency_hookscript
+create_exclusion_config
+create_applicator_script
+create_systemd_units
+
+msg_info "Reloading systemd and enabling the watcher"
+(systemctl daemon-reload && systemctl enable --now pve-auto-hook.path) >/dev/null 2>&1 &
+spinner
+msg_ok "Systemd watcher enabled and running"
+
+msg_info "Performing initial run to update existing guests"
+/usr/local/bin/pve-apply-hookscript.sh >/dev/null 2>&1 &
+spinner
+msg_ok "Initial run complete"
+
+echo -e "\n\n${GN}Installation successful!${CL}"
+echo -e "The service is now active and will monitor for new guests."
+echo -e "To ${YW}exclude${CL} a VM or LXC, add its ID to the ${YW}IGNORE_IDS${CL} variable in:"
+echo -e " ${YW}/etc/default/pve-auto-hook${CL}"
+echo -e "\nYou can monitor the service's activity with:"
+echo -e " ${YW}journalctl -fu pve-auto-hook.service${CL}\n"
+
+exit 0
From ed551624e31346a58065e0cf164f9a8e367e3b8c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 09:05:00 +0200
Subject: [PATCH 152/312] Update tools.func
---
misc/tools.func | 44 ++++++++++++++++----------------------------
1 file changed, 16 insertions(+), 28 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index 7c7e5492..697f69fc 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -901,68 +901,56 @@ function fetch_and_deploy_gh_release() {
local assets url_match=""
assets=$(echo "$json" | jq -r '.assets[].browser_download_url')
- echo "[DEBUG] Listing all available assets from release:"
- for u in $assets; do
- echo " -> $u"
- done
-
- # 1. Pattern match
+ # If explicit filename pattern is provided (param $6), match that first
if [[ -n "$asset_pattern" ]]; then
for u in $assets; do
- filename_candidate="${u##*/}"
- if [[ "$filename_candidate" == *"$asset_pattern"* ]]; then
+ case "${u##*/}" in
+ $asset_pattern)
url_match="$u"
break
- fi
+ ;;
+ esac
done
fi
- # 2. Arch match (only if no pattern match)
+ # If no match via explicit pattern, fall back to architecture heuristic
if [[ -z "$url_match" ]]; then
for u in $assets; do
- filename_candidate="${u##*/}"
- echo " [DEBUG] Checking asset: $filename_candidate"
- if [[ "$filename_candidate" == *"$arch"* && "$filename_candidate" == *.deb ]]; then
+ if [[ "$u" =~ ($arch|amd64|x86_64|aarch64|arm64).*\.deb$ ]]; then
url_match="$u"
break
fi
done
fi
- # 3. Fallback
+ # Fallback: any .deb file
if [[ -z "$url_match" ]]; then
for u in $assets; do
- filename_candidate="${u##*/}"
- if [[ "$filename_candidate" == *.deb ]]; then
- url_match="$u"
- break
- fi
+ [[ "$u" =~ \.deb$ ]] && url_match="$u" && break
done
fi
if [[ -z "$url_match" ]]; then
- echo "[DEBUG] ❌ No suitable .deb asset found!"
+ msg_error "No suitable .deb asset found for $app"
rm -rf "$tmpdir"
return 1
fi
- echo "[DEBUG] Final selected asset: $url_match"
filename="${url_match##*/}"
-
curl $download_timeout -fsSL -o "$tmpdir/$filename" "$url_match" || {
- echo "[DEBUG] ❌ Download failed: $url_match"
+ msg_error "Download failed: $url_match"
rm -rf "$tmpdir"
return 1
}
chmod 644 "$tmpdir/$filename"
- if ! $STD apt-get install -y "$tmpdir/$filename"; then
- if ! $STD dpkg -i "$tmpdir/$filename"; then
- echo "[DEBUG] ❌ Both apt and dpkg installation failed"
+ $STD apt-get install -y "$tmpdir/$filename" || {
+ $STD dpkg -i "$tmpdir/$filename" || {
+ msg_error "Both apt and dpkg installation failed"
rm -rf "$tmpdir"
return 1
- fi
- fi
+ }
+ }
### Prebuild Mode ###
elif [[ "$mode" == "prebuild" ]]; then
From cdf6605ad05479ecc7431605a8c1cc10f32b1b89 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 10:23:42 +0200
Subject: [PATCH 153/312] Delete copyparty.json
---
frontend/public/json/copyparty.json | 40 -----------------------------
1 file changed, 40 deletions(-)
delete mode 100644 frontend/public/json/copyparty.json
diff --git a/frontend/public/json/copyparty.json b/frontend/public/json/copyparty.json
deleted file mode 100644
index bc1fb40c..00000000
--- a/frontend/public/json/copyparty.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "Copyparty",
- "slug": "copyparty",
- "categories": [
- 1
- ],
- "date_created": "2025-08-18",
- "type": "addon",
- "updateable": true,
- "privileged": false,
- "interface_port": null,
- "documentation": "https://github.com/9001/copyparty?tab=readme-ov-file#the-browser",
- "website": "https://github.com/9001/copyparty",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/copyparty.webp",
- "config_path": "",
- "description": "Copyparty is a lightweight, portable HTTP file server with a browser-based interface. It supports drag-and-drop uploads, downloads, deduplication, media playback, and advanced search, making it ideal for quickly sharing and managing files.",
- "install_methods": [
- {
- "type": "default",
- "script": "tools/addon/copyparty.sh",
- "resources": {
- "cpu": null,
- "ram": null,
- "hdd": null,
- "os": null,
- "version": null
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "Execute within the Proxmox shell or in LXC",
- "type": "info"
- }
- ]
-}
From af8adf0dfea7efca06f55d17262b7b29d52f11fa Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 10:24:19 +0200
Subject: [PATCH 154/312] Delete add-iptag.json
---
frontend/public/json/add-iptag.json | 49 -----------------------------
1 file changed, 49 deletions(-)
delete mode 100644 frontend/public/json/add-iptag.json
diff --git a/frontend/public/json/add-iptag.json b/frontend/public/json/add-iptag.json
deleted file mode 100644
index da84c850..00000000
--- a/frontend/public/json/add-iptag.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "Proxmox VE LXC IP-Tag",
- "slug": "add-lxc-iptag",
- "categories": [
- 1
- ],
- "date_created": "2025-04-02",
- "type": "addon",
- "updateable": false,
- "privileged": false,
- "interface_port": null,
- "documentation": null,
- "website": null,
- "logo": "https://raw.githubusercontent.com/selfhst/icons/refs/heads/main/svg/proxmox.svg",
- "config_path": "",
- "description": "This script automatically adds IP address as tags to LXC containers using a Systemd service. The service also updates the tags if a LXC IP address is changed.",
- "install_methods": [
- {
- "type": "default",
- "script": "tools/addon/add-iptag.sh",
- "resources": {
- "cpu": null,
- "ram": null,
- "hdd": null,
- "os": null,
- "version": null
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "Execute within the Proxmox shell",
- "type": "info"
- },
- {
- "text": "Configuration: `nano /opt/iptag/iptag.conf`. iptag.service must be restarted after change.",
- "type": "info"
- },
- {
- "text": "The Proxmox Node must contain ipcalc and net-tools. `apt-get install -y ipcalc net-tools`",
- "type": "warning"
- }
- ]
-}
-
From 4c83fe789909c357686a065a00c1d609f4307fdc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 10:27:22 +0200
Subject: [PATCH 155/312] removed
---
ct/paperless-ngx.sh | 141 ---------------------
install/paperless-ngx-install.sh | 203 -------------------------------
2 files changed, 344 deletions(-)
delete mode 100644 ct/paperless-ngx.sh
delete mode 100644 install/paperless-ngx-install.sh
diff --git a/ct/paperless-ngx.sh b/ct/paperless-ngx.sh
deleted file mode 100644
index 8c0b38e8..00000000
--- a/ct/paperless-ngx.sh
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://docs.paperless-ngx.com/
-
-APP="Paperless-ngx"
-var_tags="${var_tags:-document;management}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-10}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-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/paperless ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- if ! command -v jq &>/dev/null; then
- $STD apt-get install -y jq
- fi
- RELEASE=$(curl -fsSL https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest | jq -r .tag_name | sed 's/^v//')
- if [[ "${RELEASE}" != "$(cat ~/.paperless 2>/dev/null)" ]] || [[ ! -f ~/.paperless ]]; then
- msg_info "Stopping all Paperless-ngx Services"
- systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
- msg_ok "Stopped all Paperless-ngx Services"
-
- if grep -q "uv run" /etc/systemd/system/paperless-webserver.service; then
-
- msg_info "backing up data"
- mkdir -p /opt/paperless/backup
- cp -r /opt/paperless/data /opt/paperless/backup/
- cp -r /opt/paperless/media /opt/paperless/backup/
- cp -r /opt/paperless/paperless.conf /opt/paperless/backup/
- msg_ok "Backup completed"
-
- PYTHON_VERSION="3.13" setup_uv
- fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
- fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- setup_gs
-
- msg_info "Updating to ${RELEASE}"
- cp -r /opt/paperless/backup/* /opt/paperless/
- cd /opt/paperless
- $STD uv sync --all-extras
- cd /opt/paperless/src
- $STD uv run -- python manage.py migrate
- msg_ok "Updated to ${RELEASE}"
- else
- msg_warn "You are about to migrate your Paperless-ngx installation to uv!"
- msg_custom "🔒" "It is strongly recommended to take a Proxmox snapshot first:"
- echo -e " 1. Stop the container: pct stop "
- echo -e " 2. Create a snapshot: pct snapshot pre-paperless-uv-migration"
- echo -e " 3. Start the container again\n"
-
- read -rp "Have you created a snapshot? [y/N]: " confirm
- if [[ ! "$confirm" =~ ^([yY]|[yY][eE][sS])$ ]]; then
- msg_error "Migration aborted. Please create a snapshot first."
- exit 1
- fi
- msg_info "Migrating old Paperless-ngx installation to uv"
- rm -rf /opt/paperless/venv
- find /opt/paperless -name "__pycache__" -type d -exec rm -rf {} +
-
- declare -A PATCHES=(
- ["paperless-consumer.service"]="ExecStart=uv run -- python manage.py document_consumer"
- ["paperless-scheduler.service"]="ExecStart=uv run -- celery --app paperless beat --loglevel INFO"
- ["paperless-task-queue.service"]="ExecStart=uv run -- celery --app paperless worker --loglevel INFO"
- ["paperless-webserver.service"]="ExecStart=uv run -- granian --interface asgi --ws \"paperless.asgi:application\""
- )
-
- for svc in "${!PATCHES[@]}"; do
- path=$(systemctl show -p FragmentPath "$svc" | cut -d= -f2)
- if [[ -n "$path" && -f "$path" ]]; then
- sed -i "s|^ExecStart=.*|${PATCHES[$svc]}|" "$path"
- if [[ "$svc" == "paperless-webserver.service" ]]; then
- grep -q "^Environment=GRANIAN_HOST=" "$path" ||
- sed -i '/^\[Service\]/a Environment=GRANIAN_HOST=::' "$path"
- grep -q "^Environment=GRANIAN_PORT=" "$path" ||
- sed -i '/^\[Service\]/a Environment=GRANIAN_PORT=8000' "$path"
- grep -q "^Environment=GRANIAN_WORKERS=" "$path" ||
- sed -i '/^\[Service\]/a Environment=GRANIAN_WORKERS=1' "$path"
- fi
- msg_ok "Patched $svc"
- else
- msg_error "Service file for $svc not found!"
- fi
- done
-
- $STD systemctl daemon-reload
- msg_info "backing up data"
- mkdir -p /opt/paperless/backup
- cp -r /opt/paperless/data /opt/paperless/backup/
- cp -r /opt/paperless/media /opt/paperless/backup/
- cp -r /opt/paperless/paperless.conf /opt/paperless/backup/
- msg_ok "Backup completed"
-
- PYTHON_VERSION="3.13" setup_uv
- fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
- fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
- setup_gs
-
- msg_info "Updating Paperless-ngx"
- cp -r /opt/paperless/backup/* /opt/paperless/
- cd /opt/paperless
- $STD uv sync --all-extras
- cd /opt/paperless/src
- $STD uv run -- python manage.py migrate
- msg_ok "Paperless-ngx migration and update to ${RELEASE} completed"
- fi
-
- msg_info "Starting all Paperless-ngx Services"
- systemctl start paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
- sleep 1
- msg_ok "Started all Paperless-ngx Services"
- msg_ok "Updated Successfully!\n"
- else
- msg_ok "No update required. ${APP} is already at v${RELEASE}"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
diff --git a/install/paperless-ngx-install.sh b/install/paperless-ngx-install.sh
deleted file mode 100644
index d668909f..00000000
--- a/install/paperless-ngx-install.sh
+++ /dev/null
@@ -1,203 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster) | MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://docs.paperless-ngx.com/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y \
- redis \
- build-essential \
- imagemagick \
- fonts-liberation \
- optipng \
- libpq-dev \
- libmagic-dev \
- mime-support \
- libzbar0 \
- poppler-utils \
- default-libmysqlclient-dev \
- automake \
- libtool \
- pkg-config \
- libtiff-dev \
- libpng-dev \
- libleptonica-dev
-msg_ok "Installed Dependencies"
-
-PG_VERSION="16" setup_postgresql
-PYTHON_VERSION="3.13" setup_uv
-fetch_and_deploy_gh_release "paperless" "paperless-ngx/paperless-ngx" "prebuild" "latest" "/opt/paperless" "paperless*tar.xz"
-fetch_and_deploy_gh_release "jbig2enc" "ie13/jbig2enc" "tarball" "latest" "/opt/jbig2enc"
-setup_gs
-
-msg_info "Installing OCR Dependencies (Patience)"
-$STD apt-get install -y \
- unpaper \
- icc-profiles-free \
- qpdf \
- liblept5 \
- libxml2 \
- pngquant \
- zlib1g \
- tesseract-ocr \
- tesseract-ocr-eng
-$STD sudo make install
-msg_ok "Installed OCR Dependencies"
-
-msg_info "Setup JBIG2"
-cd /opt/jbig2enc
-$STD bash ./autogen.sh
-$STD bash ./configure
-$STD make
-$STD make install
-rm -rf /opt/jbig2enc
-msg_ok "Installed JBIG2"
-
-msg_info "Setting up PostgreSQL database"
-DB_NAME=paperlessdb
-DB_USER=paperless
-DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
-SECRET_KEY="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)"
-$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
-echo "" >>~/paperless.creds
-echo -e "Paperless-ngx Database User: \e[32m$DB_USER\e[0m" >>~/paperless.creds
-echo -e "Paperless-ngx Database Password: \e[32m$DB_PASS\e[0m" >>~/paperless.creds
-echo -e "Paperless-ngx Database Name: \e[32m$DB_NAME\e[0m" >>~/paperless.creds
-
-msg_info "Installing Natural Language Toolkit (Patience)"
-$STD uv run -- python -m nltk.downloader -d /usr/share/nltk_data all
-sed -i -e 's/rights="none" pattern="PDF"/rights="read|write" pattern="PDF"/' /etc/ImageMagick-6/policy.xml
-msg_ok "Installed Natural Language Toolkit"
-
-msg_info "Setup Paperless-ngx"
-cd /opt/paperless
-$STD uv sync --all-extras
-curl -fsSL "https://raw.githubusercontent.com/paperless-ngx/paperless-ngx/main/paperless.conf.example" -o /opt/paperless/paperless.conf
-mkdir -p {consume,data,media,static}
-sed -i \
- -e 's|#PAPERLESS_REDIS=redis://localhost:6379|PAPERLESS_REDIS=redis://localhost:6379|' \
- -e "s|#PAPERLESS_CONSUMPTION_DIR=../consume|PAPERLESS_CONSUMPTION_DIR=/opt/paperless/consume|" \
- -e "s|#PAPERLESS_DATA_DIR=../data|PAPERLESS_DATA_DIR=/opt/paperless/data|" \
- -e "s|#PAPERLESS_MEDIA_ROOT=../media|PAPERLESS_MEDIA_ROOT=/opt/paperless/media|" \
- -e "s|#PAPERLESS_STATICDIR=../static|PAPERLESS_STATICDIR=/opt/paperless/static|" \
- -e 's|#PAPERLESS_DBHOST=localhost|PAPERLESS_DBHOST=localhost|' \
- -e 's|#PAPERLESS_DBPORT=5432|PAPERLESS_DBPORT=5432|' \
- -e "s|#PAPERLESS_DBNAME=paperless|PAPERLESS_DBNAME=$DB_NAME|" \
- -e "s|#PAPERLESS_DBUSER=paperless|PAPERLESS_DBUSER=$DB_USER|" \
- -e "s|#PAPERLESS_DBPASS=paperless|PAPERLESS_DBPASS=$DB_PASS|" \
- -e "s|#PAPERLESS_SECRET_KEY=change-me|PAPERLESS_SECRET_KEY=$SECRET_KEY|" \
- /opt/paperless/paperless.conf
-cd /opt/paperless/src
-$STD uv run -- python manage.py migrate
-msg_ok "Setup Paperless-ngx"
-
-msg_info "Setting up admin Paperless-ngx User & Password"
-cat <>~/paperless-ngx.creds
-msg_ok "Set up admin Paperless-ngx User & Password"
-
-msg_info "Creating Services"
-cat </etc/systemd/system/paperless-scheduler.service
-[Unit]
-Description=Paperless Celery beat
-Requires=redis.service
-
-[Service]
-WorkingDirectory=/opt/paperless/src
-ExecStart=uv run -- celery --app paperless beat --loglevel INFO
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-cat </etc/systemd/system/paperless-task-queue.service
-[Unit]
-Description=Paperless Celery Workers
-Requires=redis.service
-After=postgresql.service
-
-[Service]
-WorkingDirectory=/opt/paperless/src
-ExecStart=uv run -- celery --app paperless worker --loglevel INFO
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-cat </etc/systemd/system/paperless-consumer.service
-[Unit]
-Description=Paperless consumer
-Requires=redis.service
-
-[Service]
-WorkingDirectory=/opt/paperless/src
-ExecStartPre=/bin/sleep 2
-ExecStart=uv run -- python manage.py document_consumer
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-cat </etc/systemd/system/paperless-webserver.service
-[Unit]
-Description=Paperless webserver
-After=network.target
-Wants=network.target
-Requires=redis.service
-
-[Service]
-WorkingDirectory=/opt/paperless/src
-ExecStart=uv run -- granian --interface asginl --ws "paperless.asgi:application"
-Environment=GRANIAN_HOST=::
-Environment=GRANIAN_PORT=8000
-Environment=GRANIAN_WORKERS=1
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now paperless-webserver paperless-scheduler paperless-task-queue paperless-consumer
-msg_ok "Created Services"
-
-read -r -p "${TAB3}Would you like to add Adminer? " prompt
-if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
- setup_adminer
-fi
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-rm -rf /opt/paperless/docker
-rm -rf /tmp/ghostscript*
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
From 55efd85a1127b450a320adc4146508398b4b524a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 10:31:39 +0200
Subject: [PATCH 156/312] Update create_lxc.sh
---
misc/create_lxc.sh | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index c986bd7b..72200f8f 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -6,7 +6,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# This sets verbose mode if the global variable is set to "yes"
-if [ "$VERBOSE" == "yes" ]; then set -x; fi
+if [ "$CREATE_LXC_VERBOSE" == "yes" ]; then set -x; fi
if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
@@ -255,18 +255,17 @@ fi
# Update LXC template list
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
case "$PCT_OSTYPE" in
- debian|ubuntu)
- TEMPLATE_PATTERN="-standard_"
- ;;
- alpine|fedora|rocky|centos)
- TEMPLATE_PATTERN="-default_"
- ;;
- *)
- TEMPLATE_PATTERN=""
- ;;
+debian | ubuntu)
+ TEMPLATE_PATTERN="-standard_"
+ ;;
+alpine | fedora | rocky | centos)
+ TEMPLATE_PATTERN="-default_"
+ ;;
+*)
+ TEMPLATE_PATTERN=""
+ ;;
esac
-
# 1. Check local templates first
msg_info "Searching for template '$TEMPLATE_SEARCH'"
mapfile -t TEMPLATES < <(
@@ -284,12 +283,11 @@ else
pveam update >/dev/null 2>&1 &&
pveam available -section system |
sed -n "s/.*\($TEMPLATE_SEARCH.*$TEMPLATE_PATTERN.*\)/\1/p" |
- sort -t - -k 2 -V
+ sort -t - -k 2 -V
)
TEMPLATE_SOURCE="online"
fi
-
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null ||
echo "/var/lib/vz/template/cache/$TEMPLATE")"
From ab311f2bd2ca98b68c0dd6157d866ad37af13bc9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 11:10:35 +0200
Subject: [PATCH 157/312] Update healthchecks-install.sh
---
install/healthchecks-install.sh | 71 +++++++++++++--------------------
1 file changed, 28 insertions(+), 43 deletions(-)
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index 5ce285fe..cf0eca1e 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -21,12 +21,6 @@ $STD apt-get install -y \
libssl-dev
msg_ok "Installed Dependencies"
-msg_info "Setup Python3"
-$STD apt-get install -y \
- python3 python3-dev python3-pip
-$STD pip install --upgrade pip
-msg_ok "Setup Python3"
-
setup_uv
PG_VERSION=16 setup_postgresql
@@ -49,54 +43,45 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
} >>~/healthchecks.creds
msg_ok "Set up Database"
-msg_info "Setup healthchecks"
fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "source"
+msg_info "Setup healthchecks"
cd /opt/healthchecks
mkdir -p /opt/healthchecks/static-collected/
-$STD uv venv .venv
-$STD source .venv/bin/activate
-$STD uv pip install wheel
-$STD uv pip install gunicorn
-$STD uv pip install -r requirements.txt
+$STD uv pip install wheel gunicorn -r requirements.txt
LOCAL_IP=$(hostname -I | awk '{print $1}')
-cat </opt/healthchecks/.env
-ALLOWED_HOSTS=localhost,127.0.0.1,${LOCAL_IP},healthchecks
-DB=postgres
-DB_HOST=localhost
-DB_PORT=5432
-DB_NAME=${DB_NAME}
-DB_USER=${DB_USER}
-DB_PASSWORD=${DB_PASS}
-DB_CONN_MAX_AGE=0
-DB_SSLMODE=prefer
-DB_TARGET_SESSION_ATTRS=read-write
-DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?sslmode=prefer
+cat </opt/healthchecks/hc/local_settings.py
+DEBUG = False
-DEFAULT_FROM_EMAIL=healthchecks@example.org
-EMAIL_HOST=localhost
-EMAIL_HOST_PASSWORD=
-EMAIL_HOST_USER=
-EMAIL_PORT=587
-EMAIL_USE_TLS=True
-EMAIL_USE_VERIFICATION=True
+ALLOWED_HOSTS = ["${LOCAL_IP}", "127.0.0.1", "localhost"]
+CSRF_TRUSTED_ORIGINS = ["https://${LOCAL_IP}"]
-# Django & Healthchecks Konfiguration
-SECRET_KEY=${SECRET_KEY}
-DEBUG=True
+SECRET_KEY = "${SECRET_KEY}"
-SITE_ROOT=http://${LOCAL_IP}:8000
-SITE_NAME=MyChecks
-STATIC_ROOT=/opt/healthchecks/static-collected
+SITE_ROOT = "https://${LOCAL_IP}"
+SITE_NAME = "MyChecks"
+DEFAULT_FROM_EMAIL = "healthchecks@${LOCAL_IP}"
+STATIC_ROOT = "/opt/healthchecks/static-collected"
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': '${DB_NAME}',
+ 'USER': '${DB_USER}',
+ 'PASSWORD': '${DB_PASS}',
+ 'HOST': '127.0.0.1',
+ 'PORT': '5432',
+ 'TEST': {'CHARSET': 'UTF8'}
+ }
+}
EOF
-
-$STD .venv/bin/python3 manage.py makemigrations
-$STD .venv/bin/python3 manage.py migrate --noinput
-$STD .venv/bin/python3 manage.py collectstatic --noinput
+$STD uv run -- python manage.py makemigrations
+$STD uv run -- python manage.py migrate --noinput
+$STD uv run -- python manage.py collectstatic --noinput
ADMIN_EMAIL="admin@helper-scripts.local"
ADMIN_PASSWORD="$DB_PASS"
-cat <
Date: Thu, 21 Aug 2025 11:14:22 +0200
Subject: [PATCH 158/312] Update healthchecks-install.sh
---
install/healthchecks-install.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index cf0eca1e..6496d149 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -44,10 +44,11 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
msg_ok "Set up Database"
fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "source"
+
msg_info "Setup healthchecks"
cd /opt/healthchecks
mkdir -p /opt/healthchecks/static-collected/
-$STD uv pip install wheel gunicorn -r requirements.txt
+$STD uv pip install wheel gunicorn -r requirements.txt --system
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat </opt/healthchecks/hc/local_settings.py
DEBUG = False
From 1514caac1113210f7fbb35f3beca7addb39d88cc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 11:53:07 +0200
Subject: [PATCH 159/312] fixes
---
install/healthchecks-install.sh | 10 ++++++----
misc/tools.func | 6 +++---
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index 6496d149..ab265b5c 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -49,20 +49,22 @@ msg_info "Setup healthchecks"
cd /opt/healthchecks
mkdir -p /opt/healthchecks/static-collected/
$STD uv pip install wheel gunicorn -r requirements.txt --system
+
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat </opt/healthchecks/hc/local_settings.py
DEBUG = False
ALLOWED_HOSTS = ["${LOCAL_IP}", "127.0.0.1", "localhost"]
-CSRF_TRUSTED_ORIGINS = ["https://${LOCAL_IP}"]
+CSRF_TRUSTED_ORIGINS = ["http://${LOCAL_IP}", "https://${LOCAL_IP}"]
SECRET_KEY = "${SECRET_KEY}"
-SITE_ROOT = "https://${LOCAL_IP}"
+SITE_ROOT = "http://${LOCAL_IP}:8000"
SITE_NAME = "MyChecks"
DEFAULT_FROM_EMAIL = "healthchecks@${LOCAL_IP}"
STATIC_ROOT = "/opt/healthchecks/static-collected"
+COMPRESS_OFFLINE = True
DATABASES = {
'default': {
@@ -76,9 +78,11 @@ DATABASES = {
}
}
EOF
+
$STD uv run -- python manage.py makemigrations
$STD uv run -- python manage.py migrate --noinput
$STD uv run -- python manage.py collectstatic --noinput
+$STD uv run -- python manage.py compress
ADMIN_EMAIL="admin@helper-scripts.local"
ADMIN_PASSWORD="$DB_PASS"
@@ -98,9 +102,7 @@ After=network.target postgresql.service
[Service]
WorkingDirectory=/opt/healthchecks/
-EnvironmentFile=/opt/healthchecks/.env
ExecStart=/usr/local/bin/uv run -- gunicorn hc.wsgi:application --bind 127.0.0.1:8000
-
Restart=always
[Install]
diff --git a/misc/tools.func b/misc/tools.func
index 697f69fc..6bb819b9 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -163,7 +163,7 @@ function setup_postgresql() {
if [[ "$CURRENT_PG_VERSION" == "$PG_VERSION" ]]; then
: # PostgreSQL is already at the desired version – no action needed
else
- msg_info "Detected PostgreSQL $CURRENT_PG_VERSION, preparing upgrade to $PG_VERSION"
+ $STD msg_info "Detected PostgreSQL $CURRENT_PG_VERSION, preparing upgrade to $PG_VERSION"
NEED_PG_INSTALL=true
fi
else
@@ -173,9 +173,9 @@ function setup_postgresql() {
if [[ "$NEED_PG_INSTALL" == true ]]; then
if [[ -n "$CURRENT_PG_VERSION" ]]; then
- msg_info "Dumping PostgreSQL $CURRENT_PG_VERSION data"
+ $STD msg_info "Dumping PostgreSQL $CURRENT_PG_VERSION data"
su - postgres -c "pg_dumpall > /var/lib/postgresql/backup_$(date +%F)_v${CURRENT_PG_VERSION}.sql"
- msg_ok "Data dump completed"
+ $STD msg_ok "Data dump completed"
systemctl stop postgresql
fi
From c71d10830bf0eebe4edc8b77904a7b5d1c147b5a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 13:01:56 +0200
Subject: [PATCH 160/312] Update healthchecks-install.sh
---
install/healthchecks-install.sh | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index ab265b5c..fe1a95ba 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -18,7 +18,8 @@ $STD apt-get install -y \
gcc \
libpq-dev \
libcurl4-openssl-dev \
- libssl-dev
+ libssl-dev \
+ caddy
msg_ok "Installed Dependencies"
setup_uv
@@ -94,6 +95,18 @@ if not User.objects.filter(email="${ADMIN_EMAIL}").exists():
EOF
msg_ok "Installed healthchecks"
+msg_info "Configuring Caddy"
+cat </etc/caddy/Caddyfile
+{
+ email admin@example.com
+}
+
+${LOCAL_IP} {
+ reverse_proxy 127.0.0.1:8000
+}
+EOF
+msg_ok "Configured Caddy"
+
msg_info "Creating Service"
cat </etc/systemd/system/healthchecks.service
[Unit]
@@ -108,7 +121,7 @@ Restart=always
[Install]
WantedBy=multi-user.target
EOF
-systemctl enable -q --now healthchecks
+systemctl enable -q --now healthchecks caddy
msg_ok "Created Service"
motd_ssh
From 5fea4a4b194b5faa0398f4422f8eeb383779cd7d Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 21 Aug 2025 13:17:25 +0200
Subject: [PATCH 161/312] Update healthchecks-install.sh
---
install/healthchecks-install.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index fe1a95ba..05111846 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -30,6 +30,8 @@ DB_NAME=healthchecks_db
DB_USER=hc_user
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"
+ADMIN_EMAIL="admin@helper-scripts.local"
+ADMIN_PASSWORD="$DB_PASS"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
@@ -41,6 +43,8 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
echo "healthchecks Database User: $DB_USER"
echo "healthchecks Database Password: $DB_PASS"
echo "healthchecks Database Name: $DB_NAME"
+ echo "healthchecks Admin Email: $ADMIN_EMAIL"
+ echo "healthchecks Admin Password: $ADMIN_PASSWORD"
} >>~/healthchecks.creds
msg_ok "Set up Database"
@@ -85,8 +89,6 @@ $STD uv run -- python manage.py migrate --noinput
$STD uv run -- python manage.py collectstatic --noinput
$STD uv run -- python manage.py compress
-ADMIN_EMAIL="admin@helper-scripts.local"
-ADMIN_PASSWORD="$DB_PASS"
cat <
Date: Thu, 21 Aug 2025 13:23:17 +0200
Subject: [PATCH 162/312] Update healthchecks.sh
---
ct/healthchecks.sh | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/ct/healthchecks.sh b/ct/healthchecks.sh
index 8b55f7fd..44218b6c 100644
--- a/ct/healthchecks.sh
+++ b/ct/healthchecks.sh
@@ -20,15 +20,15 @@ color
catch_errors
function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -f /etc/systemd/system/healthchecks.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- msg_error "No Update."
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -f /etc/systemd/system/healthchecks.service ]]; then
+ msg_error "No ${APP} Installation Found!"
exit
+ fi
+ msg_error "No Update."
+ exit
}
start
@@ -38,4 +38,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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}https://${IP}${CL}"
From d8160d9a9fc159686940cbaa0533de900a356332 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Thu, 21 Aug 2025 11:23:41 +0000
Subject: [PATCH 163/312] Update .app files
---
ct/headers/alpine-rustdeskserver | 6 ++++++
ct/headers/paperless-ngx | 6 ------
2 files changed, 6 insertions(+), 6 deletions(-)
create mode 100644 ct/headers/alpine-rustdeskserver
delete mode 100644 ct/headers/paperless-ngx
diff --git a/ct/headers/alpine-rustdeskserver b/ct/headers/alpine-rustdeskserver
new file mode 100644
index 00000000..1c99e61f
--- /dev/null
+++ b/ct/headers/alpine-rustdeskserver
@@ -0,0 +1,6 @@
+ ___ __ _ ____ __ ____ __ _____
+ / | / /___ (_)___ ___ / __ \__ _______/ /_/ __ \___ _____/ /__/ ___/___ ______ _____ _____
+ / /| | / / __ \/ / __ \/ _ \______/ /_/ / / / / ___/ __/ / / / _ \/ ___/ //_/\__ \/ _ \/ ___/ | / / _ \/ ___/
+ / ___ |/ / /_/ / / / / / __/_____/ _, _/ /_/ (__ ) /_/ /_/ / __(__ ) ,< ___/ / __/ / | |/ / __/ /
+/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_|\__,_/____/\__/_____/\___/____/_/|_|/____/\___/_/ |___/\___/_/
+ /_/
diff --git a/ct/headers/paperless-ngx b/ct/headers/paperless-ngx
deleted file mode 100644
index 177cf574..00000000
--- a/ct/headers/paperless-ngx
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ __
- / __ \____ _____ ___ _____/ /__ __________ ____ ____ __ __
- / /_/ / __ `/ __ \/ _ \/ ___/ / _ \/ ___/ ___/_____/ __ \/ __ `/ |/_/
- / ____/ /_/ / /_/ / __/ / / / __(__ |__ )_____/ / / / /_/ /> <
-/_/ \__,_/ .___/\___/_/ /_/\___/____/____/ /_/ /_/\__, /_/|_|
- /_/ /____/
From 65d2d1205d094f82f6845bd943be03fdd0f7b1f2 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 10:35:25 +0200
Subject: [PATCH 164/312] Update create_lxc.sh
---
misc/create_lxc.sh | 43 +++++++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 20 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 72200f8f..210ff177 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -346,35 +346,38 @@ flock -w 60 9 || {
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- msg_error "Container creation failed. Checking if template is corrupted or incomplete."
+ msg_error "Container creation failed on ${TEMPLATE_STORAGE}. Checking template..."
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
msg_error "Template file too small or missing – re-downloading."
rm -f "$TEMPLATE_PATH"
+ pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
elif ! zstdcat "$TEMPLATE_PATH" | tar -tf - &>/dev/null; then
msg_error "Template appears to be corrupted – re-downloading."
rm -f "$TEMPLATE_PATH"
+ pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
else
- msg_error "Template is valid, but container creation still failed."
- exit 209
+ # --- NEW FALLBACK LOGIC ---
+ if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
+ msg_warn "Retrying container creation with fallback to local storage..."
+ LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
+ if [ ! -f "$LOCAL_TEMPLATE_PATH" ]; then
+ msg_info "Downloading template to local..."
+ pveam download local "$TEMPLATE"
+ fi
+ if pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
+ msg_ok "Container successfully created using fallback to local."
+ else
+ msg_error "Container creation failed even with fallback to local."
+ exit 209
+ fi
+ # Skip the rest of error handling since fallback worked
+ continue
+ else
+ msg_error "Template is valid, but container creation still failed on local."
+ exit 209
+ fi
fi
-
- # Retry download
- for attempt in {1..3}; do
- msg_info "Attempt $attempt: Re-downloading template..."
- if timeout 120 pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null; then
- msg_ok "Template re-download successful."
- break
- fi
- if [ "$attempt" -eq 3 ]; then
- msg_error "Three failed attempts. Aborting."
- exit 208
- fi
- sleep $((attempt * 5))
- done
-
- sleep 1 # I/O-Sync-Delay
- msg_ok "Re-downloaded LXC Template"
fi
if ! pct list | awk '{print $1}' | grep -qx "$CTID"; then
From 2bf4eed425919d93e882c03d4cc516db97bb7b04 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 10:37:22 +0200
Subject: [PATCH 165/312] test
---
ct/debian.sh | 4 ++--
install/debian-install.sh | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ct/debian.sh b/ct/debian.sh
index 3cc0b73d..d3bbda9b 100644
--- a/ct/debian.sh
+++ b/ct/debian.sh
@@ -13,8 +13,8 @@ var_disk="${var_disk:-15}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
-var_fuse="${var_fuse:-no}"
-var_tun="${var_tun:-no}"
+#var_fuse="${var_fuse:-no}"
+#var_tun="${var_tun:-no}"
header_info "$APP"
variables
diff --git a/install/debian-install.sh b/install/debian-install.sh
index ca9567b9..e6259184 100644
--- a/install/debian-install.sh
+++ b/install/debian-install.sh
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt-get install -y gpg
msg_ok "Installed Dependencies"
-setup_mariadb
+#setup_mariadb
#FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg
@@ -35,7 +35,7 @@ setup_mariadb
#msg_ok "Get Release $RELEASE"
#NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
-PG_VERSION="16" setup_postgresql
+#PG_VERSION="16" setup_postgresql
motd_ssh
customize
From d768bd885e5e33d2a75223197befe6ce6f1b7922 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 10:38:58 +0200
Subject: [PATCH 166/312] Update create_lxc.sh
---
misc/create_lxc.sh | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 210ff177..99753a4a 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -345,6 +345,7 @@ flock -w 60 9 || {
}
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
+
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
msg_error "Container creation failed on ${TEMPLATE_STORAGE}. Checking template..."
@@ -359,19 +360,21 @@ if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[
else
# --- NEW FALLBACK LOGIC ---
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
- msg_warn "Retrying container creation with fallback to local storage..."
+ msg_warn "Retrying container creation with fallback to local template storage..."
LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if [ ! -f "$LOCAL_TEMPLATE_PATH" ]; then
msg_info "Downloading template to local..."
+ msg_debug "pveam download local $TEMPLATE"
pveam download local "$TEMPLATE"
fi
+ msg_debug "pct create command (fallback): pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
if pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- msg_ok "Container successfully created using fallback to local."
+ msg_ok "Container successfully created using fallback to local template storage."
else
msg_error "Container creation failed even with fallback to local."
exit 209
fi
- # Skip the rest of error handling since fallback worked
+ # Skip remaining error handling since fallback worked
continue
else
msg_error "Template is valid, but container creation still failed on local."
From 07864be2a09e349ccdec8cd6f50f047034b53752 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 10:39:55 +0200
Subject: [PATCH 167/312] Update ubuntu-install.sh
---
install/ubuntu-install.sh | 96 ---------------------------------------
1 file changed, 96 deletions(-)
diff --git a/install/ubuntu-install.sh b/install/ubuntu-install.sh
index ed5dc817..97283d83 100644
--- a/install/ubuntu-install.sh
+++ b/install/ubuntu-install.sh
@@ -17,102 +17,6 @@ msg_info "Installing Dependencies"
$STD apt-get install -y jq
msg_ok "Installed Dependencies"
-# echo "Getting aceberg/WatchYourLAN..."
-# fetch_and_deploy_gh_release aceberg/WatchYourLAN
-# echo "Got Version: $RELEASE"
-
-# echo "Getting actualbudget/actual..."
-# RELEASE=$(get_gh_release actualbudget/actual)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting agl/jbig2enc..."
-# RELEASE=$(get_gh_release agl/jbig2enc)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting alexta69/metube..."
-# RELEASE=$(get_gh_release alexta69/metube)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting AlexxIT/go2rtc..."
-# RELEASE=$(get_gh_release AlexxIT/go2rtc)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting apache/tika..."
-# RELEASE=$(get_gh_release apache/tika)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting ArtifexSoftware/ghostpdl-downloads..."
-# RELEASE=$(get_gh_release ArtifexSoftware/ghostpdl-downloads)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting Athou/commafeed..."
-# RELEASE=$(get_gh_release Athou/commafeed)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting authelia/authelia..."
-# RELEASE=$(get_gh_release authelia/authelia)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting azukaar/Cosmos-Server..."
-# RELEASE=$(get_gh_release azukaar/Cosmos-Server)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting bastienwirtz/homer..."
-# RELEASE=$(get_gh_release bastienwirtz/homer)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting benjaminjonard/koillection..."
-# RELEASE=$(get_gh_release benjaminjonard/koillection)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting benzino77/tasmocompiler..."
-# RELEASE=$(get_gh_release benzino77/tasmocompiler)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting blakeblackshear/frigate..."
-# RELEASE=$(get_gh_release blakeblackshear/frigate)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting bluenviron/mediamtx..."
-# RELEASE=$(get_gh_release bluenviron/mediamtx)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting BookStackApp/BookStack..."
-# RELEASE=$(get_gh_release BookStackApp/BookStack)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting browserless/chrome..."
-# RELEASE=$(get_gh_release browserless/chrome)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting Bubka/2FAuth..."
-# RELEASE=$(get_gh_release Bubka/2FAuth)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting caddyserver/xcaddy..."
-# RELEASE=$(get_gh_release caddyserver/xcaddy)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting clusterzx/paperless-ai..."
-# RELEASE=$(get_gh_release clusterzx/paperless-ai)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting cockpit-project/cockpit..."
-# RELEASE=$(get_gh_release cockpit-project/cockpit)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting community-scripts/ProxmoxVE..."
-# RELEASE=$(get_gh_release community-scripts/ProxmoxVE)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting CorentinTh/it-tools..."
-# RELEASE=$(get_gh_release CorentinTh/it-tools)
-# echo "Got Version: $RELEASE"
-
-# echo "Getting dani-garcia/bw_web_builds..."
-# RELEASE=$(get_gh_release dani-garcia/bw_web_builds)
-# echo "Got Version: $RELEASE"
-
motd_ssh
customize
From 262b93f15410e5665caaa32359a217d897fa5607 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 11:48:01 +0200
Subject: [PATCH 168/312] Update create_lxc.sh
---
misc/create_lxc.sh | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 99753a4a..b7c8db09 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -234,6 +234,26 @@ while true; do
fi
done
+# Storage Content Validation
+msg_info "Validating content types of storage '$CONTAINER_STORAGE'"
+STORAGE_CONTENT=$(grep -A4 -E "^(zfspool|dir|lvmthin|lvm): $CONTAINER_STORAGE" /etc/pve/storage.cfg | grep content | awk '{$1=""; print $0}' | xargs)
+
+msg_debug "Storage '$CONTAINER_STORAGE' has content types: $STORAGE_CONTENT"
+
+# check if rootdir supported
+if ! grep -qw "rootdir" <<<"$STORAGE_CONTENT"; then
+ msg_error "Storage '$CONTAINER_STORAGE' does not support 'rootdir'. Cannot create LXC."
+ exit 217
+fi
+
+# check if template storage is compatible
+TEMPLATE_CONTENT=$(grep -A4 -E "^[^:]+: $TEMPLATE_STORAGE" /etc/pve/storage.cfg | grep content | awk '{$1=""; print $0}' | xargs)
+msg_debug "Template storage '$TEMPLATE_STORAGE' has content types: $TEMPLATE_CONTENT"
+
+if ! grep -qw "vztmpl" <<<"$TEMPLATE_CONTENT"; then
+ msg_warn "Template storage '$TEMPLATE_STORAGE' does not declare 'vztmpl'. This may cause pct create to fail."
+fi
+
# Check free space on selected container storage
STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }')
REQUIRED_KB=$((${PCT_DISK_SIZE:-8} * 1024 * 1024))
From 7eec53900fb4e7f8924aedf82d024222c2171a58 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 11:58:19 +0200
Subject: [PATCH 169/312] Update create_lxc.sh
---
misc/create_lxc.sh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index b7c8db09..7a5d18cf 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -245,13 +245,18 @@ if ! grep -qw "rootdir" <<<"$STORAGE_CONTENT"; then
msg_error "Storage '$CONTAINER_STORAGE' does not support 'rootdir'. Cannot create LXC."
exit 217
fi
+msg_ok "Storage '$CONTAINER_STORAGE' supports 'rootdir'"
# check if template storage is compatible
+msg_info "Validating content types of template storage '$TEMPLATE_STORAGE'"
TEMPLATE_CONTENT=$(grep -A4 -E "^[^:]+: $TEMPLATE_STORAGE" /etc/pve/storage.cfg | grep content | awk '{$1=""; print $0}' | xargs)
+
msg_debug "Template storage '$TEMPLATE_STORAGE' has content types: $TEMPLATE_CONTENT"
if ! grep -qw "vztmpl" <<<"$TEMPLATE_CONTENT"; then
msg_warn "Template storage '$TEMPLATE_STORAGE' does not declare 'vztmpl'. This may cause pct create to fail."
+else
+ msg_ok "Template storage '$TEMPLATE_STORAGE' supports 'vztmpl'"
fi
# Check free space on selected container storage
From e136c161cc1724b746d00ab836f9deff5796a7b2 Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 12:03:34 +0200
Subject: [PATCH 170/312] Added Redlib install/update script
---
ct/redlib.sh | 67 ++++++++++++++++++++
frontend/public/json/redlib.json | 35 +++++++++++
install/redlib-install.sh | 105 +++++++++++++++++++++++++++++++
3 files changed, 207 insertions(+)
create mode 100644 ct/redlib.sh
create mode 100644 frontend/public/json/redlib.json
create mode 100644 install/redlib-install.sh
diff --git a/ct/redlib.sh b/ct/redlib.sh
new file mode 100644
index 00000000..23d702bc
--- /dev/null
+++ b/ct/redlib.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: andrej-kocijan (Andrej Kocijan)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/redlib-org/redlib
+
+APP="Redlib"
+var_tags="${var_tags:-alpine;frontend}"
+var_cpu="${var_cpu:-1}"
+var_ram="${var_ram:-512}"
+var_disk="${var_disk:-1}"
+var_os="${var_os:-alpine}"
+var_version="${var_version:-3.22}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_resources
+
+ if [[ ! -d /opt/redlib ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ RELEASE=$(curl -s https://api.github.com/repos/redlib-org/redlib/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+ if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ msg_info "Updating Alpine Packages"
+ $STD apk -U upgrade
+ msg_ok "Updated Alpine Packages"
+
+ msg_info "Stopping ${APP} Service"
+ $STD rc-service redlib stop
+ msg_info "Stopped ${APP} Service"
+
+ msg_info "Updating ${APP}"
+ $STD curl -fsSL -o /tmp/redlib-x86_64-unknown-linux-musl.tar.gz \
+ "https://github.com/redlib-org/redlib/releases/latest/download/redlib-x86_64-unknown-linux-musl.tar.gz"
+ $STD tar -xzf /tmp/redlib-x86_64-unknown-linux-musl.tar.gz -C /opt/redlib
+ $STD rm /tmp/redlib-x86_64-unknown-linux-musl.tar.gz
+ msg_ok "Updated ${APP}"
+
+ msg_info "Starting ${APP} Service"
+ $STD rc-service redlib start
+ msg_ok "Started ${APP} Service"
+
+ echo "${RELEASE}" >/opt/${APP}_version.txt
+ msg_ok "Update Successful"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:5252${CL}"
diff --git a/frontend/public/json/redlib.json b/frontend/public/json/redlib.json
new file mode 100644
index 00000000..40a0b7e8
--- /dev/null
+++ b/frontend/public/json/redlib.json
@@ -0,0 +1,35 @@
+{
+ "name": "Redlib",
+ "slug": "redlib",
+ "categories": [
+ 10
+ ],
+ "date_created": "2025-08-22",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 5252,
+ "documentation": null,
+ "website": "https://github.com/redlib-org/redlib",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/redlib.webp",
+ "config_path": "/opt/redlib/redlib.conf",
+ "description": "An alternative private front-end to Reddit. Redlib hopes to provide an easier way to browse Reddit, without the ads, trackers, and bloat.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/redlib.sh",
+ "resources": {
+ "cpu": 1,
+ "ram": 512,
+ "hdd": 1,
+ "os": "alpine",
+ "version": "3.22"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/install/redlib-install.sh b/install/redlib-install.sh
new file mode 100644
index 00000000..f6208d91
--- /dev/null
+++ b/install/redlib-install.sh
@@ -0,0 +1,105 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: andrej-kocijan (Andrej Kocijan)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/redlib-org/redlib
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Downloading Redlib"
+RELEASE=$(curl -s https://api.github.com/repos/redlib-org/redlib/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
+$STD curl -fsSL -o /tmp/redlib-x86_64-unknown-linux-musl.tar.gz \
+"https://github.com/redlib-org/redlib/releases/latest/download/redlib-x86_64-unknown-linux-musl.tar.gz"
+msg_ok "Downloaded Redlib"
+
+msg_info "Installing Redlib"
+mkdir /opt/redlib
+$STD tar -xzf /tmp/redlib-x86_64-unknown-linux-musl.tar.gz -C /opt/redlib
+$STD rm /tmp/redlib-x86_64-unknown-linux-musl.tar.gz
+echo "${RELEASE}" >/opt/Redlib_version.txt
+cat </opt/redlib/redlib.conf
+############################################
+# Redlib Instance Configuration File
+# Uncomment and edit values as needed
+############################################
+
+## Instance settings
+ADDRESS=0.0.0.0
+PORT=5252 # Integer (0-65535) - Internal port
+#REDLIB_SFW_ONLY=off # ["on", "off"] - Filter all NSFW content
+#REDLIB_BANNER= # String - Displayed on instance info page
+#REDLIB_ROBOTS_DISABLE_INDEXING=off # ["on", "off"] - Disable search engine indexing
+#REDLIB_PUSHSHIFT_FRONTEND=undelete.pullpush.io # Pushshift frontend for removed links
+#REDLIB_ENABLE_RSS=off # ["on", "off"] - Enable RSS feed generation
+#REDLIB_FULL_URL= # String - Needed for proper RSS URLs
+
+## Default user settings
+#REDLIB_DEFAULT_THEME=system # Theme (system, light, dark, black, dracula, nord, laserwave, violet, gold, rosebox, gruvboxdark, gruvboxlight, tokyoNight, icebergDark, doomone, libredditBlack, libredditDark, libredditLight)
+#REDLIB_DEFAULT_FRONT_PAGE=default # ["default", "popular", "all"]
+#REDLIB_DEFAULT_LAYOUT=card # ["card", "clean", "compact"]
+#REDLIB_DEFAULT_WIDE=off # ["on", "off"]
+#REDLIB_DEFAULT_POST_SORT=hot # ["hot", "new", "top", "rising", "controversial"]
+#REDLIB_DEFAULT_COMMENT_SORT=confidence # ["confidence", "top", "new", "controversial", "old"]
+#REDLIB_DEFAULT_BLUR_SPOILER=off # ["on", "off"]
+#REDLIB_DEFAULT_SHOW_NSFW=off # ["on", "off"]
+#REDLIB_DEFAULT_BLUR_NSFW=off # ["on", "off"]
+#REDLIB_DEFAULT_USE_HLS=off # ["on", "off"]
+#REDLIB_DEFAULT_HIDE_HLS_NOTIFICATION=off # ["on", "off"]
+#REDLIB_DEFAULT_AUTOPLAY_VIDEOS=off # ["on", "off"]
+#REDLIB_DEFAULT_SUBSCRIPTIONS= # Example: sub1+sub2+sub3
+#REDLIB_DEFAULT_HIDE_AWARDS=off # ["on", "off"]
+#REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off # ["on", "off"]
+#REDLIB_DEFAULT_HIDE_SCORE=off # ["on", "off"]
+#REDLIB_DEFAULT_HIDE_SIDEBAR_AND_SUMMARY=off # ["on", "off"]
+#REDLIB_DEFAULT_FIXED_NAVBAR=on # ["on", "off"]
+#REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS=off # ["on", "off"]
+EOF
+msg_ok "Installed Redlib"
+
+msg_info "Creating Redlib Service"
+cat </etc/init.d/redlib
+#!/sbin/openrc-run
+
+name="Redlib"
+description="Redlib Service"
+command="/opt/redlib/redlib"
+pidfile="/run/redlib.pid"
+supervisor="supervise-daemon"
+command_background="yes"
+
+depend() {
+ need net
+}
+
+start_pre() {
+
+ set -a
+ . /opt/redlib/redlib.conf
+ set +a
+
+ : ${ADDRESS:=0.0.0.0}
+ : ${PORT:=5252}
+
+ command_args="-a ${ADDRESS} -p ${PORT}"
+}
+EOF
+$STD chmod +x /etc/init.d/redlib
+msg_ok "Created Redlib Service"
+
+msg_info "Enabling Redlib Service"
+$STD rc-update add redlib default
+msg_ok "Enabled Redlib Service"
+
+msg_info "Starting Redlib Service"
+$STD rc-service redlib start
+msg_ok "Started Redlib Service"
+
+motd_ssh
+customize
From 63bd61d695ef31554d4d3840d78485ee88003ab8 Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 12:13:56 +0200
Subject: [PATCH 171/312] Fixed stopping service message
---
ct/redlib.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/redlib.sh b/ct/redlib.sh
index 23d702bc..97bfb945 100644
--- a/ct/redlib.sh
+++ b/ct/redlib.sh
@@ -36,7 +36,7 @@ function update_script() {
msg_info "Stopping ${APP} Service"
$STD rc-service redlib stop
- msg_info "Stopped ${APP} Service"
+ msg_ok "Stopped ${APP} Service"
msg_info "Updating ${APP}"
$STD curl -fsSL -o /tmp/redlib-x86_64-unknown-linux-musl.tar.gz \
From 006bbd124cbe8ac6efbcc556c8ae2365ce770575 Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 12:59:31 +0200
Subject: [PATCH 172/312] Add documentation to frontend json
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
---
frontend/public/json/redlib.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/public/json/redlib.json b/frontend/public/json/redlib.json
index 40a0b7e8..0b2c7cce 100644
--- a/frontend/public/json/redlib.json
+++ b/frontend/public/json/redlib.json
@@ -9,7 +9,7 @@
"updateable": true,
"privileged": false,
"interface_port": 5252,
- "documentation": null,
+ "documentation": "https://github.com/redlib-org/redlib/blob/main/README.md",
"website": "https://github.com/redlib-org/redlib",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/redlib.webp",
"config_path": "/opt/redlib/redlib.conf",
From 33df8b7b3a1f8ed44c743dd6d2f51ece867c15fe Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 13:08:15 +0200
Subject: [PATCH 173/312] Minor fixes
---
ct/redlib.sh | 4 ++--
install/redlib-install.sh | 7 ++-----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/ct/redlib.sh b/ct/redlib.sh
index 97bfb945..264e7962 100644
--- a/ct/redlib.sh
+++ b/ct/redlib.sh
@@ -29,7 +29,7 @@ function update_script() {
fi
RELEASE=$(curl -s https://api.github.com/repos/redlib-org/redlib/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
- if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
+ if [[ "${RELEASE}" != "$(cat ~/.redlib 2>/dev/null)" ]] || [[ ! -f ~/.redlib ]]; then
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
@@ -49,7 +49,7 @@ function update_script() {
$STD rc-service redlib start
msg_ok "Started ${APP} Service"
- echo "${RELEASE}" >/opt/${APP}_version.txt
+ echo "${RELEASE}" >~/.redlib
msg_ok "Update Successful"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
diff --git a/install/redlib-install.sh b/install/redlib-install.sh
index f6208d91..97c11519 100644
--- a/install/redlib-install.sh
+++ b/install/redlib-install.sh
@@ -23,7 +23,7 @@ msg_info "Installing Redlib"
mkdir /opt/redlib
$STD tar -xzf /tmp/redlib-x86_64-unknown-linux-musl.tar.gz -C /opt/redlib
$STD rm /tmp/redlib-x86_64-unknown-linux-musl.tar.gz
-echo "${RELEASE}" >/opt/Redlib_version.txt
+echo "${RELEASE}" >~/.redlib
cat </opt/redlib/redlib.conf
############################################
# Redlib Instance Configuration File
@@ -91,11 +91,8 @@ start_pre() {
}
EOF
$STD chmod +x /etc/init.d/redlib
-msg_ok "Created Redlib Service"
-
-msg_info "Enabling Redlib Service"
$STD rc-update add redlib default
-msg_ok "Enabled Redlib Service"
+msg_ok "Created Redlib Service"
msg_info "Starting Redlib Service"
$STD rc-service redlib start
From e3f81af80d41e912822f0022d33c4dd1890f7892 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 13:36:08 +0200
Subject: [PATCH 174/312] Update alpine-install.sh
---
install/alpine-install.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/install/alpine-install.sh b/install/alpine-install.sh
index 2916be18..4922f164 100644
--- a/install/alpine-install.sh
+++ b/install/alpine-install.sh
@@ -21,5 +21,7 @@ $STD apk add nano
$STD apk add mc
msg_ok "Installed Dependencies"
+fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
+
motd_ssh
customize
From 9b2f62a3a39aa70771492aaa22a87fa174cd309f Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 13:38:12 +0200
Subject: [PATCH 175/312] Update alpine-install.func
---
misc/alpine-install.func | 1 +
1 file changed, 1 insertion(+)
diff --git a/misc/alpine-install.func b/misc/alpine-install.func
index 85c3c2a1..450e9209 100644
--- a/misc/alpine-install.func
+++ b/misc/alpine-install.func
@@ -83,6 +83,7 @@ network_check() {
update_os() {
msg_info "Updating Container OS"
$STD apk update && $STD apk upgrade
+ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
msg_ok "Updated Container OS"
}
From 302978c20a8ff02f0b89e46c232fd5684e11c366 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 13:52:31 +0200
Subject: [PATCH 176/312] uv shell
---
misc/tools.func | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/misc/tools.func b/misc/tools.func
index 6bb819b9..166d4e6f 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -1339,7 +1339,11 @@ function setup_uv() {
}
rm -rf "$TMP_DIR"
- ensure_usr_local_bin_persist
+ #ensure_usr_local_bin_persist
+ $STD uv python update-shell || {
+ msg_error "Failed to update uv shell integration"
+ return 1
+ }
msg_ok "Setup uv $LATEST_VERSION"
# Optional: install specific Python version
From 807edc284525e5ba41ff32bea92c989f62241b3c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 13:54:04 +0200
Subject: [PATCH 177/312] verbose psql
---
misc/tools.func | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index 166d4e6f..43711d9e 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -167,7 +167,6 @@ function setup_postgresql() {
NEED_PG_INSTALL=true
fi
else
- msg_info "Setup PostgreSQL $PG_VERSION"
NEED_PG_INSTALL=true
fi
@@ -205,12 +204,12 @@ function setup_postgresql() {
$STD msg_ok "PostgreSQL $PG_VERSION started"
if [[ -n "$CURRENT_PG_VERSION" ]]; then
- msg_info "Restoring dumped data"
+ $STD msg_info "Restoring dumped data"
su - postgres -c "psql < /var/lib/postgresql/backup_$(date +%F)_v${CURRENT_PG_VERSION}.sql"
- msg_ok "Data restored"
+ $STD msg_ok "Data restored"
fi
- msg_ok "PostgreSQL $PG_VERSION installed"
+ $STD msg_ok "PostgreSQL $PG_VERSION installed"
fi
# Install optional PostgreSQL modules
@@ -218,13 +217,13 @@ function setup_postgresql() {
IFS=',' read -ra MODULES <<<"$PG_MODULES"
for module in "${MODULES[@]}"; do
local pkg="postgresql-${PG_VERSION}-${module}"
- msg_info "Setup PostgreSQL module/s: $pkg"
+ $STD msg_info "Setup PostgreSQL module/s: $pkg"
$STD apt-get install -y "$pkg" || {
msg_error "Failed to install $pkg"
continue
}
done
- msg_ok "Setup PostgreSQL modules"
+ $STD msg_ok "Setup PostgreSQL modules"
fi
}
@@ -1412,7 +1411,7 @@ function setup_gs() {
return
fi
- msg_info "Setup Ghostscript $LATEST_VERSION_DOTTED"
+ msg_info "Setup Ghostscript $LATEST_VERSION_DOTTED (Patience)"
curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${LATEST_VERSION}/ghostscript-${LATEST_VERSION_DOTTED}.tar.gz" -o "$TMP_DIR/ghostscript.tar.gz"
if ! tar -xzf "$TMP_DIR/ghostscript.tar.gz" -C "$TMP_DIR"; then
From 882562d9e07ca77148e82b055b07931d5461518c Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 22 Aug 2025 13:55:06 +0200
Subject: [PATCH 178/312] Update tools.func
---
misc/tools.func | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index 43711d9e..844fabd1 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -187,21 +187,16 @@ function setup_postgresql() {
echo "deb https://apt.postgresql.org/pub/repos/apt ${DISTRO}-pgdg main" \
>/etc/apt/sources.list.d/pgdg.list
- $STD msg_ok "Repository added"
-
$STD apt-get update
+ $STD msg_ok "Repository added"
msg_info "Setup PostgreSQL $PG_VERSION"
$STD apt-get install -y "postgresql-${PG_VERSION}" "postgresql-client-${PG_VERSION}"
- msg_ok "Setup PostgreSQL $PG_VERSION"
if [[ -n "$CURRENT_PG_VERSION" ]]; then
$STD apt-get purge -y "postgresql-${CURRENT_PG_VERSION}" "postgresql-client-${CURRENT_PG_VERSION}" || true
fi
-
- $STD msg_info "Starting PostgreSQL $PG_VERSION"
systemctl enable -q --now postgresql
- $STD msg_ok "PostgreSQL $PG_VERSION started"
if [[ -n "$CURRENT_PG_VERSION" ]]; then
$STD msg_info "Restoring dumped data"
From e988634b34ddde5b0d4c7837f8b7d0cacf3d3343 Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 16:35:58 +0200
Subject: [PATCH 179/312] Source build.func from correct repo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
---
ct/redlib.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/redlib.sh b/ct/redlib.sh
index 264e7962..e62e91e1 100644
--- a/ct/redlib.sh
+++ b/ct/redlib.sh
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: andrej-kocijan (Andrej Kocijan)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
From b39235d15ec26fe8f410c9445ab8277469ae7944 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Slavi=C5=A1a=20Are=C5=BEina?=
<58952836+tremor021@users.noreply.github.com>
Date: Fri, 22 Aug 2025 17:46:21 +0200
Subject: [PATCH 180/312] Update redlib-install.sh
---
install/redlib-install.sh | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/install/redlib-install.sh b/install/redlib-install.sh
index 97c11519..5472985d 100644
--- a/install/redlib-install.sh
+++ b/install/redlib-install.sh
@@ -5,7 +5,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/redlib-org/redlib
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"e
color
verb_ip6
catch_errors
@@ -13,17 +13,9 @@ setting_up_container
network_check
update_os
-msg_info "Downloading Redlib"
-RELEASE=$(curl -s https://api.github.com/repos/redlib-org/redlib/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
-$STD curl -fsSL -o /tmp/redlib-x86_64-unknown-linux-musl.tar.gz \
-"https://github.com/redlib-org/redlib/releases/latest/download/redlib-x86_64-unknown-linux-musl.tar.gz"
-msg_ok "Downloaded Redlib"
+fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
-msg_info "Installing Redlib"
-mkdir /opt/redlib
-$STD tar -xzf /tmp/redlib-x86_64-unknown-linux-musl.tar.gz -C /opt/redlib
-$STD rm /tmp/redlib-x86_64-unknown-linux-musl.tar.gz
-echo "${RELEASE}" >~/.redlib
+msg_info "Configuring Redlib"
cat </opt/redlib/redlib.conf
############################################
# Redlib Instance Configuration File
@@ -61,7 +53,7 @@ PORT=5252 # Integer (0-65535) - Internal port
#REDLIB_DEFAULT_FIXED_NAVBAR=on # ["on", "off"]
#REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS=off # ["on", "off"]
EOF
-msg_ok "Installed Redlib"
+msg_ok "Configured Redlib"
msg_info "Creating Redlib Service"
cat </etc/init.d/redlib
From 982b2221284fdd0636db2dc38688649a0f6ba23a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Slavi=C5=A1a=20Are=C5=BEina?=
<58952836+tremor021@users.noreply.github.com>
Date: Fri, 22 Aug 2025 17:50:51 +0200
Subject: [PATCH 181/312] Update redlib.sh
---
ct/redlib.sh | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/ct/redlib.sh b/ct/redlib.sh
index e62e91e1..2a68a595 100644
--- a/ct/redlib.sh
+++ b/ct/redlib.sh
@@ -38,18 +38,12 @@ function update_script() {
$STD rc-service redlib stop
msg_ok "Stopped ${APP} Service"
- msg_info "Updating ${APP}"
- $STD curl -fsSL -o /tmp/redlib-x86_64-unknown-linux-musl.tar.gz \
- "https://github.com/redlib-org/redlib/releases/latest/download/redlib-x86_64-unknown-linux-musl.tar.gz"
- $STD tar -xzf /tmp/redlib-x86_64-unknown-linux-musl.tar.gz -C /opt/redlib
- $STD rm /tmp/redlib-x86_64-unknown-linux-musl.tar.gz
- msg_ok "Updated ${APP}"
+ fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
msg_info "Starting ${APP} Service"
$STD rc-service redlib start
msg_ok "Started ${APP} Service"
- echo "${RELEASE}" >~/.redlib
msg_ok "Update Successful"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
From 414e22416e0442e7eb91c603511563f91536251d Mon Sep 17 00:00:00 2001
From: Andrej Kocijan
Date: Fri, 22 Aug 2025 17:54:48 +0200
Subject: [PATCH 182/312] Removed version check as fetch_and_deploy_gh_release
already does that
---
ct/redlib.sh | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/ct/redlib.sh b/ct/redlib.sh
index 2a68a595..7cde4fe8 100644
--- a/ct/redlib.sh
+++ b/ct/redlib.sh
@@ -28,26 +28,21 @@ function update_script() {
exit
fi
- RELEASE=$(curl -s https://api.github.com/repos/redlib-org/redlib/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
- if [[ "${RELEASE}" != "$(cat ~/.redlib 2>/dev/null)" ]] || [[ ! -f ~/.redlib ]]; then
- msg_info "Updating Alpine Packages"
- $STD apk -U upgrade
- msg_ok "Updated Alpine Packages"
+ msg_info "Updating Alpine Packages"
+ $STD apk -U upgrade
+ msg_ok "Updated Alpine Packages"
- msg_info "Stopping ${APP} Service"
- $STD rc-service redlib stop
- msg_ok "Stopped ${APP} Service"
+ msg_info "Stopping ${APP} Service"
+ $STD rc-service redlib stop
+ msg_ok "Stopped ${APP} Service"
- fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
+ fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
- msg_info "Starting ${APP} Service"
- $STD rc-service redlib start
- msg_ok "Started ${APP} Service"
+ msg_info "Starting ${APP} Service"
+ $STD rc-service redlib start
+ msg_ok "Started ${APP} Service"
- msg_ok "Update Successful"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
- fi
+ msg_ok "Update Successful"
exit
}
From d114a4ad697ecb9872b63e45dca78a2c302fe8f8 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Fri, 22 Aug 2025 16:21:09 +0000
Subject: [PATCH 183/312] Update .app files
---
ct/headers/redlib | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 ct/headers/redlib
diff --git a/ct/headers/redlib b/ct/headers/redlib
new file mode 100644
index 00000000..b43c70b7
--- /dev/null
+++ b/ct/headers/redlib
@@ -0,0 +1,6 @@
+ ____ _____ __
+ / __ \___ ____/ / (_) /_
+ / /_/ / _ \/ __ / / / __ \
+ / _, _/ __/ /_/ / / / /_/ /
+/_/ |_|\___/\__,_/_/_/_.___/
+
From a06839993c5313f700ac5d7838580fbf037d5859 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 22 Aug 2025 18:25:43 +0200
Subject: [PATCH 184/312] Update redlib
---
ct/{redlib.sh => alpine-redlib.sh} | 2 +-
install/{redlib-install.sh => alpine-redlib-install.sh} | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
rename ct/{redlib.sh => alpine-redlib.sh} (98%)
rename install/{redlib-install.sh => alpine-redlib-install.sh} (98%)
diff --git a/ct/redlib.sh b/ct/alpine-redlib.sh
similarity index 98%
rename from ct/redlib.sh
rename to ct/alpine-redlib.sh
index 7cde4fe8..88f9fd3d 100644
--- a/ct/redlib.sh
+++ b/ct/alpine-redlib.sh
@@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/redlib-org/redlib
-APP="Redlib"
+APP="Alpine-Redlib"
var_tags="${var_tags:-alpine;frontend}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
diff --git a/install/redlib-install.sh b/install/alpine-redlib-install.sh
similarity index 98%
rename from install/redlib-install.sh
rename to install/alpine-redlib-install.sh
index 5472985d..de64b12c 100644
--- a/install/redlib-install.sh
+++ b/install/alpine-redlib-install.sh
@@ -92,3 +92,7 @@ msg_ok "Started Redlib Service"
motd_ssh
customize
+
+msg_info "Cleaning up"
+$STD apk cache clean
+msg_ok "Cleaned"
From 685d75429cf8b75cf32900e0804c5e9491301276 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 22 Aug 2025 18:41:01 +0200
Subject: [PATCH 185/312] fix
---
install/alpine-redlib-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/alpine-redlib-install.sh b/install/alpine-redlib-install.sh
index de64b12c..0f717721 100644
--- a/install/alpine-redlib-install.sh
+++ b/install/alpine-redlib-install.sh
@@ -5,7 +5,7 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/redlib-org/redlib
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"e
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
From 0d1638e3914ca2c7afa44842ced926435bbbd6bf Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 22 Aug 2025 18:45:42 +0200
Subject: [PATCH 186/312] Fix redlib json
---
frontend/public/json/redlib.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/public/json/redlib.json b/frontend/public/json/redlib.json
index 0b2c7cce..215b190f 100644
--- a/frontend/public/json/redlib.json
+++ b/frontend/public/json/redlib.json
@@ -17,7 +17,7 @@
"install_methods": [
{
"type": "default",
- "script": "ct/redlib.sh",
+ "script": "ct/alpine-redlib.sh",
"resources": {
"cpu": 1,
"ram": 512,
From 16f5e1bd3799bf04ebcfcd41f3f892d2c8d4400e Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Sun, 24 Aug 2025 06:43:00 +0000
Subject: [PATCH 187/312] Update .app files
---
ct/headers/alpine-redlib | 6 ++++++
ct/headers/redlib | 6 ------
ct/headers/resiliosync | 6 ++++++
3 files changed, 12 insertions(+), 6 deletions(-)
create mode 100644 ct/headers/alpine-redlib
delete mode 100644 ct/headers/redlib
create mode 100644 ct/headers/resiliosync
diff --git a/ct/headers/alpine-redlib b/ct/headers/alpine-redlib
new file mode 100644
index 00000000..7d8f1130
--- /dev/null
+++ b/ct/headers/alpine-redlib
@@ -0,0 +1,6 @@
+ ___ __ _ ____ _____ __
+ / | / /___ (_)___ ___ / __ \___ ____/ / (_) /_
+ / /| | / / __ \/ / __ \/ _ \______/ /_/ / _ \/ __ / / / __ \
+ / ___ |/ / /_/ / / / / / __/_____/ _, _/ __/ /_/ / / / /_/ /
+/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_|\___/\__,_/_/_/_.___/
+ /_/
diff --git a/ct/headers/redlib b/ct/headers/redlib
deleted file mode 100644
index b43c70b7..00000000
--- a/ct/headers/redlib
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ _____ __
- / __ \___ ____/ / (_) /_
- / /_/ / _ \/ __ / / / __ \
- / _, _/ __/ /_/ / / / /_/ /
-/_/ |_|\___/\__,_/_/_/_.___/
-
diff --git a/ct/headers/resiliosync b/ct/headers/resiliosync
new file mode 100644
index 00000000..500ed27e
--- /dev/null
+++ b/ct/headers/resiliosync
@@ -0,0 +1,6 @@
+ ____ _ ___ _____
+ / __ \___ _____(_) (_)___ / ___/__ ______ _____
+ / /_/ / _ \/ ___/ / / / __ \ \__ \/ / / / __ \/ ___/
+ / _, _/ __(__ ) / / / /_/ / ___/ / /_/ / / / / /__
+/_/ |_|\___/____/_/_/_/\____/ /____/\__, /_/ /_/\___/
+ /____/
From 3c307e1e9df40444e45f321649e956c0d5d598ae Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 09:48:55 -0400
Subject: [PATCH 188/312] MediaManager: fix start script path, move email
prompt to start
---
install/mediamanager-install.sh | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index ad2cb345..f58d12ff 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -13,6 +13,11 @@ setting_up_container
network_check
update_os
+read -r -p "Enter the email address of your first admin user: " admin_email
+if [[ "$admin_email" ]]; then
+ EMAIL="$admin_email"
+fi
+
msg_info "Installing dependencies"
$STD apt-get install -y yq
msg_ok "Installed dependencies"
@@ -60,11 +65,6 @@ $STD /usr/local/bin/uv venv "$VIRTUAL_ENV"
$STD /usr/local/bin/uv sync --locked --active
msg_ok "Configured MediaManager"
-read -r -p "Enter the email address of your first admin user: " admin_email
-if [[ "$admin_email" ]]; then
- EMAIL="$admin_email"
-fi
-
msg_info "Creating config and start script"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
SECRET="$(openssl rand -hex 32)"
@@ -81,7 +81,7 @@ sed -e "s/localhost:8/$LOCAL_IP:8/g" \
mkdir -p "$MEDIA_DIR"/{images,tv,movies,torrents}
-cat </opt/"$MM_DIR"/start.sh
+cat <"$MM_DIR"/start.sh
#!/usr/bin/env bash
export CONFIG_DIR="$CONFIG_DIR"
From 2176ffc1c6aec899eca6c8612c78b20058ef11a3 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:00:52 -0400
Subject: [PATCH 189/312] MediaManager: fix more path errors
---
install/mediamanager-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index f58d12ff..f37a4a11 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -88,12 +88,12 @@ export CONFIG_DIR="$CONFIG_DIR"
export FRONTEND_FILES_DIR="$FRONTEND_FILES_DIR"
export BASE_PATH=""
-cd /opt/"$MM_DIR"
+cd "$MM_DIR"
source ./venv/bin/activate
/usr/local/bin/uv run alembic upgrade head
/usr/local/bin/uv run fastapi run ./media_manager/main.py --port 8000
EOF
-chmod +x /opt/"$MM_DIR"/start.sh
+chmod +x "$MM_DIR"/start.sh
msg_ok "Created config and start script"
msg_info "Creating service"
From e779b9fcc2e4c97d93b8da7c6280844e5499bbfe Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:21:14 -0400
Subject: [PATCH 190/312] MediaManager: fix WorkingDir and add forward slash to
sed command
---
install/mediamanager-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index f37a4a11..cb89b396 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -69,7 +69,7 @@ msg_info "Creating config and start script"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
SECRET="$(openssl rand -hex 32)"
sed -e "s/localhost:8/$LOCAL_IP:8/g" \
- -e "s|/data/|$MEDIA_DIR|g" \
+ -e "s|/data/|$MEDIA_DIR/|g" \
-e 's/"db"/"localhost"/' \
-e "s/user = \"MediaManager\"/user = \"$DB_USER\"/" \
-e "s/password = \"MediaManager\"/password = \"$DB_PASS\"/" \
@@ -104,7 +104,7 @@ After=network.target
[Service]
Type=simple
-WorkingDirectory=/opt/"$MM_DIR"
+WorkingDirectory="$MM_DIR"
ExecStart=/usr/bin/bash start.sh
[Install]
From 817d622c2c30e542eb4fa5fce8dcf9380c80d693 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:24:56 -0400
Subject: [PATCH 191/312] MediaManager: increase resources, add note about
media dir
---
ct/mediamanager.sh | 2 +-
frontend/public/json/mediamanager.json | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/ct/mediamanager.sh b/ct/mediamanager.sh
index cc67d8af..f23230b4 100644
--- a/ct/mediamanager.sh
+++ b/ct/mediamanager.sh
@@ -8,7 +8,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
APP="MediaManager"
var_tags="${var_tags:-arr}"
var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
+var_ram="${var_ram:-3072}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
diff --git a/frontend/public/json/mediamanager.json b/frontend/public/json/mediamanager.json
index 5df6c4b7..c8590b01 100644
--- a/frontend/public/json/mediamanager.json
+++ b/frontend/public/json/mediamanager.json
@@ -21,7 +21,7 @@
"script": "ct/mediamanager.sh",
"resources": {
"cpu": 2,
- "ram": 2048,
+ "ram": 3072,
"hdd": 4,
"os": "Debian",
"version": "12"
@@ -36,6 +36,10 @@
{
"text": "During the installation, provide the email address of the first admin user",
"type": "info"
+ },
+ {
+ "text": "You're probably going to want to use a bind mount for the media directories",
+ "type": "info"
}
]
}
From 6465201cd189516145862e17ac7b7ac62f91a713 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:26:34 -0400
Subject: [PATCH 192/312] MediaManager: move gh deploy outside of msg block
---
ct/mediamanager.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/mediamanager.sh b/ct/mediamanager.sh
index f23230b4..1909772e 100644
--- a/ct/mediamanager.sh
+++ b/ct/mediamanager.sh
@@ -34,8 +34,8 @@ function update_script() {
systemctl stop mediamanager
msg_ok "Stopped Service"
- msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "MediaManager" "maxdorninger/MediaManager" "tarball" "latest" "/opt/mediamanager"
+ msg_info "Updating ${APP}"
MM_DIR="/opt/mm"
export CONFIG_DIR="${MM_DIR}/config"
export FRONTEND_FILES_DIR="${MM_DIR}/web/build"
From 5f96851a5d166bafabeaf511c78e67a58d945165 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:33:39 -0400
Subject: [PATCH 193/312] MediaManager: remove quotes from var in service file
---
install/mediamanager-install.sh | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index cb89b396..860057e2 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -11,13 +11,14 @@ verb_ip6
catch_errors
setting_up_container
network_check
-update_os
read -r -p "Enter the email address of your first admin user: " admin_email
if [[ "$admin_email" ]]; then
EMAIL="$admin_email"
fi
+update_os
+
msg_info "Installing dependencies"
$STD apt-get install -y yq
msg_ok "Installed dependencies"
@@ -104,7 +105,7 @@ After=network.target
[Service]
Type=simple
-WorkingDirectory="$MM_DIR"
+WorkingDirectory=${MM_DIR}
ExecStart=/usr/bin/bash start.sh
[Install]
From 624c80e0fd2ce3214731faa43865be03ebe4ad6d Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:52:27 -0400
Subject: [PATCH 194/312] MediaManager: make email prompt stand out a bit more
---
install/mediamanager-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index 860057e2..3864c6d2 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -12,7 +12,7 @@ catch_errors
setting_up_container
network_check
-read -r -p "Enter the email address of your first admin user: " admin_email
+read -r -p "${TAB3}${YW}Enter the email address of your first admin user: ${CL}" admin_email
if [[ "$admin_email" ]]; then
EMAIL="$admin_email"
fi
From 682a1f800bf65edc6332e196dae4d8f96d2c6f57 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 10:55:56 -0400
Subject: [PATCH 195/312] remove colour vars
---
install/mediamanager-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index 3864c6d2..ee68d885 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -12,7 +12,7 @@ catch_errors
setting_up_container
network_check
-read -r -p "${TAB3}${YW}Enter the email address of your first admin user: ${CL}" admin_email
+read -r -p "${TAB3}Enter the email address of your first admin user: " admin_email
if [[ "$admin_email" ]]; then
EMAIL="$admin_email"
fi
From b66e55fba23e9b2e869567d7d04b59bce5dada08 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Sun, 24 Aug 2025 19:51:23 +0200
Subject: [PATCH 196/312] Update environment configuration for Tracktor
---
install/tracktor-install.sh | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/install/tracktor-install.sh b/install/tracktor-install.sh
index d2c5fde5..3beefa4b 100644
--- a/install/tracktor-install.sh
+++ b/install/tracktor-install.sh
@@ -23,10 +23,10 @@ $STD npm install
$STD npm run build
mkdir /opt/tracktor-data
HOST_IP=$(hostname -I | awk '{print $1}')
-cat </opt/tracktor/app/server/.env
+cat </opt/tracktor/app/backend/.env
NODE_ENV=production
PUBLIC_DEMO_MODE=false
-DB_PATH=/opt/tracktor-data/vehicles.db
+DB_PATH=/opt/tracktor-data/tracktor.db
PUBLIC_API_BASE_URL=http://$HOST_IP:3000
PORT=3000
EOF
@@ -41,7 +41,7 @@ After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/tracktor
-EnvironmentFile=/opt/tracktor/app/server/.env
+EnvironmentFile=/opt/tracktor/app/backend/.env
ExecStart=/usr/bin/npm start
[Install]
From e3e6d86b6ed72a914d121b326b5eb1bf04d499dd Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Sun, 24 Aug 2025 19:51:58 +0200
Subject: [PATCH 197/312] Update backup and restore paths in tracktor.sh
---
ct/tracktor.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ct/tracktor.sh b/ct/tracktor.sh
index 864210e3..1386344d 100644
--- a/ct/tracktor.sh
+++ b/ct/tracktor.sh
@@ -35,7 +35,7 @@ function update_script() {
msg_ok "Stopped Service"
msg_info "Creating Backup"
- cp /opt/tracktor/app/server/.env /opt/tracktor.env
+ cp /opt/tracktor/app/backend/.env /opt/tracktor.env
msg_ok "Created Backup"
msg_info "Updating ${APP}"
@@ -48,7 +48,7 @@ function update_script() {
msg_ok "Updated $APP"
msg_info "Restoring Backup"
- cp /opt/tracktor.env /opt/tracktor/app/server/.env
+ cp /opt/tracktor.env /opt/tracktor/app/backend/.env
msg_ok "Restored Backup"
msg_info "Starting Service"
From 74ec341965ae4da45eb79822e5e1027d445c05ec Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 19:42:14 -0400
Subject: [PATCH 198/312] MediaManager: make sure to update UV
---
ct/mediamanager.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/ct/mediamanager.sh b/ct/mediamanager.sh
index 1909772e..d633f657 100644
--- a/ct/mediamanager.sh
+++ b/ct/mediamanager.sh
@@ -28,6 +28,8 @@ function update_script() {
exit
fi
+ setup_uv
+
RELEASE=$(curl -fsSL https://api.github.com/repos/maxdorninger/MediaManager/releases/latest | jq '.tag_name' | sed 's/^v//')
if [[ "${RELEASE}" != "$(cat ~/.mediamanager 2>/dev/null)" ]] || [[ ! -f ~/.mediamanager ]]; then
msg_info "Stopping Service"
From a9a963f9e1eedd91d3123d2e828a0391f18758b0 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 20:19:09 -0400
Subject: [PATCH 199/312] Autocaliweb
---
ct/autocaliweb.sh | 76 +++++++
frontend/public/json/autocaliweb.json | 35 +++
install/autocaliweb-install.sh | 310 ++++++++++++++++++++++++++
3 files changed, 421 insertions(+)
create mode 100644 ct/autocaliweb.sh
create mode 100644 frontend/public/json/autocaliweb.json
create mode 100644 install/autocaliweb-install.sh
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
new file mode 100644
index 00000000..cc728dd6
--- /dev/null
+++ b/ct/autocaliweb.sh
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: vhsdream
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/gelbphoenix/autocaliweb
+
+APP="Autocaliweb"
+var_tags="${var_tags:-ebooks}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-6}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+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/autocaliweb ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ setup_uv
+
+ RELEASE=$(curl -fsSL https://api.github.com/repos/gelbphoenix/autocaliweb/releases/latest | jq '.tag_name' | sed 's/^v//')
+ if [[ "${RELEASE}" != "$(cat ~/.autocaliweb 2>/dev/null)" ]] || [[ ! -f ~/.autocaliweb ]]; then
+ msg_info "Stopping Services"
+ systemctl stop autocaliweb metadata-change-detector acw-ingestor acw-auto-zipper
+ msg_ok "Stopped Services"
+
+ INSTALL_DIR="/opt/autocaliweb"
+ VIRTUAL_ENV="${INSTALL_DIR}/venv"
+ $STD tar -cf ~/autocaliweb_bkp.tar "$INSTALL_DIR"/{metadata_change_logs,dirs.json,scripts/ingest_watcher.sh,scripts/auto_zipper_wrapper.sh,scripts/metadata_change_detector_wrapper.sh}
+ fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
+ msg_info "Updating ${APP}"
+ cd "$INSTALL_DIR"
+ $STD uv sync --all-extras --active
+ cd "$INSTALL_DIR"/koreader/plugins
+ PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
+ echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
+ echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
+ echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
+ zip -r koplugin.zip acwsync.koplugin/
+ cp -r koplugin.zip "$INSTALL_DIR"/cps/static
+ mkdir -p "$INSTALL_DIR"/metadata_temp
+ $STD tar -xf ~/autocaliweb_bkp.tar --directory /
+ chown -R acw:acw "$INSTALL_DIR"
+ msg_ok "Updated $APP"
+
+ msg_info "Starting Services"
+ systemctl start autocaliweb metadata-change-detector acw-ingestor acw-auto-zipper
+ msg_ok "Started Services"
+
+ msg_ok "Updated Successfully"
+ else
+ msg_ok "Already up to date"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8083${CL}"
diff --git a/frontend/public/json/autocaliweb.json b/frontend/public/json/autocaliweb.json
new file mode 100644
index 00000000..792645a2
--- /dev/null
+++ b/frontend/public/json/autocaliweb.json
@@ -0,0 +1,35 @@
+{
+ "name": "Autocaliweb",
+ "slug": "autocaliweb",
+ "categories": [
+ 13
+ ],
+ "date_created": "2025-08-30",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8083,
+ "documentation": "https://github.com/gelbphoenix/autocaliweb/wiki",
+ "config_path": "/etc/autocaliweb",
+ "website": "https://github.com/gelbphoenix/autocaliweb",
+ "logo": "https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/master/cps/static/icon-dark.svg",
+ "description": "A modern web management system for eBooks, eComics and PDFs",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/autocaliweb.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 6,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": "admin",
+ "password": "admin123"
+ },
+ "notes": []
+}
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
new file mode 100644
index 00000000..e9ed0dd4
--- /dev/null
+++ b/install/autocaliweb-install.sh
@@ -0,0 +1,310 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2025 Community Scripts ORG
+# Author: vhsdream
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/gelbphoenix/autocaliweb
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing dependencies"
+$STD apt-get install -y --no-install-recommends \
+ git \
+ sqlite3 \
+ build-essential \
+ libldap2-dev \
+ libssl-dev \
+ libsasl-dev \
+ imagemagick \
+ ghostscript \
+ libmagic1 \
+ libxi6 \
+ libxslt1.1 \
+ libxtst6 \
+ libxrandr2 \
+ libxkbfile1 \
+ libxcomposite1 \
+ libopengl0 \
+ libnss3 \
+ libxkbcommon0 \
+ libegl1 \
+ libxdamage1 \
+ libgl1 \
+ libglx-mesa0 \
+ xz-utils \
+ xdg-utils \
+ inotify-tools \
+ binutils \
+ unrar-free \
+ zip
+msg_ok "Installed dependencies"
+
+fetch_and_deploy_gh_release "kepubify" "pgaskin/kepubify" "singlefile" "latest" "/usr/bin" "kepubify-linux-64bit"
+fetch_and_deploy_gh_release "calibre" "kovidgoyal/calibre" "prebuild" "latest" "/opt/calibre" "calibre-*-x86_64.txz"
+
+setup_uv
+
+fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
+
+msg_info "Configuring Autocaliweb"
+INSTALL_DIR="/opt/autocaliweb"
+CONFIG_DIR="/etc/autocaliweb"
+CALIBRE_LIB_DIR="/opt/calibre-library"
+INGEST_DIR="/opt/acw-book-ingest"
+SERVICE_USER="acw"
+SERVICE_GROUP="acw"
+SCRIPTS_DIR="${INSTALL_DIR}/scripts"
+VIRTUAL_ENV="${INSTALL_DIR}/venv"
+
+mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
+mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
+mkdir -p "$INSTALL_DIR"/{metadata_change_logs,metadata_temp}
+mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
+
+cd "$INSTALL_DIR"
+$STD uv venv "$VIRTUAL_ENV"
+$STD uv sync --all-extras --active
+cat <./dirs.json
+{
+ "ingest_folder": "$INGEST_DIR",
+ "calibre_library_dir": "$CALIBRE_LIB_DIR",
+ "tmp_conversion_dir": "$CONFIG_DIR/.acw_conversion_tmp"
+}
+EOF
+useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "SERVICE_USER"
+msg_ok "Configured Autocaliweb"
+
+msg_info "Creating ACWSync Plugin for KOReader"
+cd "$INSTALL_DIR"/koreader/plugins
+PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
+echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
+echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
+echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
+zip -r koplugin.zip acwsync.koplugin/
+cp -r koplugin.zip "$INSTALL_DIR"/cps/static
+msg_ok "Created ACWSync Plugin"
+
+msg_info "Initializing databases"
+KEPUBIFY_PATH=$(command -v kepubify 2>/dev/null || echo "/usr/bin/kepubify")
+EBOOK_CONVERT_PATH=$(command -v ebook-convert 2>/dev/null || echo "/usr/bin/ebook-convert")
+CALIBRE_BIN_DIR=$(dirname "$EBOOK_CONVERT_PATH")
+cp "$INSTALL_DIR"/library/metadata.db "$CALIBRE_LIB_DIR"/metadata.db
+
+cp "$INSTALL_DIR"/library/app.db "$CONFIG_DIR"/app.db
+sqlite3 "$CONFIG_DIR/app.db" <"$SCRIPTS_DIR"/ingest_watcher.sh
+#!/bin/bash
+
+WATCH_FOLDER=\$(grep -o '"ingest_folder": "[^"]*' \${INSTALL_DIR}/dirs.json | grep -o '[^"]*\$')
+echo "[acw-ingest-service] Watching folder: \$WATCH_FOLDER"
+
+# Monitor the folder for new files
+/usr/bin/inotifywait -m -r --format="%e %w%f" -e close_write -e moved_to "\$WATCH_FOLDER" |
+while read -r events filepath ; do
+ echo "[acw-ingest-service] New files detected - \$filepath - Starting Ingest Processor..."
+ # Use the Python interpreter from the virtual environment
+ \${VIRTUAL_ENV}/bin/python \${SCRIPTS_DIR}/ingest_processor.py "\$filepath"
+done
+EOF
+
+# auto-zipper
+cat <"$SCRIPTS_DIR"/auto_zipper_wrapper.sh
+#!/bin/bash
+
+# Source virtual environment
+source ${VIRTUAL_ENV}/bin/activate
+
+WAKEUP="23:59"
+
+while true; do
+ # Replace expr with modern Bash arithmetic (safer and less prone to parsing issues)
+ # fix: expr: non-integer argument and sleep: missing operand
+ SECS=\$(( \$(date -d "\$WAKEUP" +%s) - \$(date -d "now" +%s) ))
+ if [[ \$SECS -lt 0 ]]; then
+ SECS=\$(( \$(date -d "tomorrow \$WAKEUP" +%s) - \$(date -d "now" +%s) ))
+ fi
+ echo "[acw-auto-zipper] Next run in \$SECS seconds."
+ sleep \$SECS &
+ wait \$!
+
+ # Use virtual environment python
+ python ${SCRIPTS_DIR}/auto_zip.py
+
+ if [[ \$? == 1 ]]; then
+ echo "[acw-auto-zipper] Error occurred during script initialisation."
+ elif [[ \$? == 2 ]]; then
+ echo "[acw-auto-zipper] Error occurred while zipping today's files."
+ elif [[ \$? == 3 ]]; then
+ echo "[acw-auto-zipper] Error occurred while trying to remove zipped files."
+ fi
+
+ sleep 60
+done
+EOF
+
+# metadata change detector
+cat <"$SCRIPTS_DIR"/metadata_change_detector_wrapper.sh
+#!/bin/bash
+# metadata_change_detector_wrapper.sh - Wrapper for periodic metadata enforcement
+
+# Source virtual environment
+source ${VIRTUAL_ENV}/bin/activate
+
+# Configuration
+CHECK_INTERVAL=300 # Check every 5 minutes (300 seconds)
+METADATA_LOGS_DIR="${INSTALL_DIR}/metadata_change_logs"
+
+echo "[metadata-change-detector] Starting metadata change detector service..."
+echo "[metadata-change-detector] Checking for changes every \$CHECK_INTERVAL seconds"
+
+while true; do
+ # Check if there are any log files to process
+ if [ -d "\$METADATA_LOGS_DIR" ] && [ "\$(ls -A \$METADATA_LOGS_DIR 2>/dev/null)" ]; then
+ echo "[metadata-change-detector] Found metadata change logs, processing..."
+
+ # Process each log file
+ for log_file in "\$METADATA_LOGS_DIR"/*.json; do
+ if [ -f "\$log_file" ]; then
+ log_name=\$(basename "\$log_file")
+ echo "[metadata-change-detector] Processing log: \$log_name"
+
+ # Call cover_enforcer.py with the log file
+ ${INSTALL_DIR}/venv/bin/python ${SCRIPTS_DIR}/cover_enforcer.py --log "\$log_name"
+
+ if [ \$? -eq 0 ]; then
+ echo "[metadata-change-detector] Successfully processed \$log_name"
+ else
+ echo "[metadata-change-detector] Error processing \$log_name"
+ fi
+ fi
+ done
+ else
+ echo "[metadata-change-detector] No metadata changes detected"
+ fi
+
+ echo "[metadata-change-detector] Sleeping for \$CHECK_INTERVAL seconds..."
+ sleep \$CHECK_INTERVAL
+done
+EOF
+chmod +x "$SCRIPTS_DIR"/{ingest_watcher.sh,auto_zipper_wrapper.sh,metadata_change_detector_wrapper.sh}
+chown -R "$SERVICE_USER":"$SERVICE_GROUP" {"$INSTALL_DIR","$CONFIG_DIR","$INGEST_DIR","$CALIBRE_LIB_DIR"}
+
+# systemd service files
+SYS_PATH="/etc/systemd/system"
+cat <"$SYS_PATH"/autocaliweb.service
+[Unit]
+Description=Autocaliweb
+After=network.target
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=simple
+User=$SERVICE_USER
+Group=$SERVICE_GROUP
+WorkingDirectory=$INSTALL_DIR
+Environment=PATH=$INSTALL_DIR/venv/bin:/usr/bin:/bin
+Environment=PYTHONPATH=$SCRIPTS_DIR:$INSTALL_DIR
+Environment=PYTHONDONTWRITEBYTECODE=1
+Environment=PYTHONUNBUFFERED=1
+Environment=CALIBRE_DBPATH=$CONFIG_DIR
+ExecStart=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/cps.py -p $CONFIG_DIR/app.db
+
+Restart=always
+RestartSec=10
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat <"$SYS_PATH"/acw-ingestor.service
+[Unit]
+Description=Autocaliweb Ingest Processor Service
+After=autocaliweb.service
+Requires=autocaliweb.service
+
+[Service]
+User=${SERVICE_USER}
+Group=${SERVICE_GROUP}
+WorkingDirectory=${INSTALL_DIR}
+Environment=CALIBRE_DBPATH=${CONFIG_DIR}
+Environment=HOME=${CONFIG_DIR}
+ExecStart=/bin/bash ${SCRIPTS_DIR}/ingest_watcher.sh
+Restart=always
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat <"$SYS_PATH"/acw-auto-zipper.service
+[Unit]
+Description=Autocaliweb Auto Zipper Service
+After=network.target
+
+[Service]
+User=${SERVICE_USER}
+Group=${SERVICE_GROUP}
+WorkingDirectory=${INSTALL_DIR}
+Environment=CALIBRE_DBPATH=${CONFIG_DIR}
+ExecStart=${SCRIPTS_DIR}/auto_zipper_wrapper.sh
+Restart=always
+StandardOutput=journal
+StandardError=journal
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+cat <"$SYS_PATH"/metadata-change-detector.service
+[Unit]
+Description=Autocaliweb Metadata Change Detector
+After=network.target
+
+[Service]
+User=${SERVICE_USER}
+Group=${SERVICE_GROUP}
+WorkingDirectory=${INSTALL_DIR}
+ExecStart=/bin/bash ${SCRIPTS_DIR}/metadata_change_detector_wrapper.sh
+Restart=always
+StandardOutput=journal
+StandardError=journal
+Environment=CALIBRE_DBPATH=${CONFIG_DIR}
+Environment=HOME=${CONFIG_DIR}
+[Install]
+WantedBy=multi-user.target
+EOF
+
+systemctl -q enable --now autocaliweb acw-ingestor acw-auto-zipper metadata-change-detector
+msg_ok "Created scripts and service files"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From c74acde6a0b983604566556acee8834826e98bb0 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 20:28:58 -0400
Subject: [PATCH 200/312] Autocaliweb: typo fix
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index e9ed0dd4..fa08c860 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -20,7 +20,7 @@ $STD apt-get install -y --no-install-recommends \
build-essential \
libldap2-dev \
libssl-dev \
- libsasl-dev \
+ libsasl2-dev \
imagemagick \
ghostscript \
libmagic1 \
From 1f44bd8e4034cd4986ab1d5c5c171dfe842aee3f Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 20:47:13 -0400
Subject: [PATCH 201/312] Autocaliweb: manual install of Calibre; symlink
plugin dir
---
install/autocaliweb-install.sh | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index fa08c860..e9b121eb 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -46,7 +46,15 @@ $STD apt-get install -y --no-install-recommends \
msg_ok "Installed dependencies"
fetch_and_deploy_gh_release "kepubify" "pgaskin/kepubify" "singlefile" "latest" "/usr/bin" "kepubify-linux-64bit"
-fetch_and_deploy_gh_release "calibre" "kovidgoyal/calibre" "prebuild" "latest" "/opt/calibre" "calibre-*-x86_64.txz"
+
+msg_info "Installing Calibre"
+CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
+CALIBRE_VERSION=${CALIBRE_RELEASE#v}
+curl -fsSL https://github.com/kovidgoyal/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
+$STD tar -xf /tmp/calibre.txz /opt/calibre
+rm /tmp/calibre.txz
+$STD /opt/calibre/calibre_postinstall
+msg_ok "Calibre installed"
setup_uv
@@ -78,6 +86,7 @@ cat <./dirs.json
}
EOF
useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "SERVICE_USER"
+ln -sf "$CONFIG_DIR"/.config/calibre/plugins "$CONFIG_DIR"/calibre_plugins
msg_ok "Configured Autocaliweb"
msg_info "Creating ACWSync Plugin for KOReader"
From 0ce12acf2692fd0bae86956f4da81f718dece696 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Sun, 24 Aug 2025 20:54:38 -0400
Subject: [PATCH 202/312] Autocaliweb: fix Calibre download
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index e9b121eb..4c6e6400 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -50,7 +50,7 @@ fetch_and_deploy_gh_release "kepubify" "pgaskin/kepubify" "singlefile" "latest"
msg_info "Installing Calibre"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
CALIBRE_VERSION=${CALIBRE_RELEASE#v}
-curl -fsSL https://github.com/kovidgoyal/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
+curl -fsSL https://github.com/kovidgoyal/calibre/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
$STD tar -xf /tmp/calibre.txz /opt/calibre
rm /tmp/calibre.txz
$STD /opt/calibre/calibre_postinstall
From 15f835a6c2340cada88abf0df52fdd3047ccc957 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Mon, 25 Aug 2025 08:49:35 +0200
Subject: [PATCH 203/312] Remove package-lock.json during installation
Remove package-lock.json before npm install.
---
install/tracktor-install.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/install/tracktor-install.sh b/install/tracktor-install.sh
index 3beefa4b..00c6c1d7 100644
--- a/install/tracktor-install.sh
+++ b/install/tracktor-install.sh
@@ -18,7 +18,6 @@ fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest"
msg_info "Configuring Tracktor"
cd /opt/tracktor
-rm package-lock.json
$STD npm install
$STD npm run build
mkdir /opt/tracktor-data
From 6914a23c16710c2ffda7e69600e681b09282d5e8 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Mon, 25 Aug 2025 09:04:40 +0200
Subject: [PATCH 204/312] Remove package-lock.json deletion in tracktor.sh
---
ct/tracktor.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/ct/tracktor.sh b/ct/tracktor.sh
index 1386344d..c568f28d 100644
--- a/ct/tracktor.sh
+++ b/ct/tracktor.sh
@@ -42,7 +42,6 @@ function update_script() {
setup_nodejs
fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest" "/opt/tracktor"
cd /opt/tracktor
- rm package-lock.json
$STD npm install
$STD npm run build
msg_ok "Updated $APP"
From aefaaa9a5d001350f2d2975149ba64387b629bd0 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Mon, 25 Aug 2025 07:05:06 +0000
Subject: [PATCH 205/312] Update .app files
---
ct/headers/autocaliweb | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 ct/headers/autocaliweb
diff --git a/ct/headers/autocaliweb b/ct/headers/autocaliweb
new file mode 100644
index 00000000..a5aa7d63
--- /dev/null
+++ b/ct/headers/autocaliweb
@@ -0,0 +1,6 @@
+ ___ __ ___ __
+ / | __ __/ /_____ _________ _/ (_) _____ / /_
+ / /| |/ / / / __/ __ \/ ___/ __ `/ / / | /| / / _ \/ __ \
+ / ___ / /_/ / /_/ /_/ / /__/ /_/ / / /| |/ |/ / __/ /_/ /
+/_/ |_\__,_/\__/\____/\___/\__,_/_/_/ |__/|__/\___/_.___/
+
From 0334933d5c0145db32a22fda711c72f505f06b1f Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 09:51:50 +0200
Subject: [PATCH 206/312] Update tools.func
---
misc/tools.func | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index 844fabd1..1413c26c 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -379,24 +379,6 @@ function setup_mysql() {
# PHP_MAX_EXECUTION_TIME - (default: 300)
# ------------------------------------------------------------------------------
-# ------------------------------------------------------------------------------
-# Installs PHP with selected modules and configures Apache/FPM support.
-#
-# Description:
-# - Adds Sury PHP repo if needed
-# - Installs default and user-defined modules
-# - Patches php.ini for CLI, Apache, and FPM as needed
-#
-# Variables:
-# PHP_VERSION - PHP version to install (default: 8.4)
-# PHP_MODULE - Additional comma-separated modules
-# PHP_APACHE - Set YES to enable PHP with Apache
-# PHP_FPM - Set YES to enable PHP-FPM
-# PHP_MEMORY_LIMIT - (default: 512M)
-# PHP_UPLOAD_MAX_FILESIZE - (default: 128M)
-# PHP_POST_MAX_SIZE - (default: 128M)
-# PHP_MAX_EXECUTION_TIME - (default: 300)
-# ------------------------------------------------------------------------------
function setup_php() {
local PHP_VERSION="${PHP_VERSION:-8.4}"
local PHP_MODULE="${PHP_MODULE:-}"
From 2d550fb4b557453444e7075bd23bef35c0a44420 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 13:58:20 +0200
Subject: [PATCH 207/312] finalize
---
ct/healthchecks.sh | 39 ++++++++++++++++++++++----
frontend/public/json/healthchecks.json | 23 +++++++++------
install/healthchecks-install.sh | 2 +-
3 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/ct/healthchecks.sh b/ct/healthchecks.sh
index 44218b6c..f8e5e45f 100644
--- a/ct/healthchecks.sh
+++ b/ct/healthchecks.sh
@@ -7,9 +7,9 @@ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxV
APP="healthchecks"
var_tags="${var_tags:-monitoring}"
-var_cpu="${var_cpu:-4}"
-var_ram="${var_ram:-4096}"
-var_disk="${var_disk:-20}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-5}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
@@ -23,11 +23,40 @@ function update_script() {
header_info
check_container_storage
check_container_resources
- if [[ ! -f /etc/systemd/system/healthchecks.service ]]; then
+
+ if [[ ! -d /opt/healthchecks ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_error "No Update."
+
+ RELEASE=$(curl -fsSL https://api.github.com/repos/healthchecks/healthchecks/releases/latest | jq '.tag_name' | sed 's/^"v//;s/"$//')
+ if [[ "${RELEASE}" != "$(cat ~/.healthchecks 2>/dev/null)" ]] || [[ ! -f ~/.healthchecks ]]; then
+ msg_info "Stopping $APP"
+ systemctl stop healthchecks
+ msg_ok "Stopped $APP"
+
+ setup_uv
+ fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks"
+
+ msg_info "Updating $APP to v${RELEASE}"
+ cd /opt/healthchecks
+ mkdir -p /opt/healthchecks/static-collected/
+ $STD uv pip install wheel gunicorn -r requirements.txt --system
+ $STD uv run -- python manage.py makemigrations
+ $STD uv run -- python manage.py migrate --noinput
+ $STD uv run -- python manage.py collectstatic --noinput
+ $STD uv run -- python manage.py compress
+ msg_ok "Updated $APP to v${RELEASE}"
+
+ msg_info "Starting $APP"
+ systemctl start healthchecks
+ systemctl restart caddy
+ msg_ok "Started $APP"
+
+ msg_ok "Update Successful"
+ else
+ msg_ok "No update required. ${APP} is already at v${RELEASE}"
+ fi
exit
}
diff --git a/frontend/public/json/healthchecks.json b/frontend/public/json/healthchecks.json
index ac5f3fe2..a0187d17 100644
--- a/frontend/public/json/healthchecks.json
+++ b/frontend/public/json/healthchecks.json
@@ -4,24 +4,24 @@
"categories": [
9
],
- "date_created": "2025-07-02",
+ "date_created": "2025-08-25",
"type": "ct",
"updateable": true,
"privileged": false,
- "config_path": "/opt/healthchecks/.env",
+ "config_path": "/opt/healthchecks/hc/local_settings.py",
"interface_port": 3000,
"documentation": "https://healthchecks.io/",
"website": "https://healthchecks.io/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/healthchecks.svg",
- "description": "Healthchecks is an open-source self-hosted application.",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/healthchecks.webp",
+ "description": "Healthchecks is a cron job monitoring service. It listens for HTTP requests and email messages (\"pings\") from your cron jobs and scheduled tasks (\"checks\"). When a ping does not arrive on time, Healthchecks sends out alerts. Healthchecks comes with a web dashboard, API, 25+ integrations for delivering notifications, monthly email reports, WebAuthn 2FA support, team management features: projects, team members, read-only access.",
"install_methods": [
{
"type": "default",
"script": "ct/healthchecks.sh",
"resources": {
- "cpu": 1,
- "ram": 1024,
- "hdd": 2,
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 5,
"os": "Debian",
"version": "12"
}
@@ -31,5 +31,10 @@
"username": null,
"password": null
},
- "notes": []
-}
\ No newline at end of file
+ "notes": [
+ {
+ "text": "if you change your LXC-IP, you need to update /etc/caddy/Caddyfile & /opt/healthchecks/hc/local_settings.py",
+ "type": "info"
+ }
+ ]
+}
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
index 05111846..2507149d 100644
--- a/install/healthchecks-install.sh
+++ b/install/healthchecks-install.sh
@@ -48,7 +48,7 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
} >>~/healthchecks.creds
msg_ok "Set up Database"
-fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "source"
+fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks"
msg_info "Setup healthchecks"
cd /opt/healthchecks
From 9b7fbdf7d73a91598480d2f4b9ae4463f8d92cb1 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 14:25:18 +0200
Subject: [PATCH 208/312] cleanup
---
.../backup/check_and_update_json_date.yml | 60 ----
.github/workflows/backup/shellcheck.yml | 60 ----
.../workflows/backup/update_json_date.yml.bak | 90 ------
.../backup/validate-formatting.yaml.bak | 133 --------
.../workflows/backup/validate-scripts.yml.bak | 234 --------------
.github/workflows/changelog-pr.yaml | 286 ------------------
.github/workflows/close-discussion.yaml | 164 ----------
.github/workflows/close-ttek-issue.yaml | 53 ----
.github/workflows/live/changelog-pr.yml | 228 --------------
.github/workflows/live/close-discussion.yml | 122 --------
.../live/create-docker-for-runner.yml | 37 ---
.github/workflows/live/delete-json-branch.yml | 28 --
.github/workflows/live/github-release.yml | 57 ----
.github/workflows/live/script-test.yml | 177 -----------
.github/workflows/live/script_format.yml | 243 ---------------
.github/workflows/live/update-json-date.yml | 133 --------
.github/workflows/live/validate-filenames.yml | 161 ----------
17 files changed, 2266 deletions(-)
delete mode 100644 .github/workflows/backup/check_and_update_json_date.yml
delete mode 100644 .github/workflows/backup/shellcheck.yml
delete mode 100644 .github/workflows/backup/update_json_date.yml.bak
delete mode 100644 .github/workflows/backup/validate-formatting.yaml.bak
delete mode 100644 .github/workflows/backup/validate-scripts.yml.bak
delete mode 100644 .github/workflows/changelog-pr.yaml
delete mode 100644 .github/workflows/close-discussion.yaml
delete mode 100644 .github/workflows/close-ttek-issue.yaml
delete mode 100644 .github/workflows/live/changelog-pr.yml
delete mode 100644 .github/workflows/live/close-discussion.yml
delete mode 100644 .github/workflows/live/create-docker-for-runner.yml
delete mode 100644 .github/workflows/live/delete-json-branch.yml
delete mode 100644 .github/workflows/live/github-release.yml
delete mode 100644 .github/workflows/live/script-test.yml
delete mode 100644 .github/workflows/live/script_format.yml
delete mode 100644 .github/workflows/live/update-json-date.yml
delete mode 100644 .github/workflows/live/validate-filenames.yml
diff --git a/.github/workflows/backup/check_and_update_json_date.yml b/.github/workflows/backup/check_and_update_json_date.yml
deleted file mode 100644
index cde3cbba..00000000
--- a/.github/workflows/backup/check_and_update_json_date.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Update date_created in JSON files
-
-on:
- # Dieser Trigger wird für das Öffnen von PRs sowie für das Aktualisieren von offenen PRs verwendet
- pull_request:
- types: [opened, synchronize]
- schedule:
- # Dieser Trigger wird 4x am Tag ausgelöst, um sicherzustellen, dass das Datum aktualisiert wird
- - cron: "0 0,6,12,18 * * *" # Führt alle 6 Stunden aus
- workflow_dispatch: # Manuelle Ausführung des Workflows möglich
-
-jobs:
- update-date:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Install yq
- run: |
- sudo apt-get update
- sudo apt-get install -y yq
-
- - name: Set the current date
- id: set_date
- run: echo "TODAY=$(date -u +%Y-%m-%d)" >> $GITHUB_ENV
-
- - name: Check for changes in PR
- run: |
- # Hole den PR-Branch
- PR_BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge"
- git fetch origin $PR_BRANCH
-
- # Liste alle JSON-Dateien im PR auf, die geändert wurden
- CHANGED_JSON_FILES=$(git diff --name-only origin/main...$PR_BRANCH | grep '.json')
-
- if [ -z "$CHANGED_JSON_FILES" ]; then
- echo "No JSON files changed in this PR."
- exit 0
- fi
-
- # Gehe alle geänderten JSON-Dateien durch und aktualisiere das Datum
- for file in $CHANGED_JSON_FILES; do
- echo "Updating date_created in $file"
- # Setze das aktuelle Datum
- yq eval ".date_created = \"${{ env.TODAY }}\"" -i "$file"
- git add "$file"
- done
-
- - name: Commit and push changes
- run: |
- # Prüfe, ob es Änderungen gibt und committe sie
- git config user.name "json-updater-bot"
- git config user.email "github-actions[bot]@users.noreply.github.com"
-
- git commit -m "Update date_created to ${{ env.TODAY }}" || echo "No changes to commit"
-
- # Push zurück in den PR-Branch
- git push origin $PR_BRANCH
diff --git a/.github/workflows/backup/shellcheck.yml b/.github/workflows/backup/shellcheck.yml
deleted file mode 100644
index 4385fc8e..00000000
--- a/.github/workflows/backup/shellcheck.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-name: Shellcheck
-
-on:
- push:
- branches:
- - main
- pull_request:
- workflow_dispatch:
- schedule:
- - cron: "5 1 * * *"
-
-jobs:
- shellcheck:
- name: Shellcheck
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v4
-
- - name: Get changed files
- id: changed-files
- uses: tj-actions/changed-files@v45
- with:
- files: |
- **.sh
-
- - name: Download ShellCheck
- shell: bash
- env:
- INPUT_VERSION: "v0.10.0"
- run: |
- set -euo pipefail
- if [[ "${{ runner.os }}" == "macOS" ]]; then
- osvariant="darwin"
- else
- osvariant="linux"
- fi
-
- baseurl="https://github.com/koalaman/shellcheck/releases/download"
- curl -Lso "${{ github.workspace }}/sc.tar.xz" \
- "${baseurl}/${INPUT_VERSION}/shellcheck-${INPUT_VERSION}.${osvariant}.x86_64.tar.xz"
-
- tar -xf "${{ github.workspace }}/sc.tar.xz" -C "${{ github.workspace }}"
- mv "${{ github.workspace }}/shellcheck-${INPUT_VERSION}/shellcheck" \
- "${{ github.workspace }}/shellcheck"
-
- - name: Verify ShellCheck binary
- run: |
- ls -l "${{ github.workspace }}/shellcheck"
-
- - name: Display ShellCheck version
- run: |
- "${{ github.workspace }}/shellcheck" --version
-
- - name: Run ShellCheck
- if: steps.changed-files.outputs.any_changed == 'true'
- env:
- ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
- run: |
- echo "${ALL_CHANGED_FILES}" | xargs "${{ github.workspace }}/shellcheck"
diff --git a/.github/workflows/backup/update_json_date.yml.bak b/.github/workflows/backup/update_json_date.yml.bak
deleted file mode 100644
index 71012528..00000000
--- a/.github/workflows/backup/update_json_date.yml.bak
+++ /dev/null
@@ -1,90 +0,0 @@
-name: Auto Update JSON-Date
-
-on:
- push:
- branches:
- - main
- workflow_dispatch:
-
-jobs:
- update-json-dates:
- runs-on: ubuntu-latest
-
- permissions:
- contents: write
- pull-requests: write
-
- steps:
- - name: Generate a token
- id: generate-token
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ vars.APP_ID }}
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
- owner: community-scripts
- repositories: ProxmoxVED
-
- - name: Checkout repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Full history for proper detection
-
- - name: Set up Git
- run: |
- git config --global user.name "GitHub Actions"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
-
- - name: Find JSON files with incorrect date_created
- id: find_wrong_json
- run: |
- TODAY=$(date -u +"%Y-%m-%d")
- > incorrect_json_files.txt
-
- for FILE in json/*.json; do
- if [[ -f "$FILE" ]]; then
- DATE_IN_JSON=$(jq -r '.date_created' "$FILE" 2>/dev/null || echo "")
-
- if [[ "$DATE_IN_JSON" != "$TODAY" ]]; then
- echo "$FILE" >> incorrect_json_files.txt
- fi
- fi
- done
-
- if [[ -s incorrect_json_files.txt ]]; then
- echo "CHANGED=true" >> $GITHUB_ENV
- else
- echo "CHANGED=false" >> $GITHUB_ENV
- fi
-
- - name: Run update script
- if: env.CHANGED == 'true'
- run: |
- chmod +x .github/workflows/scripts/update-json.sh
- while read -r FILE; do
- .github/workflows/scripts/update-json.sh "$FILE"
- done < incorrect_json_files.txt
-
- - name: Commit and create PR if changes exist
- if: env.CHANGED == 'true'
- run: |
- git add json/*.json
- git commit -m "Auto-update date_created in incorrect JSON files"
- git checkout -b pr-fix-json-dates
- git push origin pr-fix-json-dates --force
- gh pr create --title "[core] Fix incorrect JSON date_created fields" \
- --body "This PR is auto-generated to fix incorrect `date_created` fields in JSON files." \
- --head pr-fix-json-dates \
- --base main \
- --label "automated pr"
- env:
- GH_TOKEN: ${{ steps.generate-token.outputs.token }}
-
- - name: Approve pull request
- if: env.CHANGED == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- PR_NUMBER=$(gh pr list --head "pr-fix-json-dates" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- fi
diff --git a/.github/workflows/backup/validate-formatting.yaml.bak b/.github/workflows/backup/validate-formatting.yaml.bak
deleted file mode 100644
index 8eadd0ac..00000000
--- a/.github/workflows/backup/validate-formatting.yaml.bak
+++ /dev/null
@@ -1,133 +0,0 @@
-name: Validate script formatting
-
-on:
- push:
- branches:
- - main
- pull_request_target:
- paths:
- - "**/*.sh"
- - "**/*.func"
-
-jobs:
- shfmt:
- name: Check changed files
- runs-on: ubuntu-latest
- permissions:
-
- pull-requests: write
-
- steps:
- - name: Get pull request information
- if: github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- id: pr
- with:
- script: |
- const { data: pullRequest } = await github.rest.pulls.get({
- ...context.repo,
- pull_number: context.payload.pull_request.number,
- });
- return pullRequest;
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Ensure the full history is fetched for accurate diffing
- ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }}
-
- - name: Get changed files
- id: changed-files
- run: |
- if ${{ github.event_name == 'pull_request_target' }}; then
- echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT
- else
- echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT
- fi
-
- - name: Set up Go
- if: steps.changed-files.outputs.files != ''
- uses: actions/setup-go@v5
-
- - name: Install shfmt
- if: steps.changed-files.outputs.files != ''
- run: |
- go install mvdan.cc/sh/v3/cmd/shfmt@latest
- echo "$GOPATH/bin" >> $GITHUB_PATH
-
- - name: Run shfmt
- if: steps.changed-files.outputs.files != ''
- id: shfmt
- run: |
- set +e
-
-
- shfmt_output=$(shfmt -d ${{ steps.changed-files.outputs.files }})
- if [[ $? -eq 0 ]]; then
- exit 0
- else
- echo "diff=\"$(echo -n "$shfmt_output" | base64 -w 0)\"" >> $GITHUB_OUTPUT
- printf "%s" "$shfmt_output"
- exit 1
- fi
-
- - name: Post comment with results
- if: always() && steps.changed-files.outputs.files != '' && github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- with:
- script: |
- const result = "${{ job.status }}" === "success" ? "success" : "failure";
- const diff = Buffer.from(
- ${{ steps.shfmt.outputs.diff }},
- "base64",
- ).toString();
- const issueNumber = context.payload.pull_request
- ? context.payload.pull_request.number
- : null;
- const commentIdentifier = "validate-formatting";
- let newCommentBody = `\n### Script formatting\n\n`;
-
- if (result === "failure") {
- newCommentBody +=
- `:x: We found issues in the formatting of the following changed files:\n\n\`\`\`diff\n${diff}\n\`\`\`\n`;
- } else {
- newCommentBody += `:rocket: All changed shell scripts are formatted correctly!\n`;
- }
-
- newCommentBody += `\n\n`;
-
- if (issueNumber) {
- const { data: comments } = await github.rest.issues.listComments({
- ...context.repo,
- issue_number: issueNumber,
- });
-
- const existingComment = comments.find(
- (comment) => comment.user.login === "github-actions[bot]",
-
- );
-
- if (existingComment) {
- if (existingComment.body.includes(commentIdentifier)) {
- const re = new RegExp(
- String.raw`[\s\S]*?`,
- "",
- );
- newCommentBody = existingComment.body.replace(re, newCommentBody);
- } else {
- newCommentBody = existingComment.body + "\n\n---\n\n" + newCommentBody;
- }
-
- await github.rest.issues.updateComment({
- ...context.repo,
- comment_id: existingComment.id,
- body: newCommentBody,
- });
- } else {
- await github.rest.issues.createComment({
- ...context.repo,
- issue_number: issueNumber,
- body: newCommentBody,
- });
- }
- }
diff --git a/.github/workflows/backup/validate-scripts.yml.bak b/.github/workflows/backup/validate-scripts.yml.bak
deleted file mode 100644
index acb86132..00000000
--- a/.github/workflows/backup/validate-scripts.yml.bak
+++ /dev/null
@@ -1,234 +0,0 @@
-name: Validate scripts
-on:
- push:
- branches:
- - main
- pull_request_target:
- paths:
- - "ct/*.sh"
- - "install/*.sh"
-
-jobs:
- check-scripts:
- name: Check changed files
- runs-on: ubuntu-latest
- permissions:
- pull-requests: write
-
- steps:
- - name: Debug event payload
- run: |
- echo "Event name: ${{ github.event_name }}"
- echo "Payload: $(cat $GITHUB_EVENT_PATH)"
-
- - name: Get pull request information
- if: github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- id: pr
- with:
- script: |
- const { data: pullRequest } = await github.rest.pulls.get({
- ...context.repo,
- pull_number: context.payload.pull_request.number,
- });
- return pullRequest;
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }}
-
- - name: Get changed files
- id: changed-files
- run: |
- if [ "${{ github.event_name }}" == "pull_request_target" ]; then
- echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT
- else
- echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | grep -E '\.(sh|func)$' | xargs)" >> $GITHUB_OUTPUT
- fi
-
- - name: Check build.func line
- if: always() && steps.changed-files.outputs.files != ''
- id: build-func
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if [[ "$FILE" == ct/* ]] && [[ $(sed -n '2p' "$FILE") != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" ]]; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Build.func line missing or incorrect in files:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Check executable permissions
- if: always() && steps.changed-files.outputs.files != ''
- id: check-executable
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if [[ ! -x "$FILE" ]]; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Files not executable:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Check copyright
- if: always() && steps.changed-files.outputs.files != ''
- id: check-copyright
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if ! sed -n '3p' "$FILE" | grep -qE "^# Copyright \(c\) [0-9]{4}(-[0-9]{4})? (tteck \| community-scripts ORG|community-scripts ORG|tteck)$"; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Copyright header missing or not on line 3 in files:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Check author
- if: always() && steps.changed-files.outputs.files != ''
- id: check-author
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if ! sed -n '4p' "$FILE" | grep -qE "^# Author: .+"; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Author header missing or invalid on line 4 in files:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Check license
- if: always() && steps.changed-files.outputs.files != ''
- id: check-license
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if [[ "$(sed -n '5p' "$FILE")" != "# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE" ]]; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "License header missing or not on line 5 in files:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Check source
- if: always() && steps.changed-files.outputs.files != ''
- id: check-source
- run: |
- NON_COMPLIANT_FILES=""
- for FILE in ${{ steps.changed-files.outputs.files }}; do
- if ! sed -n '6p' "$FILE" | grep -qE "^# Source: .+"; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Source header missing or not on line 6 in files:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Post results and comment
- if: always() && steps.changed-files.outputs.files != '' && github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- with:
- script: |
- const result = '${{ job.status }}' === 'success' ? 'success' : 'failure';
- const nonCompliantFiles = {
- 'Invalid build.func source': "${{ steps.build-func.outputs.files || '' }}",
- 'Not executable': "${{ steps.check-executable.outputs.files || '' }}",
- 'Copyright header line missing or invalid': "${{ steps.check-copyright.outputs.files || '' }}",
- 'Author header line missing or invalid': "${{ steps.check-author.outputs.files || '' }}",
- 'License header line missing or invalid': "${{ steps.check-license.outputs.files || '' }}",
- 'Source header line missing or invalid': "${{ steps.check-source.outputs.files || '' }}"
- };
-
- const issueNumber = context.payload.pull_request ? context.payload.pull_request.number : null;
- const commentIdentifier = 'validate-scripts';
- let newCommentBody = `\n### Script validation\n\n`;
-
- if (result === 'failure') {
- newCommentBody += ':x: We found issues in the following changed files:\n\n';
- for (const [check, files] of Object.entries(nonCompliantFiles)) {
- if (files) {
- newCommentBody += `**${check}:**\n`;
- files.trim().split(' ').forEach(file => {
- newCommentBody += `- ${file}: ${check}\n`;
- });
- newCommentBody += `\n`;
- }
- }
- } else {
- newCommentBody += `:rocket: All changed shell scripts passed validation!\n`;
- }
-
- newCommentBody += `\n\n`;
-
- if (issueNumber) {
- const { data: comments } = await github.rest.issues.listComments({
- ...context.repo,
- issue_number: issueNumber
- });
-
- const existingComment = comments.find(comment =>
- comment.body.includes(``) &&
- comment.user.login === 'github-actions[bot]'
- );
-
- if (existingComment) {
- const re = new RegExp(String.raw`[\\s\\S]*?`, "m");
- newCommentBody = existingComment.body.replace(re, newCommentBody);
-
- await github.rest.issues.updateComment({
- ...context.repo,
- comment_id: existingComment.id,
- body: newCommentBody
- });
- } else {
- await github.rest.issues.createComment({
- ...context.repo,
- issue_number: issueNumber,
- body: newCommentBody
- });
- }
- }
diff --git a/.github/workflows/changelog-pr.yaml b/.github/workflows/changelog-pr.yaml
deleted file mode 100644
index 80959d54..00000000
--- a/.github/workflows/changelog-pr.yaml
+++ /dev/null
@@ -1,286 +0,0 @@
-name: Create Changelog Pull Request
-
-on:
- push:
- branches: ["main"]
- workflow_dispatch:
-
-jobs:
- update-changelog-pull-request:
- if: github.repository == 'community-scripts/ProxmoxVED'
- runs-on: ubuntu-latest
- env:
- CONFIG_PATH: .github/changelog-pr-config.json
- BRANCH_NAME: github-action-update-changelog
- AUTOMATED_PR_LABEL: "automated pr"
- permissions:
- contents: write
- pull-requests: write
- steps:
- - name: Generate a token for PR creation
- id: generate-token
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ vars.APP_ID }}
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
- owner: community-scripts
- repositories: ProxmoxVED
-
- - name: Generate a token for PR approval and merge
- id: generate-token-merge
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
- private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- owner: community-scripts
- repositories: ProxmoxVED
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - name: Get latest dates in changelog
- run: |
- DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}')
-
- LATEST_DATE=$(echo "$DATES" | sed -n '1p')
- SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p')
- TODAY=$(date -u +%Y-%m-%d)
-
- echo "TODAY=$TODAY" >> $GITHUB_ENV
- if [[ "$LATEST_DATE" == "$TODAY" ]]; then
- echo "LATEST_DATE=$SECOND_LATEST_DATE" >> $GITHUB_ENV
- else
- echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV
- fi
-
- - name: Get categorized pull requests
- id: get-categorized-prs
- uses: actions/github-script@v7
- with:
- script: |
- async function main() {
- const fs = require('fs').promises;
- const path = require('path');
-
- const configPath = path.resolve(process.env.CONFIG_PATH);
- const fileContent = await fs.readFile(configPath, 'utf-8');
- const changelogConfig = JSON.parse(fileContent);
-
- const categorizedPRs = changelogConfig.map(obj => ({
- ...obj,
- notes: [],
- subCategories: obj.subCategories ?? (
- obj.labels.includes("update script") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
- { title: "🔧 Refactor", labels: ["refactor"], notes: [] },
- ] :
- obj.labels.includes("maintenance") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
- { title: "📡 API", labels: ["api"], notes: [] },
- { title: "Github", labels: ["github"], notes: [] },
- { title: "📝 Documentation", labels: ["documentation"], notes: [] },
- { title: "🔧 Refactor", labels: ["refactor"], notes: [] }
- ] :
- obj.labels.includes("website") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
- { title: "Script Information", labels: ["json"], notes: [] }
- ] : []
- )
- }));
-
- const latestDateInChangelog = new Date(process.env.LATEST_DATE);
- latestDateInChangelog.setUTCHours(23, 59, 59, 999);
-
- const { data: pulls } = await github.rest.pulls.list({
- owner: context.repo.owner,
- repo: "ProxmoxVE",
- base: "main",
- state: "closed",
- sort: "updated",
- direction: "desc",
- per_page: 100,
- });
-
- const filteredPRs = pulls.filter(pr =>
- pr.merged_at &&
- new Date(pr.merged_at) > latestDateInChangelog &&
- !pr.labels.some(label =>
- ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())
- )
- );
-
- for (const pr of filteredPRs) {
- const prLabels = pr.labels.map(label => label.name.toLowerCase());
- if (pr.user.login.includes("push-app-to-main[bot]")) {
-
- const scriptName = pr.title;
- try {
- const { data: relatedIssues } = await github.rest.issues.listForRepo({
- owner: context.repo.owner,
- repo: "ProxmoxVED",
- state: "all",
- labels: ["Started Migration To ProxmoxVE"]
- });
-
- const matchingIssue = relatedIssues.find(issue =>
- issue.title.toLowerCase().includes(scriptName.toLowerCase())
- );
-
- if (matchingIssue) {
- const issueAuthor = matchingIssue.user.login;
- const issueAuthorUrl = `https://github.com/${issueAuthor}`;
- prNote = `- ${pr.title} [@${issueAuthor}](${issueAuthorUrl}) ([#${pr.number}](${pr.html_url}))`;
- }
- else {
- prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`;
- }
- } catch (error) {
- console.error(`Error fetching related issues: ${error}`);
- prNote = `- ${pr.title} ([#${pr.number}](${pr.html_url}))`;
- }
- }else{
- prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`;
- }
-
-
- if (prLabels.includes("new script")) {
- const newScriptCategory = categorizedPRs.find(category =>
- category.title === "New Scripts" || category.labels.includes("new script"));
- if (newScriptCategory) {
- newScriptCategory.notes.push(prNote);
- }
- } else {
-
- let categorized = false;
- const priorityCategories = categorizedPRs.slice();
- for (const category of priorityCategories) {
- if (categorized) break;
- if (category.labels.some(label => prLabels.includes(label))) {
- if (category.subCategories && category.subCategories.length > 0) {
- const subCategory = category.subCategories.find(sub =>
- sub.labels.some(label => prLabels.includes(label))
- );
-
- if (subCategory) {
- subCategory.notes.push(prNote);
- } else {
- category.notes.push(prNote);
- }
- } else {
- category.notes.push(prNote);
- }
- categorized = true;
- }
- }
- }
-
- }
-
- return categorizedPRs;
- }
-
- return await main();
-
- - name: Update CHANGELOG.md
- uses: actions/github-script@v7
- with:
- script: |
- const fs = require('fs').promises;
- const path = require('path');
-
- const today = process.env.TODAY;
- const latestDateInChangelog = process.env.LATEST_DATE;
- const changelogPath = path.resolve('CHANGELOG.md');
- const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }};
-
- let newReleaseNotes = `## ${today}\n\n`;
- for (const { title, notes, subCategories } of categorizedPRs) {
- const hasSubcategories = subCategories && subCategories.length > 0;
- const hasMainNotes = notes.length > 0;
- const hasSubNotes = hasSubcategories && subCategories.some(sub => sub.notes && sub.notes.length > 0);
-
- if (hasMainNotes || hasSubNotes) {
- newReleaseNotes += `### ${title}\n\n`;
- }
-
- if (hasMainNotes) {
- newReleaseNotes += ` ${notes.join("\n")}\n\n`;
- }
- if (hasSubcategories) {
- for (const { title: subTitle, notes: subNotes } of subCategories) {
- if (subNotes && subNotes.length > 0) {
- newReleaseNotes += ` - #### ${subTitle}\n\n`;
- newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`;
- }
- }
- }
- }
- const changelogContent = await fs.readFile(changelogPath, 'utf-8');
- const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`);
-
- const regex = changelogIncludesTodaysReleaseNotes
- ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs")
- : new RegExp(`(?=## ${latestDateInChangelog})`, "gs");
-
- const newChangelogContent = changelogContent.replace(regex, newReleaseNotes);
- await fs.writeFile(changelogPath, newChangelogContent);
-
- - name: Check for changes
- id: verify-diff
- run: |
- git diff --quiet . || echo "changed=true" >> $GITHUB_ENV
-
- - name: Commit and push changes
- if: env.changed == 'true'
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git add CHANGELOG.md
- git commit -m "Update CHANGELOG.md"
- git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME
- git push origin $BRANCH_NAME --force
-
- - name: Create pull request if not exists
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- run: |
- PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -z "$PR_EXISTS" ]; then
- gh pr create --title "[Github Action] Update CHANGELOG.md" \
- --body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \
- --head $BRANCH_NAME \
- --base main \
- --label "$AUTOMATED_PR_LABEL"
- fi
-
- - name: Approve pull request
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- fi
-
- - name: Approve pull request and merge
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
- run: |
- git config --global user.name "github-actions-automege[bot]"
- git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
- PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- gh pr merge $PR_NUMBER --squash --admin
- fi
diff --git a/.github/workflows/close-discussion.yaml b/.github/workflows/close-discussion.yaml
deleted file mode 100644
index 9b0352f4..00000000
--- a/.github/workflows/close-discussion.yaml
+++ /dev/null
@@ -1,164 +0,0 @@
-name: Close Discussion on PR Merge
-
-on:
- push:
- branches:
- - main
-
-permissions:
- contents: read
- discussions: write
-
-jobs:
- close-discussion:
- if: github.repository == 'community-scripts/ProxmoxVED'
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@v4
-
- - name: Set Up Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "20"
-
- - name: Install Dependencies
- run: npm install zx @octokit/graphql
-
- - name: Close Discussion
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- GITHUB_SHA: ${{ github.sha }}
- GITHUB_REPOSITORY: ${{ github.repository }}
- run: |
- npx zx << 'EOF'
- import { graphql } from "@octokit/graphql";
-
- (async function () {
- try {
- const token = process.env.GITHUB_TOKEN;
- const commitSha = process.env.GITHUB_SHA;
- const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
-
- if (!token || !commitSha || !owner || !repo) {
- console.log("Missing required environment variables.");
- process.exit(1);
- }
-
- const graphqlWithAuth = graphql.defaults({
- headers: { authorization: `Bearer ${token}` },
- });
-
- // Find PR from commit SHA
- const searchQuery = `
- query($owner: String!, $repo: String!, $sha: GitObjectID!) {
- repository(owner: $owner, name: $repo) {
- object(oid: $sha) {
- ... on Commit {
- associatedPullRequests(first: 1) {
- nodes {
- number
- body
- }
- }
- }
- }
- }
- }
- `;
-
- const prResult = await graphqlWithAuth(searchQuery, {
- owner,
- repo,
- sha: commitSha,
- });
-
- const pr = prResult.repository.object.associatedPullRequests.nodes[0];
- if (!pr) {
- console.log("No PR found for this commit.");
- return;
- }
-
- const prNumber = pr.number;
- const prBody = pr.body;
-
- const match = prBody.match(/#(\d+)/);
- if (!match) {
- console.log("No discussion ID found in PR body.");
- return;
- }
-
- const discussionNumber = match[1];
- console.log(`Extracted Discussion Number: ${discussionNumber}`);
-
- // Fetch GraphQL discussion ID
- const discussionQuery = `
- query($owner: String!, $repo: String!, $number: Int!) {
- repository(owner: $owner, name: $repo) {
- discussion(number: $number) {
- id
- }
- }
- }
- `;
-
- //
- try {
- const discussionResponse = await graphqlWithAuth(discussionQuery, {
- owner,
- repo,
- number: parseInt(discussionNumber, 10),
- });
-
- const discussionQLId = discussionResponse.repository.discussion.id;
- if (!discussionQLId) {
- console.log("Failed to fetch discussion GraphQL ID.");
- return;
- }
- } catch (error) {
- console.error("Discussion not found or error occurred while fetching discussion:", error);
- return;
- }
-
- // Post comment
- const commentMutation = `
- mutation($discussionId: ID!, $body: String!) {
- addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
- comment { id body }
- }
- }
- `;
-
- const commentResponse = await graphqlWithAuth(commentMutation, {
- discussionId: discussionQLId,
- body: `Merged with PR #${prNumber}`,
- });
-
- const commentId = commentResponse.addDiscussionComment.comment.id;
- if (!commentId) {
- console.log("Failed to post the comment.");
- return;
- }
-
- console.log(`Comment Posted Successfully! Comment ID: ${commentId}`);
-
- // Mark comment as answer
- const markAnswerMutation = `
- mutation($id: ID!) {
- markDiscussionCommentAsAnswer(input: { id: $id }) {
- discussion { id title }
- }
- }
- `;
-
- await graphqlWithAuth(markAnswerMutation, { id: commentId });
-
- console.log("Comment marked as answer successfully!");
-
- } catch (error) {
- console.error("Error:", error);
- process.exit(1);
- }
- })();
- EOF
diff --git a/.github/workflows/close-ttek-issue.yaml b/.github/workflows/close-ttek-issue.yaml
deleted file mode 100644
index 037d6075..00000000
--- a/.github/workflows/close-ttek-issue.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: Auto-Close tteck Issues
-
-on:
- issues:
- types: [opened]
-
-jobs:
- close_tteck_issues:
- if: github.repository == 'community-scripts/ProxmoxVED'
- runs-on: ubuntu-latest
- steps:
- - name: Auto-close if tteck script detected
- uses: actions/github-script@v7
- with:
- script: |
- const issue = context.payload.issue;
- const content = `${issue.title}\n${issue.body}`;
- const issueNumber = issue.number;
-
- // Check for tteck script mention
- if (content.includes("tteck") || content.includes("tteck/Proxmox")) {
- const message = `Hello, it looks like you are referencing the **old tteck repo**.
-
- This repository is no longer used for active scripts.
- **Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com)
-
- Also make sure your Bash command starts with:
- \`\`\`bash
- bash <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/...)
- \`\`\`
-
- This issue is being closed automatically.`;
-
- await github.rest.issues.createComment({
- ...context.repo,
- issue_number: issueNumber,
- body: message
- });
-
- // Optionally apply a label like "not planned"
- await github.rest.issues.addLabels({
- ...context.repo,
- issue_number: issueNumber,
- labels: ["not planned"]
- });
-
- // Close the issue
- await github.rest.issues.update({
- ...context.repo,
- issue_number: issueNumber,
- state: "closed"
- });
- }
diff --git a/.github/workflows/live/changelog-pr.yml b/.github/workflows/live/changelog-pr.yml
deleted file mode 100644
index 87da5514..00000000
--- a/.github/workflows/live/changelog-pr.yml
+++ /dev/null
@@ -1,228 +0,0 @@
-name: Create Changelog Pull Request
-
-on:
- push:
- branches: ["main"]
- workflow_dispatch:
-
-jobs:
- update-changelog-pull-request:
- runs-on: ubuntu-latest
- env:
- CONFIG_PATH: .github/changelog-pr-config.json
- BRANCH_NAME: github-action-update-changelog
- AUTOMATED_PR_LABEL: "automated pr"
- permissions:
- contents: write
- pull-requests: write
- steps:
- - name: Generate a token
- id: generate-token
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ vars.APP_ID }}
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
- owner: community-scripts
- repositories: ProxmoxVED
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - name: Get latest dates in changelog
- run: |
- DATES=$(grep -E '^## [0-9]{4}-[0-9]{2}-[0-9]{2}' CHANGELOG.md | head -n 2 | awk '{print $2}')
-
- LATEST_DATE=$(echo "$DATES" | sed -n '1p')
- SECOND_LATEST_DATE=$(echo "$DATES" | sed -n '2p')
- TODAY=$(date -u +%Y-%m-%d)
-
- echo "TODAY=$TODAY" >> $GITHUB_ENV
- if [[ "$LATEST_DATE" == "$TODAY" ]]; then
- echo "LATEST_DATE=$SECOND_LATEST_DATE" >> $GITHUB_ENV
- else
- echo "LATEST_DATE=$LATEST_DATE" >> $GITHUB_ENV
- fi
-
- - name: Get categorized pull requests
- id: get-categorized-prs
- uses: actions/github-script@v7
- with:
- script: |
- const fs = require('fs').promises;
- const path = require('path');
-
- const configPath = path.resolve(process.env.CONFIG_PATH);
- const fileContent = await fs.readFile(configPath, 'utf-8');
- const changelogConfig = JSON.parse(fileContent);
-
- const categorizedPRs = changelogConfig.map(obj => ({
- ...obj,
- notes: [],
- subCategories: obj.subCategories ?? (
- obj.labels.includes("update script") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] }
- ] :
- obj.labels.includes("maintenance") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
- { title: "📡 API", labels: ["api"], notes: [] },
- { title: "Github", labels: ["github"], notes: [] }
- ] :
- obj.labels.includes("website") ? [
- { title: "🐞 Bug Fixes", labels: ["bugfix"], notes: [] },
- { title: "✨ New Features", labels: ["feature"], notes: [] },
- { title: "💥 Breaking Changes", labels: ["breaking change"], notes: [] },
- { title: "Script Information", labels: ["json"], notes: [] }
- ] : []
- )
- }));
-
- const latestDateInChangelog = new Date(process.env.LATEST_DATE);
- latestDateInChangelog.setUTCHours(23, 59, 59, 999);
-
- const { data: pulls } = await github.rest.pulls.list({
- owner: context.repo.owner,
- repo: context.repo.repo,
- base: "main",
- state: "closed",
- sort: "updated",
- direction: "desc",
- per_page: 100,
- });
-
- pulls.filter(pr =>
- pr.merged_at &&
- new Date(pr.merged_at) > latestDateInChangelog &&
- !pr.labels.some(label =>
- ["invalid", "wontdo", process.env.AUTOMATED_PR_LABEL].includes(label.name.toLowerCase())
- )
- ).forEach(pr => {
-
- const prLabels = pr.labels.map(label => label.name.toLowerCase());
- const prNote = `- ${pr.title} [@${pr.user.login}](https://github.com/${pr.user.login}) ([#${pr.number}](${pr.html_url}))`;
-
- const updateScriptsCategory = categorizedPRs.find(category =>
- category.labels.some(label => prLabels.includes(label))
- );
-
- if (updateScriptsCategory) {
-
- const subCategory = updateScriptsCategory.subCategories.find(sub =>
- sub.labels.some(label => prLabels.includes(label))
- );
-
- if (subCategory) {
- subCategory.notes.push(prNote);
- } else {
- updateScriptsCategory.notes.push(prNote);
- }
- }
- });
-
- console.log(JSON.stringify(categorizedPRs, null, 2));
-
- return categorizedPRs;
-
-
- - name: Update CHANGELOG.md
- uses: actions/github-script@v7
- with:
- script: |
- const fs = require('fs').promises;
- const path = require('path');
-
- const today = process.env.TODAY;
- const latestDateInChangelog = process.env.LATEST_DATE;
- const changelogPath = path.resolve('CHANGELOG.md');
- const categorizedPRs = ${{ steps.get-categorized-prs.outputs.result }};
-
- console.log(JSON.stringify(categorizedPRs, null, 2));
-
-
- let newReleaseNotes = `## ${today}\n\n`;
- for (const { title, notes, subCategories } of categorizedPRs) {
- const hasSubcategories = subCategories && subCategories.length > 0;
- const hasMainNotes = notes.length > 0;
- const hasSubNotes = hasSubcategories && subCategories.some(sub => sub.notes && sub.notes.length > 0);
-
-
- if (hasMainNotes || hasSubNotes) {
- newReleaseNotes += `### ${title}\n\n`;
- }
-
- if (hasMainNotes) {
- newReleaseNotes += ` ${notes.join("\n")}\n\n`;
- }
- if (hasSubcategories) {
- for (const { title: subTitle, notes: subNotes } of subCategories) {
- if (subNotes && subNotes.length > 0) {
- newReleaseNotes += ` - #### ${subTitle}\n\n`;
- newReleaseNotes += ` ${subNotes.join("\n ")}\n\n`;
- }
- }
- }
- }
-
- const changelogContent = await fs.readFile(changelogPath, 'utf-8');
- const changelogIncludesTodaysReleaseNotes = changelogContent.includes(`\n## ${today}`);
-
- const regex = changelogIncludesTodaysReleaseNotes
- ? new RegExp(`## ${today}.*(?=## ${latestDateInChangelog})`, "gs")
- : new RegExp(`(?=## ${latestDateInChangelog})`, "gs");
-
- const newChangelogContent = changelogContent.replace(regex, newReleaseNotes);
- await fs.writeFile(changelogPath, newChangelogContent);
-
- - name: Check for changes
- id: verify-diff
- run: |
- git diff --quiet . || echo "changed=true" >> $GITHUB_ENV
-
- - name: Commit and push changes
- if: env.changed == 'true'
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git add CHANGELOG.md
- git commit -m "Update CHANGELOG.md"
- git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME
- git push origin $BRANCH_NAME --force
-
- - name: Create pull request if not exists
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- run: |
- PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -z "$PR_EXISTS" ]; then
- gh pr create --title "[Github Action] Update CHANGELOG.md" \
- --body "This PR is auto-generated by a Github Action to update the CHANGELOG.md file." \
- --head $BRANCH_NAME \
- --base main \
- --label "$AUTOMATED_PR_LABEL"
- fi
-
- - name: Approve pull request
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- fi
-
- - name: Re-approve pull request after update
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- fi
diff --git a/.github/workflows/live/close-discussion.yml b/.github/workflows/live/close-discussion.yml
deleted file mode 100644
index 4b39fbf9..00000000
--- a/.github/workflows/live/close-discussion.yml
+++ /dev/null
@@ -1,122 +0,0 @@
-name: Close Discussion on PR Merge
-
-on:
- pull_request:
- types: [closed]
-
-jobs:
- close-discussion:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@v4
-
- - name: Set Up Node.js
- uses: actions/setup-node@v4
- with:
- node-version: "20"
- - name: Install Dependencies
- run: npm install zx @octokit/graphql
-
- - name: Close Discussion
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- PR_BODY: ${{ github.event.pull_request.body }}
- PR_NUMBER: ${{ github.event.pull_request.number }}
- REPO_OWNER: ${{ github.repository_owner }}
- REPO_NAME: ${{ github.event.repository.name }}
- run: |
- npx zx << 'EOF'
- import { graphql } from "@octokit/graphql";
- (async function() {
- try {
- const token = process.env.GITHUB_TOKEN;
- const prBody = process.env.PR_BODY;
- const prNumber = process.env.PR_NUMBER;
- const owner = process.env.REPO_OWNER;
- const repo = process.env.REPO_NAME;
-
- if (!token || !prBody || !prNumber || !owner || !repo) {
- console.log("Missing required environment variables.");
- process.exit(1);
- }
-
- const match = prBody.match(/#(\d+)/);
- if (!match) {
- console.log("No discussion ID found in PR body.");
- return;
- }
- const discussionNumber = match[1];
-
- console.log(`Extracted Discussion Number: ${discussionNumber}`);
- console.log(`PR Number: ${prNumber}`);
- console.log(`Repository: ${owner}/${repo}`);
-
- const graphqlWithAuth = graphql.defaults({
- headers: { authorization: `Bearer ${token}` },
- });
-
- const discussionQuery = `
- query($owner: String!, $repo: String!, $number: Int!) {
- repository(owner: $owner, name: $repo) {
- discussion(number: $number) {
- id
- }
- }
- }
- `;
-
- const discussionResponse = await graphqlWithAuth(discussionQuery, {
- owner,
- repo,
- number: parseInt(discussionNumber, 10),
- });
-
- const discussionQLId = discussionResponse.repository.discussion.id;
- if (!discussionQLId) {
- console.log("Failed to fetch discussion GraphQL ID.");
- return;
- }
-
- console.log(`GraphQL Discussion ID: ${discussionQLId}`);
-
- const commentMutation = `
- mutation($discussionId: ID!, $body: String!) {
- addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
- comment { id body }
- }
- }
- `;
-
- const commentResponse = await graphqlWithAuth(commentMutation, {
- discussionId: discussionQLId,
- body: `Merged with PR #${prNumber}`,
- });
-
- const commentId = commentResponse.addDiscussionComment.comment.id;
- if (!commentId) {
- console.log("Failed to post the comment.");
- return;
- }
-
- console.log(`Comment Posted Successfully! Comment ID: ${commentId}`);
-
- const markAnswerMutation = `
- mutation($id: ID!) {
- markDiscussionCommentAsAnswer(input: { id: $id }) {
- discussion { id title }
- }
- }
- `;
-
- await graphqlWithAuth(markAnswerMutation, { id: commentId });
-
- console.log("Comment marked as answer successfully!");
-
- } catch (error) {
- console.error("Error:", error);
- return;
- }
- })();
- EOF
\ No newline at end of file
diff --git a/.github/workflows/live/create-docker-for-runner.yml b/.github/workflows/live/create-docker-for-runner.yml
deleted file mode 100644
index c9fef0a5..00000000
--- a/.github/workflows/live/create-docker-for-runner.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Build and Publish Docker Image
-
-on:
- push:
- branches:
- - main
- paths:
- - '.github/runner/docker/**'
- schedule:
- - cron: '0 0 * * *'
-
-jobs:
- build:
- runs-on: ubuntu-latest #To ensure it always builds we use the github runner with all the right tooling
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v3
-
- - name: Log in to GHCR
- uses: docker/login-action@v2
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Build Docker image
- run: |
- repo_name=${{ github.repository }} # Get repository name
- repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
- docker build -t ghcr.io/$repo_name_lower/gh-runner-self:latest -f .github/runner/docker/gh-runner-self.dockerfile .
-
- - name: Push Docker image to GHCR
- run: |
- repo_name=${{ github.repository }} # Get repository name
- repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
- docker push ghcr.io/$repo_name_lower/gh-runner-self:latest
diff --git a/.github/workflows/live/delete-json-branch.yml b/.github/workflows/live/delete-json-branch.yml
deleted file mode 100644
index e4cdcf24..00000000
--- a/.github/workflows/live/delete-json-branch.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-name: Delete JSON date PR Branch
-
-on:
- pull_request:
- types: [closed]
- branches:
- - main
-
-jobs:
- delete_branch:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout the code
- uses: actions/checkout@v3
-
- - name: Delete PR Update Branch
- if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'pr-update-json-')
- run: |
- PR_BRANCH="${{ github.event.pull_request.head.ref }}"
- echo "Deleting branch $PR_BRANCH..."
-
- # Avoid deleting the default branch (e.g., main)
- if [[ "$PR_BRANCH" != "main" ]]; then
- git push origin --delete "$PR_BRANCH"
- else
- echo "Skipping deletion of the main branch"
- fi
\ No newline at end of file
diff --git a/.github/workflows/live/github-release.yml b/.github/workflows/live/github-release.yml
deleted file mode 100644
index 482d88a0..00000000
--- a/.github/workflows/live/github-release.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: Create Daily Release
-
-on:
- schedule:
- - cron: '1 0 * * *' # Runs daily at 00:01 UTC
- workflow_dispatch:
-
-jobs:
- create-daily-release:
- runs-on: ubuntu-latest
- permissions:
- contents: write
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Extract first 5000 characters from CHANGELOG.md
- run: head -c 5000 CHANGELOG.md > changelog_cropped.md
-
- - name: Debugging - Show extracted changelog
- run: |
- echo "=== CHANGELOG EXCERPT ==="
- cat changelog_cropped.md
- echo "========================="
-
- - name: Parse CHANGELOG.md and create release
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- YESTERDAY=$(date -u --date="yesterday" +%Y-%m-%d)
- echo "Checking for changes on: $YESTERDAY"
-
- # Ensure yesterday's date exists in the changelog
- if ! grep -q "## $YESTERDAY" changelog_cropped.md; then
- echo "No entry found for $YESTERDAY, skipping release."
- exit 0
- fi
-
- # Extract section for yesterday's date
- awk -v date="## $YESTERDAY" '
- $0 ~ date {found=1; next}
- found && /^## [0-9]{4}-[0-9]{2}-[0-9]{2}/ {exit}
- found
- ' changelog_cropped.md > changelog_tmp.md
-
- echo "=== Extracted Changelog ==="
- cat changelog_tmp.md
- echo "==========================="
-
- # Skip if no content was found
- if [ ! -s changelog_tmp.md ]; then
- echo "No changes found for $YESTERDAY, skipping release."
- exit 0
- fi
-
- # Create GitHub release
- gh release create "$YESTERDAY" -t "$YESTERDAY" -F changelog_tmp.md
diff --git a/.github/workflows/live/script-test.yml b/.github/workflows/live/script-test.yml
deleted file mode 100644
index 272a1272..00000000
--- a/.github/workflows/live/script-test.yml
+++ /dev/null
@@ -1,177 +0,0 @@
-name: Run Scripts on PVE Node for testing
-permissions:
- pull-requests: write
-on:
- pull_request_target:
- branches:
- - main
- paths:
- - 'install/**.sh'
- - 'ct/**.sh'
-
-jobs:
- run-install-script:
- runs-on: pvenode
- steps:
- - name: Checkout PR branch
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.ref }}
- repository: ${{ github.event.pull_request.head.repo.full_name }}
- fetch-depth: 0
-
- - name: Add Git safe directory
- run: |
- git config --global --add safe.directory /__w/ProxmoxVED/ProxmoxVE
-
- - name: Set up GH_TOKEN
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
-
- - name: Get Changed Files
- run: |
- CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
- CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
- echo "Changed files: $CHANGED_FILES"
- echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-
- - name: Get scripts
- id: check-install-script
- run: |
- ALL_FILES=()
- ADDED_FILES=()
- for FILE in ${{ env.SCRIPT }}; do
- if [[ $FILE =~ ^install/.*-install\.sh$ ]] || [[ $FILE =~ ^ct/.*\.sh$ ]]; then
- STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
- if [[ ! " ${ADDED_FILES[@]} " =~ " $STRIPPED_NAME " ]]; then
- ALL_FILES+=("$FILE")
- ADDED_FILES+=("$STRIPPED_NAME") # Mark this base file as added (without the path)
- fi
- fi
- done
- ALL_FILES=$(echo "${ALL_FILES[@]}" | xargs)
- echo "$ALL_FILES"
- echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV
-
- - name: Run scripts
- id: run-install
- continue-on-error: true
- run: |
- set +e
- #run for each files in /ct
- for FILE in ${{ env.ALL_FILES }}; do
- STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
- echo "Running Test for: $STRIPPED_NAME"
- if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "$FILE"; then
- echo "The script contains an interactive prompt. Skipping execution."
- continue
- fi
- if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
- CT_SCRIPT="ct/$STRIPPED_NAME.sh"
- if [[ ! -f $CT_SCRIPT ]]; then
- echo "No CT script found for $STRIPPED_NAME"
- ERROR_MSG="No CT script found for $FILE"
- echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
- continue
- fi
- if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "install/$STRIPPED_NAME-install.sh"; then
- echo "The script contains an interactive prompt. Skipping execution."
- continue
- fi
- echo "Found CT script for $STRIPPED_NAME"
- chmod +x "$CT_SCRIPT"
- RUNNING_FILE=$CT_SCRIPT
- elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
- INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
- if [[ ! -f $INSTALL_SCRIPT ]]; then
- echo "No install script found for $STRIPPED_NAME"
- ERROR_MSG="No install script found for $FILE"
- echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
- continue
- fi
- echo "Found install script for $STRIPPED_NAME"
- chmod +x "$INSTALL_SCRIPT"
- RUNNING_FILE=$FILE
- if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "ct/$STRIPPED_NAME.sh"; then
- echo "The script contains an interactive prompt. Skipping execution."
- continue
- fi
- fi
- git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
- git fetch community-scripts
- rm -f .github/workflows/scripts/app-test/pr-build.func || true
- rm -f .github/workflows/scripts/app-test/pr-install.func || true
- rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
- rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
- git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
- chmod +x $RUNNING_FILE
- chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
- chmod +x .github/workflows/scripts/app-test/pr-install.func
- chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
- chmod +x .github/workflows/scripts/app-test/pr-build.func
- sed -i 's|source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
- echo "Executing $RUNNING_FILE"
- ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
- echo "Finished running $FILE"
- if [ -n "$ERROR_MSG" ]; then
- echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
- echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
- fi
- done
- set -e # Restore exit-on-error
-
- - name: Cleanup PVE Node
- run: |
- containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}' | awk '{print $1}')
-
- for container_id in $containers; do
- status=$(pct status $container_id | awk '{print $2}')
- if [[ $status == "running" ]]; then
- pct stop $container_id
- pct destroy $container_id
- fi
- done
-
- - name: Post error comments
- run: |
- ERROR="false"
- SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 255:"
-
- # Get all existing comments on the PR
- EXISTING_COMMENTS=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '.comments[].body')
-
- for FILE in ${{ env.ALL_FILES }}; do
- STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
- if [[ ! -f result_$STRIPPED_NAME.log ]]; then
- continue
- fi
- ERROR_MSG=$(cat result_$STRIPPED_NAME.log)
-
- if [ -n "$ERROR_MSG" ]; then
- CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||")
- COMMENT_BODY=":warning: The script _**$FILE**_ failed with the following message:
${CLEANED_ERROR_MSG}
"
-
- # Check if the comment already exists
- if echo "$EXISTING_COMMENTS" | grep -qF "$COMMENT_BODY"; then
- echo "Skipping duplicate comment for $FILE"
- else
- echo "Posting error message for $FILE"
- gh pr comment ${{ github.event.pull_request.number }} \
- --repo ${{ github.repository }} \
- --body "$COMMENT_BODY"
- ERROR="true"
- fi
- fi
- done
-
- echo "ERROR=$ERROR" >> $GITHUB_ENV
-
-
diff --git a/.github/workflows/live/script_format.yml b/.github/workflows/live/script_format.yml
deleted file mode 100644
index c8ea7a4d..00000000
--- a/.github/workflows/live/script_format.yml
+++ /dev/null
@@ -1,243 +0,0 @@
-name: Script Format Check
-permissions:
- pull-requests: write
-on:
- pull_request_target:
- branches:
- - main
- paths:
- - 'install/*.sh'
- - 'ct/*.sh'
-
-jobs:
- run-install-script:
- runs-on: pvenode
- steps:
- - name: Checkout PR branch (supports forks)
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.ref }}
- repository: ${{ github.event.pull_request.head.repo.full_name }}
- fetch-depth: 0
-
- - name: Add Git safe directory
- run: |
- git config --global --add safe.directory /__w/ProxmoxVED/ProxmoxVE
-
- - name: Set up GH_TOKEN
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
-
- - name: Get Changed Files
- run: |
- CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
- CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
- echo "Changed files: $CHANGED_FILES"
- echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Check scripts
- id: run-install
- continue-on-error: true
- run: |
- for FILE in ${{ env.SCRIPT }}; do
- STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
- echo "Running Test for: $STRIPPED_NAME"
- FILE_STRIPPED="${FILE##*/}"
- LOG_FILE="result_$FILE_STRIPPED.log"
-
- if [[ $FILE =~ ^ct/.*\.sh$ ]]; then
-
- FIRST_LINE=$(sed -n '1p' "$FILE")
- [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
- SECOND_LINE=$(sed -n '2p' "$FILE")
- [[ "$SECOND_LINE" != "source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" ]] &&
- echo "Line 2 was $SECOND_LINE | Should be: source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)" >> "$LOG_FILE"
- THIRD_LINE=$(sed -n '3p' "$FILE")
- if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
- echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
- fi
-
- EXPECTED_AUTHOR="# Author:"
- EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE"
- EXPECTED_SOURCE="# Source:"
- EXPECTED_EMPTY=""
-
- for i in {4..7}; do
- LINE=$(sed -n "${i}p" "$FILE")
-
- case $i in
- 4)
- [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
- ;;
- 5)
- [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
- ;;
- 6)
- [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
- ;;
- 7)
- [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
- ;;
- esac
- done
-
-
- EXPECTED_PREFIXES=(
- "APP="
- "var_tags="
- "var_cpu=" # Must be a number
- "var_ram=" # Must be a number
- "var_disk=" # Must be a number
- "var_os=" # Must be debian, alpine, or ubuntu
- "var_version="
- "var_unprivileged=" # Must be 0 or 1
- )
-
-
- for i in {8..15}; do
- LINE=$(sed -n "${i}p" "$FILE")
- INDEX=$((i - 8))
-
- case $INDEX in
- 2|3|4) # var_cpu, var_ram, var_disk (must be numbers)
- if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then
- continue # Valid
- else
- echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
- fi
- ;;
- 5) # var_os (must be debian, alpine, or ubuntu)
- if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then
- continue # Valid
- else
- echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE"
- fi
- ;;
- 7) # var_unprivileged (must be 0 or 1)
- if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then
- continue # Valid
- else
- echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE"
- fi
- ;;
- *) # Other lines (must start with expected prefix)
- if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then
- continue # Valid
- else
- echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
- fi
- ;;
- esac
- done
-
- for i in {16..20}; do
- LINE=$(sed -n "${i}p" "$FILE")
- EXPECTED=(
- "header_info \"$APP\""
- "variables"
- "color"
- "catch_errors"
- "function update_script() {"
- )
- [[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE"
- done
- cat "$LOG_FILE"
- elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
-
- FIRST_LINE=$(sed -n '1p' "$FILE")
- [[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
-
- SECOND_LINE=$(sed -n '2p' "$FILE")
- [[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE"
-
- THIRD_LINE=$(sed -n '3p' "$FILE")
- if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
- echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2025 community-scripts ORG" >> "$LOG_FILE"
- fi
-
- EXPECTED_AUTHOR="# Author:"
- EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE"
- EXPECTED_SOURCE="# Source:"
- EXPECTED_EMPTY=""
-
- for i in {4..7}; do
- LINE=$(sed -n "${i}p" "$FILE")
-
- case $i in
- 4)
- [[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
- ;;
- 5)
- [[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
- ;;
- 6)
- [[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
- ;;
- 7)
- [[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
- ;;
- esac
- done
-
- [[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE"
-
- for i in {9..14}; do
- LINE=$(sed -n "${i}p" "$FILE")
- EXPECTED=(
- "color"
- "verb_ip6"
- "catch_errors"
- "setting_up_container"
- "network_check"
- "update_os"
- )
- [[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE"
- done
-
- [[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE"
- [[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE"
-
- LAST_3_LINES=$(tail -n 3 "$FILE")
- [[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE"
- [[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE"
- [[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE"
- cat "$LOG_FILE"
- fi
-
- done
-
-
- - name: Post error comments
- run: |
- ERROR="false"
- for FILE in ${{ env.SCRIPT }}; do
- FILE_STRIPPED="${FILE##*/}"
- LOG_FILE="result_$FILE_STRIPPED.log"
- echo $LOG_FILE
- if [[ ! -f $LOG_FILE ]]; then
- continue
- fi
- ERROR_MSG=$(cat $LOG_FILE)
-
- if [ -n "$ERROR_MSG" ]; then
- echo "Posting error message for $FILE"
- echo ${ERROR_MSG}
- gh pr comment ${{ github.event.pull_request.number }} \
- --repo ${{ github.repository }} \
- --body ":warning: The script _**$FILE**_ has the following formatting errors:
${ERROR_MSG}
"
-
-
- ERROR="true"
- fi
- done
- echo "ERROR=$ERROR" >> $GITHUB_ENV
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Fail if error
- if: ${{ env.ERROR == 'true' }}
- run: exit 1
diff --git a/.github/workflows/live/update-json-date.yml b/.github/workflows/live/update-json-date.yml
deleted file mode 100644
index 1bf965a4..00000000
--- a/.github/workflows/live/update-json-date.yml
+++ /dev/null
@@ -1,133 +0,0 @@
-name: Update JSON Date
-
-on:
- push:
- branches:
- - main
- paths:
- - 'json/**.json'
- workflow_dispatch:
-
-jobs:
- update-app-files:
- runs-on: ubuntu-latest
-
- permissions:
- contents: write
- pull-requests: write
-
- steps:
- - name: Generate a token
- id: generate-token
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ vars.APP_ID }}
- private-key: ${{ secrets.APP_PRIVATE_KEY }}
- owner: community-scripts
- repositories: ProxmoxVED
-
- - name: Generate dynamic branch name
- id: timestamp
- run: echo "BRANCH_NAME=pr-update-json-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
-
- - name: Set up GH_TOKEN
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
-
- - name: Checkout Repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 2 # Ensure we have the last two commits
-
- - name: Get Previous Commit
- id: prev_commit
- run: |
- PREV_COMMIT=$(git rev-parse HEAD^)
- echo "Previous commit: $PREV_COMMIT"
- echo "prev_commit=$PREV_COMMIT" >> $GITHUB_ENV
-
- - name: Get Newly Added JSON Files
- id: new_json_files
- run: |
- git diff --name-only --diff-filter=A ${{ env.prev_commit }} HEAD | grep '^json/.*\.json$' > new_files.txt || true
- echo "New files detected:"
- cat new_files.txt || echo "No new files."
-
- - name: Disable file mode changes
- run: git config core.fileMode false
-
- - name: Set up Git
- run: |
- git config --global user.name "GitHub Actions"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
-
- - name: Change JSON Date
- id: change-json-date
- run: |
- current_date=$(date +"%Y-%m-%d")
- while IFS= read -r file; do
- # Skip empty lines
- [[ -z "$file" ]] && continue
-
- if [[ -f "$file" ]]; then
- echo "Processing $file..."
- current_json_date=$(jq -r '.date_created // empty' "$file")
- if [[ -z "$current_json_date" || "$current_json_date" != "$current_date" ]]; then
- echo "Updating $file with date $current_date"
- jq --arg date "$current_date" '.date_created = $date' "$file" > temp.json && mv temp.json "$file"
- else
- echo "Date in $file is already up to date."
- fi
- else
- echo "Warning: File $file not found!"
- fi
- done < new_files.txt
- rm new_files.txt
-
- - name: Check if there are any changes
- run: |
- echo "Checking for changes..."
- git add -A # Untracked Dateien aufnehmen
- git status
- if git diff --cached --quiet; then
- echo "No changes detected."
- echo "changed=false" >> "$GITHUB_ENV"
- else
- echo "Changes detected:"
- git diff --stat --cached
- echo "changed=true" >> "$GITHUB_ENV"
- fi
-
- # Step 7: Commit and create PR if changes exist
- - name: Commit and create PR if changes exist
- if: env.changed == 'true'
- run: |
-
-
- git commit -m "Update date in json"
- git checkout -b ${{ env.BRANCH_NAME }}
- git push origin ${{ env.BRANCH_NAME }}
-
- gh pr create --title "[core] update date in json" \
- --body "This PR is auto-generated by a GitHub Action to update the date in json." \
- --head ${{ env.BRANCH_NAME }} \
- --base main \
- --label "automated pr"
- env:
- GH_TOKEN: ${{ steps.generate-token.outputs.token }}
-
- - name: Approve pull request
- if: env.changed == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- PR_NUMBER=$(gh pr list --head "${{ env.BRANCH_NAME }}" --json number --jq '.[].number')
- if [ -n "$PR_NUMBER" ]; then
- gh pr review $PR_NUMBER --approve
- fi
-
- - name: No changes detected
- if: env.changed == 'false'
- run: echo "No changes to commit. Workflow completed successfully."
diff --git a/.github/workflows/live/validate-filenames.yml b/.github/workflows/live/validate-filenames.yml
deleted file mode 100644
index 16f2f710..00000000
--- a/.github/workflows/live/validate-filenames.yml
+++ /dev/null
@@ -1,161 +0,0 @@
-name: Validate filenames
-
-on:
- pull_request_target:
- paths:
- - "ct/*.sh"
- - "install/*.sh"
- - "json/*.json"
-
-jobs:
- check-files:
- name: Check changed files
- runs-on: ubuntu-latest
- permissions:
- pull-requests: write
-
- steps:
- - name: Get pull request information
- if: github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- id: pr
- with:
- script: |
- const { data: pullRequest } = await github.rest.pulls.get({
- ...context.repo,
- pull_number: context.payload.pull_request.number,
- });
- return pullRequest;
-
- - name: Checkout code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Ensure the full history is fetched for accurate diffing
- ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }}
-
- - name: Get changed files
- id: changed-files
- run: |
- if ${{ github.event_name == 'pull_request_target' }}; then
- echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | xargs)" >> $GITHUB_OUTPUT
- else
- echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT
- fi
-
- - name: "Validate filenames in ct and install directory"
- if: always() && steps.changed-files.outputs.files != ''
- id: check-scripts
- run: |
- CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^(ct|install)/.*\.sh$' || true; })
-
- NON_COMPLIANT_FILES=""
- for FILE in $CHANGED_FILES; do
- # Datei "misc/create_lxc.sh" explizit überspringen
- if [[ "$FILE" == "misc/create_lxc.sh" ]]; then
- continue
- fi
- BASENAME=$(echo "$(basename "${FILE%.*}")")
- if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Non-compliant filenames found, change to lowercase:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: "Validate filenames in json directory."
- if: always() && steps.changed-files.outputs.files != ''
- id: check-json
- run: |
- CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^json/.*\.json$' || true; })
-
- NON_COMPLIANT_FILES=""
- for FILE in $CHANGED_FILES; do
- BASENAME=$(echo "$(basename "${FILE%.*}")")
- if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
- NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
- fi
- done
-
- if [ -n "$NON_COMPLIANT_FILES" ]; then
- echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
- echo "Non-compliant filenames found, change to lowercase:"
- for FILE in $NON_COMPLIANT_FILES; do
- echo "$FILE"
- done
- exit 1
- fi
-
- - name: Post results and comment
- if: always() && steps.check-scripts.outputs.files != '' && steps.check-json.outputs.files != '' && github.event_name == 'pull_request_target'
- uses: actions/github-script@v7
- with:
- script: |
- const result = "${{ job.status }}" === "success" ? "success" : "failure";
- const nonCompliantFiles = {
- script: "${{ steps.check-scripts.outputs.files }}",
- JSON: "${{ steps.check-json.outputs.files }}",
- };
-
- const issueNumber = context.payload.pull_request
- ? context.payload.pull_request.number
- : null;
- const commentIdentifier = "validate-filenames";
- let newCommentBody = `\n### Filename validation\n\n`;
-
- if (result === "failure") {
- newCommentBody += ":x: We found issues in the following changed files:\n\n";
- for (const [check, files] of Object.entries(nonCompliantFiles)) {
- if (files) {
- newCommentBody += `**${check.charAt(0).toUpperCase() + check.slice(1)} filename invalid:**\n${files
- .trim()
- .split(" ")
- .map((file) => `- ${file}`)
- .join("\n")}\n\n`;
- }
- }
- newCommentBody +=
- "Please change the filenames to lowercase and use only alphanumeric characters and dashes.\n";
- } else {
- newCommentBody += `:rocket: All files passed filename validation!\n`;
- }
-
- newCommentBody += `\n\n`;
-
- if (issueNumber) {
- const { data: comments } = await github.rest.issues.listComments({
- ...context.repo,
- issue_number: issueNumber,
- });
-
- const existingComment = comments.find(
- (comment) => comment.user.login === "github-actions[bot]",
- );
-
- if (existingComment) {
- if (existingComment.body.includes(commentIdentifier)) {
- const re = new RegExp(String.raw`[\s\S]*?`, "");
- newCommentBody = existingComment.body.replace(re, newCommentBody);
- } else {
- newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody;
- }
-
- await github.rest.issues.updateComment({
- ...context.repo,
- comment_id: existingComment.id,
- body: newCommentBody,
- });
- } else {
- await github.rest.issues.createComment({
- ...context.repo,
- issue_number: issueNumber,
- body: newCommentBody,
- });
- }
- }
From d51645e2ebce9da23ebcec92fb8875307723fe34 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 14:25:59 +0200
Subject: [PATCH 209/312] cleanup
---
ct/alpine-redlib.sh | 56 ----------
ct/healthchecks.sh | 70 -------------
frontend/public/json/healthchecks.json | 40 --------
frontend/public/json/redlib.json | 35 -------
install/alpine-redlib-install.sh | 98 ------------------
install/healthchecks-install.sh | 136 -------------------------
6 files changed, 435 deletions(-)
delete mode 100644 ct/alpine-redlib.sh
delete mode 100644 ct/healthchecks.sh
delete mode 100644 frontend/public/json/healthchecks.json
delete mode 100644 frontend/public/json/redlib.json
delete mode 100644 install/alpine-redlib-install.sh
delete mode 100644 install/healthchecks-install.sh
diff --git a/ct/alpine-redlib.sh b/ct/alpine-redlib.sh
deleted file mode 100644
index 88f9fd3d..00000000
--- a/ct/alpine-redlib.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: andrej-kocijan (Andrej Kocijan)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/redlib-org/redlib
-
-APP="Alpine-Redlib"
-var_tags="${var_tags:-alpine;frontend}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-512}"
-var_disk="${var_disk:-1}"
-var_os="${var_os:-alpine}"
-var_version="${var_version:-3.22}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_resources
-
- if [[ ! -d /opt/redlib ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- msg_info "Updating Alpine Packages"
- $STD apk -U upgrade
- msg_ok "Updated Alpine Packages"
-
- msg_info "Stopping ${APP} Service"
- $STD rc-service redlib stop
- msg_ok "Stopped ${APP} Service"
-
- fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
-
- msg_info "Starting ${APP} Service"
- $STD rc-service redlib start
- msg_ok "Started ${APP} Service"
-
- msg_ok "Update Successful"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:5252${CL}"
diff --git a/ct/healthchecks.sh b/ct/healthchecks.sh
deleted file mode 100644
index f8e5e45f..00000000
--- a/ct/healthchecks.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source:
-
-APP="healthchecks"
-var_tags="${var_tags:-monitoring}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-5}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-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/healthchecks ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- RELEASE=$(curl -fsSL https://api.github.com/repos/healthchecks/healthchecks/releases/latest | jq '.tag_name' | sed 's/^"v//;s/"$//')
- if [[ "${RELEASE}" != "$(cat ~/.healthchecks 2>/dev/null)" ]] || [[ ! -f ~/.healthchecks ]]; then
- msg_info "Stopping $APP"
- systemctl stop healthchecks
- msg_ok "Stopped $APP"
-
- setup_uv
- fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks"
-
- msg_info "Updating $APP to v${RELEASE}"
- cd /opt/healthchecks
- mkdir -p /opt/healthchecks/static-collected/
- $STD uv pip install wheel gunicorn -r requirements.txt --system
- $STD uv run -- python manage.py makemigrations
- $STD uv run -- python manage.py migrate --noinput
- $STD uv run -- python manage.py collectstatic --noinput
- $STD uv run -- python manage.py compress
- msg_ok "Updated $APP to v${RELEASE}"
-
- msg_info "Starting $APP"
- systemctl start healthchecks
- systemctl restart caddy
- msg_ok "Started $APP"
-
- msg_ok "Update Successful"
- else
- msg_ok "No update required. ${APP} is already at v${RELEASE}"
- 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 "${TAB}${GATEWAY}${BGN}https://${IP}${CL}"
diff --git a/frontend/public/json/healthchecks.json b/frontend/public/json/healthchecks.json
deleted file mode 100644
index a0187d17..00000000
--- a/frontend/public/json/healthchecks.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "Healthchecks",
- "slug": "healthchecks",
- "categories": [
- 9
- ],
- "date_created": "2025-08-25",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "config_path": "/opt/healthchecks/hc/local_settings.py",
- "interface_port": 3000,
- "documentation": "https://healthchecks.io/",
- "website": "https://healthchecks.io/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/healthchecks.webp",
- "description": "Healthchecks is a cron job monitoring service. It listens for HTTP requests and email messages (\"pings\") from your cron jobs and scheduled tasks (\"checks\"). When a ping does not arrive on time, Healthchecks sends out alerts. Healthchecks comes with a web dashboard, API, 25+ integrations for delivering notifications, monthly email reports, WebAuthn 2FA support, team management features: projects, team members, read-only access.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/healthchecks.sh",
- "resources": {
- "cpu": 2,
- "ram": 2048,
- "hdd": 5,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "if you change your LXC-IP, you need to update /etc/caddy/Caddyfile & /opt/healthchecks/hc/local_settings.py",
- "type": "info"
- }
- ]
-}
diff --git a/frontend/public/json/redlib.json b/frontend/public/json/redlib.json
deleted file mode 100644
index 215b190f..00000000
--- a/frontend/public/json/redlib.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "Redlib",
- "slug": "redlib",
- "categories": [
- 10
- ],
- "date_created": "2025-08-22",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 5252,
- "documentation": "https://github.com/redlib-org/redlib/blob/main/README.md",
- "website": "https://github.com/redlib-org/redlib",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/redlib.webp",
- "config_path": "/opt/redlib/redlib.conf",
- "description": "An alternative private front-end to Reddit. Redlib hopes to provide an easier way to browse Reddit, without the ads, trackers, and bloat.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/alpine-redlib.sh",
- "resources": {
- "cpu": 1,
- "ram": 512,
- "hdd": 1,
- "os": "alpine",
- "version": "3.22"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": []
-}
diff --git a/install/alpine-redlib-install.sh b/install/alpine-redlib-install.sh
deleted file mode 100644
index 0f717721..00000000
--- a/install/alpine-redlib-install.sh
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: andrej-kocijan (Andrej Kocijan)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/redlib-org/redlib
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
-
-msg_info "Configuring Redlib"
-cat </opt/redlib/redlib.conf
-############################################
-# Redlib Instance Configuration File
-# Uncomment and edit values as needed
-############################################
-
-## Instance settings
-ADDRESS=0.0.0.0
-PORT=5252 # Integer (0-65535) - Internal port
-#REDLIB_SFW_ONLY=off # ["on", "off"] - Filter all NSFW content
-#REDLIB_BANNER= # String - Displayed on instance info page
-#REDLIB_ROBOTS_DISABLE_INDEXING=off # ["on", "off"] - Disable search engine indexing
-#REDLIB_PUSHSHIFT_FRONTEND=undelete.pullpush.io # Pushshift frontend for removed links
-#REDLIB_ENABLE_RSS=off # ["on", "off"] - Enable RSS feed generation
-#REDLIB_FULL_URL= # String - Needed for proper RSS URLs
-
-## Default user settings
-#REDLIB_DEFAULT_THEME=system # Theme (system, light, dark, black, dracula, nord, laserwave, violet, gold, rosebox, gruvboxdark, gruvboxlight, tokyoNight, icebergDark, doomone, libredditBlack, libredditDark, libredditLight)
-#REDLIB_DEFAULT_FRONT_PAGE=default # ["default", "popular", "all"]
-#REDLIB_DEFAULT_LAYOUT=card # ["card", "clean", "compact"]
-#REDLIB_DEFAULT_WIDE=off # ["on", "off"]
-#REDLIB_DEFAULT_POST_SORT=hot # ["hot", "new", "top", "rising", "controversial"]
-#REDLIB_DEFAULT_COMMENT_SORT=confidence # ["confidence", "top", "new", "controversial", "old"]
-#REDLIB_DEFAULT_BLUR_SPOILER=off # ["on", "off"]
-#REDLIB_DEFAULT_SHOW_NSFW=off # ["on", "off"]
-#REDLIB_DEFAULT_BLUR_NSFW=off # ["on", "off"]
-#REDLIB_DEFAULT_USE_HLS=off # ["on", "off"]
-#REDLIB_DEFAULT_HIDE_HLS_NOTIFICATION=off # ["on", "off"]
-#REDLIB_DEFAULT_AUTOPLAY_VIDEOS=off # ["on", "off"]
-#REDLIB_DEFAULT_SUBSCRIPTIONS= # Example: sub1+sub2+sub3
-#REDLIB_DEFAULT_HIDE_AWARDS=off # ["on", "off"]
-#REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION=off # ["on", "off"]
-#REDLIB_DEFAULT_HIDE_SCORE=off # ["on", "off"]
-#REDLIB_DEFAULT_HIDE_SIDEBAR_AND_SUMMARY=off # ["on", "off"]
-#REDLIB_DEFAULT_FIXED_NAVBAR=on # ["on", "off"]
-#REDLIB_DEFAULT_REMOVE_DEFAULT_FEEDS=off # ["on", "off"]
-EOF
-msg_ok "Configured Redlib"
-
-msg_info "Creating Redlib Service"
-cat </etc/init.d/redlib
-#!/sbin/openrc-run
-
-name="Redlib"
-description="Redlib Service"
-command="/opt/redlib/redlib"
-pidfile="/run/redlib.pid"
-supervisor="supervise-daemon"
-command_background="yes"
-
-depend() {
- need net
-}
-
-start_pre() {
-
- set -a
- . /opt/redlib/redlib.conf
- set +a
-
- : ${ADDRESS:=0.0.0.0}
- : ${PORT:=5252}
-
- command_args="-a ${ADDRESS} -p ${PORT}"
-}
-EOF
-$STD chmod +x /etc/init.d/redlib
-$STD rc-update add redlib default
-msg_ok "Created Redlib Service"
-
-msg_info "Starting Redlib Service"
-$STD rc-service redlib start
-msg_ok "Started Redlib Service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apk cache clean
-msg_ok "Cleaned"
diff --git a/install/healthchecks-install.sh b/install/healthchecks-install.sh
deleted file mode 100644
index 2507149d..00000000
--- a/install/healthchecks-install.sh
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: MickLesk (Canbiz)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/getmaxun/maxun
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt-get install -y \
- gcc \
- libpq-dev \
- libcurl4-openssl-dev \
- libssl-dev \
- caddy
-msg_ok "Installed Dependencies"
-
-setup_uv
-PG_VERSION=16 setup_postgresql
-
-msg_info "Setup Database"
-DB_NAME=healthchecks_db
-DB_USER=hc_user
-DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
-SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"
-ADMIN_EMAIL="admin@helper-scripts.local"
-ADMIN_PASSWORD="$DB_PASS"
-
-$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
-{
- echo "healthchecks-Credentials"
- echo "healthchecks Database User: $DB_USER"
- echo "healthchecks Database Password: $DB_PASS"
- echo "healthchecks Database Name: $DB_NAME"
- echo "healthchecks Admin Email: $ADMIN_EMAIL"
- echo "healthchecks Admin Password: $ADMIN_PASSWORD"
-} >>~/healthchecks.creds
-msg_ok "Set up Database"
-
-fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks"
-
-msg_info "Setup healthchecks"
-cd /opt/healthchecks
-mkdir -p /opt/healthchecks/static-collected/
-$STD uv pip install wheel gunicorn -r requirements.txt --system
-
-LOCAL_IP=$(hostname -I | awk '{print $1}')
-cat </opt/healthchecks/hc/local_settings.py
-DEBUG = False
-
-ALLOWED_HOSTS = ["${LOCAL_IP}", "127.0.0.1", "localhost"]
-CSRF_TRUSTED_ORIGINS = ["http://${LOCAL_IP}", "https://${LOCAL_IP}"]
-
-SECRET_KEY = "${SECRET_KEY}"
-
-SITE_ROOT = "http://${LOCAL_IP}:8000"
-SITE_NAME = "MyChecks"
-DEFAULT_FROM_EMAIL = "healthchecks@${LOCAL_IP}"
-
-STATIC_ROOT = "/opt/healthchecks/static-collected"
-COMPRESS_OFFLINE = True
-
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.postgresql',
- 'NAME': '${DB_NAME}',
- 'USER': '${DB_USER}',
- 'PASSWORD': '${DB_PASS}',
- 'HOST': '127.0.0.1',
- 'PORT': '5432',
- 'TEST': {'CHARSET': 'UTF8'}
- }
-}
-EOF
-
-$STD uv run -- python manage.py makemigrations
-$STD uv run -- python manage.py migrate --noinput
-$STD uv run -- python manage.py collectstatic --noinput
-$STD uv run -- python manage.py compress
-
-cat </etc/caddy/Caddyfile
-{
- email admin@example.com
-}
-
-${LOCAL_IP} {
- reverse_proxy 127.0.0.1:8000
-}
-EOF
-msg_ok "Configured Caddy"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/healthchecks.service
-[Unit]
-Description=Healthchecks Service
-After=network.target postgresql.service
-
-[Service]
-WorkingDirectory=/opt/healthchecks/
-ExecStart=/usr/local/bin/uv run -- gunicorn hc.wsgi:application --bind 127.0.0.1:8000
-Restart=always
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now healthchecks caddy
-systemctl reload caddy
-msg_ok "Created Service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
From 3c3aabd21d265af99a8d13a455a5f3d0490a384e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 14:28:16 +0200
Subject: [PATCH 210/312] feat: expand logger with subshell-safe error handling
---
misc/alpine-install.func | 1 +
misc/api.func | 10 +++++
misc/build.func | 1 +
misc/core.func | 19 ++++++++-
misc/create_lxc.sh | 1 +
misc/install.func | 1 +
misc/logger.func | 88 ++++++++++++++++++++++++++++++++++++++++
7 files changed, 119 insertions(+), 2 deletions(-)
create mode 100644 misc/logger.func
diff --git a/misc/alpine-install.func b/misc/alpine-install.func
index 450e9209..660a3227 100644
--- a/misc/alpine-install.func
+++ b/misc/alpine-install.func
@@ -32,6 +32,7 @@ error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
+ log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
}
diff --git a/misc/api.func b/misc/api.func
index 08bdc914..58ea56e0 100644
--- a/misc/api.func
+++ b/misc/api.func
@@ -2,6 +2,16 @@
# Author: michelroegl-brunner
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
+if [[ -f "$(dirname "${BASH_SOURCE[0]}")/logger.func" ]]; then
+ source "$(dirname "${BASH_SOURCE[0]}")/logger.func"
+else
+ if command -v curl >/dev/null 2>&1; then
+ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
+ elif command -v wget >/dev/null 2>&1; then
+ source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
+ fi
+fi
+
get_error_description() {
local exit_code="$1"
case "$exit_code" in
diff --git a/misc/build.func b/misc/build.func
index 8a58664f..c2e78b58 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -43,6 +43,7 @@ error_handler() {
local line_number="$1"
local command="$2"
printf "\e[?25h"
+ log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command"
post_update_to_api "failed" "$command"
echo -e "\n$error_message\n"
diff --git a/misc/core.func b/misc/core.func
index 5df50efd..6ed1faf3 100644
--- a/misc/core.func
+++ b/misc/core.func
@@ -9,6 +9,16 @@
[[ -n "${_CORE_FUNC_LOADED:-}" ]] && return
_CORE_FUNC_LOADED=1
+if [[ -f "$(dirname "${BASH_SOURCE[0]}")/logger.func" ]]; then
+ source "$(dirname "${BASH_SOURCE[0]}")/logger.func"
+else
+ if command -v curl >/dev/null 2>&1; then
+ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
+ elif command -v wget >/dev/null 2>&1; then
+ source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
+ fi
+fi
+
load_functions() {
[[ -n "${__FUNCTIONS_LOADED:-}" ]] && return
__FUNCTIONS_LOADED=1
@@ -96,9 +106,9 @@ _tool_error_hint() {
# exit 143
# }
+# logger.func now sets strict modes and traps globally
catch_errors() {
- set -Eeuo pipefail
- trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
+ :
}
# ------------------------------------------------------------------------------
@@ -339,6 +349,7 @@ stop_spinner() {
msg_info() {
local msg="$1"
[[ -z "$msg" ]] && return
+ log_info "$msg"
if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then
declare -gA MSG_INFO_SHOWN=()
@@ -365,6 +376,7 @@ msg_info() {
msg_ok() {
local msg="$1"
[[ -z "$msg" ]] && return
+ log_info "$msg"
stop_spinner
clear_line
printf "%s %b\n" "$CM" "${GN}${msg}${CL}" >&2
@@ -374,12 +386,14 @@ msg_ok() {
msg_error() {
stop_spinner
local msg="$1"
+ log_error "$msg"
echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}"
}
msg_warn() {
stop_spinner
local msg="$1"
+ log_warn "$msg"
echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}"
}
@@ -395,6 +409,7 @@ msg_custom() {
function msg_debug() {
if [[ "${var_full_verbose:-0}" == "1" ]]; then
[[ "${var_verbose:-0}" != "1" ]] && var_verbose=1
+ log_debug "$*"
echo -e "${YWB}[$(date '+%F %T')] [DEBUG]${CL} $*"
fi
}
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 7a5d18cf..3ada6c96 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -36,6 +36,7 @@ function error_handler() {
local line_number="$1"
local command="$2"
printf "\e[?25h"
+ log_error "line $line_number: exit code $exit_code while executing command $command"
echo -e "\n${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\n"
exit "$exit_code"
}
diff --git a/misc/install.func b/misc/install.func
index e3751c29..f7ee6745 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -36,6 +36,7 @@ error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
+ log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message"
diff --git a/misc/logger.func b/misc/logger.func
new file mode 100644
index 00000000..0b929011
--- /dev/null
+++ b/misc/logger.func
@@ -0,0 +1,88 @@
+#!/usr/bin/env bash
+# Centralized logging utilities for Proxmox helper scripts
+# Provides log_* functions, stdout/stderr capture, and robust error handling.
+
+# Prevent multiple sourcing
+[[ -n "${_LOGGER_FUNC_LOADED:-}" ]] && return
+_LOGGER_FUNC_LOADED=1
+
+# ------------------------------------------------------------------------------
+# Shell options – fail fast and propagate ERR through subshells
+# ------------------------------------------------------------------------------
+set -o errexit -o nounset -o pipefail -o errtrace
+
+# ------------------------------------------------------------------------------
+# Logfile preparation
+# ------------------------------------------------------------------------------
+LOGDIR=${LOGDIR:-/var/log/proxmoxve}
+mkdir -p "$LOGDIR" 2>/dev/null || true
+
+SCRIPT_NAME="${SCRIPT_NAME:-$(basename "$0")}";
+RUN_ID="${RUN_ID:-$(date +%Y%m%d_%H%M%S)_$$}";
+LOGFILE="${LOGFILE:-$LOGDIR/${SCRIPT_NAME%.sh}_$RUN_ID.log}"
+
+LOG_LEVEL="${LOG_LEVEL:-INFO}"
+declare -A LEVELS=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3)
+
+# Preserve original stdout/stderr for terminal output
+exec 3>&1 4>&2
+
+log_msg() {
+ local level="$1"; shift
+ local msg="$*"
+ local ts
+ ts="$(date '+%Y-%m-%d %H:%M:%S')"
+ echo "[$ts] [$SCRIPT_NAME] [$level] $msg" >>"$LOGFILE"
+ if (( ${LEVELS[$level]} >= ${LEVELS[$LOG_LEVEL]} )); then
+ case "$level" in
+ DEBUG)
+ [[ "${var_full_verbose:-0}" -eq 1 ]] && echo -e "\033[36m[DEBUG]\033[0m $msg" >&3 ;;
+ INFO)
+ echo -e "\033[34m[INFO]\033[0m $msg" >&3 ;;
+ WARN)
+ echo -e "\033[33m[WARN]\033[0m $msg" >&3 ;;
+ ERROR)
+ echo -e "\033[31m[ERROR]\033[0m $msg" >&4 ;;
+ esac
+ fi
+}
+
+log_debug() { log_msg DEBUG "$*"; }
+log_info() { log_msg INFO "$*"; }
+log_warn() { log_msg WARN "$*"; }
+log_error() { log_msg ERROR "$*"; }
+
+# Backward compatible wrappers
+msg_info() { log_info "ℹ️ $*"; }
+msg_ok() { log_info "✅ $*"; }
+msg_warn() { log_warn "⚠️ $*"; }
+msg_error() { log_error "❌ $*"; }
+msg_debug() { log_debug "$*"; }
+
+# ------------------------------------------------------------------------------
+# Capture arbitrary stdout/stderr (including from subshells)
+# ------------------------------------------------------------------------------
+log_stream() {
+ local level="$1"
+ while IFS= read -r line; do
+ log_msg "$level" "$line"
+ done
+}
+
+# Redirect script output through logger
+exec > >(log_stream INFO) 2> >(log_stream ERROR)
+
+# ------------------------------------------------------------------------------
+# Error handler – logs failing command, line, and exits
+# ------------------------------------------------------------------------------
+error_handler() {
+ local code="$?"
+ local cmd="${BASH_COMMAND:-unknown}"
+ local line="${BASH_LINENO[0]:-unknown}"
+ local file="${BASH_SOURCE[1]:-unknown}"
+ log_error "command '$cmd' failed in $file:$line with exit code $code"
+ exit "$code"
+}
+
+trap error_handler ERR
+
From af46e22bd2e526ee8c8139838a196780592a8dfc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 14:30:28 +0200
Subject: [PATCH 211/312] Revert "feat: add centralized logging utilities"
---
misc/alpine-install.func | 1 -
misc/api.func | 10 -----
misc/build.func | 1 -
misc/core.func | 19 +--------
misc/create_lxc.sh | 1 -
misc/install.func | 1 -
misc/logger.func | 88 ----------------------------------------
7 files changed, 2 insertions(+), 119 deletions(-)
delete mode 100644 misc/logger.func
diff --git a/misc/alpine-install.func b/misc/alpine-install.func
index 660a3227..450e9209 100644
--- a/misc/alpine-install.func
+++ b/misc/alpine-install.func
@@ -32,7 +32,6 @@ error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
- log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message\n"
}
diff --git a/misc/api.func b/misc/api.func
index 58ea56e0..08bdc914 100644
--- a/misc/api.func
+++ b/misc/api.func
@@ -2,16 +2,6 @@
# Author: michelroegl-brunner
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
-if [[ -f "$(dirname "${BASH_SOURCE[0]}")/logger.func" ]]; then
- source "$(dirname "${BASH_SOURCE[0]}")/logger.func"
-else
- if command -v curl >/dev/null 2>&1; then
- source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
- elif command -v wget >/dev/null 2>&1; then
- source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
- fi
-fi
-
get_error_description() {
local exit_code="$1"
case "$exit_code" in
diff --git a/misc/build.func b/misc/build.func
index c2e78b58..8a58664f 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -43,7 +43,6 @@ error_handler() {
local line_number="$1"
local command="$2"
printf "\e[?25h"
- log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="[ERROR] in line $line_number: exit code $exit_code: while executing command $command"
post_update_to_api "failed" "$command"
echo -e "\n$error_message\n"
diff --git a/misc/core.func b/misc/core.func
index 6ed1faf3..5df50efd 100644
--- a/misc/core.func
+++ b/misc/core.func
@@ -9,16 +9,6 @@
[[ -n "${_CORE_FUNC_LOADED:-}" ]] && return
_CORE_FUNC_LOADED=1
-if [[ -f "$(dirname "${BASH_SOURCE[0]}")/logger.func" ]]; then
- source "$(dirname "${BASH_SOURCE[0]}")/logger.func"
-else
- if command -v curl >/dev/null 2>&1; then
- source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
- elif command -v wget >/dev/null 2>&1; then
- source <(wget -qO- https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/logger.func)
- fi
-fi
-
load_functions() {
[[ -n "${__FUNCTIONS_LOADED:-}" ]] && return
__FUNCTIONS_LOADED=1
@@ -106,9 +96,9 @@ _tool_error_hint() {
# exit 143
# }
-# logger.func now sets strict modes and traps globally
catch_errors() {
- :
+ set -Eeuo pipefail
+ trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# ------------------------------------------------------------------------------
@@ -349,7 +339,6 @@ stop_spinner() {
msg_info() {
local msg="$1"
[[ -z "$msg" ]] && return
- log_info "$msg"
if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then
declare -gA MSG_INFO_SHOWN=()
@@ -376,7 +365,6 @@ msg_info() {
msg_ok() {
local msg="$1"
[[ -z "$msg" ]] && return
- log_info "$msg"
stop_spinner
clear_line
printf "%s %b\n" "$CM" "${GN}${msg}${CL}" >&2
@@ -386,14 +374,12 @@ msg_ok() {
msg_error() {
stop_spinner
local msg="$1"
- log_error "$msg"
echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}"
}
msg_warn() {
stop_spinner
local msg="$1"
- log_warn "$msg"
echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}"
}
@@ -409,7 +395,6 @@ msg_custom() {
function msg_debug() {
if [[ "${var_full_verbose:-0}" == "1" ]]; then
[[ "${var_verbose:-0}" != "1" ]] && var_verbose=1
- log_debug "$*"
echo -e "${YWB}[$(date '+%F %T')] [DEBUG]${CL} $*"
fi
}
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 3ada6c96..7a5d18cf 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -36,7 +36,6 @@ function error_handler() {
local line_number="$1"
local command="$2"
printf "\e[?25h"
- log_error "line $line_number: exit code $exit_code while executing command $command"
echo -e "\n${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\n"
exit "$exit_code"
}
diff --git a/misc/install.func b/misc/install.func
index f7ee6745..e3751c29 100644
--- a/misc/install.func
+++ b/misc/install.func
@@ -36,7 +36,6 @@ error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
- log_error "line $line_number: exit code $exit_code while executing command $command"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
echo -e "\n$error_message"
diff --git a/misc/logger.func b/misc/logger.func
deleted file mode 100644
index 0b929011..00000000
--- a/misc/logger.func
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-# Centralized logging utilities for Proxmox helper scripts
-# Provides log_* functions, stdout/stderr capture, and robust error handling.
-
-# Prevent multiple sourcing
-[[ -n "${_LOGGER_FUNC_LOADED:-}" ]] && return
-_LOGGER_FUNC_LOADED=1
-
-# ------------------------------------------------------------------------------
-# Shell options – fail fast and propagate ERR through subshells
-# ------------------------------------------------------------------------------
-set -o errexit -o nounset -o pipefail -o errtrace
-
-# ------------------------------------------------------------------------------
-# Logfile preparation
-# ------------------------------------------------------------------------------
-LOGDIR=${LOGDIR:-/var/log/proxmoxve}
-mkdir -p "$LOGDIR" 2>/dev/null || true
-
-SCRIPT_NAME="${SCRIPT_NAME:-$(basename "$0")}";
-RUN_ID="${RUN_ID:-$(date +%Y%m%d_%H%M%S)_$$}";
-LOGFILE="${LOGFILE:-$LOGDIR/${SCRIPT_NAME%.sh}_$RUN_ID.log}"
-
-LOG_LEVEL="${LOG_LEVEL:-INFO}"
-declare -A LEVELS=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3)
-
-# Preserve original stdout/stderr for terminal output
-exec 3>&1 4>&2
-
-log_msg() {
- local level="$1"; shift
- local msg="$*"
- local ts
- ts="$(date '+%Y-%m-%d %H:%M:%S')"
- echo "[$ts] [$SCRIPT_NAME] [$level] $msg" >>"$LOGFILE"
- if (( ${LEVELS[$level]} >= ${LEVELS[$LOG_LEVEL]} )); then
- case "$level" in
- DEBUG)
- [[ "${var_full_verbose:-0}" -eq 1 ]] && echo -e "\033[36m[DEBUG]\033[0m $msg" >&3 ;;
- INFO)
- echo -e "\033[34m[INFO]\033[0m $msg" >&3 ;;
- WARN)
- echo -e "\033[33m[WARN]\033[0m $msg" >&3 ;;
- ERROR)
- echo -e "\033[31m[ERROR]\033[0m $msg" >&4 ;;
- esac
- fi
-}
-
-log_debug() { log_msg DEBUG "$*"; }
-log_info() { log_msg INFO "$*"; }
-log_warn() { log_msg WARN "$*"; }
-log_error() { log_msg ERROR "$*"; }
-
-# Backward compatible wrappers
-msg_info() { log_info "ℹ️ $*"; }
-msg_ok() { log_info "✅ $*"; }
-msg_warn() { log_warn "⚠️ $*"; }
-msg_error() { log_error "❌ $*"; }
-msg_debug() { log_debug "$*"; }
-
-# ------------------------------------------------------------------------------
-# Capture arbitrary stdout/stderr (including from subshells)
-# ------------------------------------------------------------------------------
-log_stream() {
- local level="$1"
- while IFS= read -r line; do
- log_msg "$level" "$line"
- done
-}
-
-# Redirect script output through logger
-exec > >(log_stream INFO) 2> >(log_stream ERROR)
-
-# ------------------------------------------------------------------------------
-# Error handler – logs failing command, line, and exits
-# ------------------------------------------------------------------------------
-error_handler() {
- local code="$?"
- local cmd="${BASH_COMMAND:-unknown}"
- local line="${BASH_LINENO[0]:-unknown}"
- local file="${BASH_SOURCE[1]:-unknown}"
- log_error "command '$cmd' failed in $file:$line with exit code $code"
- exit "$code"
-}
-
-trap error_handler ERR
-
From 0c903faa0b2c86fb32c648d679d8571ef3c4b391 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:23:51 +0200
Subject: [PATCH 212/312] Enhance .env setup with reverse proxy guidance
Updated .env configuration with comments for clarity.
---
install/tracktor-install.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/install/tracktor-install.sh b/install/tracktor-install.sh
index 00c6c1d7..6ec206ea 100644
--- a/install/tracktor-install.sh
+++ b/install/tracktor-install.sh
@@ -26,7 +26,8 @@ cat </opt/tracktor/app/backend/.env
NODE_ENV=production
PUBLIC_DEMO_MODE=false
DB_PATH=/opt/tracktor-data/tracktor.db
-PUBLIC_API_BASE_URL=http://$HOST_IP:3000
+PUBLIC_API_BASE_URL=http://$HOST_IP:3000 # Replace this URL if using behind reverse proxy for https traffic. Though it is optional and should work without changing
+CORS_ORIGINS=http://$HOST_IP:3000 # Here add the reverse proxy url as well to avoid cross errors from the app.
PORT=3000
EOF
msg_ok "Configured Tracktor"
From b4446368645f76d92ba3b362fd1f3291a8e18afd Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:29:43 +0200
Subject: [PATCH 213/312] Update create_lxc.sh
---
misc/create_lxc.sh | 201 +++++++++++++++++++++++++++------------------
1 file changed, 119 insertions(+), 82 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 7a5d18cf..c89e5d72 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -205,7 +205,6 @@ if qm status "$CTID" &>/dev/null || pct status "$CTID" &>/dev/null; then
fi
# This checks for the presence of valid Container Storage and Template Storage locations
-msg_info "Validating storage"
if ! check_storage_support "rootdir"; then
msg_error "No valid storage found for 'rootdir' [Container]"
exit 1
@@ -280,158 +279,196 @@ fi
# Update LXC template list
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
case "$PCT_OSTYPE" in
-debian | ubuntu)
- TEMPLATE_PATTERN="-standard_"
- ;;
-alpine | fedora | rocky | centos)
- TEMPLATE_PATTERN="-default_"
- ;;
-*)
- TEMPLATE_PATTERN=""
- ;;
+debian | ubuntu) TEMPLATE_PATTERN="-standard_" ;;
+alpine | fedora | rocky | centos) TEMPLATE_PATTERN="-default_" ;;
+*) TEMPLATE_PATTERN="" ;;
esac
-# 1. Check local templates first
msg_info "Searching for template '$TEMPLATE_SEARCH'"
-mapfile -t TEMPLATES < <(
- pveam list "$TEMPLATE_STORAGE" |
+
+# 1. get / check local templates
+mapfile -t LOCAL_TEMPLATES < <(
+ pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v s="$TEMPLATE_SEARCH" -v p="$TEMPLATE_PATTERN" '$1 ~ s && $1 ~ p {print $1}' |
sed 's/.*\///' | sort -t - -k 2 -V
)
-if [ ${#TEMPLATES[@]} -gt 0 ]; then
+# 2. get online templates
+pveam update >/dev/null 2>&1 || msg_warn "Could not update template catalog (pveam update failed)."
+mapfile -t ONLINE_TEMPLATES < <(
+ pveam available -section system 2>/dev/null |
+ sed -n "s/.*\($TEMPLATE_SEARCH.*$TEMPLATE_PATTERN.*\)/\1/p" |
+ sort -t - -k 2 -V
+)
+ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]:-}"
+
+# 3. Local vs Online
+if [ ${#LOCAL_TEMPLATES[@]} -gt 0 ]; then
+ TEMPLATE="${LOCAL_TEMPLATES[-1]}"
TEMPLATE_SOURCE="local"
else
- msg_info "No local template found, checking online repository"
- pveam update >/dev/null 2>&1
- mapfile -t TEMPLATES < <(
- pveam update >/dev/null 2>&1 &&
- pveam available -section system |
- sed -n "s/.*\($TEMPLATE_SEARCH.*$TEMPLATE_PATTERN.*\)/\1/p" |
- sort -t - -k 2 -V
- )
+ TEMPLATE="$ONLINE_TEMPLATE"
TEMPLATE_SOURCE="online"
fi
-TEMPLATE="${TEMPLATES[-1]}"
-TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null ||
- echo "/var/lib/vz/template/cache/$TEMPLATE")"
-msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
-
-msg_debug "TEMPLATE_SEARCH=$TEMPLATE_SEARCH"
-msg_debug "TEMPLATES=(${TEMPLATES[*]})"
-msg_debug "Selected TEMPLATE=$TEMPLATE"
-msg_debug "TEMPLATE_PATH=$TEMPLATE_PATH"
-
-# 4. Validate template (exists & not corrupted)
-TEMPLATE_VALID=1
-if [ ! -s "$TEMPLATE_PATH" ]; then
- TEMPLATE_VALID=0
-elif ! tar --use-compress-program=zstdcat -tf "$TEMPLATE_PATH" >/dev/null 2>&1; then
- TEMPLATE_VALID=0
+# 4. Getting Path (universal, also for nfs/cifs)
+TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || true)"
+if [[ -z "$TEMPLATE_PATH" ]]; then
+ TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg)
+ if [[ -n "$TEMPLATE_BASE" ]]; then
+ TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE"
+ fi
fi
-if [ "$TEMPLATE_VALID" -eq 0 ]; then
- msg_warn "Template $TEMPLATE is missing or corrupted. Re-downloading."
+if [[ -z "$TEMPLATE_PATH" ]]; then
+ msg_error "Unable to resolve template path for $TEMPLATE_STORAGE. Check storage type and permissions."
+ exit 220
+fi
+
+msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
+msg_debug "Resolved TEMPLATE_PATH=$TEMPLATE_PATH"
+
+# 5. Validation
+NEED_DOWNLOAD=0
+if [[ ! -f "$TEMPLATE_PATH" ]]; then
+ msg_info "Template not present locally – will download."
+ NEED_DOWNLOAD=1
+elif [[ ! -r "$TEMPLATE_PATH" ]]; then
+ msg_error "Template file exists but is not readable – check permissions."
+ exit 221
+elif [[ "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
+ msg_warn "Template file too small (<1MB) – re-downloading."
+ NEED_DOWNLOAD=1
+elif ! zstdcat "$TEMPLATE_PATH" | tar -tf - &>/dev/null; then
+ msg_warn "Template appears corrupted – re-downloading."
+ NEED_DOWNLOAD=1
+else
+ msg_ok "Template $TEMPLATE is present and valid."
+fi
+
+# 6. Update-Check (if local exist)
+if [[ "$TEMPLATE_SOURCE" == "local" && -n "$ONLINE_TEMPLATE" && "$TEMPLATE" != "$ONLINE_TEMPLATE" ]]; then
+ msg_warn "Local template is outdated: $TEMPLATE (latest available: $ONLINE_TEMPLATE)"
+ if whiptail --yesno "A newer template is available:\n$ONLINE_TEMPLATE\n\nDo you want to download and use it instead?" 12 70; then
+ TEMPLATE="$ONLINE_TEMPLATE"
+ NEED_DOWNLOAD=1
+ else
+ msg_info "Continuing with local template $TEMPLATE"
+ fi
+fi
+
+# 7. Download if needed
+if [[ "$NEED_DOWNLOAD" -eq 1 ]]; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
for attempt in {1..3}; do
- msg_info "Attempt $attempt: Downloading LXC template..."
+ msg_info "Attempt $attempt: Downloading template $TEMPLATE to $TEMPLATE_STORAGE"
if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then
msg_ok "Template download successful."
break
fi
if [ $attempt -eq 3 ]; then
- msg_error "Failed after 3 attempts. Please check network access or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE"
- exit 208
+ msg_error "Failed after 3 attempts. Please check network access, permissions, or manually run:\n pveam download $TEMPLATE_STORAGE $TEMPLATE"
+ exit 222
fi
sleep $((attempt * 5))
done
fi
-msg_info "Creating LXC Container"
-# Check and fix subuid/subgid
+# 8. Final Check – Template usability
+if ! pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$TEMPLATE"; then
+ msg_error "Template $TEMPLATE not available in storage $TEMPLATE_STORAGE after download."
+ exit 223
+fi
+msg_ok "Template $TEMPLATE is ready for container creation."
+
+# ------------------------------------------------------------------------------
+# Create LXC Container with validation, recovery and debug option
+# ------------------------------------------------------------------------------
+
+msg_info "Creating LXC container"
+
+# Ensure subuid/subgid entries exist
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
-# Combine all options
+# Assemble pct options
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
-# Secure creation of the LXC container with lock and template check
+# Secure with lockfile
lockfile="/tmp/template.${TEMPLATE}.lock"
-msg_debug "Creating lockfile: $lockfile"
exec 9>"$lockfile" || {
msg_error "Failed to create lock file '$lockfile'."
exit 200
}
flock -w 60 9 || {
- msg_error "Timeout while waiting for template lock"
+ msg_error "Timeout while waiting for template lock."
exit 211
}
+LOGFILE="/tmp/pct_create_${CTID}.log"
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
+msg_debug "Logfile: $LOGFILE"
-if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
+# First attempt
+if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >"$LOGFILE" 2>&1; then
msg_error "Container creation failed on ${TEMPLATE_STORAGE}. Checking template..."
+ # Validate template file
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
- msg_error "Template file too small or missing – re-downloading."
+ msg_warn "Template file too small or missing – re-downloading."
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
elif ! zstdcat "$TEMPLATE_PATH" | tar -tf - &>/dev/null; then
- msg_error "Template appears to be corrupted – re-downloading."
+ msg_warn "Template appears corrupted – re-downloading."
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
- else
- # --- NEW FALLBACK LOGIC ---
+ fi
+
+ # Retry after repair
+ if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
+ # Fallback to local storage
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
- msg_warn "Retrying container creation with fallback to local template storage..."
+ msg_warn "Retrying container creation with fallback to local storage..."
LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if [ ! -f "$LOCAL_TEMPLATE_PATH" ]; then
msg_info "Downloading template to local..."
- msg_debug "pveam download local $TEMPLATE"
- pveam download local "$TEMPLATE"
+ pveam download local "$TEMPLATE" >/dev/null 2>&1
fi
- msg_debug "pct create command (fallback): pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}"
- if pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
- msg_ok "Container successfully created using fallback to local template storage."
+ if pct create "$CTID" "local:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" >>"$LOGFILE" 2>&1; then
+ msg_ok "Container successfully created using local fallback."
else
- msg_error "Container creation failed even with fallback to local."
+ msg_error "Container creation failed even with local fallback. See $LOGFILE"
+ # Ask user if they want debug output
+ if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
+ set -x
+ bash -x -c "pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}" 2>&1 | tee -a "$LOGFILE"
+ set +x
+ fi
exit 209
fi
- # Skip remaining error handling since fallback worked
- continue
else
- msg_error "Template is valid, but container creation still failed on local."
+ msg_error "Container creation failed on local storage. See $LOGFILE"
+ if whiptail --yesno "pct create failed.\nDo you want to enable verbose debug mode and view detailed logs?" 12 70; then
+ set -x
+ bash -x -c "pct create $CTID local:vztmpl/${TEMPLATE} ${PCT_OPTIONS[*]}" 2>&1 | tee -a "$LOGFILE"
+ set +x
+ fi
exit 209
fi
fi
fi
+# Verify container exists
if ! pct list | awk '{print $1}' | grep -qx "$CTID"; then
- msg_error "Container ID $CTID not listed in 'pct list' – unexpected failure."
+ msg_error "Container ID $CTID not listed in 'pct list'. See $LOGFILE"
exit 215
fi
+# Verify config rootfs
if ! grep -q '^rootfs:' "/etc/pve/lxc/$CTID.conf"; then
- msg_error "RootFS entry missing in container config – storage not correctly assigned."
+ msg_error "RootFS entry missing in container config. See $LOGFILE"
exit 216
fi
-if grep -q '^hostname:' "/etc/pve/lxc/$CTID.conf"; then
- CT_HOSTNAME=$(grep '^hostname:' "/etc/pve/lxc/$CTID.conf" | awk '{print $2}')
- if [[ ! "$CT_HOSTNAME" =~ ^[a-z0-9-]+$ ]]; then
- msg_warn "Hostname '$CT_HOSTNAME' contains invalid characters – may cause issues with networking or DNS."
- fi
-fi
-
-if [[ "${PCT_RAM_SIZE:-2048}" -lt 1024 ]]; then
- msg_warn "Configured RAM (${PCT_RAM_SIZE}MB) is below 1024MB – some apps may not work properly."
-fi
-
-# comment out 19.08.2025 - PCT Options not correct, message every new lxc (without fuse too)
-# if [[ "${PCT_UNPRIVILEGED:-1}" == "1" && " ${PCT_OPTIONS[*]} " == *"fuse=1"* ]]; then
-# msg_warn "Unprivileged container with FUSE may fail unless extra device mappings are configured."
-# fi
-
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
From 1e602015b9710ca72266b48157467652ae8079b8 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:36:39 +0200
Subject: [PATCH 214/312] improve sleep
---
misc/build.func | 1 +
1 file changed, 1 insertion(+)
diff --git a/misc/build.func b/misc/build.func
index 8a58664f..fcf81c1f 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1363,6 +1363,7 @@ EOF
if [ "$var_os" != "alpine" ]; then
msg_info "Waiting for network in LXC container"
+ sleep 2
for i in {1..10}; do
# 1. Primary check: ICMP ping (fastest, but may be blocked by ISP/firewall)
if pct exec "$CTID" -- ping -c1 -W1 deb.debian.org >/dev/null 2>&1; then
From e9b7ded215e4d4463096e83f05c2984fa3c3d31e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:37:19 +0200
Subject: [PATCH 215/312] silent sleep for 3 steps
---
misc/build.func | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index fcf81c1f..011f4398 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1372,8 +1372,12 @@ EOF
fi
# Wait and retry if not reachable yet
if [ "$i" -lt 10 ]; then
- msg_warn "No network in LXC yet (try $i/10) – waiting..."
- sleep 3
+ if [ "$i" -le 3 ]; then
+ sleep 2
+ else
+ msg_warn "No network in LXC yet (try $i/10) – waiting..."
+ sleep 3
+ fi
else
# After 10 unsuccessful ping attempts, try HTTP connectivity via wget as fallback
msg_warn "Ping failed 10 times. Trying HTTP connectivity check (wget) as fallback..."
From d2cafebcd928403d1a5d07b9a44fda5c673aefc0 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:39:50 +0200
Subject: [PATCH 216/312] mariadb fallback if repo down
---
misc/tools.func | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/misc/tools.func b/misc/tools.func
index 1413c26c..96c27a30 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -299,7 +299,19 @@ setup_mariadb() {
echo "mariadb-server-$ver mariadb-server/feedback boolean false" | debconf-set-selections
done
fi
- DEBIAN_FRONTEND=noninteractive $STD apt-get install -y mariadb-server mariadb-client
+ DEBIAN_FRONTEND=noninteractive $STD apt-get install -y mariadb-server mariadb-client || {
+ msg_warn "Failed to install MariaDB ${MARIADB_VERSION} from upstream repo – trying distro package as fallback..."
+ # Cleanup, remove upstream repo to avoid conflicts
+ rm -f /etc/apt/sources.list.d/mariadb.list /etc/apt/trusted.gpg.d/mariadb.gpg
+ $STD apt-get update
+ # Final fallback: distro package
+ DEBIAN_FRONTEND=noninteractive $STD apt-get install -y mariadb-server mariadb-client || {
+ msg_error "MariaDB installation failed even with distro fallback!"
+ return 1
+ }
+ msg_ok "Setup MariaDB (distro fallback)"
+ return 0
+ }
msg_ok "Setup MariaDB $MARIADB_VERSION"
}
From 92e50a143850f9bcacf87d70e5cf3ec1a29f7d64 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 15:42:37 +0200
Subject: [PATCH 217/312] Update leantime-install.sh
---
install/leantime-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/leantime-install.sh b/install/leantime-install.sh
index ff358010..086157c8 100644
--- a/install/leantime-install.sh
+++ b/install/leantime-install.sh
@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
-PHP_VERSION=8.4 PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
+PHP_VERSION="8.4" PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
setup_mariadb
msg_info "Setting up Database"
From 36db41530af3033effa94253a630d75fc4971ed4 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Mon, 25 Aug 2025 16:39:42 +0200
Subject: [PATCH 218/312] Improve comments in tracktor-install.sh
Updated comments for clarity in environment variable configuration.
---
install/tracktor-install.sh | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/install/tracktor-install.sh b/install/tracktor-install.sh
index 6ec206ea..d0d432d9 100644
--- a/install/tracktor-install.sh
+++ b/install/tracktor-install.sh
@@ -26,8 +26,10 @@ cat </opt/tracktor/app/backend/.env
NODE_ENV=production
PUBLIC_DEMO_MODE=false
DB_PATH=/opt/tracktor-data/tracktor.db
-PUBLIC_API_BASE_URL=http://$HOST_IP:3000 # Replace this URL if using behind reverse proxy for https traffic. Though it is optional and should work without changing
-CORS_ORIGINS=http://$HOST_IP:3000 # Here add the reverse proxy url as well to avoid cross errors from the app.
+# Replace this URL if using behind reverse proxy for https traffic. Though it is optional and should work without changing
+PUBLIC_API_BASE_URL=http://$HOST_IP:3000
+# Here add the reverse proxy url as well to avoid cross errors from the app.
+CORS_ORIGINS=http://$HOST_IP:3000
PORT=3000
EOF
msg_ok "Configured Tracktor"
From f295102e72549b00fae53e98faf516cf01b9bcea Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Mon, 25 Aug 2025 16:42:21 +0200
Subject: [PATCH 219/312] Add note about updating .env file for reverse proxy
Added informational note regarding reverse proxy configuration.
---
frontend/public/json/tracktor.json | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/frontend/public/json/tracktor.json b/frontend/public/json/tracktor.json
index 2d7d0a07..0a8f7c3b 100644
--- a/frontend/public/json/tracktor.json
+++ b/frontend/public/json/tracktor.json
@@ -31,5 +31,10 @@
"username": null,
"password": null
},
- "notes": []
+ "notes": [
+ {
+ "text": "Please check and update the '/opt/tracktor/app/backend/.env' file if using behind reverse proxy.",
+ "type": "info"
+ }
+ ]
}
From 78912e2c7a6e8b8dfa898c993941a62bb50ea93a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 25 Aug 2025 16:58:00 +0200
Subject: [PATCH 220/312] Update create_lxc.sh
---
misc/create_lxc.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index c89e5d72..f4d4d07b 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -214,7 +214,6 @@ if ! check_storage_support "vztmpl"; then
exit 1
fi
-msg_info "Checking template storage"
while true; do
if select_storage template; then
TEMPLATE_STORAGE="$STORAGE_RESULT"
From b83dd90a7a6241054916346549366923e53c40a8 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 08:47:04 +0200
Subject: [PATCH 221/312] romm testing
---
ct/romm.sh | 73 +++++++++++
frontend/public/json/romm.json | 40 ++++++
install/romm-install.sh | 222 +++++++++++++++++++++++++++++++++
3 files changed, 335 insertions(+)
create mode 100644 ct/romm.sh
create mode 100644 frontend/public/json/romm.json
create mode 100644 install/romm-install.sh
diff --git a/ct/romm.sh b/ct/romm.sh
new file mode 100644
index 00000000..bcc0343e
--- /dev/null
+++ b/ct/romm.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+source <(curl -s https://raw.githubusercontent.com/DevelopmentCats/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 DevelopmentCats
+# Author: DevelopmentCats
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+# Source: https://romm.app
+# Updated: 03/10/2025
+
+APP="RomM"
+var_tags="${var_tags:-emulation}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-4096}"
+var_disk="${var_disk:-20}"
+var_os="${var_os:-ubuntu}"
+var_version="${var_version:-24.04}"
+var_unprivileged="${var_unprivileged:-1}"
+var_fuse="${var_fuse:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -d /opt/romm ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ msg_info "Stopping $APP"
+ systemctl stop romm
+ systemctl stop nginx
+ msg_ok "Stopped $APP"
+
+ msg_info "Updating $APP"
+ cd /opt/romm/app
+ git pull
+
+ # Update backend
+ cd /opt/romm/app
+ source /opt/romm/venv/bin/activate
+ pip install --upgrade pip
+ pip install poetry
+ poetry install
+
+ # Update frontend
+ cd /opt/romm/app/frontend
+ npm install
+ npm run build
+
+ echo "Updated on $(date)" >/opt/romm/version.txt
+ msg_ok "Updated $APP"
+
+ msg_info "Starting $APP"
+ systemctl start romm
+ systemctl start nginx
+ msg_ok "Started $APP"
+ msg_ok "Update Successful"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/frontend/public/json/romm.json b/frontend/public/json/romm.json
new file mode 100644
index 00000000..fc8ed35e
--- /dev/null
+++ b/frontend/public/json/romm.json
@@ -0,0 +1,40 @@
+{
+ "name": "RomM",
+ "slug": "romm",
+ "categories": [
+ 2,
+ 3
+ ],
+ "date_created": "2025-03-10",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8080,
+ "documentation": "https://docs.romm.app/latest/",
+ "website": "https://romm.app/",
+ "config_path": "/opt",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/romm.webp",
+ "description": "RomM (ROM Manager) allows you to scan, enrich, browse and play your game collection with a clean and responsive interface. Support for multiple platforms, various naming schemes, and custom tags.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/romm.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 4096,
+ "hdd": 20,
+ "os": "ubuntu",
+ "version": "24.04"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": "romm",
+ "password": "changeme"
+ },
+ "notes": [
+ "API Keys: For full functionality, you'll need API keys from IGDB, MobyGames, and/or SteamGridDB.",
+ "ROM Directory: Your ROM files should follow the RomM folder structure outlined in the documentation.",
+ "Authentication: The admin username and password will be set during the first-run setup process."
+ ]
+}
diff --git a/install/romm-install.sh b/install/romm-install.sh
new file mode 100644
index 00000000..c43acb10
--- /dev/null
+++ b/install/romm-install.sh
@@ -0,0 +1,222 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: DevelopmentCats
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://romm.app
+# Updated: 03/10/2025
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing dependencies"
+$STD apt-get install -y \
+ acl \
+ build-essential \
+ libssl-dev \
+ libffi-dev \
+ python3-dev \
+ python3-pip \
+ python3-venv \
+ libmariadb3 \
+ libmariadb-dev \
+ libpq-dev \
+ redis-tools \
+ p7zip \
+ tzdata \
+ jq
+msg_ok "Installed core dependencies"
+
+PYTHON_VERSION="3.12" setup_uv
+NODE_VERSION="22" NODE_MODULE="serve" setup_nodejs
+
+msg_info "Configuring Database"
+DB_NAME=romm
+DB_USER=romm
+DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
+$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
+$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
+$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
+{
+ echo "RomM-Credentials"
+ echo "RomM Database User: $DB_USER"
+ echo "RomM Database Password: $DB_PASS"
+ echo "RomM Database Name: $DB_NAME"
+} >~/romm.creds
+chmod 600 ~/romm.creds
+msg_ok "Configured Database"
+
+msg_info "Creating romm user and directories"
+id -u romm &>/dev/null || useradd -r -m -d /var/lib/romm -s /bin/bash romm
+mkdir -p /opt/romm \
+ /var/lib/romm/config \
+ /var/lib/romm/resources \
+ /var/lib/romm/assets/{saves,states,screenshots} \
+ /var/lib/romm/library/roms/{gba,gbc,ps} \
+ /var/lib/romm/library/bios/{gba,ps}
+chown -R romm:romm /opt/romm /var/lib/romm
+msg_ok "Created romm user and directories"
+
+msg_info "Configuring Database"
+DB_NAME=romm
+DB_USER=romm
+DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
+$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
+$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
+$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
+{
+ echo "RomM-Credentials"
+ echo "RomM Database User: $DB_USER"
+ echo "RomM Database Password: $DB_PASS"
+ echo "RomM Database Name: $DB_NAME"
+} >~/romm.creds
+msg_ok "Configured Database"
+
+fetch_and_deploy_gh_release "romm" "rommapp/romm"
+
+msg_info "Creating environment file"
+sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
+systemctl restart redis-server
+systemctl enable -q --now redis-server
+AUTH_SECRET_KEY=$(openssl rand -hex 32)
+
+cat >/opt/romm/.env </etc/systemd/system/romm-backend.service </etc/systemd/system/romm-frontend.service </etc/systemd/system/romm-worker.service </etc/systemd/system/romm-scheduler.service <
Date: Tue, 26 Aug 2025 08:47:48 +0200
Subject: [PATCH 222/312] Update romm.sh
---
ct/romm.sh | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/ct/romm.sh b/ct/romm.sh
index bcc0343e..8dc95b58 100644
--- a/ct/romm.sh
+++ b/ct/romm.sh
@@ -1,10 +1,9 @@
#!/usr/bin/env bash
-source <(curl -s https://raw.githubusercontent.com/DevelopmentCats/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 DevelopmentCats
-# Author: DevelopmentCats
+source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://romm.app
-# Updated: 03/10/2025
APP="RomM"
var_tags="${var_tags:-emulation}"
From 3e7d3fa6180dd96d066c94b035c198c82ee0d269 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Tue, 26 Aug 2025 06:48:14 +0000
Subject: [PATCH 223/312] Update .app files
---
ct/headers/alpine-redlib | 6 ------
ct/headers/healthchecks | 6 ------
ct/headers/romm | 6 ++++++
3 files changed, 6 insertions(+), 12 deletions(-)
delete mode 100644 ct/headers/alpine-redlib
delete mode 100644 ct/headers/healthchecks
create mode 100644 ct/headers/romm
diff --git a/ct/headers/alpine-redlib b/ct/headers/alpine-redlib
deleted file mode 100644
index 7d8f1130..00000000
--- a/ct/headers/alpine-redlib
+++ /dev/null
@@ -1,6 +0,0 @@
- ___ __ _ ____ _____ __
- / | / /___ (_)___ ___ / __ \___ ____/ / (_) /_
- / /| | / / __ \/ / __ \/ _ \______/ /_/ / _ \/ __ / / / __ \
- / ___ |/ / /_/ / / / / / __/_____/ _, _/ __/ /_/ / / / /_/ /
-/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_|\___/\__,_/_/_/_.___/
- /_/
diff --git a/ct/headers/healthchecks b/ct/headers/healthchecks
deleted file mode 100644
index 8f61c877..00000000
--- a/ct/headers/healthchecks
+++ /dev/null
@@ -1,6 +0,0 @@
- __ ____ __ __ __
- / /_ ___ ____ _/ / /_/ /_ _____/ /_ ___ _____/ /_______
- / __ \/ _ \/ __ `/ / __/ __ \/ ___/ __ \/ _ \/ ___/ //_/ ___/
- / / / / __/ /_/ / / /_/ / / / /__/ / / / __/ /__/ ,< (__ )
-/_/ /_/\___/\__,_/_/\__/_/ /_/\___/_/ /_/\___/\___/_/|_/____/
-
diff --git a/ct/headers/romm b/ct/headers/romm
new file mode 100644
index 00000000..7f214d48
--- /dev/null
+++ b/ct/headers/romm
@@ -0,0 +1,6 @@
+ ____ __ ___
+ / __ \____ ____ ___ / |/ /
+ / /_/ / __ \/ __ `__ \/ /|_/ /
+ / _, _/ /_/ / / / / / / / / /
+/_/ |_|\____/_/ /_/ /_/_/ /_/
+
From 19d48294dfeb1a017f57b06ac5331a08a6cb2ed1 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 08:50:53 +0200
Subject: [PATCH 224/312] Delete rustdeskserver.json
---
frontend/public/json/rustdeskserver.json | 55 ------------------------
1 file changed, 55 deletions(-)
delete mode 100644 frontend/public/json/rustdeskserver.json
diff --git a/frontend/public/json/rustdeskserver.json b/frontend/public/json/rustdeskserver.json
deleted file mode 100644
index 7dd43605..00000000
--- a/frontend/public/json/rustdeskserver.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "name": "RustDesk Server",
- "slug": "rustdeskserver",
- "categories": [
- 21
- ],
- "date_created": "2025-02-13",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 21114,
- "documentation": "https://rustdesk.com/docs/en/",
- "website": "https://rustdesk.com/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/rustdesk.webp",
- "config_path": "",
- "description": "RustDesk is a full-featured open source remote control alternative for self-hosting and security with minimal configuration.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/rustdeskserver.sh",
- "resources": {
- "cpu": 1,
- "ram": 512,
- "hdd": 2,
- "os": "debian",
- "version": "12"
- }
- },
- {
- "type": "alpine",
- "script": "ct/alpine-rustdeskserver.sh",
- "resources": {
- "cpu": 1,
- "ram": 512,
- "hdd": 2,
- "os": "alpine",
- "version": "3.22"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "Check our configuration guide for help: `https://github.com/community-scripts/ProxmoxVE/discussions/2388`",
- "type": "info"
- },
- {
- "text": "Login credentials: `cat ~/rustdesk.creds`",
- "type": "info"
- }
- ]
-}
From ba92c7b642a14522869bab62a8e026f855ffa234 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 08:51:16 +0200
Subject: [PATCH 225/312] -
---
ct/alpine-rustdeskserver.sh | 74 --------------
install/alpine-rustdeskserver-install.sh | 122 -----------------------
2 files changed, 196 deletions(-)
delete mode 100644 ct/alpine-rustdeskserver.sh
delete mode 100644 install/alpine-rustdeskserver-install.sh
diff --git a/ct/alpine-rustdeskserver.sh b/ct/alpine-rustdeskserver.sh
deleted file mode 100644
index 1494be48..00000000
--- a/ct/alpine-rustdeskserver.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: Slaviša Arežina (tremor021)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/rustdesk/rustdesk-server
-
-APP="Alpine-RustDeskServer"
-var_tags="${var_tags:-alpine;monitoring}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-512}"
-var_disk="${var_disk:-3}"
-var_os="${var_os:-alpine}"
-var_version="${var_version:-3.22}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- if [[ ! -d /opt/rustdesk-server ]]; then
- msg_error "No ${APP} Installation Found!"
- exit 1
- fi
-
- APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
- RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
- if [ "${RELEASE}" != "$(cat ~/.rustdesk-server 2>/dev/null)" ] || [ ! -f ~/.rustdesk-server ]; then
- msg_info "Updating RustDesk Server to v${RELEASE}"
- $STD apk -U upgrade
- $STD service rustdesk-server-hbbs stop
- $STD service rustdesk-server-hbbr stop
- temp_file1=$(mktemp)
- curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
- $STD unzip "$temp_file1"
- cp -r amd64/* /opt/rustdesk-server/
- echo "${RELEASE}" >~/.rustdesk-server
- $STD service rustdesk-server-hbbs start
- $STD service rustdesk-server-hbbr start
- rm -rf amd64
- rm -f $temp_file1
- msg_ok "Updated RustDesk Server successfully"
- else
- msg_ok "No update required. ${APP} is already at v${RELEASE}"
- fi
- if [ "${APIRELEASE}" != "$(cat ~/.rustdesk-api)" ] || [ ! -f ~/.rustdesk-api ]; then
- msg_info "Updating RustDesk API to v${APIRELEASE}"
- $STD service rustdesk-api stop
- temp_file2=$(mktemp)
- curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
- $STD tar zxvf "$temp_file2"
- cp -r release/* /opt/rustdesk-api
- echo "${APIRELEASE}" >~/.rustdesk-api
- $STD service rustdesk-api start
- rm -rf release
- rm -f $temp_file2
- msg_ok "Updated RustDesk API"
- else
- msg_ok "No update required. RustDesk API is already at v${APIRELEASE}"
- fi
- exit 0
-}
-
-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 IP:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:21114${CL}"
diff --git a/install/alpine-rustdeskserver-install.sh b/install/alpine-rustdeskserver-install.sh
deleted file mode 100644
index b26f3134..00000000
--- a/install/alpine-rustdeskserver-install.sh
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: Slaviša Arežina (tremor021)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/rustdesk/rustdesk-server
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-RELEASE=$(curl -s https://api.github.com/repos/rustdesk/rustdesk-server/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
-msg_info "Installing RustDesk Server v${RELEASE}"
-temp_file1=$(mktemp)
-curl -fsSL "https://github.com/rustdesk/rustdesk-server/releases/download/${RELEASE}/rustdesk-server-linux-amd64.zip" -o "$temp_file1"
-$STD unzip "$temp_file1"
-mv amd64 /opt/rustdesk-server
-mkdir -p /root/.config/rustdesk
-cd /opt/rustdesk-server
-./rustdesk-utils genkeypair > /tmp/rustdesk_keys.txt
-grep "Public Key" /tmp/rustdesk_keys.txt | awk '{print $3}' > /root/.config/rustdesk/id_ed25519.pub
-grep "Secret Key" /tmp/rustdesk_keys.txt | awk '{print $3}' > /root/.config/rustdesk/id_ed25519
-chmod 600 /root/.config/rustdesk/id_ed25519
-chmod 644 /root/.config/rustdesk/id_ed25519.pub
-rm /tmp/rustdesk_keys.txt
-echo "${RELEASE}" >~/.rustdesk-server
-msg_ok "Installed RustDesk Server v${RELEASE}"
-
-APIRELEASE=$(curl -s https://api.github.com/repos/lejianwen/rustdesk-api/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
-msg_info "Installing RustDesk API v${APIRELEASE}"
-temp_file2=$(mktemp)
-curl -fsSL "https://github.com/lejianwen/rustdesk-api/releases/download/v${APIRELEASE}/linux-amd64.tar.gz" -o "$temp_file2"
-$STD tar zxvf "$temp_file2"
-mv release /opt/rustdesk-api
-cd /opt/rustdesk-api
-ADMINPASS=$(head -c 16 /dev/urandom | xxd -p -c 16)
-$STD ./apimain reset-admin-pwd "$ADMINPASS"
-{
- echo "RustDesk WebUI"
- echo ""
- echo "Username: admin"
- echo "Password: $ADMINPASS"
-} >>~/rustdesk.creds
-echo "${APIRELEASE}" >~/.rustdesk-api
-msg_ok "Installed RustDesk API v${APIRELEASE}"
-
-msg_info "Enabling RustDesk Server Services"
-cat </etc/init.d/rustdesk-server-hbbs
-#!/sbin/openrc-run
-description="RustDesk HBBS Service"
-directory="/opt/rustdesk-server"
-command="/opt/rustdesk-server/hbbs"
-command_args=""
-command_background="true"
-command_user="root"
-pidfile="/var/run/rustdesk-server-hbbs.pid"
-output_log="/var/log/rustdesk-hbbs.log"
-error_log="/var/log/rustdesk-hbbs.err"
-
-depend() {
- use net
-}
-EOF
-
-cat </etc/init.d/rustdesk-server-hbbr
-#!/sbin/openrc-run
-description="RustDesk HBBR Service"
-directory="/opt/rustdesk-server"
-command="/opt/rustdesk-server/hbbr"
-command_args=""
-command_background="true"
-command_user="root"
-pidfile="/var/run/rustdesk-server-hbbr.pid"
-output_log="/var/log/rustdesk-hbbr.log"
-error_log="/var/log/rustdesk-hbbr.err"
-
-depend() {
- use net
-}
-EOF
-
-cat </etc/init.d/rustdesk-api
-#!/sbin/openrc-run
-description="RustDesk API Service"
-directory="/opt/rustdesk-api"
-command="/opt/rustdesk-api/apimain"
-command_args=""
-command_background="true"
-command_user="root"
-pidfile="/var/run/rustdesk-api.pid"
-output_log="/var/log/rustdesk-api.log"
-error_log="/var/log/rustdesk-api.err"
-
-depend() {
- use net
-}
-EOF
-chmod +x /etc/init.d/rustdesk-server-hbbs
-chmod +x /etc/init.d/rustdesk-server-hbbr
-chmod +x /etc/init.d/rustdesk-api
-$STD rc-update add rustdesk-server-hbbs default
-$STD rc-update add rustdesk-server-hbbr default
-$STD rc-update add rustdesk-api default
-msg_ok "Enabled RustDesk Server Services"
-
-msg_info "Starting RustDesk Server"
-$STD service rustdesk-server-hbbs start
-$STD service rustdesk-server-hbbr start
-$STD service rustdesk-api start
-msg_ok "Started RustDesk Server"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-rm -f "$temp_file1" "$temp_file2"
-$STD apk cache clean
-msg_ok "Cleaned"
From 5ff0884a58a27354596f281f138123bf25d8123f Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 08:52:59 +0200
Subject: [PATCH 226/312] Update romm.json
---
frontend/public/json/romm.json | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/frontend/public/json/romm.json b/frontend/public/json/romm.json
index fc8ed35e..364a7ea2 100644
--- a/frontend/public/json/romm.json
+++ b/frontend/public/json/romm.json
@@ -2,8 +2,7 @@
"name": "RomM",
"slug": "romm",
"categories": [
- 2,
- 3
+ 21
],
"date_created": "2025-03-10",
"type": "ct",
@@ -32,9 +31,5 @@
"username": "romm",
"password": "changeme"
},
- "notes": [
- "API Keys: For full functionality, you'll need API keys from IGDB, MobyGames, and/or SteamGridDB.",
- "ROM Directory: Your ROM files should follow the RomM folder structure outlined in the documentation.",
- "Authentication: The admin username and password will be set during the first-run setup process."
- ]
+ "notes": []
}
From 72eeff5e5ab1ac697e53271ec54cb30caa30dbc4 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 10:11:02 +0200
Subject: [PATCH 227/312] Update romm-install.sh
---
install/romm-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/install/romm-install.sh b/install/romm-install.sh
index c43acb10..7a7336c8 100644
--- a/install/romm-install.sh
+++ b/install/romm-install.sh
@@ -34,6 +34,7 @@ msg_ok "Installed core dependencies"
PYTHON_VERSION="3.12" setup_uv
NODE_VERSION="22" NODE_MODULE="serve" setup_nodejs
+setup_mariadb
msg_info "Configuring Database"
DB_NAME=romm
From 244a7f8ae2c64ea81989ab51f7c5a21c8c78d0d5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 10:25:14 +0200
Subject: [PATCH 228/312] Update romm-install.sh
---
install/romm-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/romm-install.sh b/install/romm-install.sh
index 7a7336c8..36c791c4 100644
--- a/install/romm-install.sh
+++ b/install/romm-install.sh
@@ -40,8 +40,8 @@ msg_info "Configuring Database"
DB_NAME=romm
DB_USER=romm
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
-$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
-$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
+$STD mariadb -u root -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
+$STD mariadb -u root -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "RomM-Credentials"
From af5c1b858b1245fecf77e56362c75b39ba58127e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 11:15:52 +0200
Subject: [PATCH 229/312] debian 13 template
---
ct/debian13.sh | 44 +++++++++++++++++++++++++++++++++++++
install/debian13-install.sh | 25 +++++++++++++++++++++
2 files changed, 69 insertions(+)
create mode 100644 ct/debian13.sh
create mode 100644 install/debian13-install.sh
diff --git a/ct/debian13.sh b/ct/debian13.sh
new file mode 100644
index 00000000..4be94c1c
--- /dev/null
+++ b/ct/debian13.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+# Source: https://www.debian.org/
+
+APP="Debian13"
+var_tags="${var_tags:-os}"
+var_cpu="${var_cpu:-4}"
+var_ram="${var_ram:-4096}"
+var_disk="${var_disk:-15}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-13}"
+var_unprivileged="${var_unprivileged:-1}"
+#var_fuse="${var_fuse:-no}"
+#var_tun="${var_tun:-no}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -d /var ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ msg_info "Updating $APP LXC"
+ $STD apt update
+ $STD apt -y upgrade
+ msg_ok "Updated $APP LXC"
+ exit
+}
+
+start
+build_container
+description
+
+msg_ok "Completed Successfully!"
+msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!"
diff --git a/install/debian13-install.sh b/install/debian13-install.sh
new file mode 100644
index 00000000..466d6af6
--- /dev/null
+++ b/install/debian13-install.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: MickLesk (CanbiZ)
+# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies"
+$STD apt install -y gpg
+msg_ok "Installed Dependencies"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt -y autoremove
+$STD apt -y autoclean
+msg_ok "Cleaned"
From b0c3978bbfd535daccbade3a620dd112acee6c6a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 11:25:56 +0200
Subject: [PATCH 230/312] Update create_lxc.sh
---
misc/create_lxc.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index f4d4d07b..5b10404b 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -299,7 +299,11 @@ mapfile -t ONLINE_TEMPLATES < <(
sed -n "s/.*\($TEMPLATE_SEARCH.*$TEMPLATE_PATTERN.*\)/\1/p" |
sort -t - -k 2 -V
)
-ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]:-}"
+if [ ${#ONLINE_TEMPLATES[@]} -gt 0 ]; then
+ ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
+else
+ ONLINE_TEMPLATE=""
+fi
# 3. Local vs Online
if [ ${#LOCAL_TEMPLATES[@]} -gt 0 ]; then
From 0b54c653f87f1ea2119f145ba0db100b30699ae6 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 12:32:08 +0200
Subject: [PATCH 231/312] Update create_lxc.sh
---
misc/create_lxc.sh | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 5b10404b..be4b8112 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -331,6 +331,7 @@ fi
msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
msg_debug "Resolved TEMPLATE_PATH=$TEMPLATE_PATH"
+# 5. Validation
# 5. Validation
NEED_DOWNLOAD=0
if [[ ! -f "$TEMPLATE_PATH" ]]; then
@@ -340,11 +341,19 @@ elif [[ ! -r "$TEMPLATE_PATH" ]]; then
msg_error "Template file exists but is not readable – check permissions."
exit 221
elif [[ "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
- msg_warn "Template file too small (<1MB) – re-downloading."
- NEED_DOWNLOAD=1
-elif ! zstdcat "$TEMPLATE_PATH" | tar -tf - &>/dev/null; then
- msg_warn "Template appears corrupted – re-downloading."
- NEED_DOWNLOAD=1
+ if [[ -n "$ONLINE_TEMPLATE" ]]; then
+ msg_warn "Template file too small (<1MB) – re-downloading."
+ NEED_DOWNLOAD=1
+ else
+ msg_warn "Template looks too small, but no online version exists. Keeping local file."
+ fi
+elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
+ if [[ -n "$ONLINE_TEMPLATE" ]]; then
+ msg_warn "Template appears corrupted – re-downloading."
+ NEED_DOWNLOAD=1
+ else
+ msg_warn "Template appears corrupted, but no online version exists. Keeping local file."
+ fi
else
msg_ok "Template $TEMPLATE is present and valid."
fi
@@ -422,10 +431,14 @@ if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[
msg_warn "Template file too small or missing – re-downloading."
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
- elif ! zstdcat "$TEMPLATE_PATH" | tar -tf - &>/dev/null; then
- msg_warn "Template appears corrupted – re-downloading."
- rm -f "$TEMPLATE_PATH"
- pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
+ elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
+ if [[ -n "$ONLINE_TEMPLATE" ]]; then
+ msg_warn "Template appears corrupted – re-downloading."
+ rm -f "$TEMPLATE_PATH"
+ pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
+ else
+ msg_warn "Template appears corrupted, but no online version exists. Skipping re-download."
+ fi
fi
# Retry after repair
From 7eec40d117fd9d6fc07170bdae11571f46e41530 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 12:40:19 +0200
Subject: [PATCH 232/312] Update create_lxc.sh
---
misc/create_lxc.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index be4b8112..f2aa05de 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -331,7 +331,6 @@ fi
msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
msg_debug "Resolved TEMPLATE_PATH=$TEMPLATE_PATH"
-# 5. Validation
# 5. Validation
NEED_DOWNLOAD=0
if [[ ! -f "$TEMPLATE_PATH" ]]; then
From ec1022dd3ab9557b09e763c231a67a71cc440688 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 26 Aug 2025 13:56:31 +0200
Subject: [PATCH 233/312] fix
---
install/leantime-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/leantime-install.sh b/install/leantime-install.sh
index 086157c8..e1b114bf 100644
--- a/install/leantime-install.sh
+++ b/install/leantime-install.sh
@@ -68,9 +68,9 @@ sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
"/opt/leantime/config/.env"
a2enmod -q proxy_fcgi setenvif rewrite
-a2enconf -q "php${PHP_VERSION}-fpm"
+a2enconf -q "php8.4-fpm"
-sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/${PHP_VERSION}/apache2/php.ini"
+sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/8.4/apache2/php.ini"
systemctl restart apache2
From f9f3517ed404707beeed926dc31485a4f5e713a2 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 09:54:24 -0400
Subject: [PATCH 234/312] Autocaliweb: fix tar
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 4c6e6400..09dae8a5 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -51,7 +51,7 @@ msg_info "Installing Calibre"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
CALIBRE_VERSION=${CALIBRE_RELEASE#v}
curl -fsSL https://github.com/kovidgoyal/calibre/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
-$STD tar -xf /tmp/calibre.txz /opt/calibre
+$STD tar -xf /tmp/calibre.txz -C /opt/calibre
rm /tmp/calibre.txz
$STD /opt/calibre/calibre_postinstall
msg_ok "Calibre installed"
From 230909ca3ea169d918783bcf80de42b55a65e0be Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 10:06:20 -0400
Subject: [PATCH 235/312] Autocaliweb: create calibre dir
---
install/autocaliweb-install.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 09dae8a5..faf315c1 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -51,6 +51,7 @@ msg_info "Installing Calibre"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
CALIBRE_VERSION=${CALIBRE_RELEASE#v}
curl -fsSL https://github.com/kovidgoyal/calibre/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
+mkdir -p /opt/calibre
$STD tar -xf /tmp/calibre.txz -C /opt/calibre
rm /tmp/calibre.txz
$STD /opt/calibre/calibre_postinstall
From 11b52f7703c9f20baf1753cf70982cb7cdaea187 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 14:34:02 -0400
Subject: [PATCH 236/312] Autocaliweb: add python3-dev and install via
pyproject.toml
---
install/autocaliweb-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index faf315c1..2a698b53 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -15,7 +15,7 @@ update_os
msg_info "Installing dependencies"
$STD apt-get install -y --no-install-recommends \
- git \
+ python3-dev \
sqlite3 \
build-essential \
libldap2-dev \
@@ -78,7 +78,7 @@ mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
-$STD uv sync --all-extras --active
+$STD uv pip install -r pyproject.toml --all-extras
cat <./dirs.json
{
"ingest_folder": "$INGEST_DIR",
From 3325c153cf4f3b060a20a06a449566f8592ac086 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 14:44:17 -0400
Subject: [PATCH 237/312] Autocaliweb: source venv
---
install/autocaliweb-install.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 2a698b53..741bd9ff 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -78,7 +78,9 @@ mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
+$STD source "$VIRTUAL_ENV"
$STD uv pip install -r pyproject.toml --all-extras
+$STD deactivate
cat <./dirs.json
{
"ingest_folder": "$INGEST_DIR",
From c48041711d4ebe9f0d1c11b340eedee9c841a8ed Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 14:49:59 -0400
Subject: [PATCH 238/312] fix
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 741bd9ff..0260f7ff 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -78,7 +78,7 @@ mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
-$STD source "$VIRTUAL_ENV"
+$STD source "$VIRTUAL_ENV"/bin/activate
$STD uv pip install -r pyproject.toml --all-extras
$STD deactivate
cat <./dirs.json
From 8fa33480fe0b85f29113931865784b2da5b415a2 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 15:00:34 -0400
Subject: [PATCH 239/312] Autocaliweb: fetch DB files since they aren't in
release (why?)
---
install/autocaliweb-install.sh | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 0260f7ff..7f860ff3 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -106,9 +106,8 @@ msg_info "Initializing databases"
KEPUBIFY_PATH=$(command -v kepubify 2>/dev/null || echo "/usr/bin/kepubify")
EBOOK_CONVERT_PATH=$(command -v ebook-convert 2>/dev/null || echo "/usr/bin/ebook-convert")
CALIBRE_BIN_DIR=$(dirname "$EBOOK_CONVERT_PATH")
-cp "$INSTALL_DIR"/library/metadata.db "$CALIBRE_LIB_DIR"/metadata.db
-
-cp "$INSTALL_DIR"/library/app.db "$CONFIG_DIR"/app.db
+curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/master/library/metadata.db -o "$CALIBRE_LIB_DIR"/metadata.db
+curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/master/library/app.db -o "$CONFIG_DIR"/app.db
sqlite3 "$CONFIG_DIR/app.db" <
Date: Tue, 26 Aug 2025 15:14:05 -0400
Subject: [PATCH 240/312] Autocaliweb: export venv; fix issues with vars
---
install/autocaliweb-install.sh | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 7f860ff3..a5846d2e 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -69,7 +69,7 @@ INGEST_DIR="/opt/acw-book-ingest"
SERVICE_USER="acw"
SERVICE_GROUP="acw"
SCRIPTS_DIR="${INSTALL_DIR}/scripts"
-VIRTUAL_ENV="${INSTALL_DIR}/venv"
+export VIRTUAL_ENV="${INSTALL_DIR}/venv"
mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
@@ -126,7 +126,8 @@ msg_info "Creating scripts and service files"
cat <"$SCRIPTS_DIR"/ingest_watcher.sh
#!/bin/bash
-WATCH_FOLDER=\$(grep -o '"ingest_folder": "[^"]*' \${INSTALL_DIR}/dirs.json | grep -o '[^"]*\$')
+INSTALL_PATH="$INSTALL_DIR"
+WATCH_FOLDER=\$(grep -o '"ingest_folder": "[^"]*' \${INSTALL_PATH}/dirs.json | grep -o '[^"]*\$')
echo "[acw-ingest-service] Watching folder: \$WATCH_FOLDER"
# Monitor the folder for new files
@@ -134,7 +135,7 @@ echo "[acw-ingest-service] Watching folder: \$WATCH_FOLDER"
while read -r events filepath ; do
echo "[acw-ingest-service] New files detected - \$filepath - Starting Ingest Processor..."
# Use the Python interpreter from the virtual environment
- \${VIRTUAL_ENV}/bin/python \${SCRIPTS_DIR}/ingest_processor.py "\$filepath"
+ ${VIRTUAL_ENV}/bin/python \${INSTALL_PATH}/ingest_processor.py "\$filepath"
done
EOF
From f4b00c42fd79dce13d11da655f159dcc58140401 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 15:20:01 -0400
Subject: [PATCH 241/312] Autocaliweb: revert
---
install/autocaliweb-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index a5846d2e..1ece6b6b 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -69,7 +69,7 @@ INGEST_DIR="/opt/acw-book-ingest"
SERVICE_USER="acw"
SERVICE_GROUP="acw"
SCRIPTS_DIR="${INSTALL_DIR}/scripts"
-export VIRTUAL_ENV="${INSTALL_DIR}/venv"
+VIRTUAL_ENV="${INSTALL_DIR}/venv"
mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
@@ -135,7 +135,7 @@ echo "[acw-ingest-service] Watching folder: \$WATCH_FOLDER"
while read -r events filepath ; do
echo "[acw-ingest-service] New files detected - \$filepath - Starting Ingest Processor..."
# Use the Python interpreter from the virtual environment
- ${VIRTUAL_ENV}/bin/python \${INSTALL_PATH}/ingest_processor.py "\$filepath"
+ \${INSTALL_PATH}/venv/bin/python \${INSTALL_PATH}/scripts/ingest_processor.py "\$filepath"
done
EOF
From 98b4abb2d6eb401469f144c84200b123010cace0 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 15:31:07 -0400
Subject: [PATCH 242/312] Autocaliweb: venv var gets unset after running
deactivate
---
install/autocaliweb-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 1ece6b6b..7b51f770 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -144,7 +144,7 @@ cat <"$SCRIPTS_DIR"/auto_zipper_wrapper.sh
#!/bin/bash
# Source virtual environment
-source ${VIRTUAL_ENV}/bin/activate
+source ${INSTALL_DIR}/venv/bin/activate
WAKEUP="23:59"
@@ -180,7 +180,7 @@ cat <"$SCRIPTS_DIR"/metadata_change_detector_wrapper.sh
# metadata_change_detector_wrapper.sh - Wrapper for periodic metadata enforcement
# Source virtual environment
-source ${VIRTUAL_ENV}/bin/activate
+source ${INSTALL_DIR}/venv/bin/activate
# Configuration
CHECK_INTERVAL=300 # Check every 5 minutes (300 seconds)
From 8bd7d7cf7aae30d5b168b5aee54dd259cfa2a22f Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 15:36:39 -0400
Subject: [PATCH 243/312] Autocaliweb: missing $
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 7b51f770..e09c06ca 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -88,7 +88,7 @@ cat <./dirs.json
"tmp_conversion_dir": "$CONFIG_DIR/.acw_conversion_tmp"
}
EOF
-useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "SERVICE_USER"
+useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "$SERVICE_USER"
ln -sf "$CONFIG_DIR"/.config/calibre/plugins "$CONFIG_DIR"/calibre_plugins
msg_ok "Configured Autocaliweb"
From 04214bf968bdf9249b3ec0ba5f4c2c71fc239859 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 18:01:05 -0400
Subject: [PATCH 244/312] Autocaliweb: add env, create version constraint for
pyopenssl, use lock file for deps
---
install/autocaliweb-install.sh | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index e09c06ca..50b4a5b4 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -79,7 +79,9 @@ mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
$STD source "$VIRTUAL_ENV"/bin/activate
-$STD uv pip install -r pyproject.toml --all-extras
+echo "pyopenssl>=24.2.1" >./constraint.txt
+$STD uv pip compile requirements.txt optional-requirements.txt -c constraint.txt -o combined-requirements.lock
+$STD uv pip sync combined-requirements.lock
$STD deactivate
cat <./dirs.json
{
@@ -90,6 +92,13 @@ cat <./dirs.json
EOF
useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "$SERVICE_USER"
ln -sf "$CONFIG_DIR"/.config/calibre/plugins "$CONFIG_DIR"/calibre_plugins
+cat <"$INSTALL_DIR"/.env
+ACW_INSTALL_DIR=$INSTALL_DIR
+ACW_CONFIG_DIR=$CONFIG_DIR
+ACW_USER=$SERVICE_USER
+ACW_GROUP=$SERVICE_GROUP
+LIBRARY_DIR=$CALIBRE_LIB_DIR
+EOF
msg_ok "Configured Autocaliweb"
msg_info "Creating ACWSync Plugin for KOReader"
@@ -240,6 +249,7 @@ Environment=PYTHONPATH=$SCRIPTS_DIR:$INSTALL_DIR
Environment=PYTHONDONTWRITEBYTECODE=1
Environment=PYTHONUNBUFFERED=1
Environment=CALIBRE_DBPATH=$CONFIG_DIR
+EnvironmentFile=$INSTALL_DIR/.env
ExecStart=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/cps.py -p $CONFIG_DIR/app.db
Restart=always
@@ -251,7 +261,7 @@ StandardError=journal
WantedBy=multi-user.target
EOF
-cat <"$SYS_PATH"/acw-ingestor.service
+cat <"$SYS_PATH"/acw-ingest-service.service
[Unit]
Description=Autocaliweb Ingest Processor Service
After=autocaliweb.service
From 9710331bc1a84d5865d9be8578af16ce58259ab1 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 26 Aug 2025 18:06:32 -0400
Subject: [PATCH 245/312] Autocaliweb: quiesce zip output; fix service file
enable
---
install/autocaliweb-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 50b4a5b4..e282f782 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -107,7 +107,7 @@ PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" |
echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
-zip -r koplugin.zip acwsync.koplugin/
+$STD zip -r koplugin.zip acwsync.koplugin/
cp -r koplugin.zip "$INSTALL_DIR"/cps/static
msg_ok "Created ACWSync Plugin"
@@ -320,7 +320,7 @@ Environment=HOME=${CONFIG_DIR}
WantedBy=multi-user.target
EOF
-systemctl -q enable --now autocaliweb acw-ingestor acw-auto-zipper metadata-change-detector
+systemctl -q enable --now autocaliweb acw-ingest-service acw-auto-zipper metadata-change-detector
msg_ok "Created scripts and service files"
motd_ssh
From 3a583a906d17e17dc10463de0c7ea72a6a19c474 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 10:10:08 +0200
Subject: [PATCH 246/312] garage
---
install/alpine-garage-install.sh | 98 ++++++++++++++++++++++++++++++++
install/leantime-install.sh | 18 +++---
2 files changed, 105 insertions(+), 11 deletions(-)
create mode 100644 install/alpine-garage-install.sh
diff --git a/install/alpine-garage-install.sh b/install/alpine-garage-install.sh
new file mode 100644
index 00000000..126401d9
--- /dev/null
+++ b/install/alpine-garage-install.sh
@@ -0,0 +1,98 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: MickLesk (CanbiZ)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://garagehq.deuxfleurs.fr/
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Preparing directories"
+mkdir -p /var/lib/garage/meta /var/lib/garage/data /var/lib/garage/snapshots
+msg_ok "Prepared directories"
+
+msg_info "Setup Garage packages"
+$STD apk add --no-cache garage garage-openrc openssl
+msg_ok "Setup Garage packages"
+
+# msg_info "Generating RPC secret"
+# if [[ ! -s /etc/garage.rpc_secret ]]; then
+# openssl rand -hex 32 | tr -d '\n' >/etc/garage.rpc_secret
+# chmod 600 /etc/garage.rpc_secret
+# fi
+# msg_ok "Generated RPC secret"
+
+# msg_info "Generating tokens"
+# if [[ ! -s /etc/garage.tokens.env ]]; then
+# ADMIN_TOKEN="$(openssl rand -base64 32)"
+# METRICS_TOKEN="$(openssl rand -base64 32)"
+# cat >/etc/garage.tokens.env </etc/garage.toml <>~/"$APPLICATION".creds
+} >>~/leantime.creds
msg_ok "Set up Database"
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
-msg_info "Setup ${APPLICATION}"
-APACHE_LOG_DIR=/var/log/apache2
+msg_info "Setup Leantime"
chown -R www-data:www-data "/opt/leantime"
chmod -R 750 "/opt/leantime"
@@ -55,8 +54,8 @@ cat </etc/apache2/sites-enabled/000-default.conf
Require all granted
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/access.log combined
+ ErrorLog /var/log/apache2/error.log
+ CustomLog /var/log/apache2/access.log combined
EOF
@@ -67,13 +66,10 @@ sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
-e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \
"/opt/leantime/config/.env"
-a2enmod -q proxy_fcgi setenvif rewrite
-a2enconf -q "php8.4-fpm"
-
+$STD a2enmod -q proxy_fcgi setenvif rewrite
+$STD a2enconf -q "php8.4-fpm"
sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/8.4/apache2/php.ini"
-
systemctl restart apache2
-
msg_ok "Setup ${APPLICATION}"
motd_ssh
From d0424dccb90439158d19085e019c1f4a9c1b022e Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 10:26:39 +0200
Subject: [PATCH 247/312] Update haos-vm.sh
---
vm/haos-vm.sh | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh
index 8e9e61cc..8bcb926c 100644
--- a/vm/haos-vm.sh
+++ b/vm/haos-vm.sh
@@ -184,8 +184,8 @@ function exit-script() {
function default_settings() {
BRANCH="$stable"
VMID=$(get_valid_nextid)
- FORMAT=",efitype=4m"
- MACHINE=""
+ FORMAT=",efitype=4m,pre-enrolled-keys=0"
+ MACHINE=" -machine q35"
DISK_CACHE="cache=writethrough,"
HN="haos$stable"
CPU_TYPE=" -cpu host"
@@ -198,11 +198,11 @@ function default_settings() {
START_VM="yes"
METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
+ echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
@@ -246,16 +246,16 @@ function advanced_settings() {
done
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
- "i440fx" "Machine i440fx" ON \
- "q35" "Machine q35" OFF \
+ "i440fx" "Machine i440fx" OFF \
+ "q35" "Machine q35" ON \
3>&1 1>&2 2>&3); then
if [ $MACH = q35 ]; then
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
- FORMAT=""
+ FORMAT=",efitype=4m,pre-enrolled-keys=0"
MACHINE=" -machine q35"
else
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
- FORMAT=",efitype=4m"
+ FORMAT=",efitype=4m,pre-enrolled-keys=0"
MACHINE=""
fi
else
@@ -486,7 +486,7 @@ btrfs | local-zfs)
DISK_EXT=".raw"
DISK_REF="$VMID/"
DISK_IMPORT="-format raw"
- FORMAT=",efitype=4m"
+ FORMAT=",efitype=4m,pre-enrolled-keys=0"
THIN=""
;;
esac
@@ -507,6 +507,8 @@ qm set $VMID \
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \
-boot order=scsi0 >/dev/null
+qm set $VMID -serial0 socket >/dev/null
+
DESCRIPTION=$(
cat <
From fa7cc26bf1a19aff90650ba6416172301126d165 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 10:28:13 +0200
Subject: [PATCH 248/312] Update haos-vm.sh
---
vm/haos-vm.sh | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh
index 8bcb926c..b83f1b30 100644
--- a/vm/haos-vm.sh
+++ b/vm/haos-vm.sh
@@ -142,15 +142,6 @@ function check_root() {
fi
}
-function pve_check() {
- if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
- msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
- echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
- echo -e "Exiting..."
- sleep 2
- exit
- fi
-}
function arch_check() {
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
From 95e1b1b44f891209710d5c780dd0ac75bf9e0f41 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 10:29:21 +0200
Subject: [PATCH 249/312] Update haos-vm.sh
---
vm/haos-vm.sh | 2 --
1 file changed, 2 deletions(-)
diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh
index b83f1b30..bfdef0b6 100644
--- a/vm/haos-vm.sh
+++ b/vm/haos-vm.sh
@@ -142,7 +142,6 @@ function check_root() {
fi
}
-
function arch_check() {
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
@@ -412,7 +411,6 @@ function start_script() {
check_root
arch_check
-pve_check
ssh_check
start_script
From 089634caf401245775dc88843f4d787d1cf8d03a Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 11:38:18 +0200
Subject: [PATCH 250/312] Update haos-vm.sh
---
vm/haos-vm.sh | 3 +++
1 file changed, 3 insertions(+)
diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh
index bfdef0b6..ea7ff30d 100644
--- a/vm/haos-vm.sh
+++ b/vm/haos-vm.sh
@@ -416,6 +416,9 @@ start_script
post_to_api_vm
+qm set socket 105 -serial0
+qm set serial0 -vga
+
msg_info "Validating Storage"
while read -r line; do
TAG=$(echo $line | awk '{print $1}')
From cd7240c7e2101cbdaf97127e63fb5721459ec631 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Wed, 27 Aug 2025 08:00:06 -0400
Subject: [PATCH 251/312] Autocaliweb: add version tracking in the UI
---
install/autocaliweb-install.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index e282f782..e9d04159 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -46,6 +46,7 @@ $STD apt-get install -y --no-install-recommends \
msg_ok "Installed dependencies"
fetch_and_deploy_gh_release "kepubify" "pgaskin/kepubify" "singlefile" "latest" "/usr/bin" "kepubify-linux-64bit"
+KEPUB_VERSION="$(/usr/bin/kepubify --version)"
msg_info "Installing Calibre"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
@@ -75,6 +76,9 @@ mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
mkdir -p "$INSTALL_DIR"/{metadata_change_logs,metadata_temp}
mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
+echo "$CALIBRE_VERSION" >"$INSTALL_DIR"/CALIBRE_RELEASE
+echo "${KEPUB_VERSION#v}" >"$INSTALL_DIR"/KEPUBIFY_RELEASE
+sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
From b64dd8184e841a27eaa0ba311d7959711ca0cc03 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Wed, 27 Aug 2025 08:35:12 -0400
Subject: [PATCH 252/312] Autocaliweb: configure update function
---
ct/autocaliweb.sh | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
index cc728dd6..68986512 100644
--- a/ct/autocaliweb.sh
+++ b/ct/autocaliweb.sh
@@ -30,10 +30,10 @@ function update_script() {
setup_uv
- RELEASE=$(curl -fsSL https://api.github.com/repos/gelbphoenix/autocaliweb/releases/latest | jq '.tag_name' | sed 's/^v//')
+ RELEASE=$(curl -fsSL https://api.github.com/repos/gelbphoenix/autocaliweb/releases/latest | jq '.tag_name' | sed 's/^"v//;s/"$//')
if [[ "${RELEASE}" != "$(cat ~/.autocaliweb 2>/dev/null)" ]] || [[ ! -f ~/.autocaliweb ]]; then
msg_info "Stopping Services"
- systemctl stop autocaliweb metadata-change-detector acw-ingestor acw-auto-zipper
+ systemctl stop autocaliweb metadata-change-detector acw-ingest-service acw-auto-zipper
msg_ok "Stopped Services"
INSTALL_DIR="/opt/autocaliweb"
@@ -42,21 +42,30 @@ function update_script() {
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Updating ${APP}"
cd "$INSTALL_DIR"
- $STD uv sync --all-extras --active
+ $STD source "$VIRTUAL_ENV"/bin/activate
+ echo "pyopenssl>=24.2.1" >./constraint.txt
+ $STD uv pip compile requirements.txt optional-requirements.txt -c constraint.txt -o combined-requirements.lock
+ $STD uv pip sync combined-requirements.lock
+ $STD deactivate
cd "$INSTALL_DIR"/koreader/plugins
PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
- zip -r koplugin.zip acwsync.koplugin/
+ $STD zip -r koplugin.zip acwsync.koplugin/
cp -r koplugin.zip "$INSTALL_DIR"/cps/static
mkdir -p "$INSTALL_DIR"/metadata_temp
$STD tar -xf ~/autocaliweb_bkp.tar --directory /
+ KEPUB_VERSION="$(/usr/bin/kepubify --version)"
+ CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
+ echo "${KEPUB_VERSION#v}" >"$INSTALL_DIR"/KEPUBIFY_RELEASE
+ echo "${CALIBRE_RELEASE#v}" >/"$INSTALL_DIR"/CALIBRE_RELEASE
+ sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
chown -R acw:acw "$INSTALL_DIR"
msg_ok "Updated $APP"
msg_info "Starting Services"
- systemctl start autocaliweb metadata-change-detector acw-ingestor acw-auto-zipper
+ systemctl start autocaliweb metadata-change-detector acw-ingest-service acw-auto-zipper
msg_ok "Started Services"
msg_ok "Updated Successfully"
From ac361754cda58f25cd621de483b39ef7bd636524 Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Wed, 27 Aug 2025 12:35:28 +0000
Subject: [PATCH 253/312] Update .app files
---
ct/headers/alpine-rustdeskserver | 6 ------
ct/headers/debian13 | 6 ++++++
2 files changed, 6 insertions(+), 6 deletions(-)
delete mode 100644 ct/headers/alpine-rustdeskserver
create mode 100644 ct/headers/debian13
diff --git a/ct/headers/alpine-rustdeskserver b/ct/headers/alpine-rustdeskserver
deleted file mode 100644
index 1c99e61f..00000000
--- a/ct/headers/alpine-rustdeskserver
+++ /dev/null
@@ -1,6 +0,0 @@
- ___ __ _ ____ __ ____ __ _____
- / | / /___ (_)___ ___ / __ \__ _______/ /_/ __ \___ _____/ /__/ ___/___ ______ _____ _____
- / /| | / / __ \/ / __ \/ _ \______/ /_/ / / / / ___/ __/ / / / _ \/ ___/ //_/\__ \/ _ \/ ___/ | / / _ \/ ___/
- / ___ |/ / /_/ / / / / / __/_____/ _, _/ /_/ (__ ) /_/ /_/ / __(__ ) ,< ___/ / __/ / | |/ / __/ /
-/_/ |_/_/ .___/_/_/ /_/\___/ /_/ |_|\__,_/____/\__/_____/\___/____/_/|_|/____/\___/_/ |___/\___/_/
- /_/
diff --git a/ct/headers/debian13 b/ct/headers/debian13
new file mode 100644
index 00000000..467acace
--- /dev/null
+++ b/ct/headers/debian13
@@ -0,0 +1,6 @@
+ ____ __ _ ________
+ / __ \___ / /_ (_)___ _____ < /__ /
+ / / / / _ \/ __ \/ / __ `/ __ \/ / /_ <
+ / /_/ / __/ /_/ / / /_/ / / / / /___/ /
+/_____/\___/_.___/_/\__,_/_/ /_/_//____/
+
From c97be769aae8b9c6bf740bcd456ab578184b586e Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Wed, 27 Aug 2025 09:10:17 -0400
Subject: [PATCH 254/312] Autocaliweb: add env file to temp backup
---
ct/autocaliweb.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
index 68986512..ceeccd3f 100644
--- a/ct/autocaliweb.sh
+++ b/ct/autocaliweb.sh
@@ -38,7 +38,7 @@ function update_script() {
INSTALL_DIR="/opt/autocaliweb"
VIRTUAL_ENV="${INSTALL_DIR}/venv"
- $STD tar -cf ~/autocaliweb_bkp.tar "$INSTALL_DIR"/{metadata_change_logs,dirs.json,scripts/ingest_watcher.sh,scripts/auto_zipper_wrapper.sh,scripts/metadata_change_detector_wrapper.sh}
+ $STD tar -cf ~/autocaliweb_bkp.tar "$INSTALL_DIR"/{metadata_change_logs,dirs.json,.env,scripts/ingest_watcher.sh,scripts/auto_zipper_wrapper.sh,scripts/metadata_change_detector_wrapper.sh}
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Updating ${APP}"
cd "$INSTALL_DIR"
From 73d2bab42a3b9fc24db1b815264314c1f9c5dabc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 27 Aug 2025 16:02:20 +0200
Subject: [PATCH 255/312] Update mediamanager-install.sh
---
install/mediamanager-install.sh | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
index ee68d885..3aa0df7b 100644
--- a/install/mediamanager-install.sh
+++ b/install/mediamanager-install.sh
@@ -11,18 +11,14 @@ verb_ip6
catch_errors
setting_up_container
network_check
+update_os
read -r -p "${TAB3}Enter the email address of your first admin user: " admin_email
if [[ "$admin_email" ]]; then
EMAIL="$admin_email"
fi
-update_os
-
-msg_info "Installing dependencies"
-$STD apt-get install -y yq
-msg_ok "Installed dependencies"
-
+setup_yq
NODE_VERSION="24" setup_nodejs
setup_uv
PG_VERSION="17" setup_postgresql
@@ -43,6 +39,7 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8'
msg_ok "Set up PostgreSQL"
fetch_and_deploy_gh_release "MediaManager" "maxdorninger/MediaManager" "tarball" "latest" "/opt/mediamanager"
+
msg_info "Configuring MediaManager"
MM_DIR="/opt/mm"
MEDIA_DIR="${MM_DIR}/media"
From 191d9655038d4b1aab9627b727773183877e5302 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Wed, 27 Aug 2025 14:01:16 -0400
Subject: [PATCH 256/312] Autocaliweb: use uv lock
- Broken until ACW is updated (issue with pyopenssl/cryptography)
---
ct/autocaliweb.sh | 9 ++++-----
install/autocaliweb-install.sh | 6 +-----
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
index ceeccd3f..e7f33ba0 100644
--- a/ct/autocaliweb.sh
+++ b/ct/autocaliweb.sh
@@ -42,11 +42,10 @@ function update_script() {
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Updating ${APP}"
cd "$INSTALL_DIR"
- $STD source "$VIRTUAL_ENV"/bin/activate
- echo "pyopenssl>=24.2.1" >./constraint.txt
- $STD uv pip compile requirements.txt optional-requirements.txt -c constraint.txt -o combined-requirements.lock
- $STD uv pip sync combined-requirements.lock
- $STD deactivate
+ if [[ ! -d "$VIRTUAL_ENV" ]]; then
+ $STD uv venv "$VIRTUAL_ENV"
+ fi
+ $STD uv sync --all-extras --active
cd "$INSTALL_DIR"/koreader/plugins
PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index e9d04159..9a97b37f 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -82,11 +82,7 @@ sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
-$STD source "$VIRTUAL_ENV"/bin/activate
-echo "pyopenssl>=24.2.1" >./constraint.txt
-$STD uv pip compile requirements.txt optional-requirements.txt -c constraint.txt -o combined-requirements.lock
-$STD uv pip sync combined-requirements.lock
-$STD deactivate
+$STD uv sync --all-extras --active
cat <./dirs.json
{
"ingest_folder": "$INGEST_DIR",
From 28a2c12deeb0a629dfcfaf624cdb42f16de0d346 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 28 Aug 2025 09:43:39 +0200
Subject: [PATCH 257/312] test
---
ct/flaresolverr.sh | 56 +++++++++++++++++++++++++
install/flaresolverr-install.sh | 72 +++++++++++++++++++++++++++++++++
2 files changed, 128 insertions(+)
create mode 100644 ct/flaresolverr.sh
create mode 100644 install/flaresolverr-install.sh
diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh
new file mode 100644
index 00000000..95703f86
--- /dev/null
+++ b/ct/flaresolverr.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster) | Co-Author: remz1337
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/FlareSolverr/FlareSolverr
+
+APP="FlareSolverr"
+var_tags="${var_tags:-proxy}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-4}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ RELEASE=$(curl -fsSL https://api.github.com/repos/FlareSolverr/FlareSolverr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
+ if [[ "${RELEASE}" != "$(cat ~/.flaresolverr 2>/dev/null)" ]] || [[ ! -f ~/.flaresolverr ]]; then
+ msg_info "Stopping service"
+ systemctl stop flaresolverr
+ msg_ok "Stopped service"
+
+ rm -rf /opt/flaresolverr
+ fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
+
+ msg_info "Starting service"
+ systemctl start flaresolverr
+ msg_ok "Started service"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8191${CL}"
diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh
new file mode 100644
index 00000000..628d3205
--- /dev/null
+++ b/install/flaresolverr-install.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 tteck
+# Author: tteck (tteckster)
+# Co-Author: remz1337
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/FlareSolverr/FlareSolverr
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies"
+$STD apt-get install -y \
+ apt-transport-https \
+ xvfb
+msg_ok "Installed Dependencies"
+
+msg_info "Installing Chrome"
+curl -fsSL "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
+echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google-chrome.list
+$STD apt update
+$STD apt install -y google-chrome-stable
+msg_ok "Installed Chrome"
+
+PYTHON_VERSION="3.13"setup_uv
+
+msg_info "prepare uv python 3.13"
+UV_PY="$(uv python find 3.13)"
+cat <<'EOF' >/usr/local/bin/python3
+#!/bin/bash
+exec "$UV_PY/bin/python3.13" "$@"
+EOF
+chmod +x /usr/local/bin/python3
+ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
+msg_ok "prepared python 3.13"
+
+
+fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/flaresolverr.service
+[Unit]
+Description=FlareSolverr
+After=network.target
+[Service]
+SyslogIdentifier=flaresolverr
+Restart=always
+RestartSec=5
+Type=simple
+Environment="LOG_LEVEL=info"
+Environment="CAPTCHA_SOLVER=none"
+WorkingDirectory=/opt/flaresolverr
+ExecStart=/opt/flaresolverr/flaresolverr
+TimeoutStopSec=30
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now flaresolverr
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 69d66814815f0562eb8418df651ab6427860c63b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 28 Aug 2025 09:56:08 +0200
Subject: [PATCH 258/312] testing
---
ct/flaresolverr.sh | 12 ++++++++++++
install/flaresolverr-install.sh | 1 -
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh
index 95703f86..ea82e5fa 100644
--- a/ct/flaresolverr.sh
+++ b/ct/flaresolverr.sh
@@ -34,6 +34,18 @@ function update_script() {
systemctl stop flaresolverr
msg_ok "Stopped service"
+ PYTHON_VERSION="3.13"setup_uv
+
+ msg_info "prepare uv python 3.13"
+ UV_PY="$(uv python find 3.13)"
+ cat <<'EOF' >/usr/local/bin/python3
+#!/bin/bash
+exec "$UV_PY/bin/python3.13" "$@"
+EOF
+ chmod +x /usr/local/bin/python3
+ ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
+ msg_ok "prepared python 3.13"
+
rm -rf /opt/flaresolverr
fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh
index 628d3205..b7ddbbca 100644
--- a/install/flaresolverr-install.sh
+++ b/install/flaresolverr-install.sh
@@ -39,7 +39,6 @@ chmod +x /usr/local/bin/python3
ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
msg_ok "prepared python 3.13"
-
fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
msg_info "Creating Service"
From 3bab2781e2520ed09e10b4d80f76e8435b7fd5c9 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 28 Aug 2025 10:02:13 +0200
Subject: [PATCH 259/312] fixes
---
ct/flaresolverr.sh | 2 +-
install/flaresolverr-install.sh | 16 ++++++++--------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh
index ea82e5fa..e1cac141 100644
--- a/ct/flaresolverr.sh
+++ b/ct/flaresolverr.sh
@@ -34,7 +34,7 @@ function update_script() {
systemctl stop flaresolverr
msg_ok "Stopped service"
- PYTHON_VERSION="3.13"setup_uv
+ PYTHON_VERSION="3.13" setup_uv
msg_info "prepare uv python 3.13"
UV_PY="$(uv python find 3.13)"
diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh
index b7ddbbca..43dfe477 100644
--- a/install/flaresolverr-install.sh
+++ b/install/flaresolverr-install.sh
@@ -20,14 +20,7 @@ $STD apt-get install -y \
xvfb
msg_ok "Installed Dependencies"
-msg_info "Installing Chrome"
-curl -fsSL "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
-echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google-chrome.list
-$STD apt update
-$STD apt install -y google-chrome-stable
-msg_ok "Installed Chrome"
-
-PYTHON_VERSION="3.13"setup_uv
+PYTHON_VERSION="3.13" setup_uv
msg_info "prepare uv python 3.13"
UV_PY="$(uv python find 3.13)"
@@ -39,6 +32,13 @@ chmod +x /usr/local/bin/python3
ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
msg_ok "prepared python 3.13"
+msg_info "Installing Chrome"
+curl -fsSL "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
+echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google-chrome.list
+$STD apt update
+$STD apt install -y google-chrome-stable
+msg_ok "Installed Chrome"
+
fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
msg_info "Creating Service"
From 431f2bd74168227ffd21c57b80728b2344c3876b Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 28 Aug 2025 13:51:26 +0200
Subject: [PATCH 260/312] ddd
---
ct/flaresolverr.sh | 9 ++++-----
misc/tools.func | 22 +++++++++++++++++++++-
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh
index e1cac141..cf2860f2 100644
--- a/ct/flaresolverr.sh
+++ b/ct/flaresolverr.sh
@@ -28,8 +28,9 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- RELEASE=$(curl -fsSL https://api.github.com/repos/FlareSolverr/FlareSolverr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
- if [[ "${RELEASE}" != "$(cat ~/.flaresolverr 2>/dev/null)" ]] || [[ ! -f ~/.flaresolverr ]]; then
+
+ if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr"; then
+
msg_info "Stopping service"
systemctl stop flaresolverr
msg_ok "Stopped service"
@@ -52,10 +53,8 @@ EOF
msg_info "Starting service"
systemctl start flaresolverr
msg_ok "Started service"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
- exit
+ exit 0
}
start
diff --git a/misc/tools.func b/misc/tools.func
index 96c27a30..f5e7b533 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -2001,7 +2001,27 @@ EOF
fi
}
-check_for_update() {
+# ------------------------------------------------------------------------------
+# Checks for new GitHub release (latest tag).
+#
+# Description:
+# - Queries the GitHub API for the latest release tag
+# - Compares it to a local cached version (~/.)
+# - If newer, sets global CHECK_UPDATE_RELEASE and returns 0
+#
+# Usage:
+# check_for_gh_release "AppName" "user/repo"
+# if [[ $? -eq 0 ]]; then
+# echo "New version available: $CHECK_UPDATE_RELEASE"
+# # trigger update...
+# fi
+#
+# Notes:
+# - Requires `jq` (auto-installed if missing)
+# - Does not modify anything, only checks version state
+# - Does not support pre-releases
+# ------------------------------------------------------------------------------
+check_for_gh_release() {
local app="$1"
local source="$2"
local current_file="$HOME/.${app,,}"
From 694de8a7586c76a624a45fbac9afe6666f69a459 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 28 Aug 2025 16:11:05 +0200
Subject: [PATCH 261/312] Update tools.func
---
misc/tools.func | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/misc/tools.func b/misc/tools.func
index f5e7b533..6b619c44 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -2024,6 +2024,7 @@ EOF
check_for_gh_release() {
local app="$1"
local source="$2"
+ local pinned_version="${3:-}" # optional
local current_file="$HOME/.${app,,}"
msg_info "Check for update: ${app}"
@@ -2043,34 +2044,40 @@ check_for_gh_release() {
fi
# get latest release
- local release
+local release
release=$(curl -fsSL "https://api.github.com/repos/${source}/releases/latest" |
jq -r '.tag_name' | sed 's/^v//')
- # DEBUG
- #echo "[DEBUG] Latest release fetched: '${release}'"
-
if [[ -z "$release" ]]; then
msg_error "Unable to determine latest release for ${app}"
return 1
fi
local current=""
- if [[ -f "$current_file" ]]; then
- current=$(<"$current_file")
+ [[ -f "$current_file" ]] && current=$(<"$current_file")
+
+ # PINNED Releases
+ if [[ -n "$pinned_version" ]]; then
+ if [[ "$pinned_version" == "$release" ]]; then
+ msg_ok "${app} pinned to v${pinned_version} (no update needed)"
+ return 1
+ else
+ if [[ "$current" == "$pinned_version" ]]; then
+ msg_ok "${app} pinned to v${pinned_version} (already installed, upstream v${release})"
+ return 1
+ fi
+ msg_info "${app} pinned to v${pinned_version} (upstream v${release}) → update/downgrade required"
+ CHECK_UPDATE_RELEASE="$pinned_version"
+ return 0
+ fi
fi
- # DEBUG
- #echo "[DEBUG] Current file: '${current_file}'"
- #echo "[DEBUG] Current version read: '${current}'"
-
if [[ "$release" != "$current" ]] || [[ ! -f "$current_file" ]]; then
- #echo "[DEBUG] Decision: Update required (release='${release}' current='${current}')"
CHECK_UPDATE_RELEASE="$release"
+ msg_info "New release available: v${release} (current: v${current:-none})"
return 0
else
- #echo "[DEBUG] Decision: No update (release='${release}' current='${current}')"
msg_ok "${app} is up to date (v${release})"
return 1
fi
-}
+}
\ No newline at end of file
From 34b0ccac5df3deec2314cfa38f788ada19d59e95 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Thu, 28 Aug 2025 13:15:49 -0400
Subject: [PATCH 262/312] Autocaliweb: update DB download paths
---
install/autocaliweb-install.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 9a97b37f..49e36772 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -115,8 +115,8 @@ msg_info "Initializing databases"
KEPUBIFY_PATH=$(command -v kepubify 2>/dev/null || echo "/usr/bin/kepubify")
EBOOK_CONVERT_PATH=$(command -v ebook-convert 2>/dev/null || echo "/usr/bin/ebook-convert")
CALIBRE_BIN_DIR=$(dirname "$EBOOK_CONVERT_PATH")
-curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/master/library/metadata.db -o "$CALIBRE_LIB_DIR"/metadata.db
-curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/master/library/app.db -o "$CONFIG_DIR"/app.db
+curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/main/library/metadata.db -o "$CALIBRE_LIB_DIR"/metadata.db
+curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/main/library/app.db -o "$CONFIG_DIR"/app.db
sqlite3 "$CONFIG_DIR/app.db" <
Date: Fri, 29 Aug 2025 11:41:08 +0200
Subject: [PATCH 263/312] tt
---
ct/flaresolverr.sh | 67 ------------
install/flaresolverr-install.sh | 71 ------------
tools/pve/prx-add-ips.sh | 187 ++++++++++++++++++++++++++++++++
3 files changed, 187 insertions(+), 138 deletions(-)
delete mode 100644 ct/flaresolverr.sh
delete mode 100644 install/flaresolverr-install.sh
create mode 100644 tools/pve/prx-add-ips.sh
diff --git a/ct/flaresolverr.sh b/ct/flaresolverr.sh
deleted file mode 100644
index cf2860f2..00000000
--- a/ct/flaresolverr.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster) | Co-Author: remz1337
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/FlareSolverr/FlareSolverr
-
-APP="FlareSolverr"
-var_tags="${var_tags:-proxy}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-4}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -f /etc/systemd/system/flaresolverr.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr"; then
-
- msg_info "Stopping service"
- systemctl stop flaresolverr
- msg_ok "Stopped service"
-
- PYTHON_VERSION="3.13" setup_uv
-
- msg_info "prepare uv python 3.13"
- UV_PY="$(uv python find 3.13)"
- cat <<'EOF' >/usr/local/bin/python3
-#!/bin/bash
-exec "$UV_PY/bin/python3.13" "$@"
-EOF
- chmod +x /usr/local/bin/python3
- ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
- msg_ok "prepared python 3.13"
-
- rm -rf /opt/flaresolverr
- fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
-
- msg_info "Starting service"
- systemctl start flaresolverr
- msg_ok "Started service"
- fi
- exit 0
-}
-
-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 "${TAB}${GATEWAY}${BGN}http://${IP}:8191${CL}"
diff --git a/install/flaresolverr-install.sh b/install/flaresolverr-install.sh
deleted file mode 100644
index 43dfe477..00000000
--- a/install/flaresolverr-install.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# Co-Author: remz1337
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/FlareSolverr/FlareSolverr
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt-get install -y \
- apt-transport-https \
- xvfb
-msg_ok "Installed Dependencies"
-
-PYTHON_VERSION="3.13" setup_uv
-
-msg_info "prepare uv python 3.13"
-UV_PY="$(uv python find 3.13)"
-cat <<'EOF' >/usr/local/bin/python3
-#!/bin/bash
-exec "$UV_PY/bin/python3.13" "$@"
-EOF
-chmod +x /usr/local/bin/python3
-ln -sf "$UV_PY/bin/python3.13" /usr/local/bin/python3.13
-msg_ok "prepared python 3.13"
-
-msg_info "Installing Chrome"
-curl -fsSL "https://dl.google.com/linux/linux_signing_key.pub" | gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg
-echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" >/etc/apt/sources.list.d/google-chrome.list
-$STD apt update
-$STD apt install -y google-chrome-stable
-msg_ok "Installed Chrome"
-
-fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/flaresolverr.service
-[Unit]
-Description=FlareSolverr
-After=network.target
-[Service]
-SyslogIdentifier=flaresolverr
-Restart=always
-RestartSec=5
-Type=simple
-Environment="LOG_LEVEL=info"
-Environment="CAPTCHA_SOLVER=none"
-WorkingDirectory=/opt/flaresolverr
-ExecStart=/opt/flaresolverr/flaresolverr
-TimeoutStopSec=30
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now flaresolverr
-msg_ok "Created Service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/tools/pve/prx-add-ips.sh b/tools/pve/prx-add-ips.sh
new file mode 100644
index 00000000..244cffd4
--- /dev/null
+++ b/tools/pve/prx-add-ips.sh
@@ -0,0 +1,187 @@
+#!/usr/bin/env bash
+# -----------------------------------------------------------------
+# Proxmox Add-IPs (LXC + VMs → Tags)
+# -----------------------------------------------------------------
+# © 2021-2025 community-scripts ORG
+# Author: MickLesk (CanbiZ)
+# License: MIT
+# -----------------------------------------------------------------
+
+APP="Proxmox Add-IPs"
+FILE_PATH="/usr/local/bin/prx-add-ips"
+CONF_DIR="/opt/prx-add-ips"
+CONF_FILE="$CONF_DIR/prx-add-ips.conf"
+
+set -Eeuo pipefail
+
+# --- Farben (optional) ---
+YW="\033[33m"
+GN="\033[1;92m"
+RD="\033[01;31m"
+CL="\033[m"
+msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; }
+msg_info() { msg "${YW}➜ $1${CL}"; }
+msg_ok() { msg "${GN}✔ $1${CL}"; }
+msg_error() { msg "${RD}✖ $1${CL}"; }
+
+# -----------------------------------------------------------------
+# Installation
+# -----------------------------------------------------------------
+if [[ -f "$FILE_PATH" ]]; then
+ msg_info "$APP already installed at $FILE_PATH"
+ exit 0
+fi
+
+msg_info "Installing dependencies"
+apt-get update -qq
+apt-get install -y jq ipcalc net-tools >/dev/null
+msg_ok "Dependencies installed"
+
+mkdir -p "$CONF_DIR"
+
+# -----------------------------------------------------------------
+# Config
+# -----------------------------------------------------------------
+if [[ ! -f "$CONF_FILE" ]]; then
+ cat <"$CONF_FILE"
+# prx-add-ips.conf – configuration for Proxmox Add-IPs
+
+# Allowed CIDRs
+CIDR_LIST=(
+ 192.168.0.0/16
+ 10.0.0.0/8
+ 172.16.0.0/12
+)
+
+# Main loop interval in seconds
+LOOP_INTERVAL=60
+
+# Use colored output? (true/false)
+USE_COLOR=true
+EOF
+ msg_ok "Default config written to $CONF_FILE"
+else
+ msg_info "Config $CONF_FILE already exists"
+fi
+
+# -----------------------------------------------------------------
+# Main Script
+# -----------------------------------------------------------------
+cat <<"EOF" >"$FILE_PATH"
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+CONFIG_FILE="/opt/prx-add-ips/prx-add-ips.conf"
+[[ -f "$CONFIG_FILE" ]] && source "$CONFIG_FILE"
+
+YW="\033[33m"; GN="\033[1;92m"; RD="\033[01;31m"; CL="\033[m"
+msg() { [[ "${USE_COLOR:-true}" == "true" ]] && echo -e "$@" || echo -e "$(echo "$@" | sed -E 's/\x1B\[[0-9;]*[JKmsu]//g')"; }
+msg_info() { msg "${YW}➜ $1${CL}"; }
+msg_ok() { msg "${GN}✔ $1${CL}"; }
+msg_error(){ msg "${RD}✖ $1${CL}"; }
+
+is_valid_ipv4() {
+ local ip=$1
+ [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
+ for part in ${ip//./ }; do
+ ((part >= 0 && part <= 255)) || return 1
+ done
+ return 0
+}
+
+ip_in_cidrs() {
+ local ip="$1"
+ for cidr in "${CIDR_LIST[@]}"; do
+ ipcalc -nb "$cidr" "$ip" &>/dev/null && return 0
+ done
+ return 1
+}
+
+set_tags() {
+ local vmid="$1" kind="$2"; shift 2
+ local ips=("$@")
+
+ # aktuelle Tags holen
+ local existing_tags=()
+ mapfile -t existing_tags < <($kind config "$vmid" | awk '/tags:/{$1=""; print}' | tr ';' '\n')
+
+ local existing_ips=()
+ local non_ip_tags=()
+ for t in "${existing_tags[@]}"; do
+ if is_valid_ipv4 "$t"; then
+ existing_ips+=("$t")
+ else
+ non_ip_tags+=("$t")
+ fi
+ done
+
+ local new_tags=("${non_ip_tags[@]}" "${ips[@]}")
+ new_tags=($(printf "%s\n" "${new_tags[@]}" | sort -u))
+
+ if [[ "$(printf "%s\n" "${existing_ips[@]}" | sort -u)" != "$(printf "%s\n" "${ips[@]}" | sort -u)" ]]; then
+ msg_info "$kind $vmid → updating tags to ${new_tags[*]}"
+ $kind set "$vmid" -tags "$(IFS=';'; echo "${new_tags[*]}")"
+ else
+ msg_info "$kind $vmid → no IP change"
+ fi
+}
+
+update_lxc_iptags() {
+ for vmid in $(pct list | awk 'NR>1 {print $1}'); do
+ local ips=()
+ for ip in $(lxc-info -n "$vmid" -iH 2>/dev/null); do
+ is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && ips+=("$ip")
+ done
+ [[ ${#ips[@]} -gt 0 ]] && set_tags "$vmid" pct "${ips[@]}"
+ done
+}
+
+update_vm_iptags() {
+ for vmid in $(qm list | awk 'NR>1 {print $1}'); do
+ if qm agent "$vmid" ping &>/dev/null; then
+ local ips=()
+ mapfile -t ips < <(qm agent "$vmid" network-get-interfaces \
+ | jq -r '.[]?."ip-addresses"[]?."ip-address" | select(test("^[0-9]+\\."))')
+ local filtered=()
+ for ip in "${ips[@]}"; do
+ is_valid_ipv4 "$ip" && ip_in_cidrs "$ip" && filtered+=("$ip")
+ done
+ [[ ${#filtered[@]} -gt 0 ]] && set_tags "$vmid" qm "${filtered[@]}"
+ fi
+ done
+}
+
+while true; do
+ update_lxc_iptags
+ update_vm_iptags
+ sleep "${LOOP_INTERVAL:-60}"
+done
+EOF
+
+chmod +x "$FILE_PATH"
+msg_ok "Main script installed to $FILE_PATH"
+
+# -----------------------------------------------------------------
+# Systemd Service
+# -----------------------------------------------------------------
+SERVICE="/etc/systemd/system/prx-add-ips.service"
+if [[ ! -f "$SERVICE" ]]; then
+ cat <"$SERVICE"
+[Unit]
+Description=Proxmox Add-IPs (LXC + VM)
+After=network.target
+
+[Service]
+Type=simple
+ExecStart=$FILE_PATH
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+ msg_ok "Service created"
+fi
+
+systemctl daemon-reload
+systemctl enable -q --now prx-add-ips.service
+msg_ok "$APP service started"
From b6cd9d457c39fa65fbb79c900693d8a8d08e1885 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 29 Aug 2025 12:52:28 +0200
Subject: [PATCH 264/312] Zitadel testing
---
ct/zitadel.sh | 62 +++++++++++++++
install/zitadel-install.sh | 149 +++++++++++++++++++++++++++++++++++++
2 files changed, 211 insertions(+)
create mode 100644 ct/zitadel.sh
create mode 100644 install/zitadel-install.sh
diff --git a/ct/zitadel.sh b/ct/zitadel.sh
new file mode 100644
index 00000000..c35c7b39
--- /dev/null
+++ b/ct/zitadel.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: dave-yap (dave-yap)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://zitadel.com/
+
+APP="Zitadel"
+var_tags="${var_tags:-identity-provider}"
+var_cpu="${var_cpu:-1}"
+var_ram="${var_ram:-1024}"
+var_disk="${var_disk:-8}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+ if [[ ! -f /etc/systemd/system/zitadel.service ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ RELEASE=$(curl -fsSL https://api.github.com/repos/zitadel/zitadel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ if [[ ! -f ~/.zitadel ]] || [[ "${RELEASE}" != "$(cat ~/.zitadel)" ]]; then
+ msg_info "Stopping $APP"
+ systemctl stop zitadel
+ msg_ok "Stopped $APP"
+
+ rm -f /usr/local/bin/zitadel
+ fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-amd64.tar.gz"
+
+ msg_info "Updating $APP to ${RELEASE}"
+ $STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --init-projections=true
+ msg_ok "Updated $APP to ${RELEASE}"
+
+ msg_info "Starting $APP"
+ systemctl start zitadel
+ msg_ok "Started $APP"
+
+ msg_ok "Update Successful"
+ else
+ msg_ok "No update required. ${APP} is already at ${RELEASE}"
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080/ui/console${CL}"
diff --git a/install/zitadel-install.sh b/install/zitadel-install.sh
new file mode 100644
index 00000000..ba8cbdc4
--- /dev/null
+++ b/install/zitadel-install.sh
@@ -0,0 +1,149 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: dave-yap
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://zitadel.com/
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing Dependencies (Patience)"
+$STD apt-get install -y ca-certificates
+msg_ok "Installed Dependecies"
+
+PG_VERSION="17" setup_postgresql
+
+msg_info "Installing Postgresql"
+DB_NAME="zitadel"
+DB_USER="zitadel"
+DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
+DB_ADMIN_USER="root"
+DB_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
+systemctl start postgresql
+$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
+$STD sudo -u postgres psql -c "CREATE USER $DB_ADMIN_USER WITH PASSWORD '$DB_ADMIN_PASS' SUPERUSER;"
+$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_ADMIN_USER;"
+{
+ echo "Application Credentials"
+ echo "DB_NAME: $DB_NAME"
+ echo "DB_USER: $DB_USER"
+ echo "DB_PASS: $DB_PASS"
+ echo "DB_ADMIN_USER: $DB_ADMIN_USER"
+ echo "DB_ADMIN_PASS: $DB_ADMIN_PASS"
+} >>~/zitadel.creds
+msg_ok "Installed PostgreSQL"
+
+fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-amd64.tar.gz"
+
+msg_info "Setting up Zitadel Environments"
+mkdir -p /opt/zitadel
+echo "/opt/zitadel/config.yaml" >"/opt/zitadel/.config"
+head -c 32 < <(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9') >"/opt/zitadel/.masterkey"
+{
+ echo "Config location: $(cat "/opt/zitadel/.config")"
+ echo "Masterkey: $(cat "/opt/zitadel/.masterkey")"
+} >>~/zitadel.creds
+cat </opt/zitadel/config.yaml
+Port: 8080
+ExternalPort: 8080
+ExternalDomain: localhost
+ExternalSecure: false
+TLS:
+ Enabled: false
+ KeyPath: ""
+ Key: ""
+ CertPath: ""
+ Cert: ""
+
+Database:
+ postgres:
+ Host: localhost
+ Port: 5432
+ Database: ${DB_NAME}
+ User:
+ Username: ${DB_USER}
+ Password: ${DB_PASS}
+ SSL:
+ Mode: disable
+ RootCert: ""
+ Cert: ""
+ Key: ""
+ Admin:
+ Username: ${DB_ADMIN_USER}
+ Password: ${DB_ADMIN_PASS}
+ SSL:
+ Mode: disable
+ RootCert: ""
+ Cert: ""
+ Key: ""
+DefaultInstance:
+ Features:
+ LoginV2:
+ Required: false
+EOF
+msg_ok "Installed Zitadel Enviroments"
+
+msg_info "Creating Services"
+cat </etc/systemd/system/zitadel.service
+[Unit]
+Description=ZITADEL Identiy Server
+After=network.target postgresql.service
+Wants=postgresql.service
+
+[Service]
+Type=simple
+User=zitadel
+Group=zitadel
+ExecStart=/usr/local/bin/zitadel start --masterkeyFile "/opt/zitadel/.masterkey" --config "/opt/zitadel/config.yaml"
+Restart=always
+RestartSec=5
+TimeoutStartSec=0
+
+# Security Hardening options
+ProtectSystem=full
+ProtectHome=true
+PrivateTmp=true
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q zitadel
+msg_ok "Created Services"
+
+msg_info "Zitadel initial setup"
+$STD zitadel start-from-init --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
+sleep 60
+kill $(lsof -i | awk '/zitadel/ {print $2}' | head -n1)
+useradd zitadel
+msg_ok "Zitadel initialized"
+
+msg_info "Set ExternalDomain to current IP and restart Zitadel"
+IP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
+sed -i "0,/localhost/s/localhost/${IP}/" /opt/zitadel/config.yaml
+systemctl stop -q zitadel
+$STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
+systemctl restart -q zitadel
+msg_ok "Zitadel restarted with ExternalDomain set to current IP"
+
+msg_info "Create zitadel-rerun.sh"
+cat <~/zitadel-rerun.sh
+systemctl stop zitadel
+timeout --kill-after=5s 15s zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
+systemctl restart zitadel
+EOF
+msg_ok "Bash script for rerunning Zitadel after changing Zitadel config.yaml"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
From 6c742a1d66259455dc53002cd8fe67ad166c4eb7 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 29 Aug 2025 12:53:44 +0200
Subject: [PATCH 265/312] test
---
install/zitadel-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/zitadel-install.sh b/install/zitadel-install.sh
index ba8cbdc4..5b5a8451 100644
--- a/install/zitadel-install.sh
+++ b/install/zitadel-install.sh
@@ -118,7 +118,7 @@ systemctl enable -q zitadel
msg_ok "Created Services"
msg_info "Zitadel initial setup"
-$STD zitadel start-from-init --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
+zitadel start-from-init --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml &>/dev/null &
sleep 60
kill $(lsof -i | awk '/zitadel/ {print $2}' | head -n1)
useradd zitadel
From e0442f88f8351a40f514956829aeb5dffa5722a5 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 30 Aug 2025 06:52:26 +0000
Subject: [PATCH 266/312] Bump next in /frontend in the npm_and_yarn group
across 1 directory
Bumps the npm_and_yarn group with 1 update in the /frontend directory: [next](https://github.com/vercel/next.js).
Updates `next` from 15.2.4 to 15.5.2
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.2.4...v15.5.2)
---
updated-dependencies:
- dependency-name: next
dependency-version: 15.5.2
dependency-type: direct:production
dependency-group: npm_and_yarn
...
Signed-off-by: dependabot[bot]
---
frontend/package-lock.json | 590 ++++++++++++++++++++++++++++++++-----
frontend/package.json | 2 +-
2 files changed, 513 insertions(+), 79 deletions(-)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index fe7ecb63..20bb2092 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -33,7 +33,7 @@
"fuse.js": "^7.1.0",
"lucide-react": "^0.453.0",
"mini-svg-data-uri": "^1.4.4",
- "next": "15.2.4",
+ "next": "15.5.2",
"next-themes": "^0.3.0",
"nuqs": "^2.4.1",
"pocketbase": "^0.21.5",
@@ -441,9 +441,9 @@
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
- "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz",
+ "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==",
"license": "MIT",
"optional": true,
"dependencies": {
@@ -1267,6 +1267,22 @@
"url": "https://opencollective.com/libvips"
}
},
+ "node_modules/@img/sharp-libvips-linux-ppc64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz",
+ "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@img/sharp-libvips-linux-s390x": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
@@ -1375,6 +1391,28 @@
"@img/sharp-libvips-linux-arm64": "1.0.4"
}
},
+ "node_modules/@img/sharp-linux-ppc64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz",
+ "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-ppc64": "1.2.0"
+ }
+ },
"node_modules/@img/sharp-linux-s390x": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
@@ -1482,6 +1520,25 @@
"url": "https://opencollective.com/libvips"
}
},
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz",
+ "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@img/sharp-win32-ia32": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
@@ -1598,9 +1655,9 @@
"license": "MIT"
},
"node_modules/@next/env": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.4.tgz",
- "integrity": "sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.2.tgz",
+ "integrity": "sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
@@ -1644,9 +1701,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.4.tgz",
- "integrity": "sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.2.tgz",
+ "integrity": "sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ==",
"cpu": [
"arm64"
],
@@ -1660,9 +1717,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.4.tgz",
- "integrity": "sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.2.tgz",
+ "integrity": "sha512-2DjnmR6JHK4X+dgTXt5/sOCu/7yPtqpYt8s8hLkHFK3MGkka2snTv3yRMdHvuRtJVkPwCGsvBSwmoQCHatauFQ==",
"cpu": [
"x64"
],
@@ -1676,9 +1733,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.4.tgz",
- "integrity": "sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.2.tgz",
+ "integrity": "sha512-3j7SWDBS2Wov/L9q0mFJtEvQ5miIqfO4l7d2m9Mo06ddsgUK8gWfHGgbjdFlCp2Ek7MmMQZSxpGFqcC8zGh2AA==",
"cpu": [
"arm64"
],
@@ -1692,9 +1749,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.4.tgz",
- "integrity": "sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.2.tgz",
+ "integrity": "sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g==",
"cpu": [
"arm64"
],
@@ -1708,9 +1765,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.4.tgz",
- "integrity": "sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.2.tgz",
+ "integrity": "sha512-o1RV/KOODQh6dM6ZRJGZbc+MOAHww33Vbs5JC9Mp1gDk8cpEO+cYC/l7rweiEalkSm5/1WGa4zY7xrNwObN4+Q==",
"cpu": [
"x64"
],
@@ -1724,9 +1781,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.4.tgz",
- "integrity": "sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.2.tgz",
+ "integrity": "sha512-/VUnh7w8RElYZ0IV83nUcP/J4KJ6LLYliiBIri3p3aW2giF+PAVgZb6mk8jbQSB3WlTai8gEmCAr7kptFa1H6g==",
"cpu": [
"x64"
],
@@ -1740,9 +1797,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.4.tgz",
- "integrity": "sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.2.tgz",
+ "integrity": "sha512-sMPyTvRcNKXseNQ/7qRfVRLa0VhR0esmQ29DD6pqvG71+JdVnESJaHPA8t7bc67KD5spP3+DOCNLhqlEI2ZgQg==",
"cpu": [
"arm64"
],
@@ -1756,9 +1813,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.4.tgz",
- "integrity": "sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.2.tgz",
+ "integrity": "sha512-W5VvyZHnxG/2ukhZF/9Ikdra5fdNftxI6ybeVKYvBPDtyx7x4jPPSNduUkfH5fo3zG0JQ0bPxgy41af2JX5D4Q==",
"cpu": [
"x64"
],
@@ -3043,12 +3100,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@swc/counter": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
- "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
- "license": "Apache-2.0"
- },
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
@@ -4041,17 +4092,6 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
- "node_modules/busboy": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
- "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
- "dependencies": {
- "streamsearch": "^1.1.0"
- },
- "engines": {
- "node": ">=10.16.0"
- }
- },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -4660,9 +4700,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
- "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
+ "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
"license": "Apache-2.0",
"engines": {
"node": ">=8"
@@ -7252,15 +7292,13 @@
"license": "MIT"
},
"node_modules/next": {
- "version": "15.2.4",
- "resolved": "https://registry.npmjs.org/next/-/next-15.2.4.tgz",
- "integrity": "sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==",
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/next/-/next-15.5.2.tgz",
+ "integrity": "sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q==",
"license": "MIT",
"dependencies": {
- "@next/env": "15.2.4",
- "@swc/counter": "0.1.3",
+ "@next/env": "15.5.2",
"@swc/helpers": "0.5.15",
- "busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
"styled-jsx": "5.1.6"
@@ -7272,19 +7310,19 @@
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "15.2.4",
- "@next/swc-darwin-x64": "15.2.4",
- "@next/swc-linux-arm64-gnu": "15.2.4",
- "@next/swc-linux-arm64-musl": "15.2.4",
- "@next/swc-linux-x64-gnu": "15.2.4",
- "@next/swc-linux-x64-musl": "15.2.4",
- "@next/swc-win32-arm64-msvc": "15.2.4",
- "@next/swc-win32-x64-msvc": "15.2.4",
- "sharp": "^0.33.5"
+ "@next/swc-darwin-arm64": "15.5.2",
+ "@next/swc-darwin-x64": "15.5.2",
+ "@next/swc-linux-arm64-gnu": "15.5.2",
+ "@next/swc-linux-arm64-musl": "15.5.2",
+ "@next/swc-linux-x64-gnu": "15.5.2",
+ "@next/swc-linux-x64-musl": "15.5.2",
+ "@next/swc-win32-arm64-msvc": "15.5.2",
+ "@next/swc-win32-x64-msvc": "15.5.2",
+ "sharp": "^0.34.3"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
- "@playwright/test": "^1.41.2",
+ "@playwright/test": "^1.51.1",
"babel-plugin-react-compiler": "*",
"react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
"react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
@@ -7315,6 +7353,367 @@
"react-dom": "^16.8 || ^17 || ^18"
}
},
+ "node_modules/next/node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz",
+ "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-darwin-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz",
+ "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz",
+ "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz",
+ "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz",
+ "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz",
+ "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz",
+ "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz",
+ "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz",
+ "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz",
+ "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linux-arm": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz",
+ "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linux-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz",
+ "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linux-s390x": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz",
+ "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linux-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz",
+ "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz",
+ "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz",
+ "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.0"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-wasm32": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz",
+ "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.4.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-win32-ia32": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz",
+ "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/next/node_modules/@img/sharp-win32-x64": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz",
+ "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -7343,6 +7742,49 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/next/node_modules/sharp": {
+ "version": "0.34.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz",
+ "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.4",
+ "semver": "^7.7.2"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.3",
+ "@img/sharp-darwin-x64": "0.34.3",
+ "@img/sharp-libvips-darwin-arm64": "1.2.0",
+ "@img/sharp-libvips-darwin-x64": "1.2.0",
+ "@img/sharp-libvips-linux-arm": "1.2.0",
+ "@img/sharp-libvips-linux-arm64": "1.2.0",
+ "@img/sharp-libvips-linux-ppc64": "1.2.0",
+ "@img/sharp-libvips-linux-s390x": "1.2.0",
+ "@img/sharp-libvips-linux-x64": "1.2.0",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.0",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.0",
+ "@img/sharp-linux-arm": "0.34.3",
+ "@img/sharp-linux-arm64": "0.34.3",
+ "@img/sharp-linux-ppc64": "0.34.3",
+ "@img/sharp-linux-s390x": "0.34.3",
+ "@img/sharp-linux-x64": "0.34.3",
+ "@img/sharp-linuxmusl-arm64": "0.34.3",
+ "@img/sharp-linuxmusl-x64": "0.34.3",
+ "@img/sharp-wasm32": "0.34.3",
+ "@img/sharp-win32-arm64": "0.34.3",
+ "@img/sharp-win32-ia32": "0.34.3",
+ "@img/sharp-win32-x64": "0.34.3"
+ }
+ },
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
@@ -8631,9 +9073,9 @@
"license": "MIT"
},
"node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -8848,14 +9290,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/streamsearch": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
- "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
- "engines": {
- "node": ">=10.0.0"
- }
- },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 50379a32..27421f71 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -44,7 +44,7 @@
"fuse.js": "^7.1.0",
"lucide-react": "^0.453.0",
"mini-svg-data-uri": "^1.4.4",
- "next": "15.2.4",
+ "next": "15.5.2",
"next-themes": "^0.3.0",
"nuqs": "^2.4.1",
"pocketbase": "^0.21.5",
From c043da1b0ef5362199c71cbf6d129b0163e6dd08 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Mon, 1 Sep 2025 09:17:02 +0200
Subject: [PATCH 267/312] Create alpine-tools.func
---
misc/alpine-tools.func | 535 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 535 insertions(+)
create mode 100644 misc/alpine-tools.func
diff --git a/misc/alpine-tools.func b/misc/alpine-tools.func
new file mode 100644
index 00000000..b03f4f08
--- /dev/null
+++ b/misc/alpine-tools.func
@@ -0,0 +1,535 @@
+#!/bin/ash
+# shellcheck shell=ash
+
+# Erwartet vorhandene msg_* und optional $STD aus deinem Framework.
+
+# ------------------------------
+# kleine Helfer
+# ------------------------------
+lower() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; }
+has() { command -v "$1" >/dev/null 2>&1; }
+
+need_tool() {
+ # usage: need_tool curl jq unzip ...
+ # installiert fehlende Tools via apk --no-cache
+ local missing=0 t
+ for t in "$@"; do
+ if ! has "$t"; then missing=1; fi
+ done
+ if [ "$missing" -eq 1 ]; then
+ msg_info "Installing tools: $*"
+ # busybox 'apk' ist vorhanden auf Alpine
+ apk add --no-cache "$@" >/dev/null 2>&1 || {
+ msg_error "apk add failed for: $*"
+ return 1
+ }
+ msg_ok "Tools ready: $*"
+ fi
+}
+
+net_resolves() {
+ # robust gegen fehlendes getent auf busybox
+ # usage: net_resolves api.github.com
+ local host="$1"
+ ping -c1 -W1 "$host" >/dev/null 2>&1 || nslookup "$host" >/dev/null 2>&1
+}
+
+ensure_usr_local_bin_persist() {
+ local PROFILE_FILE="/etc/profile.d/10-localbin.sh"
+ if [ ! -f "$PROFILE_FILE" ]; then
+ echo 'case ":$PATH:" in *:/usr/local/bin:*) ;; *) export PATH="/usr/local/bin:$PATH";; esac' >"$PROFILE_FILE"
+ chmod +x "$PROFILE_FILE"
+ fi
+}
+
+download_with_progress() {
+ # $1 url, $2 dest
+ local url="$1" out="$2" cl
+ need_tool curl pv || return 1
+ cl=$(curl -fsSLI "$url" 2>/dev/null | awk 'tolower($0) ~ /^content-length:/ {print $2}' | tr -d '\r')
+ if [ -n "$cl" ]; then
+ curl -fsSL "$url" | pv -s "$cl" >"$out" || {
+ msg_error "Download failed: $url"
+ return 1
+ }
+ else
+ curl -fL# -o "$out" "$url" || {
+ msg_error "Download failed: $url"
+ return 1
+ }
+ fi
+}
+
+# ------------------------------
+# GitHub: Release prüfen
+# ------------------------------
+check_for_gh_release() {
+ # app, repo, [pinned]
+ local app="$1" source="$2" pinned="${3:-}"
+ local app_lc
+ app_lc="$(lower "$app" | tr -d ' ')"
+ local current_file="$HOME/.${app_lc}"
+ local current="" release tag
+
+ msg_info "Check for update: $app"
+
+ net_resolves api.github.com || {
+ msg_error "DNS/network error: api.github.com"
+ return 1
+ }
+ need_tool curl jq || return 1
+
+ tag=$(curl -fsSL "https://api.github.com/repos/${source}/releases/latest" | jq -r '.tag_name // empty')
+ [ -z "$tag" ] && {
+ msg_error "Unable to fetch latest tag for $app"
+ return 1
+ }
+ release="${tag#v}"
+
+ [ -f "$current_file" ] && current="$(cat "$current_file")"
+
+ if [ -n "$pinned" ]; then
+ if [ "$pinned" = "$release" ]; then
+ msg_ok "$app pinned to v$pinned (no update)"
+ return 1
+ fi
+ if [ "$current" = "$pinned" ]; then
+ msg_ok "$app pinned v$pinned installed (upstream v$release)"
+ return 1
+ fi
+ msg_info "$app pinned v$pinned (upstream v$release) → update/downgrade"
+ CHECK_UPDATE_RELEASE="$pinned"
+ return 0
+ fi
+
+ if [ "$release" != "$current" ] || [ ! -f "$current_file" ]; then
+ CHECK_UPDATE_RELEASE="$release"
+ msg_info "New release available: v$release (current: v${current:-none})"
+ return 0
+ fi
+
+ msg_ok "$app is up to date (v$release)"
+ return 1
+}
+
+# ------------------------------
+# GitHub: Release holen & deployen (Alpine)
+# modes: tarball | prebuild | singlefile
+# ------------------------------
+fetch_and_deploy_gh() {
+ # $1 app, $2 repo, [$3 mode], [$4 version], [$5 target], [$6 asset_pattern]
+ local app="$1" repo="$2" mode="${3:-tarball}" version="${4:-latest}" target="${5:-/opt/$1}" pattern="${6:-}"
+ local app_lc
+ app_lc="$(lower "$app" | tr -d ' ')"
+ local vfile="$HOME/.${app_lc}"
+ local json url filename tmpd unpack
+
+ net_resolves api.github.com || {
+ msg_error "DNS/network error"
+ return 1
+ }
+ need_tool curl jq tar || return 1
+ [ "$mode" = "prebuild" ] || [ "$mode" = "singlefile" ] && need_tool unzip >/dev/null 2>&1 || true
+
+ tmpd="$(mktemp -d)" || return 1
+ mkdir -p "$target"
+
+ # Release JSON
+ if [ "$version" = "latest" ]; then
+ json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/latest")" || {
+ msg_error "GitHub API failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ else
+ json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/tags/$version")" || {
+ msg_error "GitHub API failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ fi
+
+ # Effektive Version
+ version="$(printf '%s' "$json" | jq -r '.tag_name // empty')"
+ version="${version#v}"
+
+ [ -z "$version" ] && {
+ msg_error "No tag in release json"
+ rm -rf "$tmpd"
+ return 1
+ }
+
+ case "$mode" in
+ tarball | source)
+ url="$(printf '%s' "$json" | jq -r '.tarball_url // empty')"
+ [ -z "$url" ] && url="https://github.com/$repo/archive/refs/tags/v$version.tar.gz"
+ filename="${app_lc}-${version}.tar.gz"
+ download_with_progress "$url" "$tmpd/$filename" || {
+ rm -rf "$tmpd"
+ return 1
+ }
+ tar -xzf "$tmpd/$filename" -C "$tmpd" || {
+ msg_error "tar extract failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ unpack="$(find "$tmpd" -mindepth 1 -maxdepth 1 -type d | head -n1)"
+ # Inhalte nach target kopieren (inkl. dotfiles)
+ (cd "$unpack" && tar -cf - .) | (cd "$target" && tar -xf -) || {
+ msg_error "copy failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ ;;
+ prebuild)
+ [ -n "$pattern" ] || {
+ msg_error "prebuild requires asset pattern"
+ rm -rf "$tmpd"
+ return 1
+ }
+ url="$(printf '%s' "$json" | jq -r '.assets[].browser_download_url' | awk -v p="$pattern" '
+ BEGIN{IGNORECASE=1}
+ $0 ~ p {print; exit}
+ ')"
+ [ -z "$url" ] && {
+ msg_error "asset not found for pattern: $pattern"
+ rm -rf "$tmpd"
+ return 1
+ }
+ filename="${url##*/}"
+ download_with_progress "$url" "$tmpd/$filename" || {
+ rm -rf "$tmpd"
+ return 1
+ }
+ # entpacken je nach Format
+ case "$filename" in
+ *.zip)
+ need_tool unzip || {
+ rm -rf "$tmpd"
+ return 1
+ }
+ mkdir -p "$tmpd/unp"
+ unzip -q "$tmpd/$filename" -d "$tmpd/unp"
+ ;;
+ *.tar.gz | *.tgz | *.tar.xz | *.tar.zst | *.tar.bz2)
+ mkdir -p "$tmpd/unp"
+ tar -xf "$tmpd/$filename" -C "$tmpd/unp"
+ ;;
+ *)
+ msg_error "unsupported archive: $filename"
+ rm -rf "$tmpd"
+ return 1
+ ;;
+ esac
+ # top-level folder ggf. strippen
+ if [ "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -z "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type f | head -n1)" ]; then
+ unpack="$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d)"
+ (cd "$unpack" && tar -cf - .) | (cd "$target" && tar -xf -) || {
+ msg_error "copy failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ else
+ (cd "$tmpd/unp" && tar -cf - .) | (cd "$target" && tar -xf -) || {
+ msg_error "copy failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+ fi
+ ;;
+ singlefile)
+ [ -n "$pattern" ] || {
+ msg_error "singlefile requires asset pattern"
+ rm -rf "$tmpd"
+ return 1
+ }
+ url="$(printf '%s' "$json" | jq -r '.assets[].browser_download_url' | awk -v p="$pattern" '
+ BEGIN{IGNORECASE=1}
+ $0 ~ p {print; exit}
+ ')"
+ [ -z "$url" ] && {
+ msg_error "asset not found for pattern: $pattern"
+ rm -rf "$tmpd"
+ return 1
+ }
+ filename="${url##*/}"
+ download_with_progress "$url" "$target/$app" || {
+ rm -rf "$tmpd"
+ return 1
+ }
+ chmod +x "$target/$app"
+ ;;
+ *)
+ msg_error "Unknown mode: $mode"
+ rm -rf "$tmpd"
+ return 1
+ ;;
+ esac
+
+ echo "$version" >"$vfile"
+ ensure_usr_local_bin_persist
+ rm -rf "$tmpd"
+ msg_ok "Deployed $app ($version) → $target"
+}
+
+# ------------------------------
+# yq (mikefarah) – Alpine
+# ------------------------------
+setup_yq() {
+ # bevorzugt apk, optional FORCE_GH=1 → GitHub Binary
+ if [ "${FORCE_GH:-0}" != "1" ] && apk info -e yq >/dev/null 2>&1; then
+ msg_info "Updating yq via apk"
+ apk add --no-cache --upgrade yq >/dev/null 2>&1 || true
+ msg_ok "yq ready ($(yq --version 2>/dev/null))"
+ return 0
+ fi
+
+ need_tool curl || return 1
+ local arch bin url tmp
+ case "$(uname -m)" in
+ x86_64) arch="amd64" ;;
+ aarch64) arch="arm64" ;;
+ *)
+ msg_error "Unsupported arch for yq: $(uname -m)"
+ return 1
+ ;;
+ esac
+ url="https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${arch}"
+ tmp="$(mktemp)"
+ download_with_progress "$url" "$tmp" || return 1
+ install -m 0755 "$tmp" /usr/local/bin/yq
+ rm -f "$tmp"
+ msg_ok "Setup yq ($(yq --version 2>/dev/null))"
+}
+
+# ------------------------------
+# Adminer – Alpine
+# ------------------------------
+setup_adminer() {
+ need_tool curl || return 1
+ msg_info "Setup Adminer (Alpine)"
+ mkdir -p /var/www/localhost/htdocs/adminer
+ curl -fsSL https://github.com/vrana/adminer/releases/latest/download/adminer.php \
+ -o /var/www/localhost/htdocs/adminer/index.php || {
+ msg_error "Adminer download failed"
+ return 1
+ }
+ msg_ok "Adminer at /adminer (served by your webserver)"
+}
+
+# ------------------------------
+# uv – Alpine (musl tarball)
+# Optional: PYTHON_VERSION="3.12"
+# ------------------------------
+setup_uv() {
+ need_tool curl tar || return 1
+ local UV_BIN="/usr/local/bin/uv"
+ local arch tarball url tmpd ver installed
+
+ case "$(uname -m)" in
+ x86_64) arch="x86_64-unknown-linux-musl" ;;
+ aarch64) arch="aarch64-unknown-linux-musl" ;;
+ *)
+ msg_error "Unsupported arch for uv: $(uname -m)"
+ return 1
+ ;;
+ esac
+
+ ver="$(curl -fsSL https://api.github.com/repos/astral-sh/uv/releases/latest | jq -r '.tag_name' 2>/dev/null)"
+ ver="${ver#v}"
+ [ -z "$ver" ] && {
+ msg_error "uv: cannot determine latest version"
+ return 1
+ }
+
+ if has "$UV_BIN"; then
+ installed="$($UV_BIN -V 2>/dev/null | awk '{print $2}')"
+ [ "$installed" = "$ver" ] && {
+ msg_ok "uv $ver already installed"
+ return 0
+ }
+ msg_info "Updating uv $installed → $ver"
+ else
+ msg_info "Setup uv $ver"
+ fi
+
+ tmpd="$(mktemp -d)" || return 1
+ tarball="uv-${arch}.tar.gz"
+ url="https://github.com/astral-sh/uv/releases/download/v${ver}/${tarball}"
+
+ download_with_progress "$url" "$tmpd/uv.tar.gz" || {
+ rm -rf "$tmpd"
+ return 1
+ }
+ tar -xzf "$tmpd/uv.tar.gz" -C "$tmpd" || {
+ msg_error "uv: extract failed"
+ rm -rf "$tmpd"
+ return 1
+ }
+
+ # tar enthält ./uv
+ if [ -x "$tmpd/uv" ]; then
+ install -m 0755 "$tmpd/uv" "$UV_BIN"
+ else
+ # fallback: in Unterordner
+ install -m 0755 "$tmpd"/*/uv "$UV_BIN" 2>/dev/null || {
+ msg_error "uv binary not found in tar"
+ rm -rf "$tmpd"
+ return 1
+ }
+ fi
+ rm -rf "$tmpd"
+ ensure_usr_local_bin_persist
+ msg_ok "Setup uv $ver"
+
+ if [ -n "${PYTHON_VERSION:-}" ]; then
+ # uv liefert cpython builds für musl; den neuesten Patchstand finden:
+ local match
+ match="$(uv python list --only-downloads 2>/dev/null | awk -v maj="$PYTHON_VERSION" '
+ $0 ~ "^cpython-"maj"\\." { print $0 }' | awk -F- '{print $2}' | sort -V | tail -n1)"
+ [ -z "$match" ] && {
+ msg_error "No matching Python for $PYTHON_VERSION"
+ return 1
+ }
+ if ! uv python list | grep -q "cpython-${match}-linux"; then
+ msg_info "Installing Python $match via uv"
+ uv python install "$match" || {
+ msg_error "uv python install failed"
+ return 1
+ }
+ msg_ok "Python $match installed (uv)"
+ fi
+ fi
+}
+
+# ------------------------------
+# Java – Alpine (OpenJDK)
+# JAVA_VERSION: 17|21 (Default 21)
+# ------------------------------
+setup_java() {
+ local JAVA_VERSION="${JAVA_VERSION:-21}" pkg
+ case "$JAVA_VERSION" in
+ 17) pkg="openjdk17-jdk" ;;
+ 21 | *) pkg="openjdk21-jdk" ;;
+ esac
+ msg_info "Setup Java (OpenJDK $JAVA_VERSION)"
+ apk add --no-cache "$pkg" >/dev/null 2>&1 || {
+ msg_error "apk add $pkg failed"
+ return 1
+ }
+ # JAVA_HOME setzen
+ local prof="/etc/profile.d/20-java.sh"
+ if [ ! -f "$prof" ]; then
+ echo 'export JAVA_HOME=$(dirname $(dirname $(readlink -f $(command -v java))))' >"$prof"
+ echo 'case ":$PATH:" in *:$JAVA_HOME/bin:*) ;; *) export PATH="$JAVA_HOME/bin:$PATH";; esac' >>"$prof"
+ chmod +x "$prof"
+ fi
+ msg_ok "Java ready: $(java -version 2>&1 | head -n1)"
+}
+
+# ------------------------------
+# Go – Alpine (apk bevorzugt; optional GO_VERSION tarball)
+# ------------------------------
+setup_go() {
+ if [ -z "${GO_VERSION:-}" ]; then
+ msg_info "Setup Go (apk)"
+ apk add --no-cache go >/dev/null 2>&1 || {
+ msg_error "apk add go failed"
+ return 1
+ }
+ msg_ok "Go ready: $(go version 2>/dev/null)"
+ return 0
+ fi
+
+ # explizite Version via offizielles tar.gz
+ need_tool curl tar || return 1
+ local ARCH TARBALL URL TMP
+ case "$(uname -m)" in
+ x86_64) ARCH="amd64" ;;
+ aarch64) ARCH="arm64" ;;
+ *)
+ msg_error "Unsupported arch for Go: $(uname -m)"
+ return 1
+ ;;
+ esac
+ TARBALL="go${GO_VERSION}.linux-${ARCH}.tar.gz"
+ URL="https://go.dev/dl/${TARBALL}"
+ msg_info "Setup Go $GO_VERSION (tarball)"
+ TMP="$(mktemp)"
+ download_with_progress "$URL" "$TMP" || return 1
+ rm -rf /usr/local/go
+ tar -C /usr/local -xzf "$TMP" || {
+ msg_error "extract go failed"
+ rm -f "$TMP"
+ return 1
+ }
+ rm -f "$TMP"
+ ln -sf /usr/local/go/bin/go /usr/local/bin/go
+ ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
+ ensure_usr_local_bin_persist
+ msg_ok "Go ready: $(go version 2>/dev/null)"
+}
+
+# ------------------------------
+# Composer – Alpine
+# nutzt php83-cli + openssl + phar
+# ------------------------------
+setup_composer() {
+ local COMPOSER_BIN="/usr/local/bin/composer"
+ if ! has php; then
+ # bevorzugt php83 auf Alpine 3.20/3.21+
+ msg_info "Installing PHP CLI for Composer"
+ apk add --no-cache php83-cli php83-openssl php83-phar php83-iconv >/dev/null 2>&1 || {
+ # Fallback auf generisches php-cli
+ apk add --no-cache php-cli php-openssl php-phar php-iconv >/dev/null 2>&1 || {
+ msg_error "Failed to install php-cli for composer"
+ return 1
+ }
+ }
+ fi
+
+ if [ -x "$COMPOSER_BIN" ]; then
+ msg_info "Updating Composer"
+ else
+ msg_info "Setup Composer"
+ fi
+
+ need_tool curl || return 1
+ curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php || {
+ msg_error "composer installer download failed"
+ return 1
+ }
+ php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer >/dev/null 2>&1 || {
+ msg_error "composer install failed"
+ return 1
+ }
+ rm -f /tmp/composer-setup.php
+ ensure_usr_local_bin_persist
+ msg_ok "Composer ready: $(composer --version 2>/dev/null)"
+}
+
+# ------------------------------
+# Adminer/uv/go/java/yq/composer stehen oben
+# ------------------------------
+
+# ------------------------------
+# (Optional) LOCAL_IP import – POSIX-safe
+# ------------------------------
+import_local_ip() {
+ # lädt LOCAL_IP aus /run/local-ip.env oder ermittelt es best effort
+ local IP_FILE="/run/local-ip.env"
+ if [ -f "$IP_FILE" ]; then
+ # shellcheck disable=SC1090
+ . "$IP_FILE"
+ fi
+ if [ -z "${LOCAL_IP:-}" ]; then
+ LOCAL_IP="$(ip route get 1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')"
+ [ -z "$LOCAL_IP" ] && LOCAL_IP="$(hostname -i 2>/dev/null | awk '{print $1}')"
+ [ -z "$LOCAL_IP" ] && {
+ msg_error "Could not determine LOCAL_IP"
+ return 1
+ }
+ echo "LOCAL_IP=$LOCAL_IP" >"$IP_FILE"
+ fi
+ export LOCAL_IP
+}
From 005f1204d81c6b12d7c8763612c2eb6ea762aa06 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 10:32:11 +0200
Subject: [PATCH 268/312] Update alpine-install.func
---
misc/alpine-install.func | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/alpine-install.func b/misc/alpine-install.func
index 450e9209..906d5b14 100644
--- a/misc/alpine-install.func
+++ b/misc/alpine-install.func
@@ -83,7 +83,7 @@ network_check() {
update_os() {
msg_info "Updating Container OS"
$STD apk update && $STD apk upgrade
- source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
+ source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/alpine-tools.func)
msg_ok "Updated Container OS"
}
From a9de7571ec8d1be387d049d4014250351b190518 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 10:52:25 +0200
Subject: [PATCH 269/312] Update build.func
---
misc/build.func | 324 +++++++++++++++++++++++++++++++++---------------
1 file changed, 222 insertions(+), 102 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 011f4398..15151f6e 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -13,7 +13,7 @@ variables() {
DIAGNOSTICS="yes" # sets the DIAGNOSTICS variable to "yes", used for the API call.
METHOD="default" # sets the METHOD variable to "default", used for the API call.
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable.
- CT_TYPE=${var_unprivileged:-$CT_TYPE}
+ #CT_TYPE=${var_unprivileged:-$CT_TYPE}
}
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func)
@@ -214,93 +214,6 @@ ssh_check() {
fi
}
-# select_storage() {
-# local CLASS=$1 CONTENT CONTENT_LABEL
-# case $CLASS in
-# container)
-# CONTENT='rootdir'
-# CONTENT_LABEL='Container'
-# ;;
-# template)
-# CONTENT='vztmpl'
-# CONTENT_LABEL='Template'
-# ;;
-# iso)
-# CONTENT='iso'
-# CONTENT_LABEL='ISO image'
-# ;;
-# images)
-# CONTENT='images'
-# CONTENT_LABEL='VM Disk image'
-# ;;
-# backup)
-# CONTENT='backup'
-# CONTENT_LABEL='Backup'
-# ;;
-# snippets)
-# CONTENT='snippets'
-# CONTENT_LABEL='Snippets'
-# ;;
-# *)
-# msg_error "Invalid storage class '$CLASS'."
-# exit 201
-# ;;
-# esac
-
-# command -v whiptail >/dev/null || {
-# msg_error "whiptail missing."
-# exit 220
-# }
-# command -v numfmt >/dev/null || {
-# msg_error "numfmt missing."
-# exit 221
-# }
-
-# local -a MENU
-# while read -r line; do
-# local TAG=$(echo "$line" | awk '{print $1}')
-# local TYPE=$(echo "$line" | awk '{printf "%-10s", $2}')
-# local FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf "%9sB", $6}')
-# MENU+=("$TAG" "Type: $TYPE Free: $FREE" "OFF")
-# done < <(pvesm status -content "$CONTENT" | awk 'NR>1')
-
-# if [ ${#MENU[@]} -eq 0 ]; then
-# msg_error "No storage found for content type '$CONTENT'."
-# exit 203
-# fi
-
-# if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
-# echo "${MENU[0]}"
-# return
-# fi
-
-# local STORAGE
-# STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
-# "Which storage pool for ${CONTENT_LABEL,,}?\n(Spacebar to select)" \
-# 16 70 6 "${MENU[@]}" 3>&1 1>&2 2>&3) || {
-# msg_error "Storage selection cancelled by user."
-# exit 202
-# }
-# echo "$STORAGE"
-# }
-
-# manage_default_storage() {
-# local file="/usr/local/community-scripts/default_storage"
-# mkdir -p /usr/local/community-scripts
-
-# local tmpl=$(select_storage template)
-# local cont=$(select_storage container)
-
-# cat <"$file"
-# TEMPLATE_STORAGE=$tmpl
-# CONTAINER_STORAGE=$cont
-# EOF
-
-# msg_ok "Default Storage set: Template=${BL}$tmpl${CL} ${GN}|${CL} Container=${BL}$cont${CL}"
-# whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
-# --msgbox "Default Storage set:\n\nTemplate: $tmpl\nContainer: $cont" 10 58
-# }
-
base_settings() {
# Default Settings
CT_TYPE=${var_unprivileged:-"1"}
@@ -902,6 +815,205 @@ EOF
}
+# ------------------------------------------------------------------------------
+# default_var_settings
+#
+# - Ensures /usr/local/community-scripts/default.vars exists (creates if missing)
+# - Loads var_* values from default.vars (safe parser, no source/eval)
+# - Precedence: ENV var_* > default.vars > built-in defaults
+# - Maps var_verbose → VERBOSE
+# - Calls base_settings "$VERBOSE" and echo_default
+# ------------------------------------------------------------------------------
+default_var_settings() {
+ # Allowed var_* keys (alphabetically sorted)
+ local VAR_WHITELIST=(
+ var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_ctid var_disk var_fuse
+ var_gateway var_hostname var_ipv6_method var_ipv6_static var_mac var_mtu
+ var_net var_ns var_os var_pw var_ram var_storage var_tags var_tun var_unprivileged
+ var_verbose var_version var_vlan var_ssh var_ssh_authorized_key
+ )
+
+ # Snapshot: environment variables (highest precedence)
+ declare -A _HARD_ENV=()
+ local _k
+ for _k in "${VAR_WHITELIST[@]}"; do
+ if printenv "$_k" >/dev/null 2>&1; then _HARD_ENV["$_k"]=1; fi
+ done
+
+ # Find default.vars (first valid path wins)
+ local _find_default_vars
+ _find_default_vars() {
+ local f
+ for f in \
+ /usr/local/community-scripts/default.vars \
+ "$HOME/.config/community-scripts/default.vars" \
+ "./default.vars"; do
+ [ -f "$f" ] && {
+ echo "$f"
+ return 0
+ }
+ done
+ return 1
+ }
+
+ # Ensure default.vars exists, create with sane defaults if missing
+ local _ensure_default_vars
+ _ensure_default_vars() {
+ _find_default_vars >/dev/null 2>&1 && return 0
+ local canonical="/usr/local/community-scripts/default.vars"
+ msg_info "No default.vars found. Creating ${canonical}"
+ mkdir -p /usr/local/community-scripts
+ cat >"$canonical" <<'EOF'
+# Community-Scripts defaults (var_* only). Lines starting with # are comments.
+# Precedence: ENV var_* > default.vars > built-ins.
+# Keep keys alphabetically sorted.
+
+# CT/OS
+var_os=debian
+var_version=12
+var_unprivileged=1
+
+# Resources
+var_cpu=1
+var_disk=4
+var_ram=1024
+
+# Network
+var_brg=vmbr0
+var_net=dhcp
+var_ipv6_method=auto
+# var_gateway=
+# var_ipv6_static=
+# var_vlan=
+# var_mtu=
+# var_mac=
+# var_ns=
+# var_storage=
+
+# SSH
+var_ssh=no
+# var_ssh_authorized_key=
+
+# APT Cacher
+# var_apt_cacher=yes
+# var_apt_cacher_ip=192.168.1.10
+
+# Features/Tags
+var_fuse=no
+var_tun=no
+var_tags=community-script
+var_verbose=no
+
+# Security (root PW) – empty => Autologin
+# var_pw=
+
+# CTID/Hostname – empty => auto
+# var_ctid=
+# var_hostname=
+EOF
+ chmod 0644 "$canonical"
+ msg_ok "Created ${canonical}"
+ }
+
+ # Whitelist check
+ local _is_whitelisted_key
+ _is_whitelisted_key() {
+ local k="$1"
+ local w
+ for w in "${VAR_WHITELIST[@]}"; do [ "$k" = "$w" ] && return 0; done
+ return 1
+ }
+
+ # Safe parser for KEY=VALUE lines
+ local _load_vars_file
+ _load_vars_file() {
+ local file="$1"
+ [ -f "$file" ] || return 0
+ msg_info "Loading defaults from ${file}"
+ local line key val
+ while IFS= read -r line || [ -n "$line" ]; do
+ line="${line#"${line%%[![:space:]]*}"}"
+ line="${line%"${line##*[![:space:]]}"}"
+ [[ -z "$line" || "$line" == \#* ]] && continue
+ if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
+ local var_key="${BASH_REMATCH[1]}"
+ local var_val="${BASH_REMATCH[2]}"
+
+ [[ "$var_key" != var_* ]] && continue
+ _is_whitelisted_key "$var_key" || {
+ msg_debug "Ignore non-whitelisted ${var_key}"
+ continue
+ }
+
+ # Strip quotes
+ if [[ "$var_val" =~ ^\"(.*)\"$ ]]; then
+ var_val="${BASH_REMATCH[1]}"
+ elif [[ "$var_val" =~ ^\'(.*)\'$ ]]; then
+ var_val="${BASH_REMATCH[1]}"
+ fi
+
+ # Unsafe check without regex (formatter-friendly)
+ local _unsafe=""
+ case "$var_val" in
+ *'$('*) _unsafe=1 ;;
+ *'`'*) _unsafe=1 ;;
+ *';'*) _unsafe=1 ;;
+ *'&'*) _unsafe=1 ;;
+ *'<('*) _unsafe=1 ;;
+ esac
+ if [[ -n "$_unsafe" ]]; then
+ msg_warn "Ignoring ${var_key} from ${file}: unsafe characters"
+ continue
+ fi
+
+ # Hard env wins
+ if [[ -n "${_HARD_ENV[$var_key]:-}" ]]; then
+ continue
+ fi
+
+ # Set only if not already exported
+ if [[ -z "${!var_key+x}" ]]; then
+ export "${var_key}=${var_val}"
+ fi
+
+ else
+ msg_warn "Malformed line in ${file}: ${line}"
+ fi
+
+ done <"$file"
+ msg_ok "Loaded ${file}"
+ }
+
+ # 1) Ensure file exists
+ _ensure_default_vars
+
+ # 2) Load file
+ local dv
+ dv="$(_find_default_vars)" || {
+ msg_error "default.vars not found after ensure step"
+ return 1
+ }
+ _load_vars_file "$dv"
+
+ # 3) Map var_verbose → VERBOSE
+ if [[ -n "${var_verbose:-}" ]]; then
+ case "${var_verbose,,}" in
+ 1 | yes | true | on) VERBOSE="yes" ;;
+ 0 | no | false | off) VERBOSE="no" ;;
+ *) VERBOSE="${var_verbose}" ;;
+ esac
+ else
+ VERBOSE="no"
+ fi
+
+ # 4) Apply base settings and show summary
+ METHOD="mydefaults-global"
+ base_settings "$VERBOSE"
+ header_info
+ echo -e "${DEFAULT}${BOLD}${BL}Using My Defaults (default.vars) on node $PVEHOST_NAME${CL}"
+ echo_default
+}
+
install_script() {
pve_check
shell_check
@@ -931,23 +1043,27 @@ install_script() {
ADVANCED | advanced | 3)
CHOICE="3"
;;
+ DEFAULT_VARS | default_vars | 4)
+ CHOICE="4"
+ ;;
*)
echo -e "\n${CROSS}${RD}Invalid PRESET value: ${PRESET}${CL}\n"
exit 1
;;
esac
else
+ #"4" "Use Config File" \
+ #"5" "Manage Default Storage" \
while true; do
TMP_CHOICE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
--title "SETTINGS" \
- --menu "Choose an option:" 20 60 7 \
+ --menu "Choose an option:" 20 60 6 \
"1" "Default Settings" \
"2" "Default Settings (with verbose)" \
"3" "Advanced Settings" \
- "4" "Use Config File" \
- "5" "Manage Default Storage" \
- "6" "Diagnostic Settings" \
- "7" "Exit" \
+ "4" "My Default Vars" \
+ "5" "Diagnostic Settings" \
+ "6" "Exit" \
--default-item "1" 3>&1 1>&2 2>&3) || true
if [ -z "$TMP_CHOICE" ]; then
@@ -984,17 +1100,21 @@ install_script() {
base_settings
advanced_settings
;;
+ # 4)
+ # header_info
+ # echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}"
+ # METHOD="advanced"
+ # source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func)
+ # config_file
+ # ;;
4)
- header_info
- echo -e "${INFO}${HOLD} ${GN}Using Config File on node $PVEHOST_NAME${CL}"
- METHOD="advanced"
- source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/config-file.func)
- config_file
+ # My Defaults (default.vars)
+ default_var_settings || {
+ msg_error "Failed to apply default.vars"
+ exit 1
+ }
;;
5)
- manage_default_storage
- ;;
- 6)
if [[ $DIAGNOSTICS == "yes" ]]; then
if whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "DIAGNOSTICS SETTINGS" --yesno "Send Diagnostics of LXC Installation?\n\nCurrent setting: ${DIAGNOSTICS}" 10 58 \
--yes-button "No" --no-button "Back"; then
@@ -1011,7 +1131,7 @@ install_script() {
fi
fi
;;
- 7)
+ 6)
echo -e "\n${CROSS}${RD}Script terminated. Have a great day!${CL}\n"
exit 0
;;
From 9aeb67624d5907a0589163a7f676adc6685f9e34 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 10:54:51 +0200
Subject: [PATCH 270/312] dev
---
misc/build.func | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 15151f6e..88c3395a 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -829,8 +829,8 @@ default_var_settings() {
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_ctid var_disk var_fuse
var_gateway var_hostname var_ipv6_method var_ipv6_static var_mac var_mtu
- var_net var_ns var_os var_pw var_ram var_storage var_tags var_tun var_unprivileged
- var_verbose var_version var_vlan var_ssh var_ssh_authorized_key
+ var_net var_ns var_pw var_ram var_storage var_tags var_tun var_unprivileged
+ var_verbose var_vlan var_ssh var_ssh_authorized_key
)
# Snapshot: environment variables (highest precedence)
@@ -864,13 +864,12 @@ default_var_settings() {
msg_info "No default.vars found. Creating ${canonical}"
mkdir -p /usr/local/community-scripts
cat >"$canonical" <<'EOF'
+ cat >"$canonical" <<'EOF'
# Community-Scripts defaults (var_* only). Lines starting with # are comments.
# Precedence: ENV var_* > default.vars > built-ins.
# Keep keys alphabetically sorted.
-# CT/OS
-var_os=debian
-var_version=12
+# Container type
var_unprivileged=1
# Resources
@@ -894,20 +893,20 @@ var_ipv6_method=auto
var_ssh=no
# var_ssh_authorized_key=
-# APT Cacher
+# APT cacher (optional)
# var_apt_cacher=yes
# var_apt_cacher_ip=192.168.1.10
-# Features/Tags
+# Features/Tags/verbosity
var_fuse=no
var_tun=no
var_tags=community-script
var_verbose=no
-# Security (root PW) – empty => Autologin
+# Security (root PW) – empty => autologin
# var_pw=
-# CTID/Hostname – empty => auto
+# Optional fixed CTID/hostname – empty => auto
# var_ctid=
# var_hostname=
EOF
From 6525f097b31102ef672877f3a3df6cbb82619941 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 11:07:31 +0200
Subject: [PATCH 271/312] Update build.func
---
misc/build.func | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 88c3395a..ef345f80 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -829,8 +829,8 @@ default_var_settings() {
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_ctid var_disk var_fuse
var_gateway var_hostname var_ipv6_method var_ipv6_static var_mac var_mtu
- var_net var_ns var_pw var_ram var_storage var_tags var_tun var_unprivileged
- var_verbose var_vlan var_ssh var_ssh_authorized_key
+ var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged
+ var_verbose var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
)
# Snapshot: environment variables (highest precedence)
@@ -864,7 +864,6 @@ default_var_settings() {
msg_info "No default.vars found. Creating ${canonical}"
mkdir -p /usr/local/community-scripts
cat >"$canonical" <<'EOF'
- cat >"$canonical" <<'EOF'
# Community-Scripts defaults (var_* only). Lines starting with # are comments.
# Precedence: ENV var_* > default.vars > built-ins.
# Keep keys alphabetically sorted.
@@ -872,6 +871,11 @@ default_var_settings() {
# Container type
var_unprivileged=1
+# Storage
+# Example: "local", "docker", ...
+# var_template_storage=local
+# var_container_storage=docker
+
# Resources
var_cpu=1
var_disk=4
@@ -880,14 +884,13 @@ var_ram=1024
# Network
var_brg=vmbr0
var_net=dhcp
-var_ipv6_method=auto
+var_ipv6_method=none
# var_gateway=
# var_ipv6_static=
# var_vlan=
# var_mtu=
# var_mac=
# var_ns=
-# var_storage=
# SSH
var_ssh=no
From d044aaa785f8e945270e1f9d21efe0570eec1071 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 11:10:00 +0200
Subject: [PATCH 272/312] storage preselection
---
misc/create_lxc.sh | 95 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 79 insertions(+), 16 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index f2aa05de..83b31d1a 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -58,6 +58,55 @@ function exit_script() {
exit 1
}
+# Resolve and validate a preselected storage for a given class.
+# class: "template" -> requires content=vztmpl
+# "container" -> requires content=rootdir
+resolve_storage_preselect() {
+ local class="$1"
+ local preselect="$2"
+ local required_content=""
+ case "$class" in
+ template) required_content="vztmpl" ;;
+ container) required_content="rootdir" ;;
+ *) return 1 ;;
+ esac
+
+ # No preselect provided
+ [ -z "$preselect" ] && return 1
+
+ # Check storage exists and supports required content
+ if ! pvesm status -content "$required_content" | awk 'NR>1{print $1}' | grep -qx -- "$preselect"; then
+ msg_warn "Preselected storage '${preselect}' does not support content '${required_content}' (or not found)"
+ return 1
+ fi
+
+ # Build human-readable info string from pvesm status
+ # Expected columns: Name Type Status Total Used Free ...
+ local line total used free
+ line="$(pvesm status | awk -v s="$preselect" 'NR>1 && $1==s {print $0}')"
+ if [ -z "$line" ]; then
+ STORAGE_INFO="n/a"
+ else
+ total="$(echo "$line" | awk '{print $4}')"
+ used="$(echo "$line" | awk '{print $5}')"
+ free="$(echo "$line" | awk '{print $6}')"
+ # Format bytes to IEC
+ local total_h used_h free_h
+ if command -v numfmt >/dev/null 2>&1; then
+ total_h="$(numfmt --to=iec --suffix=B --format %.1f "$total" 2>/dev/null || echo "$total")"
+ used_h="$(numfmt --to=iec --suffix=B --format %.1f "$used" 2>/dev/null || echo "$used")"
+ free_h="$(numfmt --to=iec --suffix=B --format %.1f "$free" 2>/dev/null || echo "$free")"
+ STORAGE_INFO="Free: ${free_h} Used: ${used_h}"
+ else
+ STORAGE_INFO="Free: ${free} Used: ${used}"
+ fi
+ fi
+
+ # Set outputs expected by your callers
+ STORAGE_RESULT="$preselect"
+ return 0
+}
+
function check_storage_support() {
local CONTENT="$1"
local -a VALID_STORAGES=()
@@ -214,23 +263,37 @@ if ! check_storage_support "vztmpl"; then
exit 1
fi
-while true; do
- if select_storage template; then
- TEMPLATE_STORAGE="$STORAGE_RESULT"
- TEMPLATE_STORAGE_INFO="$STORAGE_INFO"
- msg_ok "Storage ${BL}$TEMPLATE_STORAGE${CL} ($TEMPLATE_STORAGE_INFO) [Template]"
- break
- fi
-done
+# Template storage selection
+if resolve_storage_preselect template "${TEMPLATE_STORAGE}"; then
+ TEMPLATE_STORAGE="$STORAGE_RESULT"
+ TEMPLATE_STORAGE_INFO="$STORAGE_INFO"
+ msg_ok "Storage ${BL}${TEMPLATE_STORAGE}${CL} (${TEMPLATE_STORAGE_INFO}) [Template]"
+else
+ while true; do
+ if select_storage template; then
+ TEMPLATE_STORAGE="$STORAGE_RESULT"
+ TEMPLATE_STORAGE_INFO="$STORAGE_INFO"
+ msg_ok "Storage ${BL}${TEMPLATE_STORAGE}${CL} (${TEMPLATE_STORAGE_INFO}) [Template]"
+ break
+ fi
+ done
+fi
-while true; do
- if select_storage container; then
- CONTAINER_STORAGE="$STORAGE_RESULT"
- CONTAINER_STORAGE_INFO="$STORAGE_INFO"
- msg_ok "Storage ${BL}$CONTAINER_STORAGE${CL} ($CONTAINER_STORAGE_INFO) [Container]"
- break
- fi
-done
+# Container storage selection
+if resolve_storage_preselect container "${CONTAINER_STORAGE}"; then
+ CONTAINER_STORAGE="$STORAGE_RESULT"
+ CONTAINER_STORAGE_INFO="$STORAGE_INFO"
+ msg_ok "Storage ${BL}${CONTAINER_STORAGE}${CL} (${CONTAINER_STORAGE_INFO}) [Container]"
+else
+ while true; do
+ if select_storage container; then
+ CONTAINER_STORAGE="$STORAGE_RESULT"
+ CONTAINER_STORAGE_INFO="$STORAGE_INFO"
+ msg_ok "Storage ${BL}${CONTAINER_STORAGE}${CL} (${CONTAINER_STORAGE_INFO}) [Container]"
+ break
+ fi
+ done
+fi
# Storage Content Validation
msg_info "Validating content types of storage '$CONTAINER_STORAGE'"
From 3720e1c6f053db93a7c8189e6bd6d43a3cc569c0 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 11:11:36 +0200
Subject: [PATCH 273/312] Update build.func
---
misc/build.func | 2 ++
1 file changed, 2 insertions(+)
diff --git a/misc/build.func b/misc/build.func
index ef345f80..e203738c 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1285,6 +1285,8 @@ build_container() {
-unprivileged $CT_TYPE
$PW
"
+ export TEMPLATE_STORAGE="${var_template_storage:-}"
+ export CONTAINER_STORAGE="${var_container_storage:-}"
bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/create_lxc.sh)" || exit
if [ $? -ne 0 ]; then
exit 200
From 5ebb011f356d9381fb13ef48b7244e31d0405dc5 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 11:21:32 +0200
Subject: [PATCH 274/312] Update build.func
---
misc/build.func | 187 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 187 insertions(+)
diff --git a/misc/build.func b/misc/build.func
index e203738c..5e84c226 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1016,6 +1016,192 @@ EOF
echo_default
}
+get_app_defaults_path() {
+ local n="${NSAPP:-${APP,,}}"
+ echo "/usr/local/community-scripts/defaults/${n}.vars"
+}
+
+# ------------------------------------------------------------------------------
+# maybe_offer_save_app_defaults
+#
+# - Called after advanced_settings returned with fully chosen values.
+# - If no .vars exists, offers to persist current advanced settings
+# into /usr/local/community-scripts/defaults/.vars
+# - Only writes whitelisted var_* keys.
+# - Extracts raw values from flags like ",gw=..." ",mtu=..." etc.
+# ------------------------------------------------------------------------------
+maybe_offer_save_app_defaults() {
+ local app_vars_path
+ app_vars_path="$(get_app_defaults_path)"
+
+ # Only offer if file does not exist yet
+ if [ -f "$app_vars_path" ]; then
+ return 0
+ fi
+
+ # Ask user (English prompt as requested)
+ if ! whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
+ --yesno "Save these advanced settings as defaults for ${APP}?\n\nThis will create:\n${app_vars_path}" 12 72; then
+ return 0
+ fi
+
+ # Ensure directory exists
+ mkdir -p "$(dirname "$app_vars_path")"
+
+ # Normalizers (extract raw values from flags used during building)
+ local _val
+
+ # NET/GATE: NET is either 'dhcp' or a CIDR; GATE holds ',gw=IP' or ''
+ local _net="${NET:-}"
+ local _gate=""
+ if [[ "${GATE:-}" =~ ^,gw= ]]; then
+ _gate="${GATE#,gw=}"
+ fi
+
+ # IPv6: method + optional static + optional gateway
+ local _ipv6_method="${IPV6_METHOD:-auto}"
+ local _ipv6_static=""
+ local _ipv6_gateway=""
+ case "$_ipv6_method" in
+ static)
+ _ipv6_static="${IPV6_ADDR:-}"
+ _ipv6_gateway="${IPV6_GATE:-}"
+ ;;
+ esac
+
+ # MTU: MTU looks like ',mtu=1500' or ''
+ local _mtu=""
+ if [[ "${MTU:-}" =~ ^,mtu= ]]; then
+ _mtu="${MTU#,mtu=}"
+ fi
+
+ # VLAN: ',tag=NN' or ''
+ local _vlan=""
+ if [[ "${VLAN:-}" =~ ^,tag= ]]; then
+ _vlan="${VLAN#,tag=}"
+ fi
+
+ # MAC: ',hwaddr=XX:XX:...' or ''
+ local _mac=""
+ if [[ "${MAC:-}" =~ ^,hwaddr= ]]; then
+ _mac="${MAC#,hwaddr=}"
+ fi
+
+ # DNS nameserver: NS is like '-nameserver=IP' or ''
+ local _ns=""
+ if [[ "${NS:-}" =~ ^-nameserver= ]]; then
+ _ns="${NS#-nameserver=}"
+ fi
+
+ # Search domain: SD is like '-searchdomain=foo' or ''
+ local _searchdomain=""
+ if [[ "${SD:-}" =~ ^-searchdomain= ]]; then
+ _searchdomain="${SD#-searchdomain=}"
+ fi
+
+ # Authorized key: raw string already
+ local _ssh_auth="${SSH_AUTHORIZED_KEY:-}"
+
+ # SSH enabled: "yes"/"no"
+ local _ssh="${SSH:-no}"
+
+ # APT cacher
+ local _apt_cacher="${APT_CACHER:-}"
+ local _apt_cacher_ip="${APT_CACHER_IP:-}"
+
+ # Features
+ local _fuse="${ENABLE_FUSE:-no}"
+ local _tun="${ENABLE_TUN:-no}"
+
+ # Tags: TAGS may include 'community-script;' etc. Keep as-is unless empty
+ local _tags="${TAGS:-}"
+
+ # Unprivileged container type: CT_TYPE is "1" (unpriv) or "0" (priv)
+ local _unpriv="${CT_TYPE:-1}"
+
+ # Resources and names
+ local _cpu="${CORE_COUNT:-1}"
+ local _ram="${RAM_SIZE:-1024}"
+ local _disk="${DISK_SIZE:-4}"
+ local _hostname="${HN:-$NSAPP}"
+
+ # Verbose
+ local _verbose="${VERBOSE:-no}"
+
+ # Optional storages if already known in this phase
+ local _tpl_storage="${TEMPLATE_STORAGE:-}"
+ local _ct_storage="${CONTAINER_STORAGE:-}"
+
+ # Sanitize function for values (basic safety for config file)
+ _sanitize_value() {
+ local s="$1"
+ # Disallow backticks, $(), <(), ;, &
+ case "$s" in
+ *'$('* | *'`'* | *';'* | *'&'* | *'<('*)
+ echo ""
+ ;;
+ *)
+ echo "$s"
+ ;;
+ esac
+ }
+
+ # Build the file content
+ {
+ echo "# App-specific defaults for ${APP} (${NSAPP})"
+ echo "# Generated on $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
+ echo "# Only var_* keys are read by the loader."
+ echo
+
+ # Container type
+ echo "var_unprivileged=$(_sanitize_value "$_unpriv")"
+
+ # Resources
+ echo "var_cpu=$(_sanitize_value "$_cpu")"
+ echo "var_ram=$(_sanitize_value "$_ram")"
+ echo "var_disk=$(_sanitize_value "$_disk")"
+
+ # Network
+ [ -n "$BRG" ] && echo "var_brg=$(_sanitize_value "$BRG")"
+ [ -n "$_net" ] && echo "var_net=$(_sanitize_value "$_net")"
+ [ -n "$_gate" ] && echo "var_gateway=$(_sanitize_value "$_gate")"
+ [ -n "$_mtu" ] && echo "var_mtu=$(_sanitize_value "$_mtu")"
+ [ -n "$_vlan" ] && echo "var_vlan=$(_sanitize_value "$_vlan")"
+ [ -n "$_mac" ] && echo "var_mac=$(_sanitize_value "$_mac")"
+ [ -n "$_ns" ] && echo "var_ns=$(_sanitize_value "$_ns")"
+
+ # IPv6
+ [ -n "$_ipv6_method" ] && echo "var_ipv6_method=$(_sanitize_value "$_ipv6_method")"
+ [ -n "$_ipv6_static" ] && echo "var_ipv6_static=$(_sanitize_value "$_ipv6_static")"
+ # Note: we do not persist a dedicated var for IPv6 gateway; can be derived if needed
+
+ # SSH
+ [ -n "$_ssh" ] && echo "var_ssh=$(_sanitize_value "$_ssh")"
+ [ -n "$_ssh_auth" ] && echo "var_ssh_authorized_key=$(_sanitize_value "$_ssh_auth")"
+
+ # APT cacher
+ [ -n "$_apt_cacher" ] && echo "var_apt_cacher=$(_sanitize_value "$_apt_cacher")"
+ [ -n "$_apt_cacher_ip" ] && echo "var_apt_cacher_ip=$(_sanitize_value "$_apt_cacher_ip")"
+
+ # Features / tags / verbosity
+ [ -n "$_fuse" ] && echo "var_fuse=$(_sanitize_value "$_fuse")"
+ [ -n "$_tun" ] && echo "var_tun=$(_sanitize_value "$_tun")"
+ [ -n "$_tags" ] && echo "var_tags=$(_sanitize_value "$_tags")"
+ [ -n "$_verbose" ] && echo "var_verbose=$(_sanitize_value "$_verbose")"
+
+ # Identity (optional)
+ [ -n "$_hostname" ] && echo "var_hostname=$(_sanitize_value "$_hostname")"
+ [ -n "$_searchdomain" ] && echo "var_searchdomain=$(_sanitize_value "$_searchdomain")"
+
+ # Storage (optional, if known at this stage)
+ [ -n "$_tpl_storage" ] && echo "var_template_storage=$(_sanitize_value "$_tpl_storage")"
+ [ -n "$_ct_storage" ] && echo "var_container_storage=$(_sanitize_value "$_ct_storage")"
+ } >"$app_vars_path"
+
+ chmod 0644 "$app_vars_path"
+ msg_ok "Saved app defaults: ${app_vars_path}"
+}
+
install_script() {
pve_check
shell_check
@@ -1101,6 +1287,7 @@ install_script() {
METHOD="advanced"
base_settings
advanced_settings
+ maybe_offer_save_app_defaults
;;
# 4)
# header_info
From 36d2b0fb7f883c2969ae9d7d6a2c3bd5a6f9d9d8 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 20:33:44 +0200
Subject: [PATCH 275/312] fix docker formatting
---
vm/docker-vm.sh | 730 ++++++++++++++++++++++++------------------------
1 file changed, 361 insertions(+), 369 deletions(-)
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index 67455134..a396bac5 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -2,13 +2,15 @@
# Copyright (c) 2021-2025 community-scripts ORG
# Author: thost96 (thost96) | Co-Author: michelroegl-brunner
+# Refactor (q35 + PVE9 virt-customize network fix): MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+set -e
source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
function header_info() {
- clear
- cat <<"EOF"
+ clear
+ cat <<"EOF"
____ __ _ ____ ___
/ __ \____ _____/ /_____ _____ | | / / |/ /
/ / / / __ \/ ___/ //_/ _ \/ ___/ | | / / /|_/ /
@@ -19,6 +21,8 @@ EOF
}
header_info
echo -e "\n Loading..."
+
+# ---------- Globals ----------
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
@@ -29,13 +33,10 @@ DISK_SIZE="10G"
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
-HA=$(echo "\033[1;34m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
-CL=$(echo "\033[m")
-
CL=$(echo "\033[m")
BOLD=$(echo "\033[1m")
BFR="\\r\\033[K"
@@ -59,349 +60,276 @@ MACADDRESS="${TAB}🔗${TAB}${CL}"
VLANTAG="${TAB}🏷️${TAB}${CL}"
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
+CLOUD="${TAB}☁️${TAB}${CL}"
+
THIN="discard=on,ssd=1,"
-set -e
+
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap cleanup EXIT
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
+
function error_handler() {
- local exit_code="$?"
- local line_number="$1"
- local command="$2"
- post_update_to_api "failed" "${command}"
- local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
- echo -e "\n$error_message\n"
- cleanup_vmid
+ local exit_code="$?"
+ local line_number="$1"
+ local command="$2"
+ local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
+ post_update_to_api "failed" "${command}"
+ echo -e "\n$error_message\n"
+ cleanup_vmid
}
function get_valid_nextid() {
- local try_id
- try_id=$(pvesh get /cluster/nextid)
- while true; do
- if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
- try_id=$((try_id + 1))
- continue
- fi
- if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
- try_id=$((try_id + 1))
- continue
- fi
- break
- done
- echo "$try_id"
+ local try_id
+ try_id=$(pvesh get /cluster/nextid)
+ while true; do
+ if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
+ try_id=$((try_id + 1))
+ continue
+ fi
+ if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
+ try_id=$((try_id + 1))
+ continue
+ fi
+ break
+ done
+ echo "$try_id"
}
function cleanup_vmid() {
- if qm status $VMID &>/dev/null; then
- qm stop $VMID &>/dev/null
- qm destroy $VMID &>/dev/null
- fi
+ if qm status $VMID &>/dev/null; then
+ qm stop $VMID &>/dev/null || true
+ qm destroy $VMID &>/dev/null || true
+ fi
}
function cleanup() {
- popd >/dev/null
- post_update_to_api "done" "none"
- rm -rf $TEMP_DIR
+ popd >/dev/null || true
+ post_update_to_api "done" "none"
+ rm -rf "$TEMP_DIR"
}
TEMP_DIR=$(mktemp -d)
-pushd $TEMP_DIR >/dev/null
-if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
- :
-else
- header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
+pushd "$TEMP_DIR" >/dev/null
+
+if ! whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
+ header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
fi
-function msg_info() {
- local msg="$1"
- echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
-}
-
-function msg_ok() {
- local msg="$1"
- echo -e "${BFR}${CM}${GN}${msg}${CL}"
-}
-
-function msg_error() {
- local msg="$1"
- echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
-}
+function msg_info() { echo -ne "${TAB}${YW}${HOLD}$1${HOLD}"; }
+function msg_ok() { echo -e "${BFR}${CM}${GN}$1${CL}"; }
+function msg_error() { echo -e "${BFR}${CROSS}${RD}$1${CL}"; }
function check_root() {
- if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
- clear
- msg_error "Please run this script as root."
- echo -e "\nExiting..."
- sleep 2
- exit
- fi
+ if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
+ clear
+ msg_error "Please run this script as root."
+ echo -e "\nExiting..."
+ sleep 2
+ exit
+ fi
}
-function pve_check() {
- if ! pveversion | grep -Eq "pve-manager/8\.[1-4](\.[0-9]+)*"; then
- msg_error "${CROSS}${RD}This version of Proxmox Virtual Environment is not supported"
- echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
- echo -e "Exiting..."
- sleep 2
- exit
- fi
+# Supported: Proxmox VE 8.0.x – 8.9.x and 9.0 (NOT 9.1+)
+pve_check() {
+ local PVE_VER
+ PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
+ if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
+ local MINOR="${BASH_REMATCH[1]}"
+ ((MINOR >= 0 && MINOR <= 9)) && return 0
+ msg_error "This version of Proxmox VE is not supported."
+ exit 1
+ fi
+ if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
+ local MINOR="${BASH_REMATCH[1]}"
+ ((MINOR == 0)) && return 0
+ msg_error "This version of Proxmox VE is not yet supported (9.1+)."
+ exit 1
+ fi
+ msg_error "This version of Proxmox VE is not supported (need 8.x or 9.0)."
+ exit 1
}
function arch_check() {
- if [ "$(dpkg --print-architecture)" != "amd64" ]; then
- echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
- echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
- echo -e "Exiting..."
- sleep 2
- exit
- fi
+ if [ "$(dpkg --print-architecture)" != "amd64" ]; then
+ echo -e "\n ${INFO}This script will not work with PiMox! \n"
+ echo -e "\n Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
+ echo -e "Exiting..."
+ sleep 2
+ exit
+ fi
}
function ssh_check() {
- if command -v pveversion >/dev/null 2>&1; then
- if [ -n "${SSH_CLIENT:+x}" ]; then
- if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
- echo "you've been warned"
- else
- clear
- exit
- fi
+ if command -v pveversion >/dev/null 2>&1 && [ -n "${SSH_CLIENT:+x}" ]; then
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Proceed anyway?" 10 62; then
+ :
+ else
+ clear
+ exit
+ fi
fi
- fi
}
function exit-script() {
- clear
- echo -e "\n${CROSS}${RD}User exited script${CL}\n"
- exit
+ clear
+ echo -e "\n${CROSS}${RD}User exited script${CL}\n"
+ exit
}
function default_settings() {
- VMID=$(get_valid_nextid)
- FORMAT=",efitype=4m"
- MACHINE=""
- DISK_CACHE=""
- DISK_SIZE="8G"
- HN="docker"
- CPU_TYPE=""
- CORE_COUNT="2"
- RAM_SIZE="4096"
- BRG="vmbr0"
- MAC="$GEN_MAC"
- VLAN=""
- MTU=""
- START_VM="yes"
- METHOD="default"
- echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
- echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
- echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
- echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
- echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
- echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
- echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
- echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
- echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
- echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above default settings${CL}"
+ VMID=$(get_valid_nextid)
+ FORMAT=",efitype=4m"
+ DISK_CACHE=""
+ DISK_SIZE="10G"
+ HN="docker"
+ CPU_TYPE=""
+ CORE_COUNT="2"
+ RAM_SIZE="4096"
+ BRG="vmbr0"
+ MAC="$GEN_MAC"
+ VLAN=""
+ MTU=""
+ START_VM="yes"
+ METHOD="default"
+ echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
+ echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
+ echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
+ echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
+ echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
+ echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
+ echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
+ echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
+ echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
+ echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
+ echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above default settings${CL}"
}
function advanced_settings() {
- METHOD="advanced"
- [ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
- while true; do
- if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z "$VMID" ]; then
- VMID=$(get_valid_nextid)
- fi
- if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
- echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
- sleep 2
- continue
- fi
- echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
- break
+ METHOD="advanced"
+ [ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
+ while true; do
+ if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ [ -z "$VMID" ] && VMID=$(get_valid_nextid)
+ if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
+ echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
+ sleep 2
+ continue
+ fi
+ echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
+ break
+ else exit-script; fi
+ done
+
+ # Force q35 like our other scripts
+ FORMAT=",efitype=4m"
+ echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
+
+ if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
+ if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then DISK_SIZE="${DISK_SIZE}G"; fi
+ [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]] || {
+ echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size.${CL}"
+ exit-script
+ }
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
+ else exit-script; fi
+
+ if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
+ "0" "None (Default)" ON "1" "Write Through" OFF 3>&1 1>&2 2>&3); then
+ if [ "$DISK_CACHE" = "1" ]; then
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
+ DISK_CACHE="cache=writethrough,"
+ else
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
+ DISK_CACHE=""
+ fi
+ else exit-script; fi
+
+ if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ if [ -z "$VM_NAME" ]; then HN="docker"; else HN=$(echo ${VM_NAME,,} | tr -d ' '); fi
+ echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
+ else exit-script; fi
+
+ if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
+ "0" "KVM64 (Default)" ON "1" "Host" OFF 3>&1 1>&2 2>&3); then
+ if [ "$CPU_TYPE1" = "1" ]; then
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
+ CPU_TYPE=" -cpu host"
+ else
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
+ CPU_TYPE=""
+ fi
+ else exit-script; fi
+
+ if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ [ -z "$CORE_COUNT" ] && CORE_COUNT="2"
+ echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
+ else exit-script; fi
+
+ if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ [ -z "$RAM_SIZE" ] && RAM_SIZE="2048"
+ echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
+ else exit-script; fi
+
+ if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ [ -z "$BRG" ] && BRG="vmbr0"
+ echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
+ else exit-script; fi
+
+ if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ if [ -z "$MAC1" ]; then MAC="$GEN_MAC"; else MAC="$MAC1"; fi
+ echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
+ else exit-script; fi
+
+ if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ if [ -z "$VLAN1" ]; then
+ VLAN1="Default"
+ VLAN=""
+ else VLAN=",tag=$VLAN1"; fi
+ echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
+ else exit-script; fi
+
+ if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ if [ -z "$MTU1" ]; then
+ MTU1="Default"
+ MTU=""
+ else MTU=",mtu=$MTU1"; fi
+ echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
+ else exit-script; fi
+
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58; then
+ echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
+ START_VM="yes"
else
- exit-script
+ echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
+ START_VM="no"
fi
- done
- if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
- "i440fx" "Machine i440fx" ON \
- "q35" "Machine q35" OFF \
- 3>&1 1>&2 2>&3); then
- if [ $MACH = q35 ]; then
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
- FORMAT=""
- MACHINE=" -machine q35"
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58; then
+ echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
else
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
- FORMAT=",efitype=4m"
- MACHINE=""
+ header_info
+ echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
+ advanced_settings
fi
- else
- exit-script
- fi
-
- if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
- if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
- DISK_SIZE="${DISK_SIZE}G"
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
- elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; then
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
- else
- echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
- exit-script
- fi
- else
- exit-script
- fi
-
- if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
- "0" "None (Default)" ON \
- "1" "Write Through" OFF \
- 3>&1 1>&2 2>&3); then
- if [ $DISK_CACHE = "1" ]; then
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
- DISK_CACHE="cache=writethrough,"
- else
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
- DISK_CACHE=""
- fi
- else
- exit-script
- fi
-
- if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $VM_NAME ]; then
- HN="docker"
- echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
- else
- HN=$(echo ${VM_NAME,,} | tr -d ' ')
- echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
- fi
- else
- exit-script
- fi
-
- if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
- "0" "KVM64 (Default)" ON \
- "1" "Host" OFF \
- 3>&1 1>&2 2>&3); then
- if [ $CPU_TYPE1 = "1" ]; then
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
- CPU_TYPE=" -cpu host"
- else
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
- CPU_TYPE=""
- fi
- else
- exit-script
- fi
-
- if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $CORE_COUNT ]; then
- CORE_COUNT="2"
- echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
- else
- echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
- fi
- else
- exit-script
- fi
-
- if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $RAM_SIZE ]; then
- RAM_SIZE="2048"
- echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
- else
- echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
- fi
- else
- exit-script
- fi
-
- if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $BRG ]; then
- BRG="vmbr0"
- echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
- else
- echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
- fi
- else
- exit-script
- fi
-
- if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $MAC1 ]; then
- MAC="$GEN_MAC"
- echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
- else
- MAC="$MAC1"
- echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
- fi
- else
- exit-script
- fi
-
- if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $VLAN1 ]; then
- VLAN1="Default"
- VLAN=""
- echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
- else
- VLAN=",tag=$VLAN1"
- echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
- fi
- else
- exit-script
- fi
-
- if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
- if [ -z $MTU1 ]; then
- MTU1="Default"
- MTU=""
- echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
- else
- MTU=",mtu=$MTU1"
- echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
- fi
- else
- exit-script
- fi
-
- if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
- echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
- START_VM="yes"
- else
- echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
- START_VM="no"
- fi
-
- if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
- echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
- else
- header_info
- echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
- advanced_settings
- fi
}
function start_script() {
- if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
- header_info
- echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
- default_settings
- else
- header_info
- echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
- advanced_settings
- fi
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58; then
+ header_info
+ echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
+ default_settings
+ else
+ header_info
+ echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
+ advanced_settings
+ fi
}
+
check_root
arch_check
pve_check
@@ -409,103 +337,165 @@ ssh_check
start_script
post_to_api_vm
+# ---------- Storage selection ----------
msg_info "Validating Storage"
while read -r line; do
- TAG=$(echo $line | awk '{print $1}')
- TYPE=$(echo $line | awk '{printf "%-10s", $2}')
- FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
- ITEM=" Type: $TYPE Free: $FREE "
- OFFSET=2
- if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
- MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
- fi
- STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
+ TAG=$(echo $line | awk '{print $1}')
+ TYPE=$(echo $line | awk '{printf "%-10s", $2}')
+ FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
+ ITEM=" Type: $TYPE Free: $FREE "
+ OFFSET=2
+ if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
+ MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
+ fi
+ STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content images | awk 'NR>1')
VALID=$(pvesm status -content images | awk 'NR>1')
if [ -z "$VALID" ]; then
- msg_error "Unable to detect a valid storage location."
- exit
+ msg_error "Unable to detect a valid storage location."
+ exit
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
- STORAGE=${STORAGE_MENU[0]}
+ STORAGE=${STORAGE_MENU[0]}
else
- while [ -z "${STORAGE:+x}" ]; do
- STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
- "Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
- 16 $(($MSG_MAX_LENGTH + 23)) 6 \
- "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
- done
+ while [ -z "${STORAGE:+x}" ]; do
+ STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
+ "Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
+ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
+ "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
+ done
fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
+
+# ---------- Download Debian Cloud Image ----------
msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image"
URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
-sleep 2
+sleep 1
msg_ok "${CL}${BL}${URL}${CL}"
curl -f#SL -o "$(basename "$URL")" "$URL"
echo -en "\e[1A\e[0K"
-FILE=$(basename $URL)
+FILE=$(basename "$URL")
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
-STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
-case $STORAGE_TYPE in
-nfs | dir)
- DISK_EXT=".qcow2"
- DISK_REF="$VMID/"
- DISK_IMPORT="-format qcow2"
- THIN=""
- ;;
-btrfs)
- DISK_EXT=".raw"
- DISK_REF="$VMID/"
- DISK_IMPORT="-format raw"
- FORMAT=",efitype=4m"
- THIN=""
- ;;
-esac
-for i in {0,1}; do
- disk="DISK$i"
- eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
- eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
-done
-
+# ---------- Ensure libguestfs-tools ----------
if ! command -v virt-customize &>/dev/null; then
- msg_info "Installing Pre-Requisite libguestfs-tools onto Host"
- apt-get -qq update >/dev/null
- apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
- msg_ok "Installed libguestfs-tools successfully"
+ msg_info "Installing libguestfs-tools on host"
+ apt-get -qq update >/dev/null
+ apt-get -qq install -y libguestfs-tools lsb-release >/dev/null
+ msg_ok "Installed libguestfs-tools"
fi
-msg_info "Adding UniFi OS Server Installer to Debian 12 Qcow2 Disk Image"
-UOS_VERSION="4.2.23"
-UOS_URL="https://fw-download.ubnt.com/data/unifi-os-server/8b93-linux-x64-4.2.23-158fa00b-6b2c-4cd8-94ea-e92bc4a81369.23-x64"
-UOS_INSTALLER="unifi-os-server-${UOS_VERSION}.bin"
+# ---------- First-boot Docker installer (avoids network in virt-customize on PVE9) ----------
+msg_info "Preparing first-boot Docker install (inside guest)"
+mkdir -p firstboot
+cat >firstboot/firstboot-docker.sh <<'EOSH'
+#!/usr/bin/env bash
+set -e
+LOG=/var/log/firstboot-docker.log
+exec >>"$LOG" 2>&1
+
+touch /var/lib/firstboot/.running
+export DEBIAN_FRONTEND=noninteractive
+
+apt-get update -qq
+apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https software-properties-common lsb-release
+
+install -m 0755 -d /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+chmod a+r /etc/apt/keyrings/docker.gpg
+echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" >/etc/apt/sources.list.d/docker.list
+
+apt-get update -qq
+apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+systemctl enable --now qemu-guest-agent || true
+systemctl enable --now docker
+
+mkdir -p /var/lib/firstboot
+date > /var/lib/firstboot/docker.done
+rm -f /var/lib/firstboot/.running
+EOSH
+chmod +x firstboot/firstboot-docker.sh
+
+cat >firstboot/firstboot-docker.service <<'EOUNIT'
+[Unit]
+Description=First boot: install Docker & QGA
+After=network-online.target
+Wants=network-online.target
+ConditionPathExists=!/var/lib/firstboot/docker.done
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/sbin/firstboot-docker.sh
+RemainAfterExit=no
+
+[Install]
+WantedBy=multi-user.target
+EOUNIT
+
+# hostname + machine-id reset for cloud-init style behaviour
+echo "$HN" >firstboot/hostname
+
+# Inject files without requiring guest network
virt-customize -q -a "${FILE}" \
- --install qemu-guest-agent,ca-certificates,curl,lsb-release,podman \
- --run-command "curl -fsSL '${UOS_URL}' -o /root/${UOS_INSTALLER} && chmod +x /root/${UOS_INSTALLER}" >/dev/null
-
-msg_ok "Added UniFi OS Server Installer to Debian 12 Qcow2 Disk Image successfully"
+ --copy-in firstboot/firstboot-docker.sh:/usr/local/sbin \
+ --copy-in firstboot/firstboot-docker.service:/etc/systemd/system \
+ --copy-in firstboot/hostname:/etc \
+ --run-command "chmod +x /usr/local/sbin/firstboot-docker.sh" \
+ --run-command "systemctl enable firstboot-docker.service" \
+ --run-command "echo -n > /etc/machine-id" \
+ --run-command "truncate -s 0 /etc/hostname && mv /etc/hostname /etc/hostname.orig && echo '${HN}' >/etc/hostname" >/dev/null
+msg_ok "Prepared first-boot installer & hostname"
+# ---------- Expand partition offline ----------
msg_info "Expanding root partition to use full disk space"
qemu-img create -f qcow2 expanded.qcow2 ${DISK_SIZE} >/dev/null 2>&1
virt-resize --expand /dev/sda1 ${FILE} expanded.qcow2 >/dev/null 2>&1
mv expanded.qcow2 ${FILE} >/dev/null 2>&1
msg_ok "Expanded image to full size"
-msg_info "Creating a Docker VM"
-qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
- -name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
-pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
-qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
-qm set $VMID \
- -efidisk0 ${DISK0_REF}${FORMAT} \
- -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
- -boot order=scsi0 \
- -serial0 socket >/dev/null
-qm resize $VMID scsi0 8G >/dev/null
-qm set $VMID --agent enabled=1 >/dev/null
+# ---------- Create VM shell (q35) ----------
+msg_info "Creating a Docker VM shell"
+qm create "$VMID" -machine q35 -bios ovmf -agent 1 -tablet 0 -localtime 1 ${CPU_TYPE} \
+ -cores "$CORE_COUNT" -memory "$RAM_SIZE" -name "$HN" -tags community-script \
+ -net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
+msg_ok "Created VM shell"
+# ---------- Import disk ----------
+msg_info "Importing disk into storage ($STORAGE)"
+if qm disk import --help >/dev/null 2>&1; then
+ IMPORT_CMD=(qm disk import)
+else
+ IMPORT_CMD=(qm importdisk)
+fi
+IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "${FILE}" "$STORAGE" --format qcow2 2>&1 || true)"
+DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
+[[ -z "$DISK_REF" ]] && DISK_REF="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
+[[ -z "$DISK_REF" ]] && {
+ msg_error "Unable to determine imported disk reference."
+ echo "$IMPORT_OUT"
+ exit 1
+}
+msg_ok "Imported disk (${CL}${BL}${DISK_REF}${CL})"
+
+# ---------- Attach EFI + root disk ----------
+msg_info "Attaching EFI and root disk"
+qm set "$VMID" \
+ --efidisk0 "${STORAGE}:0${FORMAT}" \
+ --scsi0 "${DISK_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE}" \
+ --boot order=scsi0 \
+ --serial0 socket >/dev/null
+qm set "$VMID" --agent enabled=1 >/dev/null
+msg_ok "Attached EFI and root disk"
+
+# ---------- Ensure final size (PVE layer) ----------
+msg_info "Resizing disk to $DISK_SIZE (PVE layer)"
+qm resize "$VMID" scsi0 "${DISK_SIZE}" >/dev/null || true
+msg_ok "Resized disk"
+
+# ---------- Description ----------
DESCRIPTION=$(
- cat <
@@ -537,10 +527,12 @@ EOF
qm set "$VMID" -description "$DESCRIPTION" >/dev/null
msg_ok "Created a Docker VM ${CL}${BL}(${HN})"
+
if [ "$START_VM" == "yes" ]; then
- msg_info "Starting Docker VM"
- qm start $VMID
- msg_ok "Started Docker VM"
+ msg_info "Starting Docker VM"
+ qm start $VMID
+ msg_ok "Started Docker VM"
fi
+
post_update_to_api "done" "none"
msg_ok "Completed Successfully!\n"
From ed6dad511e97b4ca6b46b45e67b732b6443aa7ca Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 20:47:08 +0200
Subject: [PATCH 276/312] Update docker-vm.sh
---
vm/docker-vm.sh | 143 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 114 insertions(+), 29 deletions(-)
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index a396bac5..6655c7e6 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -337,6 +337,48 @@ ssh_check
start_script
post_to_api_vm
+function choose_os() {
+ if OS_CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
+ --title "Choose Base OS" \
+ --radiolist "Select the OS for the Docker VM:" 12 60 3 \
+ "debian12" "Debian 12 (Bookworm, stable & best for scripts)" ON \
+ "debian13" "Debian 13 (Trixie, newer, but repos lag)" OFF \
+ "ubuntu24" "Ubuntu 24.04 LTS (modern kernel, GPU/AI friendly)" OFF \
+ 3>&1 1>&2 2>&3); then
+ case "$OS_CHOICE" in
+ debian12)
+ var_os="debian"
+ var_version="12"
+ URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
+ ;;
+ debian13)
+ var_os="debian"
+ var_version="13"
+ URL="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-$(dpkg --print-architecture).qcow2"
+ ;;
+ ubuntu24)
+ var_os="ubuntu"
+ var_version="24.04"
+ URL="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-$(dpkg --print-architecture).img"
+ ;;
+ esac
+ echo -e "${OS}${BOLD}${DGN}Selected OS: ${BGN}${OS_CHOICE}${CL}"
+ else
+ exit-script
+ fi
+}
+
+PVE_VER=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1 | cut -d'.' -f1)
+
+if [ "$PVE_VER" -eq 8 ]; then
+ INSTALL_MODE="direct"
+elif [ "$PVE_VER" -eq 9 ]; then
+ INSTALL_MODE="firstboot"
+else
+ msg_error "Unsupported Proxmox VE version: $PVE_VER"
+ exit 1
+fi
+
# ---------- Storage selection ----------
msg_info "Validating Storage"
while read -r line; do
@@ -368,12 +410,9 @@ msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
# ---------- Download Debian Cloud Image ----------
-msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image"
-URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
-sleep 1
-msg_ok "${CL}${BL}${URL}${CL}"
+choose_os
+msg_info "Retrieving Cloud Image for $var_os $var_version"
curl -f#SL -o "$(basename "$URL")" "$URL"
-echo -en "\e[1A\e[0K"
FILE=$(basename "$URL")
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
@@ -385,25 +424,72 @@ if ! command -v virt-customize &>/dev/null; then
msg_ok "Installed libguestfs-tools"
fi
-# ---------- First-boot Docker installer (avoids network in virt-customize on PVE9) ----------
-msg_info "Preparing first-boot Docker install (inside guest)"
-mkdir -p firstboot
-cat >firstboot/firstboot-docker.sh <<'EOSH'
+# ---------- Decide distro codename & Docker repo base from chosen URL ----------
+# (choose_os must have set $URL and we've downloaded $FILE above; we only need URL to derive codename)
+if [[ "$URL" == *"/bookworm/"* || "$FILE" == *"debian-12-"* ]]; then
+ CODENAME="bookworm"
+ DOCKER_BASE="https://download.docker.com/linux/debian"
+elif [[ "$URL" == *"/trixie/"* || "$FILE" == *"debian-13-"* ]]; then
+ CODENAME="trixie"
+ DOCKER_BASE="https://download.docker.com/linux/debian"
+elif [[ "$URL" == *"/noble/"* || "$FILE" == *"noble-"* ]]; then
+ CODENAME="noble"
+ DOCKER_BASE="https://download.docker.com/linux/ubuntu"
+else
+ CODENAME="bookworm"
+ DOCKER_BASE="https://download.docker.com/linux/debian"
+fi
+
+# ---------- Detect PVE major version and select install mode ----------
+PVE_MAJ=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1 | cut -d'.' -f1)
+if [ "$PVE_MAJ" -eq 8 ]; then
+ INSTALL_MODE="direct" # fast path: install Docker directly into image
+else
+ INSTALL_MODE="firstboot" # robust path for PVE9: install Docker at first boot inside guest
+fi
+
+# ---------- Optional: allow manual override ----------
+if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker Installation Mode" \
+ --yesno "Detected PVE ${PVE_MAJ}. Use ${INSTALL_MODE^^} mode?\n\nYes = ${INSTALL_MODE^^}\nNo = Switch to the other mode" 11 70; then
+ : # keep detected mode
+else
+ if [ "$INSTALL_MODE" = "direct" ]; then INSTALL_MODE="firstboot"; else INSTALL_MODE="direct"; fi
+fi
+
+# ---------- PVE8: Direct install into image via virt-customize ----------
+if [ "$INSTALL_MODE" = "direct" ]; then
+ msg_info "Injecting Docker directly into image (${CODENAME}, $(basename "$DOCKER_BASE"))"
+ virt-customize -q -a "${FILE}" \
+ --install qemu-guest-agent,apt-transport-https,ca-certificates,curl,gnupg,lsb-release \
+ --run-command "install -m 0755 -d /etc/apt/keyrings" \
+ --run-command "curl -fsSL ${DOCKER_BASE}/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg" \
+ --run-command "chmod a+r /etc/apt/keyrings/docker.gpg" \
+ --run-command "echo 'deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable' > /etc/apt/sources.list.d/docker.list" \
+ --run-command "apt-get update -qq" \
+ --run-command "apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" \
+ --run-command "systemctl enable docker" \
+ --run-command "systemctl enable qemu-guest-agent" >/dev/null
+ msg_ok "Docker injected into image"
+fi
+
+# ---------- PVE9: First-boot installer inside guest ----------
+if [ "$INSTALL_MODE" = "firstboot" ]; then
+ msg_info "Preparing first-boot Docker installer (${CODENAME}, $(basename "$DOCKER_BASE"))"
+ mkdir -p firstboot
+ cat >firstboot/firstboot-docker.sh <>"$LOG" 2>&1
+exec >>"\$LOG" 2>&1
-touch /var/lib/firstboot/.running
export DEBIAN_FRONTEND=noninteractive
-
apt-get update -qq
apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https software-properties-common lsb-release
install -m 0755 -d /etc/apt/keyrings
-curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+curl -fsSL ${DOCKER_BASE}/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
-echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" >/etc/apt/sources.list.d/docker.list
+echo "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable" >/etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
@@ -413,11 +499,10 @@ systemctl enable --now docker
mkdir -p /var/lib/firstboot
date > /var/lib/firstboot/docker.done
-rm -f /var/lib/firstboot/.running
EOSH
-chmod +x firstboot/firstboot-docker.sh
+ chmod +x firstboot/firstboot-docker.sh
-cat >firstboot/firstboot-docker.service <<'EOUNIT'
+ cat >firstboot/firstboot-docker.service <<'EOUNIT'
[Unit]
Description=First boot: install Docker & QGA
After=network-online.target
@@ -433,19 +518,19 @@ RemainAfterExit=no
WantedBy=multi-user.target
EOUNIT
-# hostname + machine-id reset for cloud-init style behaviour
-echo "$HN" >firstboot/hostname
+ # hostname + machine-id reset for cloud-init style behaviour
+ echo "$HN" >firstboot/hostname
-# Inject files without requiring guest network
-virt-customize -q -a "${FILE}" \
- --copy-in firstboot/firstboot-docker.sh:/usr/local/sbin \
- --copy-in firstboot/firstboot-docker.service:/etc/systemd/system \
- --copy-in firstboot/hostname:/etc \
- --run-command "chmod +x /usr/local/sbin/firstboot-docker.sh" \
- --run-command "systemctl enable firstboot-docker.service" \
- --run-command "echo -n > /etc/machine-id" \
- --run-command "truncate -s 0 /etc/hostname && mv /etc/hostname /etc/hostname.orig && echo '${HN}' >/etc/hostname" >/dev/null
-msg_ok "Prepared first-boot installer & hostname"
+ virt-customize -q -a "${FILE}" \
+ --copy-in firstboot/firstboot-docker.sh:/usr/local/sbin \
+ --copy-in firstboot/firstboot-docker.service:/etc/systemd/system \
+ --copy-in firstboot/hostname:/etc \
+ --run-command "chmod +x /usr/local/sbin/firstboot-docker.sh" \
+ --run-command "systemctl enable firstboot-docker.service" \
+ --run-command "echo -n > /etc/machine-id" \
+ --run-command "truncate -s 0 /etc/hostname && mv /etc/hostname /etc/hostname.orig && echo '${HN}' >/etc/hostname" >/dev/null
+ msg_ok "First-boot Docker installer injected"
+fi
# ---------- Expand partition offline ----------
msg_info "Expanding root partition to use full disk space"
From 2203b24bdd258696fdf533922816094cd50b2877 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 20:59:05 +0200
Subject: [PATCH 277/312] path fix
---
vm/docker-vm.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index 6655c7e6..2dc856f5 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -493,6 +493,10 @@ echo "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker
apt-get update -qq
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
+sed -i 's#^ENV_PATH.*#ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
+printf 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n' >/etc/environment
+grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc
systemctl enable --now qemu-guest-agent || true
systemctl enable --now docker
From 5aedc07b3cf7a4498615263ece9ff0c7704388a7 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 21:10:20 +0200
Subject: [PATCH 278/312] fix pve9
---
vm/docker-vm.sh | 103 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 81 insertions(+), 22 deletions(-)
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index 2dc856f5..22558e03 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -456,6 +456,7 @@ else
if [ "$INSTALL_MODE" = "direct" ]; then INSTALL_MODE="firstboot"; else INSTALL_MODE="direct"; fi
fi
+# ---------- PVE8: Direct install into image via virt-customize ----------
# ---------- PVE8: Direct install into image via virt-customize ----------
if [ "$INSTALL_MODE" = "direct" ]; then
msg_info "Injecting Docker directly into image (${CODENAME}, $(basename "$DOCKER_BASE"))"
@@ -468,7 +469,14 @@ if [ "$INSTALL_MODE" = "direct" ]; then
--run-command "apt-get update -qq" \
--run-command "apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" \
--run-command "systemctl enable docker" \
- --run-command "systemctl enable qemu-guest-agent" >/dev/null
+ --run-command "systemctl enable qemu-guest-agent"
+
+ # ensure PATH in the guest for root (non-login shells, qm terminal, etc.)
+ --run-command "sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true" \
+ --run-command "sed -i 's#^ENV_PATH.*#ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true" \
+ --run-command "printf 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n' >/etc/environment" \
+ --run-command "grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc" \
+ >/dev/null
msg_ok "Docker injected into image"
fi
@@ -476,46 +484,97 @@ fi
if [ "$INSTALL_MODE" = "firstboot" ]; then
msg_info "Preparing first-boot Docker installer (${CODENAME}, $(basename "$DOCKER_BASE"))"
mkdir -p firstboot
- cat >firstboot/firstboot-docker.sh <firstboot/firstboot-docker.sh <<'EOSH'
#!/usr/bin/env bash
-set -e
+set -euxo pipefail
+
LOG=/var/log/firstboot-docker.log
-exec >>"\$LOG" 2>&1
+exec >>"$LOG" 2>&1
-export DEBIAN_FRONTEND=noninteractive
-apt-get update -qq
-apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https software-properties-common lsb-release
+mark_done() {
+ mkdir -p /var/lib/firstboot
+ date > /var/lib/firstboot/docker.done
+}
-install -m 0755 -d /etc/apt/keyrings
-curl -fsSL ${DOCKER_BASE}/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
-chmod a+r /etc/apt/keyrings/docker.gpg
-echo "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable" >/etc/apt/sources.list.d/docker.list
+retry() {
+ local tries=$1; shift
+ local n=0
+ until "$@"; do
+ n=$((n+1))
+ if [ "$n" -ge "$tries" ]; then return 1; fi
+ sleep 5
+ done
+}
-apt-get update -qq
-apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
-sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
-sed -i 's#^ENV_PATH.*#ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
-printf 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n' >/etc/environment
-grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc
+wait_network() {
+ # DNS + HTTPS reachability
+ retry 30 getent hosts deb.debian.org || retry 30 getent hosts archive.ubuntu.com
+ retry 30 bash -c 'curl -fsS https://download.docker.com/ >/dev/null'
+}
-systemctl enable --now qemu-guest-agent || true
-systemctl enable --now docker
+fix_path() {
+ sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
+ sed -i 's#^ENV_PATH.*#ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true
+ printf 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n' >/etc/environment
+ grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc
+ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+}
-mkdir -p /var/lib/firstboot
-date > /var/lib/firstboot/docker.done
+main() {
+ export DEBIAN_FRONTEND=noninteractive
+
+ wait_network
+
+ # Distro erkennen -> Codename + Docker-Repo
+ . /etc/os-release
+ CODENAME="${VERSION_CODENAME:-bookworm}"
+ case "$ID" in
+ ubuntu) DOCKER_BASE="https://download.docker.com/linux/ubuntu" ;;
+ debian|*) DOCKER_BASE="https://download.docker.com/linux/debian" ;;
+ esac
+
+ # Basispakete mit Retries
+ retry 10 apt-get update -qq
+ retry 5 apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https lsb-release software-properties-common
+
+ # Docker GPG + Repo
+ install -m 0755 -d /etc/apt/keyrings
+ curl -fsSL "${DOCKER_BASE}/gpg" | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
+ chmod a+r /etc/apt/keyrings/docker.gpg
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable" > /etc/apt/sources.list.d/docker.list
+
+ retry 10 apt-get update -qq
+ retry 5 apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+ systemctl enable --now qemu-guest-agent || true
+ systemctl enable --now docker
+
+ # PATH sicherstellen
+ fix_path
+
+ # Erfolg validieren
+ command -v docker >/dev/null
+ systemctl is-active --quiet docker
+
+ mark_done
+}
+main
EOSH
chmod +x firstboot/firstboot-docker.sh
cat >firstboot/firstboot-docker.service <<'EOUNIT'
[Unit]
Description=First boot: install Docker & QGA
-After=network-online.target
+After=network-online.target cloud-init.service
Wants=network-online.target
ConditionPathExists=!/var/lib/firstboot/docker.done
+StartLimitIntervalSec=0
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/firstboot-docker.sh
+Restart=on-failure
+RestartSec=10s
RemainAfterExit=no
[Install]
From 8086160fbd41ac42362a0b1a1e5cd0e65c02c6be Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Tue, 2 Sep 2025 21:46:53 +0200
Subject: [PATCH 279/312] dev
---
vm/docker-vm.sh | 114 +++++++++++++++++++++---------------------------
1 file changed, 50 insertions(+), 64 deletions(-)
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index 22558e03..137baf92 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -2,7 +2,7 @@
# Copyright (c) 2021-2025 community-scripts ORG
# Author: thost96 (thost96) | Co-Author: michelroegl-brunner
-# Refactor (q35 + PVE9 virt-customize network fix): MickLesk
+# Refactor (q35 + PVE9 virt-customize network fix + robustness): MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
set -e
@@ -162,9 +162,7 @@ function arch_check() {
function ssh_check() {
if command -v pveversion >/dev/null 2>&1 && [ -n "${SSH_CLIENT:+x}" ]; then
- if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Proceed anyway?" 10 62; then
- :
- else
+ if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Proceed anyway?" 10 62; then :; else
clear
exit
fi
@@ -224,7 +222,6 @@ function advanced_settings() {
else exit-script; fi
done
- # Force q35 like our other scripts
FORMAT=",efitype=4m"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}"
@@ -241,11 +238,11 @@ function advanced_settings() {
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "None (Default)" ON "1" "Write Through" OFF 3>&1 1>&2 2>&3); then
if [ "$DISK_CACHE" = "1" ]; then
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
DISK_CACHE="cache=writethrough,"
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
else
- echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
DISK_CACHE=""
+ echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
fi
else exit-script; fi
@@ -257,11 +254,11 @@ function advanced_settings() {
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "KVM64 (Default)" ON "1" "Host" OFF 3>&1 1>&2 2>&3); then
if [ "$CPU_TYPE1" = "1" ]; then
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
CPU_TYPE=" -cpu host"
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
else
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
CPU_TYPE=""
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
fi
else exit-script; fi
@@ -369,7 +366,6 @@ function choose_os() {
}
PVE_VER=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1 | cut -d'.' -f1)
-
if [ "$PVE_VER" -eq 8 ]; then
INSTALL_MODE="direct"
elif [ "$PVE_VER" -eq 9 ]; then
@@ -409,13 +405,22 @@ fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
-# ---------- Download Debian Cloud Image ----------
+# ---------- Download Cloud Image ----------
choose_os
msg_info "Retrieving Cloud Image for $var_os $var_version"
-curl -f#SL -o "$(basename "$URL")" "$URL"
+curl --retry 30 --retry-delay 3 --retry-connrefused -fSL -o "$(basename "$URL")" "$URL"
FILE=$(basename "$URL")
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
+# Ubuntu RAW → qcow2
+if [[ "$FILE" == *.img ]]; then
+ msg_info "Converting RAW image to qcow2"
+ qemu-img convert -O qcow2 "$FILE" "${FILE%.img}.qcow2"
+ rm -f "$FILE"
+ FILE="${FILE%.img}.qcow2"
+ msg_ok "Converted to ${CL}${BL}${FILE}${CL}"
+fi
+
# ---------- Ensure libguestfs-tools ----------
if ! command -v virt-customize &>/dev/null; then
msg_info "Installing libguestfs-tools on host"
@@ -424,8 +429,7 @@ if ! command -v virt-customize &>/dev/null; then
msg_ok "Installed libguestfs-tools"
fi
-# ---------- Decide distro codename & Docker repo base from chosen URL ----------
-# (choose_os must have set $URL and we've downloaded $FILE above; we only need URL to derive codename)
+# ---------- Decide distro codename & Docker repo base ----------
if [[ "$URL" == *"/bookworm/"* || "$FILE" == *"debian-12-"* ]]; then
CODENAME="bookworm"
DOCKER_BASE="https://download.docker.com/linux/debian"
@@ -439,24 +443,22 @@ else
CODENAME="bookworm"
DOCKER_BASE="https://download.docker.com/linux/debian"
fi
-
-# ---------- Detect PVE major version and select install mode ----------
-PVE_MAJ=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1 | cut -d'.' -f1)
-if [ "$PVE_MAJ" -eq 8 ]; then
- INSTALL_MODE="direct" # fast path: install Docker directly into image
-else
- INSTALL_MODE="firstboot" # robust path for PVE9: install Docker at first boot inside guest
+# Map Debian trixie → bookworm (Docker-Repo oft später)
+REPO_CODENAME="$CODENAME"
+if [[ "$DOCKER_BASE" == *"linux/debian"* && "$CODENAME" == "trixie" ]]; then
+ REPO_CODENAME="bookworm"
fi
+# ---------- Detect PVE major version (again; independent var) ----------
+PVE_MAJ=$(pveversion | awk -F'/' '{print $2}' | cut -d'-' -f1 | cut -d'.' -f1)
+if [ "$PVE_MAJ" -eq 8 ]; then INSTALL_MODE="direct"; else INSTALL_MODE="firstboot"; fi
+
# ---------- Optional: allow manual override ----------
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker Installation Mode" \
- --yesno "Detected PVE ${PVE_MAJ}. Use ${INSTALL_MODE^^} mode?\n\nYes = ${INSTALL_MODE^^}\nNo = Switch to the other mode" 11 70; then
- : # keep detected mode
-else
+ --yesno "Detected PVE ${PVE_MAJ}. Use ${INSTALL_MODE^^} mode?\n\nYes = ${INSTALL_MODE^^}\nNo = Switch to the other mode" 11 70; then :; else
if [ "$INSTALL_MODE" = "direct" ]; then INSTALL_MODE="firstboot"; else INSTALL_MODE="direct"; fi
fi
-# ---------- PVE8: Direct install into image via virt-customize ----------
# ---------- PVE8: Direct install into image via virt-customize ----------
if [ "$INSTALL_MODE" = "direct" ]; then
msg_info "Injecting Docker directly into image (${CODENAME}, $(basename "$DOCKER_BASE"))"
@@ -465,18 +467,19 @@ if [ "$INSTALL_MODE" = "direct" ]; then
--run-command "install -m 0755 -d /etc/apt/keyrings" \
--run-command "curl -fsSL ${DOCKER_BASE}/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg" \
--run-command "chmod a+r /etc/apt/keyrings/docker.gpg" \
- --run-command "echo 'deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable' > /etc/apt/sources.list.d/docker.list" \
+ --run-command "echo 'deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${REPO_CODENAME} stable' > /etc/apt/sources.list.d/docker.list" \
--run-command "apt-get update -qq" \
--run-command "apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" \
--run-command "systemctl enable docker" \
- --run-command "systemctl enable qemu-guest-agent"
+ --run-command "systemctl enable qemu-guest-agent" >/dev/null
- # ensure PATH in the guest for root (non-login shells, qm terminal, etc.)
- --run-command "sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true" \
+ # PATH-Fix separat
+ virt-customize -q -a "${FILE}" \
+ --run-command "sed -i 's#^ENV_SUPATH.*#ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true" \
--run-command "sed -i 's#^ENV_PATH.*#ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#' /etc/login.defs || true" \
--run-command "printf 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\n' >/etc/environment" \
- --run-command "grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc" \
- >/dev/null
+ --run-command "grep -q 'export PATH=' /root/.bashrc || echo 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' >> /root/.bashrc" >/dev/null
+
msg_ok "Docker injected into image"
fi
@@ -491,25 +494,12 @@ set -euxo pipefail
LOG=/var/log/firstboot-docker.log
exec >>"$LOG" 2>&1
-mark_done() {
- mkdir -p /var/lib/firstboot
- date > /var/lib/firstboot/docker.done
-}
-
-retry() {
- local tries=$1; shift
- local n=0
- until "$@"; do
- n=$((n+1))
- if [ "$n" -ge "$tries" ]; then return 1; fi
- sleep 5
- done
-}
+mark_done() { mkdir -p /var/lib/firstboot; date > /var/lib/firstboot/docker.done; }
+retry() { local t=$1; shift; local n=0; until "$@"; do n=$((n+1)); [ "$n" -ge "$t" ] && return 1; sleep 5; done; }
wait_network() {
- # DNS + HTTPS reachability
- retry 30 getent hosts deb.debian.org || retry 30 getent hosts archive.ubuntu.com
- retry 30 bash -c 'curl -fsS https://download.docker.com/ >/dev/null'
+ retry 60 getent hosts deb.debian.org || retry 60 getent hosts archive.ubuntu.com
+ retry 60 bash -lc 'curl -fsS https://download.docker.com/ >/dev/null'
}
fix_path() {
@@ -522,37 +512,36 @@ fix_path() {
main() {
export DEBIAN_FRONTEND=noninteractive
+ mkdir -p /etc/apt/apt.conf.d
+ printf 'Acquire::Retries "10";\nAcquire::http::Timeout "60";\nAcquire::https::Timeout "60";\n' >/etc/apt/apt.conf.d/80-retries-timeouts
wait_network
- # Distro erkennen -> Codename + Docker-Repo
. /etc/os-release
CODENAME="${VERSION_CODENAME:-bookworm}"
case "$ID" in
ubuntu) DOCKER_BASE="https://download.docker.com/linux/ubuntu" ;;
debian|*) DOCKER_BASE="https://download.docker.com/linux/debian" ;;
esac
+ REPO_CODENAME="$CODENAME"
+ if [ "$ID" = "debian" ] && [ "$CODENAME" = "trixie" ]; then REPO_CODENAME="bookworm"; fi
- # Basispakete mit Retries
- retry 10 apt-get update -qq
- retry 5 apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https lsb-release software-properties-common
+ retry 20 apt-get update -qq
+ retry 10 apt-get install -y ca-certificates curl gnupg qemu-guest-agent apt-transport-https lsb-release software-properties-common
- # Docker GPG + Repo
install -m 0755 -d /etc/apt/keyrings
curl -fsSL "${DOCKER_BASE}/gpg" | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${CODENAME} stable" > /etc/apt/sources.list.d/docker.list
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${DOCKER_BASE} ${REPO_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
- retry 10 apt-get update -qq
- retry 5 apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+ retry 20 apt-get update -qq
+ retry 10 apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable --now qemu-guest-agent || true
systemctl enable --now docker
- # PATH sicherstellen
fix_path
- # Erfolg validieren
command -v docker >/dev/null
systemctl is-active --quiet docker
@@ -575,13 +564,13 @@ Type=oneshot
ExecStart=/usr/local/sbin/firstboot-docker.sh
Restart=on-failure
RestartSec=10s
+TimeoutStartSec=0
RemainAfterExit=no
[Install]
WantedBy=multi-user.target
EOUNIT
- # hostname + machine-id reset for cloud-init style behaviour
echo "$HN" >firstboot/hostname
virt-customize -q -a "${FILE}" \
@@ -592,6 +581,7 @@ EOUNIT
--run-command "systemctl enable firstboot-docker.service" \
--run-command "echo -n > /etc/machine-id" \
--run-command "truncate -s 0 /etc/hostname && mv /etc/hostname /etc/hostname.orig && echo '${HN}' >/etc/hostname" >/dev/null
+
msg_ok "First-boot Docker installer injected"
fi
@@ -611,11 +601,7 @@ msg_ok "Created VM shell"
# ---------- Import disk ----------
msg_info "Importing disk into storage ($STORAGE)"
-if qm disk import --help >/dev/null 2>&1; then
- IMPORT_CMD=(qm disk import)
-else
- IMPORT_CMD=(qm importdisk)
-fi
+if qm disk import --help >/dev/null 2>&1; then IMPORT_CMD=(qm disk import); else IMPORT_CMD=(qm importdisk); fi
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "${FILE}" "$STORAGE" --format qcow2 2>&1 || true)"
DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
[[ -z "$DISK_REF" ]] && DISK_REF="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
From 24b594faeaeb9a4da94825b3b951bdbd0a409339 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 2 Sep 2025 16:16:27 -0400
Subject: [PATCH 280/312] trying to fix broken container creation
---
misc/create_lxc.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 83b31d1a..23b148be 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -466,8 +466,8 @@ grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subui
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
# Assemble pct options
-PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
-[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
+PCT_OPTIONS=("${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}")
+[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
# Secure with lockfile
lockfile="/tmp/template.${TEMPLATE}.lock"
From 8fd2b0c20d62e4cc2b3a56bebead967dcc654fb4 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 2 Sep 2025 16:19:15 -0400
Subject: [PATCH 281/312] revert one test
---
misc/create_lxc.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index 23b148be..dc92cac9 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -467,7 +467,7 @@ grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgi
# Assemble pct options
PCT_OPTIONS=("${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}")
-[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
+[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
# Secure with lockfile
lockfile="/tmp/template.${TEMPLATE}.lock"
From d95e5d7c9399e27cbfd833918030950c4ffa8d64 Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 2 Sep 2025 16:22:38 -0400
Subject: [PATCH 282/312] next test
---
misc/create_lxc.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/misc/create_lxc.sh b/misc/create_lxc.sh
index dc92cac9..ea53362e 100644
--- a/misc/create_lxc.sh
+++ b/misc/create_lxc.sh
@@ -466,8 +466,8 @@ grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subui
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
# Assemble pct options
-PCT_OPTIONS=("${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}")
-[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
+PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
+[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
# Secure with lockfile
lockfile="/tmp/template.${TEMPLATE}.lock"
From 08743166bdb585ebca13c918a1bd116bd53a313c Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Tue, 2 Sep 2025 16:55:54 -0400
Subject: [PATCH 283/312] Autocaliweb: export the venv
---
install/autocaliweb-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/autocaliweb-install.sh b/install/autocaliweb-install.sh
index 49e36772..0686473c 100644
--- a/install/autocaliweb-install.sh
+++ b/install/autocaliweb-install.sh
@@ -70,7 +70,7 @@ INGEST_DIR="/opt/acw-book-ingest"
SERVICE_USER="acw"
SERVICE_GROUP="acw"
SCRIPTS_DIR="${INSTALL_DIR}/scripts"
-VIRTUAL_ENV="${INSTALL_DIR}/venv"
+export VIRTUAL_ENV="${INSTALL_DIR}/venv"
mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
From d5b550493b7b2e5e91f244abe7fb7b30a33a7730 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 09:45:11 +0200
Subject: [PATCH 284/312] Cleanup
---
ct/debian13.sh | 44 ----
ct/{ => deferred}/librespeed.sh | 0
ct/{ => deferred}/vikunja.sh | 0
ct/litellm.sh | 60 -----
ct/mediamanager.sh | 80 -------
ct/nginxproxymanager.sh | 158 -------------
ct/proxmox-backup-server.sh | 44 ----
ct/tracktor.sh | 70 ------
ct/traefik.sh | 58 -----
ct/zitadel.sh | 62 -----
frontend/public/json/librespeed.json | 35 ---
frontend/public/json/litellm.json | 40 ----
frontend/public/json/mediamanager.json | 45 ----
frontend/public/json/tracktor.json | 40 ----
frontend/public/json/vikunja.json | 35 ---
install/debian13-install.sh | 25 --
install/{ => deferred}/vikunja-install.sh | 0
install/jeedom-install.sh | 94 --------
install/librespeed-install.sh | 54 -----
install/litellm-install.sh | 80 -------
install/mediamanager-install.sh | 120 ----------
install/nginxproxymanager-install.sh | 171 --------------
install/proxmox-backup-server-install.sh | 39 ----
install/tracktor-install.sh | 61 -----
install/traefik-install.sh | 266 ----------------------
install/zitadel-install.sh | 149 ------------
26 files changed, 1830 deletions(-)
delete mode 100644 ct/debian13.sh
rename ct/{ => deferred}/librespeed.sh (100%)
rename ct/{ => deferred}/vikunja.sh (100%)
delete mode 100644 ct/litellm.sh
delete mode 100644 ct/mediamanager.sh
delete mode 100644 ct/nginxproxymanager.sh
delete mode 100644 ct/proxmox-backup-server.sh
delete mode 100644 ct/tracktor.sh
delete mode 100644 ct/traefik.sh
delete mode 100644 ct/zitadel.sh
delete mode 100644 frontend/public/json/librespeed.json
delete mode 100644 frontend/public/json/litellm.json
delete mode 100644 frontend/public/json/mediamanager.json
delete mode 100644 frontend/public/json/tracktor.json
delete mode 100644 frontend/public/json/vikunja.json
delete mode 100644 install/debian13-install.sh
rename install/{ => deferred}/vikunja-install.sh (100%)
delete mode 100644 install/jeedom-install.sh
delete mode 100644 install/librespeed-install.sh
delete mode 100644 install/litellm-install.sh
delete mode 100644 install/mediamanager-install.sh
delete mode 100644 install/nginxproxymanager-install.sh
delete mode 100644 install/proxmox-backup-server-install.sh
delete mode 100644 install/tracktor-install.sh
delete mode 100644 install/traefik-install.sh
delete mode 100644 install/zitadel-install.sh
diff --git a/ct/debian13.sh b/ct/debian13.sh
deleted file mode 100644
index 4be94c1c..00000000
--- a/ct/debian13.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
-# Source: https://www.debian.org/
-
-APP="Debian13"
-var_tags="${var_tags:-os}"
-var_cpu="${var_cpu:-4}"
-var_ram="${var_ram:-4096}"
-var_disk="${var_disk:-15}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-13}"
-var_unprivileged="${var_unprivileged:-1}"
-#var_fuse="${var_fuse:-no}"
-#var_tun="${var_tun:-no}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -d /var ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- msg_info "Updating $APP LXC"
- $STD apt update
- $STD apt -y upgrade
- msg_ok "Updated $APP LXC"
- exit
-}
-
-start
-build_container
-description
-
-msg_ok "Completed Successfully!"
-msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!"
diff --git a/ct/librespeed.sh b/ct/deferred/librespeed.sh
similarity index 100%
rename from ct/librespeed.sh
rename to ct/deferred/librespeed.sh
diff --git a/ct/vikunja.sh b/ct/deferred/vikunja.sh
similarity index 100%
rename from ct/vikunja.sh
rename to ct/deferred/vikunja.sh
diff --git a/ct/litellm.sh b/ct/litellm.sh
deleted file mode 100644
index 8d2b7f73..00000000
--- a/ct/litellm.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: stout01
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/BerriAI/litellm
-
-APP="LiteLLM"
-var_tags="${var_tags:-ai;interface}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-4}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -f /etc/systemd/system/litellm.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- msg_info "Stopping ${APP}"
- systemctl stop litellm
- msg_ok "Stopped ${APP}"
-
- VENV_PATH="/opt/litellm/.venv"
- PYTHON_VERSION="3.13" setup_uv
-
- msg_info "Updating $APP"
- $STD "$VENV_PATH/bin/python" -m pip install --upgrade litellm[proxy] prisma
-
- msg_info "Updating DB Schema"
- $STD uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
- msg_ok "DB Schema Updated"
-
- msg_info "Starting ${APP}"
- systemctl start litellm
- msg_ok "Started ${APP}"
- msg_ok "Updated Successfully"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:4000${CL}"
diff --git a/ct/mediamanager.sh b/ct/mediamanager.sh
deleted file mode 100644
index d633f657..00000000
--- a/ct/mediamanager.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/maxdorninger/MediaManager
-
-APP="MediaManager"
-var_tags="${var_tags:-arr}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-3072}"
-var_disk="${var_disk:-4}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-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/mediamanager ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- setup_uv
-
- RELEASE=$(curl -fsSL https://api.github.com/repos/maxdorninger/MediaManager/releases/latest | jq '.tag_name' | sed 's/^v//')
- if [[ "${RELEASE}" != "$(cat ~/.mediamanager 2>/dev/null)" ]] || [[ ! -f ~/.mediamanager ]]; then
- msg_info "Stopping Service"
- systemctl stop mediamanager
- msg_ok "Stopped Service"
-
- fetch_and_deploy_gh_release "MediaManager" "maxdorninger/MediaManager" "tarball" "latest" "/opt/mediamanager"
- msg_info "Updating ${APP}"
- MM_DIR="/opt/mm"
- export CONFIG_DIR="${MM_DIR}/config"
- export FRONTEND_FILES_DIR="${MM_DIR}/web/build"
- export BASE_PATH=""
- export PUBLIC_VERSION=""
- export PUBLIC_API_URL="${BASE_PATH}/api/v1"
- export BASE_PATH="${BASE_PATH}/web"
- cd /opt/mediamanager/web
- $STD npm ci
- $STD npm run build
- rm -rf "$FRONTEND_FILES_DIR"/build
- cp -r build "$FRONTEND_FILES_DIR"
-
- export BASE_PATH=""
- export VIRTUAL_ENV="/opt/${MM_DIR}/venv"
- cd /opt/mediamanager
- rm -rf "$MM_DIR"/{media_manager,alembic*}
- cp -r {media_manager,alembic*} "$MM_DIR"
- $STD /usr/local/bin/uv sync --locked --active
- msg_ok "Updated $APP"
-
- msg_info "Starting Service"
- systemctl start mediamanager
- msg_ok "Started Service"
-
- msg_ok "Updated Successfully"
- else
- msg_ok "Already up to date"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh
deleted file mode 100644
index eb7259de..00000000
--- a/ct/nginxproxymanager.sh
+++ /dev/null
@@ -1,158 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://nginxproxymanager.com/
-
-APP="Nginx Proxy Manager"
-var_tags="${var_tags:-proxy}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-1024}"
-var_disk="${var_disk:-4}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -f /lib/systemd/system/npm.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- if ! command -v pnpm &>/dev/null; then
- msg_info "Installing pnpm"
- #export NODE_OPTIONS=--openssl-legacy-provider
- $STD npm install -g pnpm@8.15
- msg_ok "Installed pnpm"
- fi
- RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
- grep "tag_name" |
- awk '{print substr($2, 3, length($2)-4) }')
- msg_info "Stopping Services"
- systemctl stop openresty
- systemctl stop npm
- msg_ok "Stopped Services"
-
- msg_info "Cleaning Old Files"
- rm -rf /app \
- /var/www/html \
- /etc/nginx \
- /var/log/nginx \
- /var/lib/nginx \
- "$STD" /var/cache/nginx
- msg_ok "Cleaned Old Files"
-
- msg_info "Downloading NPM v${RELEASE}"
- curl -fsSL "https://codeload.github.com/NginxProxyManager/nginx-proxy-manager/tar.gz/v${RELEASE}" | tar -xz
- cd nginx-proxy-manager-"${RELEASE}"
- msg_ok "Downloaded NPM v${RELEASE}"
-
- msg_info "Setting up Enviroment"
- ln -sf /usr/bin/python3 /usr/bin/python
- ln -sf /usr/bin/certbot /opt/certbot/bin/certbot
- ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
- ln -sf /usr/local/openresty/nginx/ /etc/nginx
- sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" backend/package.json
- sed -i "s|\"version\": \"0.0.0\"|\"version\": \"$RELEASE\"|" frontend/package.json
- sed -i 's+^daemon+#daemon+g' docker/rootfs/etc/nginx/nginx.conf
- NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
- for NGINX_CONF in $NGINX_CONFS; do
- sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
- done
- mkdir -p /var/www/html /etc/nginx/logs
- cp -r docker/rootfs/var/www/html/* /var/www/html/
- cp -r docker/rootfs/etc/nginx/* /etc/nginx/
- cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
- cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
- ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
- rm -f /etc/nginx/conf.d/dev.conf
- mkdir -p /tmp/nginx/body \
- /run/nginx \
- /data/nginx \
- /data/custom_ssl \
- /data/logs \
- /data/access \
- /data/nginx/default_host \
- /data/nginx/default_www \
- /data/nginx/proxy_host \
- /data/nginx/redirection_host \
- /data/nginx/stream \
- /data/nginx/dead_host \
- /data/nginx/temp \
- /var/lib/nginx/cache/public \
- /var/lib/nginx/cache/private \
- /var/cache/nginx/proxy_temp
- chmod -R 777 /var/cache/nginx
- chown root /tmp/nginx
- echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
- if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
- $STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
- fi
- mkdir -p /app/global /app/frontend/images
- cp -r backend/* /app
- cp -r global/* /app/global
- $STD python3 -m pip install --no-cache-dir --break-system-packages certbot-dns-cloudflare
- msg_ok "Setup Enviroment"
-
- msg_info "Building Frontend"
- cd ./frontend
- $STD pnpm install
- $STD pnpm upgrade
- $STD pnpm run build
- cp -r dist/* /app/frontend
- cp -r app-images/* /app/frontend/images
- msg_ok "Built Frontend"
-
- msg_info "Initializing Backend"
- $STD rm -rf /app/config/default.json
- if [ ! -f /app/config/production.json ]; then
- cat <<'EOF' >/app/config/production.json
-{
- "database": {
- "engine": "knex-native",
- "knex": {
- "client": "sqlite3",
- "connection": {
- "filename": "/data/database.sqlite"
- }
- }
- }
-}
-EOF
- fi
- cd /app
- $STD pnpm install
- msg_ok "Initialized Backend"
-
- msg_info "Starting Services"
- sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
- sed -i 's/su npm npm/su root root/g' /etc/logrotate.d/nginx-proxy-manager
- sed -i 's/include-system-site-packages = false/include-system-site-packages = true/g' /opt/certbot/pyvenv.cfg
- systemctl enable -q --now openresty
- systemctl enable -q --now npm
- msg_ok "Started Services"
-
- msg_info "Cleaning up"
- rm -rf ~/nginx-proxy-manager-*
- msg_ok "Cleaned"
-
- msg_ok "Updated Successfully"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:81${CL}"
diff --git a/ct/proxmox-backup-server.sh b/ct/proxmox-backup-server.sh
deleted file mode 100644
index 5463b1eb..00000000
--- a/ct/proxmox-backup-server.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.proxmox.com/en/proxmox-backup-server
-
-APP="Proxmox-Backup-Server"
-var_tags="${var_tags:-backup}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-10}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -e /usr/sbin/proxmox-backup-manager ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- msg_info "Updating $APP LXC"
- $STD apt-get update
- $STD apt-get -y upgrade
- msg_ok "Updated $APP LXC"
- 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 "${TAB}${GATEWAY}${BGN}https://${IP}:8007${CL}"
diff --git a/ct/tracktor.sh b/ct/tracktor.sh
deleted file mode 100644
index c568f28d..00000000
--- a/ct/tracktor.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: CrazyWolf13
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://tracktor.bytedge.in/
-
-APP="tracktor"
-var_tags="${var_tags:-car;monitoring}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-4096}"
-var_disk="${var_disk:-6}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-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/tracktor ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- RELEASE=$(curl -fsSL https://api.github.com/repos/javedh-dev/tracktor/releases/latest | jq -r '.tag_name' | sed 's/^v//')
- if [[ "${RELEASE}" != "$(cat ~/.tracktor 2>/dev/null)" ]] || [[ ! -f ~/.tracktor ]]; then
- msg_info "Stopping Service"
- systemctl stop tracktor
- msg_ok "Stopped Service"
-
- msg_info "Creating Backup"
- cp /opt/tracktor/app/backend/.env /opt/tracktor.env
- msg_ok "Created Backup"
-
- msg_info "Updating ${APP}"
- setup_nodejs
- fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest" "/opt/tracktor"
- cd /opt/tracktor
- $STD npm install
- $STD npm run build
- msg_ok "Updated $APP"
-
- msg_info "Restoring Backup"
- cp /opt/tracktor.env /opt/tracktor/app/backend/.env
- msg_ok "Restored Backup"
-
- msg_info "Starting Service"
- systemctl start tracktor
- msg_ok "Started Service"
- msg_ok "Updated Successfully"
- else
- msg_ok "Already up to date"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/traefik.sh b/ct/traefik.sh
deleted file mode 100644
index fe4d80f9..00000000
--- a/ct/traefik.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://traefik.io/
-
-APP="Traefik"
-var_tags="${var_tags:-proxy}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-512}"
-var_disk="${var_disk:-2}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -f /etc/systemd/system/traefik.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- RELEASE=$(curl -fsSL https://api.github.com/repos/traefik/traefik/releases | grep -oP '"tag_name":\s*"v\K[\d.]+?(?=")' | sort -V | tail -n 1)
- msg_info "Updating $APP LXC"
- if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
- curl -fsSL "https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz" -o $(basename "https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz")
- tar -C /tmp -xzf traefik*.tar.gz
- mv /tmp/traefik /usr/bin/
- rm -rf traefik*.tar.gz
- systemctl restart traefik.service
- echo "${RELEASE}" >/opt/${APP}_version.txt
- msg_ok "Updated $APP LXC"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
-echo -e "Commands available are as below:"
-echo -e "addsite - creating a config"
-echo -e "ensite - enables a config"
-echo -e "dissite - disables a config"
-echo -e "editsite - edits a config"
diff --git a/ct/zitadel.sh b/ct/zitadel.sh
deleted file mode 100644
index c35c7b39..00000000
--- a/ct/zitadel.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: dave-yap (dave-yap)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://zitadel.com/
-
-APP="Zitadel"
-var_tags="${var_tags:-identity-provider}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-1024}"
-var_disk="${var_disk:-8}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-12}"
-var_unprivileged="${var_unprivileged:-1}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
- if [[ ! -f /etc/systemd/system/zitadel.service ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- RELEASE=$(curl -fsSL https://api.github.com/repos/zitadel/zitadel/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
- if [[ ! -f ~/.zitadel ]] || [[ "${RELEASE}" != "$(cat ~/.zitadel)" ]]; then
- msg_info "Stopping $APP"
- systemctl stop zitadel
- msg_ok "Stopped $APP"
-
- rm -f /usr/local/bin/zitadel
- fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-amd64.tar.gz"
-
- msg_info "Updating $APP to ${RELEASE}"
- $STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --init-projections=true
- msg_ok "Updated $APP to ${RELEASE}"
-
- msg_info "Starting $APP"
- systemctl start zitadel
- msg_ok "Started $APP"
-
- msg_ok "Update Successful"
- else
- msg_ok "No update required. ${APP} is already at ${RELEASE}"
- 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080/ui/console${CL}"
diff --git a/frontend/public/json/librespeed.json b/frontend/public/json/librespeed.json
deleted file mode 100644
index 713b2fe8..00000000
--- a/frontend/public/json/librespeed.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "Librespeed",
- "slug": "librespeed",
- "categories": [
- 4
- ],
- "date_created": "2025-04-26",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 80,
- "documentation": "https://github.com/librespeed/speedtest/blob/master/doc.md",
- "config_path": "",
- "website": "https://librespeed.org",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/librespeed.webp",
- "description": "No Flash, No Java, No Websocket, No Bullshit. This is a very lightweight speed test implemented in Javascript, using XMLHttpRequest and Web Workers.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/librespeed.sh",
- "resources": {
- "cpu": 1,
- "ram": 512,
- "hdd": 4,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": "root",
- "password": null
- },
- "notes": []
-}
diff --git a/frontend/public/json/litellm.json b/frontend/public/json/litellm.json
deleted file mode 100644
index b2e7b7d7..00000000
--- a/frontend/public/json/litellm.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "LiteLLM",
- "slug": "litellm",
- "categories": [
- 20
- ],
- "date_created": "2025-08-07",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 4000,
- "documentation": "https://docs.litellm.ai/",
- "config_path": "/opt/litellm/litellm.yaml",
- "website": "https://www.litellm.ai/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/litellm-light.webp",
- "description": "LLM proxy to call 100+ LLMs in a unified interface & track spend, set budgets per virtual key/user",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/litellm.sh",
- "resources": {
- "cpu": 2,
- "ram": 2048,
- "hdd": 4,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": "admin",
- "password": "sk-1234"
- },
- "notes": [
- {
- "text": "Update master key in the config file",
- "type": "info"
- }
- ]
-}
diff --git a/frontend/public/json/mediamanager.json b/frontend/public/json/mediamanager.json
deleted file mode 100644
index c8590b01..00000000
--- a/frontend/public/json/mediamanager.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "name": "MediaManager",
- "slug": "mediamanager",
- "categories": [
- 14,
- 13
- ],
- "date_created": "2025-07-22",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 8000,
- "documentation": "https://maxdorninger.github.io/MediaManager/introduction.html",
- "config_path": "/opt/mm_data/config.toml",
- "website": "https://github.com/maxdorninger/MediaManager",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/mediamanager.webp",
- "description": "A modern selfhosted media management system for your media library",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/mediamanager.sh",
- "resources": {
- "cpu": 2,
- "ram": 3072,
- "hdd": 4,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": "",
- "password": "admin"
- },
- "notes": [
- {
- "text": "During the installation, provide the email address of the first admin user",
- "type": "info"
- },
- {
- "text": "You're probably going to want to use a bind mount for the media directories",
- "type": "info"
- }
- ]
-}
diff --git a/frontend/public/json/tracktor.json b/frontend/public/json/tracktor.json
deleted file mode 100644
index 0a8f7c3b..00000000
--- a/frontend/public/json/tracktor.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "Tracktor",
- "slug": "tracktor",
- "categories": [
- 9
- ],
- "date_created": "2025-08-06",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 3000,
- "documentation": "https://tracktor.bytedge.in/introduction.html",
- "config_path": "/opt/tracktor/app/server/.env",
- "website": "https://tracktor.bytedge.in/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/tracktor.svg",
- "description": "Tracktor is an open-source web application for comprehensive vehicle management.\nEasily track ⛽ fuel consumption, 🛠️ maintenance, 🛡️ insurance, and 📄 regulatory documents for all your vehicles in one place. ",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/tracktor.sh",
- "resources": {
- "cpu": 1,
- "ram": 1024,
- "hdd": 6,
- "os": "Debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": [
- {
- "text": "Please check and update the '/opt/tracktor/app/backend/.env' file if using behind reverse proxy.",
- "type": "info"
- }
- ]
-}
diff --git a/frontend/public/json/vikunja.json b/frontend/public/json/vikunja.json
deleted file mode 100644
index ea171140..00000000
--- a/frontend/public/json/vikunja.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "name": "Vikunja",
- "slug": "vikunja",
- "categories": [
- 12
- ],
- "date_created": "2024-11-05",
- "type": "ct",
- "updateable": true,
- "privileged": false,
- "interface_port": 3456,
- "documentation": null,
- "website": "https://vikunja.io/",
- "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/vikunja.webp",
- "config_path": "/etc/vikunja/config.yml",
- "description": "Vikunja is a powerful self-hosted todo app. It allows you to create and manage to-do lists. You can plan tasks, set priorities and collaborate with others. The best part is that your data is safe with you and you can customize the app to your liking. It's like a personal assistant that helps you stay organized.",
- "install_methods": [
- {
- "type": "default",
- "script": "ct/vikunja.sh",
- "resources": {
- "cpu": 1,
- "ram": 1024,
- "hdd": 4,
- "os": "debian",
- "version": "12"
- }
- }
- ],
- "default_credentials": {
- "username": null,
- "password": null
- },
- "notes": []
-}
diff --git a/install/debian13-install.sh b/install/debian13-install.sh
deleted file mode 100644
index 466d6af6..00000000
--- a/install/debian13-install.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt install -y gpg
-msg_ok "Installed Dependencies"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt -y autoremove
-$STD apt -y autoclean
-msg_ok "Cleaned"
diff --git a/install/vikunja-install.sh b/install/deferred/vikunja-install.sh
similarity index 100%
rename from install/vikunja-install.sh
rename to install/deferred/vikunja-install.sh
diff --git a/install/jeedom-install.sh b/install/jeedom-install.sh
deleted file mode 100644
index d868e84b..00000000
--- a/install/jeedom-install.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: Mips2648
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://jeedom.com/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing dependencies"
-$STD apt-get install -y \
- lsb-release \
- git
-msg_ok "Dependencies installed"
-
-DEFAULT_BRANCH="master"
-REPO_URL="https://github.com/jeedom/core.git"
-
-echo
-while true; do
- read -rp "${TAB3}Enter branch to use (master, beta, alpha...) (Default: ${DEFAULT_BRANCH}): " BRANCH
- BRANCH="${BRANCH:-$DEFAULT_BRANCH}"
-
- if git ls-remote --heads "$REPO_URL" "refs/heads/$BRANCH" | grep -q .; then
- break
- else
- msg_error "Branch '$BRANCH' does not exist on remote. Please try again."
- fi
-done
-
-msg_info "Downloading Jeedom installation script"
-cd /tmp
-wget -q https://raw.githubusercontent.com/jeedom/core/"${BRANCH}"/install/install.sh
-chmod +x install.sh
-msg_ok "Installation script downloaded"
-
-msg_info "Install Jeedom main dependencies, please wait"
-$STD ./install.sh -v "$BRANCH" -s 2
-msg_ok "Installed Jeedom main dependencies"
-
-msg_info "Install Database"
-$STD ./install.sh -v "$BRANCH" -s 3
-msg_ok "Database installed"
-
-msg_info "Install Apache"
-$STD ./install.sh -v "$BRANCH" -s 4
-msg_ok "Apache installed"
-
-msg_info "Install PHP and dependencies"
-$STD ./install.sh -v "$BRANCH" -s 5
-msg_ok "PHP installed"
-
-msg_info "Download Jeedom core"
-$STD ./install.sh -v "$BRANCH" -s 6
-msg_ok "Download done"
-
-msg_info "Database customisation"
-$STD ./install.sh -v "$BRANCH" -s 7
-msg_ok "Database customisation done"
-
-msg_info "Jeedom customisation"
-$STD ./install.sh -v "$BRANCH" -s 8
-msg_ok "Jeedom customisation done"
-
-msg_info "Configuring Jeedom"
-$STD ./install.sh -v "$BRANCH" -s 9
-msg_ok "Jeedom configured"
-
-msg_info "Installing Jeedom"
-$STD ./install.sh -v "$BRANCH" -s 10
-msg_ok "Jeedom installed"
-
-msg_info "Post installation"
-$STD ./install.sh -v "$BRANCH" -s 11
-msg_ok "Post installation done"
-
-msg_info "Check installation"
-$STD ./install.sh -v "$BRANCH" -s 12
-msg_ok "Installation checked, everything is successfuly installed. A reboot is recommended."
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-rm -rf /tmp/install.sh
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/librespeed-install.sh b/install/librespeed-install.sh
deleted file mode 100644
index 8b2bc48a..00000000
--- a/install/librespeed-install.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: elvito
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/librespeed/speedtest
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt-get update
-$STD apt-get install -y \
- caddy \
- php-fpm
-msg_ok "Installed Dependencies"
-
-msg_info "Installing librespeed"
-temp_file=$(mktemp)
-RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
-curl -fsSL "https://github.com/librespeed/speedtest/archive/refs/tags/${RELEASE}.zip" -o "$temp_file"
-mkdir -p /opt/librespeed
-mkdir -p /temp
-unzip -q "$temp_file" -d /temp
-cd /temp/speedtest-"${RELEASE}"
-cp -u favicon.ico index.html speedtest.js speedtest_worker.js /opt/librespeed/
-cp -ru backend results /opt/librespeed/
-
-cat </etc/caddy/Caddyfile
-:80 {
- root * /opt/librespeed
- file_server
- php_fastcgi unix//run/php/php-fpm.sock
-}
-EOF
-
-systemctl restart caddy
-echo "${RELEASE}" >/opt/"${APP}_version.txt"
-msg_ok "Installation completed"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-rm -rf /temp
-rm -f "$temp_file"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/litellm-install.sh b/install/litellm-install.sh
deleted file mode 100644
index b79341f9..00000000
--- a/install/litellm-install.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: stout01
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/BerriAI/litellm
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-PG_VERSION="17" setup_postgresql
-PYTHON_VERSION="3.13" setup_uv
-
-msg_info "Setting up PostgreSQL"
-DB_NAME="litellm_db"
-DB_USER="litellm"
-DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
-$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN 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 "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
-{
- echo "${APPLICATION} Credentials"
- echo "Database Name: $DB_NAME"
- echo "Database User: $DB_USER"
- echo "Database Password: $DB_PASS"
-} >>~/litellm.creds
-msg_ok "Set up PostgreSQL"
-
-msg_info "Setting up Virtual Environment"
-mkdir -p /opt/litellm
-cd /opt/litellm
-$STD uv venv /opt/litellm/.venv
-$STD /opt/litellm/.venv/bin/python -m ensurepip --upgrade
-$STD /opt/litellm/.venv/bin/python -m pip install --upgrade pip
-$STD /opt/litellm/.venv/bin/python -m pip install litellm[proxy] prisma
-msg_ok "Installed LiteLLM"
-
-msg_info "Configuring LiteLLM"
-mkdir -p /opt
-cat </opt/litellm/litellm.yaml
-general_settings:
- master_key: sk-1234
- database_url: postgresql://$DB_USER:$DB_PASS@127.0.0.1:5432/$DB_NAME
- store_model_in_db: true
-EOF
-
-uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml --use_prisma_db_push --skip_server_startup
-msg_ok "Configured LiteLLM"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/litellm.service
-[Unit]
-Description=LiteLLM
-
-[Service]
-Type=simple
-ExecStart=uv --directory=/opt/litellm run litellm --config /opt/litellm/litellm.yaml
-Restart=always
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-systemctl enable -q --now litellm
-msg_ok "Created Service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/mediamanager-install.sh b/install/mediamanager-install.sh
deleted file mode 100644
index 3aa0df7b..00000000
--- a/install/mediamanager-install.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2025 Community Scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/maxdorninger/MediaManager
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-read -r -p "${TAB3}Enter the email address of your first admin user: " admin_email
-if [[ "$admin_email" ]]; then
- EMAIL="$admin_email"
-fi
-
-setup_yq
-NODE_VERSION="24" setup_nodejs
-setup_uv
-PG_VERSION="17" setup_postgresql
-
-msg_info "Setting up PostgreSQL"
-DB_NAME="mm_db"
-DB_USER="mm_user"
-DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
-$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
-$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;"
-$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
-{
- echo "MediaManager Credentials"
- echo "MediaManager Database User: $DB_USER"
- echo "MediaManager Database Password: $DB_PASS"
- echo "MediaManager Database Name: $DB_NAME"
-} >>~/mediamanager.creds
-msg_ok "Set up PostgreSQL"
-
-fetch_and_deploy_gh_release "MediaManager" "maxdorninger/MediaManager" "tarball" "latest" "/opt/mediamanager"
-
-msg_info "Configuring MediaManager"
-MM_DIR="/opt/mm"
-MEDIA_DIR="${MM_DIR}/media"
-export CONFIG_DIR="${MM_DIR}/config"
-export FRONTEND_FILES_DIR="${MM_DIR}/web/build"
-export BASE_PATH=""
-export PUBLIC_VERSION=""
-export PUBLIC_API_URL="${BASE_PATH}/api/v1"
-export BASE_PATH="${BASE_PATH}/web"
-cd /opt/mediamanager/web
-$STD npm ci
-$STD npm run build
-mkdir -p {"$MM_DIR"/web,"$MEDIA_DIR","$CONFIG_DIR"}
-cp -r build "$FRONTEND_FILES_DIR"
-
-export BASE_PATH=""
-export VIRTUAL_ENV="${MM_DIR}/venv"
-cd /opt/mediamanager
-cp -r {media_manager,alembic*} "$MM_DIR"
-$STD /usr/local/bin/uv venv "$VIRTUAL_ENV"
-$STD /usr/local/bin/uv sync --locked --active
-msg_ok "Configured MediaManager"
-
-msg_info "Creating config and start script"
-LOCAL_IP="$(hostname -I | awk '{print $1}')"
-SECRET="$(openssl rand -hex 32)"
-sed -e "s/localhost:8/$LOCAL_IP:8/g" \
- -e "s|/data/|$MEDIA_DIR/|g" \
- -e 's/"db"/"localhost"/' \
- -e "s/user = \"MediaManager\"/user = \"$DB_USER\"/" \
- -e "s/password = \"MediaManager\"/password = \"$DB_PASS\"/" \
- -e "s/dbname = \"MediaManager\"/dbname = \"$DB_NAME\"/" \
- -e "/^token_secret/s/=.*/= \"$SECRET\"/" \
- -e "s/admin@example.com/$EMAIL/" \
- -e '/^admin_emails/s/, .*/]/' \
- /opt/mediamanager/config.example.toml >"$CONFIG_DIR"/config.toml
-
-mkdir -p "$MEDIA_DIR"/{images,tv,movies,torrents}
-
-cat <"$MM_DIR"/start.sh
-#!/usr/bin/env bash
-
-export CONFIG_DIR="$CONFIG_DIR"
-export FRONTEND_FILES_DIR="$FRONTEND_FILES_DIR"
-export BASE_PATH=""
-
-cd "$MM_DIR"
-source ./venv/bin/activate
-/usr/local/bin/uv run alembic upgrade head
-/usr/local/bin/uv run fastapi run ./media_manager/main.py --port 8000
-EOF
-chmod +x "$MM_DIR"/start.sh
-msg_ok "Created config and start script"
-
-msg_info "Creating service"
-cat </etc/systemd/system/mediamanager.service
-[Unit]
-Description=MediaManager Backend Service
-After=network.target
-
-[Service]
-Type=simple
-WorkingDirectory=${MM_DIR}
-ExecStart=/usr/bin/bash start.sh
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now mediamanager
-msg_ok "Created service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/nginxproxymanager-install.sh b/install/nginxproxymanager-install.sh
deleted file mode 100644
index 9aaf4cc4..00000000
--- a/install/nginxproxymanager-install.sh
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://nginxproxymanager.com/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt-get update
-$STD apt-get -y install \
- ca-certificates \
- apache2-utils \
- logrotate \
- build-essential \
- jq \
- git
-msg_ok "Installed Dependencies"
-
-NODE_VERSION="16" NODE_MODULE="yarn" setup_nodejs
-PYTHON_VERSION="3.12" setup_uv
-fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "latest" "/tmp/nginxproxymanager"
-
-msg_info "Installing Python Dependencies"
-$STD apt-get install -y \
- python3 \
- python3-dev \
- python3-venv
-msg_ok "Installed Python Dependencies"
-
-msg_info "Setting up Certbot Environment"
-$STD uv venv /opt/certbot
-$STD uv pip install --python \
- certbot \
- certbot-dns-cloudflare \
- certbot-dns-multi
-msg_ok "Certbot Environment Ready"
-
-msg_info "Installing Openresty"
-VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
-curl -fsSL "https://openresty.org/package/pubkey.gpg" | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg
-echo -e "deb http://openresty.org/package/debian $VERSION openresty" >/etc/apt/sources.list.d/openresty.list
-$STD apt-get update
-$STD apt-get -y install openresty
-msg_ok "Installed Openresty"
-
-msg_info "Setting up Environment"
-ln -sf /usr/bin/python3 /usr/bin/python
-ln -sf /opt/certbot/bin/certbot /usr/bin/certbot
-ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
-ln -sf /usr/local/openresty/nginx/ /etc/nginx
-sed -i 's+^daemon+#daemon+g' /tmp/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
-NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
-for NGINX_CONF in $NGINX_CONFS; do
- sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
-done
-
-mkdir -p /var/www/html /etc/nginx/logs
-cd /tmp/nginxproxymanager
-cp -r docker/rootfs/var/www/html/* /var/www/html/
-cp -r docker/rootfs/etc/nginx/* /etc/nginx/
-cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
-cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
-ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
-rm -f /etc/nginx/conf.d/dev.conf
-
-mkdir -p /tmp/nginx/body \
- /run/nginx \
- /data/nginx \
- /data/custom_ssl \
- /data/logs \
- /data/access \
- /data/nginx/default_host \
- /data/nginx/default_www \
- /data/nginx/proxy_host \
- /data/nginx/redirection_host \
- /data/nginx/stream \
- /data/nginx/dead_host \
- /data/nginx/temp \
- /var/lib/nginx/cache/public \
- /var/lib/nginx/cache/private \
- /var/cache/nginx/proxy_temp
-
-chmod -R 777 /var/cache/nginx
-chown root /tmp/nginx
-
-echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
-
-if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
- openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null
-fi
-
-mkdir -p /app/global /app/frontend/images
-cd /tmp/nginxproxymanager
-cp -r backend/* /app
-cp -r global/* /app/global
-msg_ok "Set up Environment"
-
-msg_info "Building Frontend"
-cd /tmp/nginxproxymanager/frontend
-$STD yarn install --frozen-lockfile
-$STD yarn build
-cp -r dist/* /app/frontend
-cp -r app-images/* /app/frontend/images
-msg_ok "Built Frontend"
-
-msg_info "Initializing Backend"
-rm -rf /app/config/default.json
-if [ ! -f /app/config/production.json ]; then
- cat <<'EOF' >/app/config/production.json
-{
- "database": {
- "engine": "knex-native",
- "knex": {
- "client": "sqlite3",
- "connection": {
- "filename": "/data/database.sqlite"
- }
- }
- }
-}
-EOF
-fi
-cd /app
-$STD yarn install --production
-msg_ok "Initialized Backend"
-
-msg_info "Creating Service"
-cat <<'EOF' >/lib/systemd/system/npm.service
-[Unit]
-Description=Nginx Proxy Manager
-After=network.target
-Wants=openresty.service
-
-[Service]
-Type=simple
-Environment=NODE_ENV=production
-Environment=NODE_OPTIONS=--openssl-legacy-provider
-ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
-ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=1024
-WorkingDirectory=/app
-Restart=on-failure
-
-[Install]
-WantedBy=multi-user.target
-EOF
-msg_ok "Created Service"
-
-motd_ssh
-customize
-
-msg_info "Starting Services"
-sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
-sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
-systemctl enable -q --now openresty
-systemctl enable -q --now npm
-msg_ok "Started Services"
-
-msg_info "Cleaning up"
-rm -rf /tmp/*
-systemctl restart openresty
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/proxmox-backup-server-install.sh b/install/proxmox-backup-server-install.sh
deleted file mode 100644
index cac095b9..00000000
--- a/install/proxmox-backup-server-install.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.proxmox.com/en/proxmox-backup-server
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-read -rp "${TAB3}Do you want to use the Enterprise repository (requires valid subscription key)? [y/N]: " USE_ENTERPRISE_REPO
-
-msg_info "Installing Proxmox Backup Server"
-curl -fsSL https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg |
- gpg --dearmor -o /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
-if [[ "$USE_ENTERPRISE_REPO" =~ ^([yY].*)$ ]]; then
- echo "deb https://enterprise.proxmox.com/debian/pbs bookworm pbs-enterprise" >/etc/apt/sources.list.d/pbs-enterprise.list
- msg_ok "Enterprise repository enabled. Make sure your subscription key is installed."
-else
- echo "deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription" >>/etc/apt/sources.list
- msg_ok "No-subscription repository enabled."
-fi
-
-$STD apt-get update
-$STD apt-get install -y proxmox-backup-server
-msg_ok "Installed Proxmox Backup Server"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/tracktor-install.sh b/install/tracktor-install.sh
deleted file mode 100644
index d0d432d9..00000000
--- a/install/tracktor-install.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2025 Community Scripts ORG
-# Author: CrazyWolf13
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://tracktor.bytedge.in
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-setup_nodejs
-fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest" "/opt/tracktor"
-
-msg_info "Configuring Tracktor"
-cd /opt/tracktor
-$STD npm install
-$STD npm run build
-mkdir /opt/tracktor-data
-HOST_IP=$(hostname -I | awk '{print $1}')
-cat </opt/tracktor/app/backend/.env
-NODE_ENV=production
-PUBLIC_DEMO_MODE=false
-DB_PATH=/opt/tracktor-data/tracktor.db
-# Replace this URL if using behind reverse proxy for https traffic. Though it is optional and should work without changing
-PUBLIC_API_BASE_URL=http://$HOST_IP:3000
-# Here add the reverse proxy url as well to avoid cross errors from the app.
-CORS_ORIGINS=http://$HOST_IP:3000
-PORT=3000
-EOF
-msg_ok "Configured Tracktor"
-
-msg_info "Creating service"
-cat </etc/systemd/system/tracktor.service
-[Unit]
-Description=Tracktor Service
-After=network.target
-
-[Service]
-Type=simple
-WorkingDirectory=/opt/tracktor
-EnvironmentFile=/opt/tracktor/app/backend/.env
-ExecStart=/usr/bin/npm start
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now tracktor
-msg_ok "Created service"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/traefik-install.sh b/install/traefik-install.sh
deleted file mode 100644
index 3f3dc2fb..00000000
--- a/install/traefik-install.sh
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 tteck
-# Author: tteck (tteckster)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://traefik.io/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt-get install -y apt-transport-https
-msg_ok "Installed Dependencies"
-
-RELEASE=$(curl -fsSL https://api.github.com/repos/traefik/traefik/releases | grep -oP '"tag_name":\s*"v\K[\d.]+?(?=")' | sort -V | tail -n 1)
-msg_info "Installing Traefik v${RELEASE}"
-mkdir -p /etc/traefik/{conf.d,ssl,sites-available}
-curl -fsSL "https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz" -o "traefik_v${RELEASE}_linux_amd64.tar.gz"
-tar -C /tmp -xzf traefik*.tar.gz
-mv /tmp/traefik /usr/bin/
-rm -rf traefik*.tar.gz
-echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
-msg_ok "Installed Traefik v${RELEASE}"
-
-msg_info "Creating Traefik configuration"
-cat <<'EOF' >/etc/traefik/traefik.yaml
-providers:
- file:
- directory: /etc/traefik/conf.d/
- watch: true
-
-entryPoints:
- web:
- address: ':80'
- http:
- redirections:
- entryPoint:
- to: websecure
- scheme: https
- websecure:
- address: ':443'
- http:
- tls:
- certResolver: letsencrypt
- # Uncomment below if using cloudflare
- /*
- forwardedHeaders:
- trustedIPs:
- - 173.245.48.0/20
- - 103.21.244.0/22
- - 103.22.200.0/22
- - 103.31.101.64/22
- - 141.101.64.0/18
- - 108.162.192.0/18
- - 190.93.240.0/20
- - 188.114.96.0/20
- - 197.234.240.0/22
- - 198.41.128.0/17
- - 162.158.0.0/15
- - 104.16.0.0/13
- - 104.16.0.0/13
- - 172.64.0.0/13
- - 131.0.72.0/22
- */
- asDefault: true
- traefik:
- address: ':8080'
-
-certificatesResolvers:
- letsencrypt:
- acme:
- email: "foo@bar.com"
- storage: /etc/traefik/ssl/acme.json
- tlsChallenge: {}
-
-# Uncomment below if you are using self signed or no certificate
-#serversTransport:
-# insecureSkipVerify: true
-
-api:
- dashboard: true
- insecure: true
-
-log:
- filePath: /var/log/traefik/traefik.log
- format: json
- level: INFO
-
-accessLog:
- filePath: /var/log/traefik/traefik-access.log
- format: json
- filters:
- statusCodes:
- - "200"
- - "400-599"
- retryAttempts: true
- minDuration: "10ms"
- bufferingSize: 0
- fields:
- headers:
- defaultMode: drop
- names:
- User-Agent: keep
-EOF
-msg_ok "Created Traefik configuration"
-
-msg_info "Creating Service"
-cat <<'EOF' >/etc/systemd/system/traefik.service
-[Unit]
-Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience
-
-[Service]
-Type=notify
-ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.yaml
-Restart=on-failure
-ExecReload=/bin/kill -USR1 \$MAINPID
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-systemctl enable -q --now traefik
-msg_ok "Created Service"
-
-msg_info "Creating site templates"
-cat <<'EOF' >/etc/traefik/template.yaml.tpl
-http:
- routers:
- ${hostname}:
- rule: Host(`${FQDN}`)
- service: ${hostname}
- tls:
- certResolver: letsencrypt
- services:
- ${hostname}:
- loadbalancer:
- servers:
- - url: "${URL}"
-EOF
-msg_ok "Template Created"
-
-msg_info "Creating Helper Scripts"
-cat <<'EOF' >/usr/bin/addsite
-#!/bin/bash
-
-function setup_site() {
- hostname="$(whiptail --inputbox "Enter the hostname of the Site" 8 78 --title "Hostname" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- FQDN="$(whiptail --inputbox "Enter the FQDN of the Site" 8 78 --title "FQDN" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- URL="$(whiptail --inputbox "Enter the URL of the Site (For example http://192.168.x.x:8080)" 8 78 --title "URL" 3>&1 1>&2 2>&3)"
- exitstatus=$?
- [[ "$exitstatus" = 1 ]] && return;
- filename="/etc/traefik/sites-available/${hostname}.yaml"
- export hostname FQDN URL
- envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > ${filename}
-}
-
-setup_site
-EOF
-
-cat <<'EOF' >/usr/bin/ensite
-#!/bin/bash
-
-function ensite() {
- DIR="/etc/traefik/sites-available"
- files=( "$DIR"/* )
-
- opts=()
- for f in "${files[@]}"; do
- name="${f##*/}"
- opts+=( "$name" "" )
- done
-
- choice=$(whiptail \
- --title "Select an entry" \
- --menu "Choose a site" \
- 20 60 12 \
- "${opts[@]}" \
- 3>&1 1>&2 2>&3)
-
- if [ $? -eq 0 ]; then
- ln -s $DIR/$choice /etc/traefik/conf.d
- else
- return
- fi
-}
-
-ensite
-EOF
-
-cat <<'EOF' >/usr/bin/dissite
-#!/bin/bash
-
-function dissite() {
- DIR="/etc/traefik/conf.d"
- files=( "$DIR"/* )
-
- opts=()
- for f in "${files[@]}"; do
- name="${f##*/}"
- opts+=( "$name" "" )
- done
-
- choice=$(whiptail \
- --title "Select an entry" \
- --menu "Choose a site" \
- 20 60 12 \
- "${opts[@]}" \
- 3>&1 1>&2 2>&3)
-
- if [ $? -eq 0 ]; then
- rm $DIR/$choice
- else
- return
- fi
-}
-
-dissite
-EOF
-
-cat <<'EOF' >/usr/bin/editsite
-#!/bin/bash
-
-function edit_site() {
- DIR="/etc/traefik/sites-available"
- files=( "$DIR"/* )
-
- opts=()
- for f in "${files[@]}"; do
- name="${f##*/}"
- opts+=( "$name" "" )
- done
-
- choice=$(whiptail \
- --title "Select an entry" \
- --menu "Choose a site" \
- 20 60 12 \
- "${opts[@]}" \
- 3>&1 1>&2 2>&3)
-
- if [ $? -eq 0 ]; then
- nano $DIR/$choice
- else
- return
- fi
-}
-
-edit_site
-EOF
-msg_ok "Helper Scripts Created"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
diff --git a/install/zitadel-install.sh b/install/zitadel-install.sh
deleted file mode 100644
index 5b5a8451..00000000
--- a/install/zitadel-install.sh
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2025 community-scripts ORG
-# Author: dave-yap
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://zitadel.com/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies (Patience)"
-$STD apt-get install -y ca-certificates
-msg_ok "Installed Dependecies"
-
-PG_VERSION="17" setup_postgresql
-
-msg_info "Installing Postgresql"
-DB_NAME="zitadel"
-DB_USER="zitadel"
-DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
-DB_ADMIN_USER="root"
-DB_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
-systemctl start postgresql
-$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
-$STD sudo -u postgres psql -c "CREATE USER $DB_ADMIN_USER WITH PASSWORD '$DB_ADMIN_PASS' SUPERUSER;"
-$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_ADMIN_USER;"
-{
- echo "Application Credentials"
- echo "DB_NAME: $DB_NAME"
- echo "DB_USER: $DB_USER"
- echo "DB_PASS: $DB_PASS"
- echo "DB_ADMIN_USER: $DB_ADMIN_USER"
- echo "DB_ADMIN_PASS: $DB_ADMIN_PASS"
-} >>~/zitadel.creds
-msg_ok "Installed PostgreSQL"
-
-fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-amd64.tar.gz"
-
-msg_info "Setting up Zitadel Environments"
-mkdir -p /opt/zitadel
-echo "/opt/zitadel/config.yaml" >"/opt/zitadel/.config"
-head -c 32 < <(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9') >"/opt/zitadel/.masterkey"
-{
- echo "Config location: $(cat "/opt/zitadel/.config")"
- echo "Masterkey: $(cat "/opt/zitadel/.masterkey")"
-} >>~/zitadel.creds
-cat </opt/zitadel/config.yaml
-Port: 8080
-ExternalPort: 8080
-ExternalDomain: localhost
-ExternalSecure: false
-TLS:
- Enabled: false
- KeyPath: ""
- Key: ""
- CertPath: ""
- Cert: ""
-
-Database:
- postgres:
- Host: localhost
- Port: 5432
- Database: ${DB_NAME}
- User:
- Username: ${DB_USER}
- Password: ${DB_PASS}
- SSL:
- Mode: disable
- RootCert: ""
- Cert: ""
- Key: ""
- Admin:
- Username: ${DB_ADMIN_USER}
- Password: ${DB_ADMIN_PASS}
- SSL:
- Mode: disable
- RootCert: ""
- Cert: ""
- Key: ""
-DefaultInstance:
- Features:
- LoginV2:
- Required: false
-EOF
-msg_ok "Installed Zitadel Enviroments"
-
-msg_info "Creating Services"
-cat </etc/systemd/system/zitadel.service
-[Unit]
-Description=ZITADEL Identiy Server
-After=network.target postgresql.service
-Wants=postgresql.service
-
-[Service]
-Type=simple
-User=zitadel
-Group=zitadel
-ExecStart=/usr/local/bin/zitadel start --masterkeyFile "/opt/zitadel/.masterkey" --config "/opt/zitadel/config.yaml"
-Restart=always
-RestartSec=5
-TimeoutStartSec=0
-
-# Security Hardening options
-ProtectSystem=full
-ProtectHome=true
-PrivateTmp=true
-NoNewPrivileges=true
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q zitadel
-msg_ok "Created Services"
-
-msg_info "Zitadel initial setup"
-zitadel start-from-init --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml &>/dev/null &
-sleep 60
-kill $(lsof -i | awk '/zitadel/ {print $2}' | head -n1)
-useradd zitadel
-msg_ok "Zitadel initialized"
-
-msg_info "Set ExternalDomain to current IP and restart Zitadel"
-IP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
-sed -i "0,/localhost/s/localhost/${IP}/" /opt/zitadel/config.yaml
-systemctl stop -q zitadel
-$STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
-systemctl restart -q zitadel
-msg_ok "Zitadel restarted with ExternalDomain set to current IP"
-
-msg_info "Create zitadel-rerun.sh"
-cat <~/zitadel-rerun.sh
-systemctl stop zitadel
-timeout --kill-after=5s 15s zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml
-systemctl restart zitadel
-EOF
-msg_ok "Bash script for rerunning Zitadel after changing Zitadel config.yaml"
-
-motd_ssh
-customize
-
-msg_info "Cleaning up"
-$STD apt-get -y autoremove
-$STD apt-get -y autoclean
-msg_ok "Cleaned"
From 7d679aaef7be549ea348f89bc2cc76a60ed480ec Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 10:12:56 +0200
Subject: [PATCH 285/312] Update dispatcharr-install.sh
---
install/dispatcharr-install.sh | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/install/dispatcharr-install.sh b/install/dispatcharr-install.sh
index 29e9457c..f5af7f5f 100644
--- a/install/dispatcharr-install.sh
+++ b/install/dispatcharr-install.sh
@@ -31,9 +31,10 @@ $STD apt-get install -y \
streamlink
msg_ok "Installed Dependencies"
-setup_uv
+PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" setup_nodejs
PG_VERSION="16" setup_postgresql
+fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
msg_info "Set up PostgreSQL Database"
DB_NAME=dispatcharr_db
@@ -53,21 +54,16 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
} >>~/dispatcharr.creds
msg_ok "Set up PostgreSQL Database"
-fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
-
-#chown -R "$APP_USER:$APP_GROUP" {/etc/dispatcharr,/opt/dispatcharr,/data}
-
-msg_info "Install Python Requirements"
+msg_info "Setup Python Requirements"
mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
mkdir -p /etc/dispatcharr
sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "/opt/dispatcharr/apps/output/views.py"
cd /opt/dispatcharr
-python3 -m venv env
-source env/bin/activate
-
-$STD pip install --upgrade pip
-$STD pip install -r requirements.txt
-$STD pip install gunicorn
+UV_PY="${PYTHON_VERSION:-3.13}"
+$STD uv python install "$UV_PY"
+$STD uv venv --python "$UV_PY" .venv
+$STD uv pip install --python ./.venv/bin/python -r requirements.txt
+$STD uv pip install --python ./.venv/bin/python gunicorn gevent celery daphne
ln -sf /usr/bin/ffmpeg /opt/dispatcharr/env/bin/ffmpeg
msg_ok "Python Requirements Installed"
@@ -79,13 +75,12 @@ msg_ok "Built Frontend"
msg_info "Running Django Migrations"
cd /opt/dispatcharr
-source env/bin/activate
set -o allexport
source /etc/dispatcharr/dispatcharr.env
set +o allexport
-$STD python manage.py migrate --noinput
-$STD python manage.py collectstatic --noinput
+$STD ./.venv/bin/python manage.py migrate --noinput
+$STD ./.venv/bin/python manage.py collectstatic --noinput
msg_ok "Migrations Complete"
msg_info "Configuring Nginx"
From fbb093844e9c85f7644838741dff2c6cb568e4d4 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 10:23:46 +0200
Subject: [PATCH 286/312] fixes
---
ct/uhf.sh | 37 +++++++++++++++++++------------------
install/uhf-install.sh | 5 ++---
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/ct/uhf.sh b/ct/uhf.sh
index 308c6296..09a30202 100644
--- a/ct/uhf.sh
+++ b/ct/uhf.sh
@@ -27,28 +27,29 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_info "Stopping ${APP}"
- systemctl stop uhf-server
- msg_ok "Stopped ${APP}"
+ if check_for_gh_release "uhf-server" "swapplications/uhf-server-dist"; then
+ msg_info "Stopping Service"
+ systemctl stop uhf-server
+ msg_ok "Stopped Service"
- msg_info "Updating APT packages"
- $STD apt-get update
- $STD apt-get -y upgrade
- msg_ok "Package list updated"
+ msg_info "Updating APT packages"
+ $STD apt-get update
+ $STD apt-get -y upgrade
+ msg_ok "Package list updated"
- fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "latest" "/opt/comskip" "comskip-x64-*.zip"
- fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
+ fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "latest" "/opt/comskip" "comskip-x64-*.zip"
+ fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
- msg_info "Starting ${APP}"
- systemctl start uhf-server
- msg_ok "Started ${APP}"
+ msg_info "Starting Service"
+ systemctl start uhf-server
+ msg_ok "Started Service"
- msg_info "Cleaning up"
- $STD apt-get -y autoremove
- $STD apt-get -y autoclean
- msg_ok "Cleaned"
-
- msg_ok "Updated Successfully"
+ msg_info "Cleaning up"
+ $STD apt-get -y autoremove
+ $STD apt-get -y autoclean
+ msg_ok "Cleaned"
+ msg_ok "Updated Successfully"
+ fi
exit
}
diff --git a/install/uhf-install.sh b/install/uhf-install.sh
index 8b9ddf84..c0447cf3 100644
--- a/install/uhf-install.sh
+++ b/install/uhf-install.sh
@@ -34,9 +34,8 @@ fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "lates
fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
msg_info "Creating Service"
-service_path=""
cat </etc/systemd/system/uhf-server.service
-echo "[Unit]
+[Unit]
Description=UHF Server service
After=syslog.target network-online.target
[Service]
@@ -47,7 +46,7 @@ ExecStart=/opt/uhf-server/uhf-server
[Install]
WantedBy=multi-user.target
EOF
-systemctl enable --now -q uhf-server.service
+systemctl enable -q --now uhf-server
msg_ok "Created Service"
motd_ssh
From 64f90572f9f5d2cb53fad52a425d99abad42aacf Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 10:27:09 +0200
Subject: [PATCH 287/312] Update uhf-install.sh
---
install/uhf-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/uhf-install.sh b/install/uhf-install.sh
index c0447cf3..f6bb6ad3 100644
--- a/install/uhf-install.sh
+++ b/install/uhf-install.sh
@@ -14,7 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies"
-setup_ffmpeg
+apt install -y ffmpeg
msg_ok "Installed Dependencies"
msg_info "Setting Up UHF Server Environment"
From 1fc593ef3849295a2fa206b598bd3aae688f4ffc Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 10:27:19 +0200
Subject: [PATCH 288/312] Update uhf-install.sh
---
install/uhf-install.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/uhf-install.sh b/install/uhf-install.sh
index f6bb6ad3..e414878c 100644
--- a/install/uhf-install.sh
+++ b/install/uhf-install.sh
@@ -14,7 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies"
-apt install -y ffmpeg
+$STD apt install -y ffmpeg
msg_ok "Installed Dependencies"
msg_info "Setting Up UHF Server Environment"
From 8739822db602a72cf3320c17b3c5749956db8137 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Wed, 3 Sep 2025 10:38:49 +0200
Subject: [PATCH 289/312] Update dispatcharr-install.sh
---
install/dispatcharr-install.sh | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/install/dispatcharr-install.sh b/install/dispatcharr-install.sh
index f5af7f5f..98d9435a 100644
--- a/install/dispatcharr-install.sh
+++ b/install/dispatcharr-install.sh
@@ -54,16 +54,21 @@ $STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
} >>~/dispatcharr.creds
msg_ok "Set up PostgreSQL Database"
-msg_info "Setup Python Requirements"
-mkdir -p /data/{db,epgs,logos,m3us,recordings,uploads}
-mkdir -p /etc/dispatcharr
-sed -i 's/program\[\x27channel_id\x27\]/program["channel_id"]/g' "/opt/dispatcharr/apps/output/views.py"
-cd /opt/dispatcharr
+msg_info "Setup Python (uv) requirements (system)"
UV_PY="${PYTHON_VERSION:-3.13}"
$STD uv python install "$UV_PY"
-$STD uv venv --python "$UV_PY" .venv
-$STD uv pip install --python ./.venv/bin/python -r requirements.txt
-$STD uv pip install --python ./.venv/bin/python gunicorn gevent celery daphne
+cd /opt/dispatcharr
+PYPI_URL="https://pypi.org/simple"
+mapfile -t EXTRA_INDEX_URLS < <(grep -E '^(--(extra-)?index-url|-i)\s' requirements.txt 2>/dev/null | awk '{print $2}' | sed 's#/*$##')
+
+UV_INDEX_ARGS=(--index-url "$PYPI_URL" --index-strategy unsafe-best-match)
+for u in "${EXTRA_INDEX_URLS[@]}"; do
+ [[ -n "$u" && "$u" != "$PYPI_URL" ]] && UV_INDEX_ARGS+=(--extra-index-url "$u")
+done
+if [[ -f requirements.txt ]]; then
+ $STD uv pip install --system "${UV_INDEX_ARGS[@]}" -r requirements.txt
+fi
+$STD uv pip install --system "${UV_INDEX_ARGS[@]}" gunicorn gevent celery daphne
ln -sf /usr/bin/ffmpeg /opt/dispatcharr/env/bin/ffmpeg
msg_ok "Python Requirements Installed"
From aa4c843b1e105dd7ca8c8bdc2f53a732d9de169f Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Wed, 3 Sep 2025 11:13:35 -0400
Subject: [PATCH 290/312] Autocaliweb: export VIRTUAL_ENV in update
---
ct/autocaliweb.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
index e7f33ba0..e2aa9735 100644
--- a/ct/autocaliweb.sh
+++ b/ct/autocaliweb.sh
@@ -37,7 +37,7 @@ function update_script() {
msg_ok "Stopped Services"
INSTALL_DIR="/opt/autocaliweb"
- VIRTUAL_ENV="${INSTALL_DIR}/venv"
+ export VIRTUAL_ENV="${INSTALL_DIR}/venv"
$STD tar -cf ~/autocaliweb_bkp.tar "$INSTALL_DIR"/{metadata_change_logs,dirs.json,.env,scripts/ingest_watcher.sh,scripts/auto_zipper_wrapper.sh,scripts/metadata_change_detector_wrapper.sh}
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Updating ${APP}"
From bf951a09ed47e5de8f9858c738faeca96138a50e Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Wed, 3 Sep 2025 15:14:05 +0000
Subject: [PATCH 291/312] Update .app files
---
ct/headers/debian13 | 6 ------
ct/headers/librespeed | 6 ------
ct/headers/litellm | 6 ------
ct/headers/mediamanager | 6 ------
ct/headers/nginxproxymanager | 6 ------
ct/headers/proxmox-backup-server | 6 ------
ct/headers/tracktor | 6 ------
ct/headers/traefik | 6 ------
ct/headers/vikunja | 6 ------
tools/headers/prx-add-ips | 6 ++++++
10 files changed, 6 insertions(+), 54 deletions(-)
delete mode 100644 ct/headers/debian13
delete mode 100644 ct/headers/librespeed
delete mode 100644 ct/headers/litellm
delete mode 100644 ct/headers/mediamanager
delete mode 100644 ct/headers/nginxproxymanager
delete mode 100644 ct/headers/proxmox-backup-server
delete mode 100644 ct/headers/tracktor
delete mode 100644 ct/headers/traefik
delete mode 100644 ct/headers/vikunja
create mode 100644 tools/headers/prx-add-ips
diff --git a/ct/headers/debian13 b/ct/headers/debian13
deleted file mode 100644
index 467acace..00000000
--- a/ct/headers/debian13
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ __ _ ________
- / __ \___ / /_ (_)___ _____ < /__ /
- / / / / _ \/ __ \/ / __ `/ __ \/ / /_ <
- / /_/ / __/ /_/ / / /_/ / / / / /___/ /
-/_____/\___/_.___/_/\__,_/_/ /_/_//____/
-
diff --git a/ct/headers/librespeed b/ct/headers/librespeed
deleted file mode 100644
index b75b5cec..00000000
--- a/ct/headers/librespeed
+++ /dev/null
@@ -1,6 +0,0 @@
- ___ __ __
- / (_) /_ ________ _________ ___ ___ ____/ /
- / / / __ \/ ___/ _ \/ ___/ __ \/ _ \/ _ \/ __ /
- / / / /_/ / / / __(__ ) /_/ / __/ __/ /_/ /
-/_/_/_.___/_/ \___/____/ .___/\___/\___/\__,_/
- /_/
diff --git a/ct/headers/litellm b/ct/headers/litellm
deleted file mode 100644
index 1360a8ff..00000000
--- a/ct/headers/litellm
+++ /dev/null
@@ -1,6 +0,0 @@
- __ _ __ __ __ __ ___
- / / (_) /____ / / / / / |/ /
- / / / / __/ _ \/ / / / / /|_/ /
- / /___/ / /_/ __/ /___/ /___/ / / /
-/_____/_/\__/\___/_____/_____/_/ /_/
-
diff --git a/ct/headers/mediamanager b/ct/headers/mediamanager
deleted file mode 100644
index b05f4db7..00000000
--- a/ct/headers/mediamanager
+++ /dev/null
@@ -1,6 +0,0 @@
- __ ___ ___ __ ___
- / |/ /__ ____/ (_)___ _/ |/ /___ _____ ____ _____ ____ _____
- / /|_/ / _ \/ __ / / __ `/ /|_/ / __ `/ __ \/ __ `/ __ `/ _ \/ ___/
- / / / / __/ /_/ / / /_/ / / / / /_/ / / / / /_/ / /_/ / __/ /
-/_/ /_/\___/\__,_/_/\__,_/_/ /_/\__,_/_/ /_/\__,_/\__, /\___/_/
- /____/
diff --git a/ct/headers/nginxproxymanager b/ct/headers/nginxproxymanager
deleted file mode 100644
index d68d0c9d..00000000
--- a/ct/headers/nginxproxymanager
+++ /dev/null
@@ -1,6 +0,0 @@
- _ __ _ ____ __ ___
- / | / /___ _(_)___ _ __ / __ \_________ _ ____ __ / |/ /___ _____ ____ _____ ____ _____
- / |/ / __ `/ / __ \| |/_/ / /_/ / ___/ __ \| |/_/ / / / / /|_/ / __ `/ __ \/ __ `/ __ `/ _ \/ ___/
- / /| / /_/ / / / / /> < / ____/ / / /_/ /> /_/ / / / / / /_/ / / / / /_/ / /_/ / __/ /
-/_/ |_/\__, /_/_/ /_/_/|_| /_/ /_/ \____/_/|_|\__, / /_/ /_/\__,_/_/ /_/\__,_/\__, /\___/_/
- /____/ /____/ /____/
diff --git a/ct/headers/proxmox-backup-server b/ct/headers/proxmox-backup-server
deleted file mode 100644
index 8536d112..00000000
--- a/ct/headers/proxmox-backup-server
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ ____ __ _____
- / __ \_________ _ ______ ___ ____ _ __ / __ )____ ______/ /____ ______ / ___/___ ______ _____ _____
- / /_/ / ___/ __ \| |/_/ __ `__ \/ __ \| |/_/_____/ __ / __ `/ ___/ //_/ / / / __ \______\__ \/ _ \/ ___/ | / / _ \/ ___/
- / ____/ / / /_/ /> / / / / / /_/ /> / / / / / /_/ /> < / ___ / /_/ / /_/ /_____// // ____(__ )
+/_/ /_/ \____/_/|_/_/ /_/ /_/\____/_/|_| /_/ |_\__,_/\__,_/ /___/_/ /____/
+
From ae770c38ea242e2546081a82f394c4e48d92be8d Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 4 Sep 2025 14:05:38 +0200
Subject: [PATCH 292/312] ssh key feature
---
misc/build.func | 117 ++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 108 insertions(+), 9 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 5e84c226..c14babc2 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -281,6 +281,34 @@ exit_script() {
exit
}
+find_host_ssh_keys() {
+ local glob="${var_ssh_import_glob:-/root/.ssh/*}"
+ local files=()
+ local f
+ local total=0
+ local keyre='^(ssh-(rsa|ed25519|ecdsa)|sk-(ssh-ed25519|ecdsa-sha2-nistp256))\s+'
+
+ shopt -s nullglob
+ for f in $glob; do
+ # skip directories / unreadable
+ [[ -f "$f" && -r "$f" ]] || continue
+ # count lines that look like authorized_keys entries
+ local c
+ c=$(awk -v RS='\r?\n' '$0 ~ /^#/ {next} $0 ~ /'"$keyre"'/ {cnt++} END{print cnt+0}' "$f")
+ if [[ "${c:-0}" -gt 0 ]]; then
+ files+=("$f")
+ total=$((total + c))
+ fi
+ done
+ shopt -u nullglob
+
+ FOUND_HOST_KEY_COUNT="$total"
+ (
+ IFS=:
+ echo "${files[*]}"
+ )
+}
+
# This function allows the user to configure advanced settings for the script.
advanced_settings() {
whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox --title "Here is an instructional tip:" "To make a selection, use the Spacebar." 8 58
@@ -705,23 +733,48 @@ advanced_settings() {
exit_script
fi
- SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --inputbox "SSH Authorized key for root (leave empty for none)" 8 58 --title "SSH Key" 3>&1 1>&2 2>&3)"
-
- if [[ -z "${SSH_AUTHORIZED_KEY}" ]]; then
- SSH_AUTHORIZED_KEY=""
+ SSH_AUTHORIZED_KEY=""
+ if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno \
+ --title "SSH KEY (Manual)" --yesno "Enter a manual SSH public key now?\n(Choose 'No' to skip manual entry)" 10 70); then
+ SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
+ --inputbox "Paste a single SSH public key line (ssh-ed25519 ...)" 10 70 --title "SSH Public Key" 3>&1 1>&2 2>&3)"
fi
- if [[ "$PW" == -password* || -n "$SSH_AUTHORIZED_KEY" ]]; then
- if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then
+ SSH_IMPORT_FILES=""
+ HOST_KEYS_AVAILABLE="no"
+ SSH_IMPORT_FILES="$(find_host_ssh_keys)"
+ if [[ -n "$SSH_IMPORT_FILES" && "${FOUND_HOST_KEY_COUNT:-0}" -gt 0 ]]; then
+ HOST_KEYS_AVAILABLE="yes"
+ fi
+
+ SSH_SOURCE="none"
+ if [[ "$HOST_KEYS_AVAILABLE" == "yes" ]]; then
+ SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
+ "Choose how to provision SSH keys for root:" 14 70 4 \
+ "none" "No keys" \
+ "host" "Import host store (${FOUND_HOST_KEY_COUNT} keys total)" \
+ "manual" "Use the entered single key" \
+ "both" "Host store + manual key (dedupe)" 3>&1 1>&2 2>&3) || exit_script
+ else
+ SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
+ "No host keys detected; choose manual/none:" 12 70 2 \
+ "none" "No keys" \
+ "manual" "Use the entered single key" 3>&1 1>&2 2>&3) || exit_script
+ fi
+
+ # 4) enable SSH?
+ if [[ "$SSH_SOURCE" != "none" || "$PW" == -password* ]]; then
+ if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno \
+ --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then
SSH="yes"
else
SSH="no"
fi
- echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
else
SSH="no"
- echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
fi
+ echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
+ export SSH_SOURCE SSH_AUTHORIZED_KEY SSH_IMPORT_FILES
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then
ENABLE_FUSE="yes"
@@ -1369,6 +1422,52 @@ check_container_storage() {
fi
}
+install_ssh_keys_into_ct() {
+ [[ "$SSH" != "yes" ]] && return 0
+
+ local tmp="$(mktemp)" any=0
+ local keyre='^(ssh-(rsa|ed25519|ecdsa)|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+'
+
+ case "$SSH_SOURCE" in
+ host | both)
+ if [[ -n "${SSH_IMPORT_FILES:-}" ]]; then
+ IFS=: read -r -a _files <<<"$SSH_IMPORT_FILES"
+ for f in "${_files[@]}"; do
+ [[ -r "$f" ]] || continue
+ awk '$0 !~ /^#/ && $0 ~ /'"$keyre"'/ {print $0}' "$f" >>"$tmp"
+ any=1
+ done
+ fi
+ ;;
+ esac
+
+ case "$SSH_SOURCE" in
+ manual | both)
+ if [[ -n "${SSH_AUTHORIZED_KEY:-}" ]]; then
+ echo "${SSH_AUTHORIZED_KEY}" | awk '$0 !~ /^#/ && $0 ~ /'"$keyre"'/ {print $0}' >>"$tmp"
+ any=1
+ fi
+ ;;
+ esac
+
+ if [[ "$any" -eq 0 ]]; then
+ rm -f "$tmp"
+ msg_warn "No SSH keys to install (skipping)."
+ return 0
+ fi
+
+ sort -u -o "$tmp" "$tmp"
+
+ msg_info "Installing SSH keys into CT ${CTID}"
+ pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh'
+ pct push "$CTID" "$tmp" /root/.ssh/authorized_keys >/dev/null 2>&1 ||
+ pct exec "$CTID" -- sh -c "cat > /root/.ssh/authorized_keys" <"$tmp"
+ pct exec "$CTID" -- sh -c 'chmod 600 /root/.ssh/authorized_keys'
+
+ rm -f "$tmp"
+ msg_ok "Installed SSH keys into CT ${CTID}"
+}
+
start() {
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/tools.func)
if command -v pveversion >/dev/null 2>&1; then
@@ -1753,7 +1852,7 @@ EOF'
}
fi
msg_ok "Customized LXC Container"
-
+ install_ssh_keys_into_ct
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/install/${var_install}.sh)"
}
From 399b5d9705c6e9c54453169166c22779bf0adfa0 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 4 Sep 2025 14:19:40 +0200
Subject: [PATCH 293/312] Update build.func
---
misc/build.func | 114 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 82 insertions(+), 32 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index c14babc2..4cc9a9fe 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -282,25 +282,53 @@ exit_script() {
}
find_host_ssh_keys() {
- local glob="${var_ssh_import_glob:-/root/.ssh/*}"
- local files=()
- local f
- local total=0
- local keyre='^(ssh-(rsa|ed25519|ecdsa)|sk-(ssh-ed25519|ecdsa-sha2-nistp256))\s+'
+ local glob_override="${var_ssh_import_glob:-}"
+ local -a candidates=()
- shopt -s nullglob
- for f in $glob; do
- # skip directories / unreadable
+ if [[ -n "$glob_override" ]]; then
+ shopt -s nullglob
+ candidates+=($glob_override)
+ shopt -u nullglob
+ else
+ shopt -s nullglob
+ candidates+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
+ candidates+=(/root/.ssh/*.pub)
+ candidates+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
+ shopt -u nullglob
+ fi
+
+ local -A seen=()
+ local files=()
+ local total=0
+ local f
+
+ for f in "${candidates[@]}"; do
[[ -f "$f" && -r "$f" ]] || continue
- # count lines that look like authorized_keys entries
+
+ case "$(basename "$f")" in
+ known_hosts | known_hosts.* | config) continue ;;
+ id_*) [[ "$f" != *.pub ]] && continue ;;
+ esac
+
local c
- c=$(awk -v RS='\r?\n' '$0 ~ /^#/ {next} $0 ~ /'"$keyre"'/ {cnt++} END{print cnt+0}' "$f")
- if [[ "${c:-0}" -gt 0 ]]; then
- files+=("$f")
- total=$((total + c))
+ c=$(tr -d '\r' <"$f" | awk '
+ /^[[:space:]]*#/ {next}
+ /^[[:space:]]*$/ {next}
+ # Startet mit Key-Typ
+ /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {cnt++; next}
+ # Oder startet mit authorized_keys-Optionen und enthält später einen Key
+ /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
+ && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {cnt++}
+ END {print cnt+0}
+ ')
+ if ((c > 0)); then
+ [[ -n "${seen[$f]:-}" ]] || {
+ files+=("$f")
+ seen[$f]=1
+ total=$((total + c))
+ }
fi
done
- shopt -u nullglob
FOUND_HOST_KEY_COUNT="$total"
(
@@ -1425,30 +1453,40 @@ check_container_storage() {
install_ssh_keys_into_ct() {
[[ "$SSH" != "yes" ]] && return 0
- local tmp="$(mktemp)" any=0
- local keyre='^(ssh-(rsa|ed25519|ecdsa)|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+'
-
- case "$SSH_SOURCE" in
- host | both)
+ local tmp
+ tmp="$(mktemp)" || return 1
+ local any=0
+ if [[ "$SSH_SOURCE" == "host" || "$SSH_SOURCE" == "both" ]]; then
if [[ -n "${SSH_IMPORT_FILES:-}" ]]; then
IFS=: read -r -a _files <<<"$SSH_IMPORT_FILES"
for f in "${_files[@]}"; do
[[ -r "$f" ]] || continue
- awk '$0 !~ /^#/ && $0 ~ /'"$keyre"'/ {print $0}' "$f" >>"$tmp"
+ tr -d '\r' <"$f" | awk '
+ /^[[:space:]]*#/ {next}
+ /^[[:space:]]*$/ {next}
+ # reine Keyzeile
+ /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {print; next}
+ # authorized_keys mit Optionen
+ /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
+ && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {print}
+ ' >>"$tmp"
any=1
done
fi
- ;;
- esac
+ fi
- case "$SSH_SOURCE" in
- manual | both)
+ if [[ "$SSH_SOURCE" == "manual" || "$SSH_SOURCE" == "both" ]]; then
if [[ -n "${SSH_AUTHORIZED_KEY:-}" ]]; then
- echo "${SSH_AUTHORIZED_KEY}" | awk '$0 !~ /^#/ && $0 ~ /'"$keyre"'/ {print $0}' >>"$tmp"
+ printf '%s\n' "$SSH_AUTHORIZED_KEY" | tr -d '\r' | awk '
+ /^[[:space:]]*#/ {next}
+ /^[[:space:]]*$/ {next}
+ /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {print; next}
+ /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
+ && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {print}
+ ' >>"$tmp"
any=1
fi
- ;;
- esac
+ fi
if [[ "$any" -eq 0 ]]; then
rm -f "$tmp"
@@ -1456,14 +1494,26 @@ install_ssh_keys_into_ct() {
return 0
fi
- sort -u -o "$tmp" "$tmp"
+ # Dedupe + clean EOF
+ sort -u "$tmp" -o "$tmp"
+ printf '\n' >>"$tmp"
msg_info "Installing SSH keys into CT ${CTID}"
- pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh'
- pct push "$CTID" "$tmp" /root/.ssh/authorized_keys >/dev/null 2>&1 ||
- pct exec "$CTID" -- sh -c "cat > /root/.ssh/authorized_keys" <"$tmp"
- pct exec "$CTID" -- sh -c 'chmod 600 /root/.ssh/authorized_keys'
+ pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh' || {
+ msg_error "prepare /root/.ssh failed"
+ rm -f "$tmp"
+ return 1
+ }
+ if ! pct push "$CTID" "$tmp" /root/.ssh/authorized_keys >/dev/null 2>&1; then
+ pct exec "$CTID" -- sh -c "cat > /root/.ssh/authorized_keys" <"$tmp" || {
+ msg_error "write authorized_keys failed"
+ rm -f "$tmp"
+ return 1
+ }
+ fi
+
+ pct exec "$CTID" -- sh -c 'chmod 600 /root/.ssh/authorized_keys' || true
rm -f "$tmp"
msg_ok "Installed SSH keys into CT ${CTID}"
}
From 919eb89681dab5fd5f93b6c474634b958d4de4ad Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 4 Sep 2025 14:41:48 +0200
Subject: [PATCH 294/312] Update build.func
---
misc/build.func | 106 +++++++++++++++++++++++-------------------------
1 file changed, 50 insertions(+), 56 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 4cc9a9fe..9d601503 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -282,54 +282,50 @@ exit_script() {
}
find_host_ssh_keys() {
- local glob_override="${var_ssh_import_glob:-}"
- local -a candidates=()
+ local re='(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))'
+ local -a files=() cand=()
+ local g="${var_ssh_import_glob:-}"
+ local total=0 f base c
- if [[ -n "$glob_override" ]]; then
- shopt -s nullglob
- candidates+=($glob_override)
- shopt -u nullglob
+ shopt -s nullglob
+ if [[ -n "$g" ]]; then
+ for pat in $g; do cand+=($pat); done
else
- shopt -s nullglob
- candidates+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
- candidates+=(/root/.ssh/*.pub)
- candidates+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
- shopt -u nullglob
+ cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
+ cand+=(/root/.ssh/*.pub)
+ cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
fi
+ shopt -u nullglob
- local -A seen=()
- local files=()
- local total=0
- local f
-
- for f in "${candidates[@]}"; do
+ for f in "${cand[@]}"; do
[[ -f "$f" && -r "$f" ]] || continue
-
- case "$(basename "$f")" in
+ base="$(basename -- "$f")"
+ case "$base" in
known_hosts | known_hosts.* | config) continue ;;
id_*) [[ "$f" != *.pub ]] && continue ;;
esac
- local c
+ # CRLF safe check for host keys
c=$(tr -d '\r' <"$f" | awk '
/^[[:space:]]*#/ {next}
/^[[:space:]]*$/ {next}
- # Startet mit Key-Typ
- /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {cnt++; next}
- # Oder startet mit authorized_keys-Optionen und enthält später einen Key
- /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
- && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {cnt++}
- END {print cnt+0}
- ')
+ {print}
+ ' | grep -E -c '"$re"' || true)
+
if ((c > 0)); then
- [[ -n "${seen[$f]:-}" ]] || {
- files+=("$f")
- seen[$f]=1
- total=$((total + c))
- }
+ files+=("$f")
+ total=$((total + c))
fi
done
+ # Fallback to /root/.ssh/authorized_keys
+ if ((${#files[@]} == 0)) && [[ -r /root/.ssh/authorized_keys ]]; then
+ if grep -E -q "$re" /root/.ssh/authorized_keys; then
+ files+=(/root/.ssh/authorized_keys)
+ total=$((total + $(grep -E -c "$re" /root/.ssh/authorized_keys || echo 0)))
+ fi
+ fi
+
FOUND_HOST_KEY_COUNT="$total"
(
IFS=:
@@ -761,39 +757,36 @@ advanced_settings() {
exit_script
fi
- SSH_AUTHORIZED_KEY=""
- if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno \
- --title "SSH KEY (Manual)" --yesno "Enter a manual SSH public key now?\n(Choose 'No' to skip manual entry)" 10 70); then
- SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
- --inputbox "Paste a single SSH public key line (ssh-ed25519 ...)" 10 70 --title "SSH Public Key" 3>&1 1>&2 2>&3)"
- fi
-
- SSH_IMPORT_FILES=""
- HOST_KEYS_AVAILABLE="no"
+ # --- SSH key provisioning (one dialog) ---
SSH_IMPORT_FILES="$(find_host_ssh_keys)"
- if [[ -n "$SSH_IMPORT_FILES" && "${FOUND_HOST_KEY_COUNT:-0}" -gt 0 ]]; then
- HOST_KEYS_AVAILABLE="yes"
- fi
+ HOST_KEYS_AVAILABLE="no"
+ [[ -n "$SSH_IMPORT_FILES" && "${FOUND_HOST_KEY_COUNT:-0}" -gt 0 ]] && HOST_KEYS_AVAILABLE="yes"
+ msg_debug "SSH host files: $SSH_IMPORT_FILES (keys=${FOUND_HOST_KEY_COUNT:-0})"
- SSH_SOURCE="none"
if [[ "$HOST_KEYS_AVAILABLE" == "yes" ]]; then
SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
- "Choose how to provision SSH keys for root:" 14 70 4 \
- "none" "No keys" \
- "host" "Import host store (${FOUND_HOST_KEY_COUNT} keys total)" \
- "manual" "Use the entered single key" \
- "both" "Host store + manual key (dedupe)" 3>&1 1>&2 2>&3) || exit_script
+ "Provision SSH keys for root:" 14 72 4 \
+ "host" "Use keys from host (${FOUND_HOST_KEY_COUNT} found)" \
+ "manual" "Paste a single public key" \
+ "both" "Host + Manual (dedupe)" \
+ "none" "No keys" 3>&1 1>&2 2>&3) || exit_script
else
SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
- "No host keys detected; choose manual/none:" 12 70 2 \
- "none" "No keys" \
- "manual" "Use the entered single key" 3>&1 1>&2 2>&3) || exit_script
+ "No host keys detected; choose manual/none:" 12 72 2 \
+ "manual" "Paste a single public key" \
+ "none" "No keys" 3>&1 1>&2 2>&3) || exit_script
fi
- # 4) enable SSH?
+ # Manual-Eingabe nur wenn nötig
+ SSH_AUTHORIZED_KEY=""
+ if [[ "$SSH_SOURCE" == "manual" || "$SSH_SOURCE" == "both" ]]; then
+ SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
+ --inputbox "Paste one SSH public key line (ssh-ed25519/ssh-rsa/...)" 10 72 --title "SSH Public Key" 3>&1 1>&2 2>&3)"
+ fi
+
+ # SSH aktivieren, wenn Quelle != none oder PW gesetzt
if [[ "$SSH_SOURCE" != "none" || "$PW" == -password* ]]; then
- if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno \
- --title "SSH ACCESS" --yesno "Enable Root SSH Access?" 10 58); then
+ if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable root SSH access?" 10 58); then
SSH="yes"
else
SSH="no"
@@ -802,6 +795,7 @@ advanced_settings() {
SSH="no"
fi
echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
+
export SSH_SOURCE SSH_AUTHORIZED_KEY SSH_IMPORT_FILES
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then
From 584ea1f11c322376c7a37294228d57520fb422dd Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Thu, 4 Sep 2025 14:54:42 +0200
Subject: [PATCH 295/312] Update build.func
---
misc/build.func | 234 +++++++++++++++++++++++++++++++-----------------
1 file changed, 154 insertions(+), 80 deletions(-)
diff --git a/misc/build.func b/misc/build.func
index 9d601503..08ed7cc2 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -214,6 +214,30 @@ ssh_check() {
fi
}
+install_ssh_keys_into_ct() {
+ [[ "$SSH" != "yes" ]] && return 0
+
+ if [[ -n "$SSH_KEYS_FILE" && -s "$SSH_KEYS_FILE" ]]; then
+ msg_info "Installing selected SSH keys into CT ${CTID}"
+ pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh' || {
+ msg_error "prepare /root/.ssh failed"
+ return 1
+ }
+ pct push "$CTID" "$SSH_KEYS_FILE" /root/.ssh/authorized_keys >/dev/null 2>&1 ||
+ pct exec "$CTID" -- sh -c "cat > /root/.ssh/authorized_keys" <"$SSH_KEYS_FILE" || {
+ msg_error "write authorized_keys failed"
+ return 1
+ }
+ pct exec "$CTID" -- sh -c 'chmod 600 /root/.ssh/authorized_keys' || true
+ msg_ok "Installed SSH keys into CT ${CTID}"
+ return 0
+ fi
+
+ # Fallback: nichts ausgewählt
+ msg_warn "No SSH keys to install (skipping)."
+ return 0
+}
+
base_settings() {
# Default Settings
CT_TYPE=${var_unprivileged:-"1"}
@@ -758,34 +782,83 @@ advanced_settings() {
fi
# --- SSH key provisioning (one dialog) ---
- SSH_IMPORT_FILES="$(find_host_ssh_keys)"
- HOST_KEYS_AVAILABLE="no"
- [[ -n "$SSH_IMPORT_FILES" && "${FOUND_HOST_KEY_COUNT:-0}" -gt 0 ]] && HOST_KEYS_AVAILABLE="yes"
- msg_debug "SSH host files: $SSH_IMPORT_FILES (keys=${FOUND_HOST_KEY_COUNT:-0})"
+ SSH_KEYS_FILE="$(mktemp)" # ausgewählte Keys landen hier (eine Datei, mehrere Zeilen)
+ : >"$SSH_KEYS_FILE"
- if [[ "$HOST_KEYS_AVAILABLE" == "yes" ]]; then
- SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
+ # 2.1 Default-Files finden und ggf. Auswahl anbieten
+ IFS=$'\0' read -r -d '' -a _def_files < <(ssh_discover_default_files && printf '\0')
+ ssh_build_choices_from_files "${_def_files[@]}"
+ DEF_KEYS_COUNT="$COUNT"
+
+ if [[ "$DEF_KEYS_COUNT" -gt 0 ]]; then
+ SSH_KEY_MODE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
"Provision SSH keys for root:" 14 72 4 \
- "host" "Use keys from host (${FOUND_HOST_KEY_COUNT} found)" \
+ "found" "Select from detected keys (${DEF_KEYS_COUNT})" \
"manual" "Paste a single public key" \
- "both" "Host + Manual (dedupe)" \
+ "folder" "Scan another folder (path or glob)" \
"none" "No keys" 3>&1 1>&2 2>&3) || exit_script
else
- SSH_SOURCE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
+ SSH_KEY_MODE=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
"No host keys detected; choose manual/none:" 12 72 2 \
"manual" "Paste a single public key" \
"none" "No keys" 3>&1 1>&2 2>&3) || exit_script
fi
- # Manual-Eingabe nur wenn nötig
- SSH_AUTHORIZED_KEY=""
- if [[ "$SSH_SOURCE" == "manual" || "$SSH_SOURCE" == "both" ]]; then
+ case "$SSH_KEY_MODE" in
+ found)
+ # Checkliste einzelner Keys
+ SEL=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SELECT HOST KEYS" \
+ --checklist "Select one or more keys to import:" 20 78 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
+ for tag in $SEL; do
+ tag="${tag%\"}"
+ tag="${tag#\"}"
+ line=$(grep -E "^${tag}\|" "$MAPFILE" | head -n1 | cut -d'|' -f2-)
+ [[ -n "$line" ]] && printf '%s\n' "$line" >>"$SSH_KEYS_FILE"
+ done
+ ;;
+ manual)
SSH_AUTHORIZED_KEY="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
--inputbox "Paste one SSH public key line (ssh-ed25519/ssh-rsa/...)" 10 72 --title "SSH Public Key" 3>&1 1>&2 2>&3)"
+ [[ -n "$SSH_AUTHORIZED_KEY" ]] && printf '%s\n' "$SSH_AUTHORIZED_KEY" >>"$SSH_KEYS_FILE"
+ ;;
+ folder)
+ GLOB_PATH="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
+ --inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub)" 10 72 --title "Scan Folder/Glob" 3>&1 1>&2 2>&3)"
+ if [[ -n "$GLOB_PATH" ]]; then
+ # expandiere Globs
+ shopt -s nullglob
+ read -r -a _scan_files <<<"$GLOB_PATH"
+ shopt -u nullglob
+ if [[ "${#_scan_files[@]}" -gt 0 ]]; then
+ ssh_build_choices_from_files "${_scan_files[@]}"
+ if [[ "$COUNT" -gt 0 ]]; then
+ SEL=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SELECT FOLDER KEYS" \
+ --checklist "Select key(s) to import:" 20 78 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
+ for tag in $SEL; do
+ tag="${tag%\"}"
+ tag="${tag#\"}"
+ line=$(grep -E "^${tag}\|" "$MAPFILE" | head -n1 | cut -d'|' -f2-)
+ [[ -n "$line" ]] && printf '%s\n' "$line" >>"$SSH_KEYS_FILE"
+ done
+ else
+ whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "No keys found in: $GLOB_PATH" 8 60
+ fi
+ else
+ whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --msgbox "Path/glob returned no files." 8 60
+ fi
+ fi
+ ;;
+ none) : ;;
+ esac
+
+ # Dedupe + sauberer EOF
+ if [[ -s "$SSH_KEYS_FILE" ]]; then
+ sort -u -o "$SSH_KEYS_FILE" "$SSH_KEYS_FILE"
+ printf '\n' >>"$SSH_KEYS_FILE"
fi
- # SSH aktivieren, wenn Quelle != none oder PW gesetzt
- if [[ "$SSH_SOURCE" != "none" || "$PW" == -password* ]]; then
+ # SSH aktivieren, wenn Keys oder PW
+ if [[ -s "$SSH_KEYS_FILE" || "$PW" == -password* ]]; then
if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable root SSH access?" 10 58); then
SSH="yes"
else
@@ -796,8 +869,7 @@ advanced_settings() {
fi
echo -e "${ROOTSSH}${BOLD}${DGN}Root SSH Access: ${BGN}$SSH${CL}"
- export SSH_SOURCE SSH_AUTHORIZED_KEY SSH_IMPORT_FILES
-
+ export SSH_KEYS_FILE
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "FUSE Support" --yesno "Enable FUSE support?\nRequired for tools like rclone, mergerfs, AppImage, etc." 10 58); then
ENABLE_FUSE="yes"
else
@@ -1444,72 +1516,74 @@ check_container_storage() {
fi
}
-install_ssh_keys_into_ct() {
- [[ "$SSH" != "yes" ]] && return 0
-
- local tmp
- tmp="$(mktemp)" || return 1
- local any=0
- if [[ "$SSH_SOURCE" == "host" || "$SSH_SOURCE" == "both" ]]; then
- if [[ -n "${SSH_IMPORT_FILES:-}" ]]; then
- IFS=: read -r -a _files <<<"$SSH_IMPORT_FILES"
- for f in "${_files[@]}"; do
- [[ -r "$f" ]] || continue
- tr -d '\r' <"$f" | awk '
- /^[[:space:]]*#/ {next}
- /^[[:space:]]*$/ {next}
- # reine Keyzeile
- /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {print; next}
- # authorized_keys mit Optionen
- /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
- && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {print}
- ' >>"$tmp"
- any=1
- done
- fi
- fi
-
- if [[ "$SSH_SOURCE" == "manual" || "$SSH_SOURCE" == "both" ]]; then
- if [[ -n "${SSH_AUTHORIZED_KEY:-}" ]]; then
- printf '%s\n' "$SSH_AUTHORIZED_KEY" | tr -d '\r' | awk '
- /^[[:space:]]*#/ {next}
- /^[[:space:]]*$/ {next}
- /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {print; next}
- /^(command=|environment=|from=|no-agent-forwarding|no-port-forwarding|no-pty|no-user-rc|no-X11-forwarding|permitopen=|principals=|tunnel=)/ \
- && /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))/ {print}
- ' >>"$tmp"
- any=1
- fi
- fi
-
- if [[ "$any" -eq 0 ]]; then
- rm -f "$tmp"
- msg_warn "No SSH keys to install (skipping)."
- return 0
- fi
-
- # Dedupe + clean EOF
- sort -u "$tmp" -o "$tmp"
- printf '\n' >>"$tmp"
-
- msg_info "Installing SSH keys into CT ${CTID}"
- pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh' || {
- msg_error "prepare /root/.ssh failed"
- rm -f "$tmp"
- return 1
- }
-
- if ! pct push "$CTID" "$tmp" /root/.ssh/authorized_keys >/dev/null 2>&1; then
- pct exec "$CTID" -- sh -c "cat > /root/.ssh/authorized_keys" <"$tmp" || {
- msg_error "write authorized_keys failed"
- rm -f "$tmp"
- return 1
+ssh_extract_keys_from_file() {
+ local f="$1"
+ [[ -r "$f" ]] || return 0
+ tr -d '\r' <"$f" | awk '
+ /^[[:space:]]*#/ {next}
+ /^[[:space:]]*$/ {next}
+ # nackt: typ base64 [comment]
+ /^(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/ {print; next}
+ # mit Optionen: finde ab erstem Key-Typ
+ {
+ match($0, /(ssh-(rsa|ed25519)|ecdsa-sha2-nistp256|sk-(ssh-ed25519|ecdsa-sha2-nistp256))[[:space:]]+/)
+ if (RSTART>0) { print substr($0, RSTART) }
}
- fi
+ '
+}
- pct exec "$CTID" -- sh -c 'chmod 600 /root/.ssh/authorized_keys' || true
- rm -f "$tmp"
- msg_ok "Installed SSH keys into CT ${CTID}"
+ssh_build_choices_from_files() {
+ local -a files=("$@")
+ CHOICES=()
+ COUNT=0
+ MAPFILE="$(mktemp)"
+ local id key typ fp cmt base ln=0
+
+ for f in "${files[@]}"; do
+ [[ -f "$f" && -r "$f" ]] || continue
+ base="$(basename -- "$f")"
+ case "$base" in
+ known_hosts | known_hosts.* | config) continue ;;
+ id_*) [[ "$f" != *.pub ]] && continue ;;
+ esac
+
+ # jede Key-Zeile mappen -> K|
+ while IFS= read -r key; do
+ [[ -n "$key" ]] || continue
+
+ # Fingerprint/Type/Comment hübsch machen (best effort)
+ typ=""
+ fp=""
+ cmt=""
+ # Nur der pure Key-Teil (ohne Optionen) ist schon in 'key' enthalten
+ read -r _typ _b64 _cmt <<<"$key"
+ typ="${_typ:-key}"
+ cmt="${_cmt:-}"
+ # Fingerprint via ssh-keygen (falls verfügbar)
+ if command -v ssh-keygen >/dev/null 2>&1; then
+ fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
+ fi
+ # Label kürzen
+ [[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
+
+ ln=$((ln + 1))
+ COUNT=$((COUNT + 1))
+ id="K${COUNT}"
+ echo "${id}|${key}" >>"$MAPFILE"
+ CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
+ done < <(ssh_extract_keys_from_file "$f")
+ done
+}
+
+# Sucht Standard-Quellen (authorized_keys, *.pub, /etc/ssh/authorized_keys.d/*)
+ssh_discover_default_files() {
+ local -a cand=()
+ shopt -s nullglob
+ cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
+ cand+=(/root/.ssh/*.pub)
+ cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
+ shopt -u nullglob
+ printf '%s\0' "${cand[@]}"
}
start() {
From e5ef51e69dd75bed48667b70c6926f63d9b5d54d Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 5 Sep 2025 09:03:10 +0200
Subject: [PATCH 296/312] -
---
ct/leantime.sh | 28 +++++++++++++++++++++-------
install/leantime-install.sh | 5 +----
misc/build.func | 11 ++++-------
3 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/ct/leantime.sh b/ct/leantime.sh
index f49c503a..6a029571 100644
--- a/ct/leantime.sh
+++ b/ct/leantime.sh
@@ -1,6 +1,5 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
-
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Stroopwafe1
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
@@ -25,16 +24,31 @@ function update_script() {
check_container_storage
check_container_resources
- if [[ ! -d /opt/${APP} ]]; then
+ if [[ ! -d /opt/leantime ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
- msg_info "Creating Backup"
- mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql"
- tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" "/opt/${APP}"
- msg_ok "Backup Created"
- fetch_and_deploy_gh_release "$APP" "Leantime/leantime" "prebuild" "latest" "/opt/${APP}" Leantime-v[0-9].[0-9].[0-9].tar.gz
+ if check_for_gh_release "leantime" "Leantime/leantime"; then
+ msg_info "Creating Backup"
+ mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql"
+ tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" "/opt/${APP}"
+ mv /opt/leantime /opt/leantime_bak
+ msg_ok "Backup Created"
+
+ fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
+
+ msg_info "Restoring Config & Permissions"
+ mv /opt/leantime_bak/config/.env /opt/leantime/config/.env
+ chown -R www-data:www-data "/opt/leantime"
+ chmod -R 750 "/opt/leantime"
+ msg_ok "Restored Config & Permissions"
+
+ msg_info "Removing Backup"
+ rm -rf /opt/leantime_bak
+ msg_ok "Removed Backup"
+ msg_ok "Updated Successfully"
+ fi
exit
}
diff --git a/install/leantime-install.sh b/install/leantime-install.sh
index 8c72b30a..db67e925 100644
--- a/install/leantime-install.sh
+++ b/install/leantime-install.sh
@@ -36,7 +36,6 @@ fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "
msg_info "Setup Leantime"
chown -R www-data:www-data "/opt/leantime"
chmod -R 750 "/opt/leantime"
-
cat </etc/apache2/sites-enabled/000-default.conf
ServerAdmin webmaster@localhost
@@ -58,19 +57,17 @@ cat </etc/apache2/sites-enabled/000-default.conf
CustomLog /var/log/apache2/access.log combined
EOF
-
mv "/opt/leantime/config/sample.env" "/opt/leantime/config/.env"
sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
-e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \
-e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \
-e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \
"/opt/leantime/config/.env"
-
$STD a2enmod -q proxy_fcgi setenvif rewrite
$STD a2enconf -q "php8.4-fpm"
sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/8.4/apache2/php.ini"
systemctl restart apache2
-msg_ok "Setup ${APPLICATION}"
+msg_ok "Setup leantime"
motd_ssh
customize
diff --git a/misc/build.func b/misc/build.func
index 08ed7cc2..766aab33 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -782,10 +782,9 @@ advanced_settings() {
fi
# --- SSH key provisioning (one dialog) ---
- SSH_KEYS_FILE="$(mktemp)" # ausgewählte Keys landen hier (eine Datei, mehrere Zeilen)
+ SSH_KEYS_FILE="$(mktemp)"
: >"$SSH_KEYS_FILE"
- # 2.1 Default-Files finden und ggf. Auswahl anbieten
IFS=$'\0' read -r -d '' -a _def_files < <(ssh_discover_default_files && printf '\0')
ssh_build_choices_from_files "${_def_files[@]}"
DEF_KEYS_COUNT="$COUNT"
@@ -806,9 +805,8 @@ advanced_settings() {
case "$SSH_KEY_MODE" in
found)
- # Checkliste einzelner Keys
SEL=$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --title "SELECT HOST KEYS" \
- --checklist "Select one or more keys to import:" 20 78 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
+ --checklist "Select one or more keys to import:" 20 20 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
for tag in $SEL; do
tag="${tag%\"}"
tag="${tag#\"}"
@@ -825,7 +823,6 @@ advanced_settings() {
GLOB_PATH="$(whiptail --backtitle "[dev] Proxmox VE Helper Scripts" \
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub)" 10 72 --title "Scan Folder/Glob" 3>&1 1>&2 2>&3)"
if [[ -n "$GLOB_PATH" ]]; then
- # expandiere Globs
shopt -s nullglob
read -r -a _scan_files <<<"$GLOB_PATH"
shopt -u nullglob
@@ -851,13 +848,13 @@ advanced_settings() {
none) : ;;
esac
- # Dedupe + sauberer EOF
+ # Dedupe + clean EOF
if [[ -s "$SSH_KEYS_FILE" ]]; then
sort -u -o "$SSH_KEYS_FILE" "$SSH_KEYS_FILE"
printf '\n' >>"$SSH_KEYS_FILE"
fi
- # SSH aktivieren, wenn Keys oder PW
+ # SSH activate, if keys found or password set
if [[ -s "$SSH_KEYS_FILE" || "$PW" == -password* ]]; then
if (whiptail --backtitle "[dev] Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable root SSH access?" 10 58); then
SSH="yes"
From 61f98ba7b2bca08e8bf4ade7a9f223e955e98bc2 Mon Sep 17 00:00:00 2001
From: CanbiZ <47820557+MickLesk@users.noreply.github.com>
Date: Fri, 5 Sep 2025 09:40:57 +0200
Subject: [PATCH 297/312] Update librenms-install.sh
---
install/librenms-install.sh | 46 ++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/install/librenms-install.sh b/install/librenms-install.sh
index bea0d4a8..46f3c5bf 100644
--- a/install/librenms-install.sh
+++ b/install/librenms-install.sh
@@ -15,28 +15,28 @@ update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
- lsb-release \
- ca-certificates \
- acl \
- fping \
- graphviz \
- imagemagick \
- mtr-tiny \
- nginx \
- nmap \
- rrdtool \
- snmp \
- snmpd
+ lsb-release \
+ ca-certificates \
+ acl \
+ fping \
+ graphviz \
+ imagemagick \
+ mtr-tiny \
+ nginx \
+ nmap \
+ rrdtool \
+ snmp \
+ snmpd
msg_ok "Installed Dependencies"
-PHP_VERSION=8.2 PHP_FPM=YES PHP_APACHE=NO PHP_MODULE="gmp,mysql,snmp" setup_php
+PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="gmp,mysql,snmp" setup_php
setup_mariadb
setup_composer
-setup_uv
+PYTHON_VERSION="3.13" setup_uv
msg_info "Installing Python"
$STD apt-get install -y \
- python3-{dotenv,pymysql,redis,setuptools,systemd,pip}
+ python3-{dotenv,pymysql,redis,setuptools,systemd,pip}
msg_ok "Installed Python"
msg_info "Configuring Database"
@@ -47,16 +47,17 @@ $STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
- echo "LibreNMS-Credentials"
- echo "LibreNMS Database User: $DB_USER"
- echo "LibreNMS Database Password: $DB_PASS"
- echo "LibreNMS Database Name: $DB_NAME"
+ echo "LibreNMS-Credentials"
+ echo "LibreNMS Database User: $DB_USER"
+ echo "LibreNMS Database Password: $DB_PASS"
+ echo "LibreNMS Database Name: $DB_NAME"
} >>~/librenms.creds
msg_ok "Configured Database"
-msg_info "Setup Librenms"
+fetch_and_deploy_gh_release "LibreNMS" "librenms/librenms"
+
+msg_info "Configuring LibreNMS"
$STD useradd librenms -d /opt/librenms -M -r -s "$(which bash)"
-fetch_and_deploy_gh_release "librenms/librenms"
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
cd /opt/librenms
@@ -72,7 +73,7 @@ chown -R librenms:librenms /opt/librenms
chmod 771 /opt/librenms
setfacl -d -m g::rwx /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
-msg_ok "Setup LibreNMS"
+msg_ok "Configured LibreNMS"
msg_info "Configure MariaDB"
sed -i "/\[mysqld\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf
@@ -147,7 +148,6 @@ motd_ssh
customize
msg_info "Cleaning up"
-rm -f $tmp_file
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
From 2dcc7736dc68fda5596b5b7ef40a644b8d12390d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?=
Date: Fri, 5 Sep 2025 11:43:19 +0100
Subject: [PATCH 298/312] Added ct, install and json files
---
ct/stylus.sh | 62 ++++++++++++++++++++++++++++++++
frontend/public/json/stylus.json | 40 +++++++++++++++++++++
install/stylus-install.sh | 62 ++++++++++++++++++++++++++++++++
3 files changed, 164 insertions(+)
create mode 100644 ct/stylus.sh
create mode 100644 frontend/public/json/stylus.json
create mode 100644 install/stylus-install.sh
diff --git a/ct/stylus.sh b/ct/stylus.sh
new file mode 100644
index 00000000..8c3c5568
--- /dev/null
+++ b/ct/stylus.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: luismco
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/mmastrac/stylus
+
+APP="Stylus"
+var_tags="${var_tags:-network}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-2048}"
+var_disk="${var_disk:-8}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+var_unprivileged="${var_unprivileged:-1}"
+var_fuse="${var_fuse:-1}"
+
+header_info "$APP"
+variables
+color
+catch_errors
+
+function update_script() {
+ header_info
+ check_container_storage
+ check_container_resources
+
+ if [[ ! -d /opt/stylus ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ RELEASE=$(curl -fsSL https://api.github.com/repos/mmastrac/stylus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
+ if [[ ! -f /opt/stylus/stylus_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/stylus/stylus_version.txt)" ]]; then
+ msg_info "Stopping $APP"
+ systemctl stop stylus
+ msg_ok "Stopped $APP"
+
+ msg_info "Updating $APP"
+ $STD rustup update
+ $STD cargo install-update -a
+ $STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > /opt/stylus/stylus_version.txt"
+ msg_ok "Updated $APP"
+
+ msg_info "Starting $APP"
+ systemctl start stylus
+ msg_ok "Started $APP"
+ msg_ok "Update Successful"
+ else
+ msg_ok "No update required. ${APP} is already at v${RELEASE}."
+ 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
diff --git a/frontend/public/json/stylus.json b/frontend/public/json/stylus.json
new file mode 100644
index 00000000..4a8efe03
--- /dev/null
+++ b/frontend/public/json/stylus.json
@@ -0,0 +1,40 @@
+{
+ "name": "Stylus",
+ "slug": "stylus",
+ "categories": [
+ 4
+ ],
+ "date_created": "2025-09-05",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "interface_port": 8000,
+ "documentation": "https://mmastrac.github.io/stylus/",
+ "website": "https://github.com/mmastrac/stylus",
+ "logo": null,
+ "config_path": "/opt/stylus/",
+ "description": "Stylus (style + status) is a lightweight status page for infrastructure and networks. Configure a set of bash scripts that test the various parts of your infrastructure, set up visualizations with minimal configuration, and Stylus will generate you a dashboard for your system.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/stylus.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 2048,
+ "hdd": 8,
+ "os": "debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": [
+ {
+ "text": "Configuration Path: `/opt/stylus/`",
+ "type": "info"
+ }
+ ]
+}
diff --git a/install/stylus-install.sh b/install/stylus-install.sh
new file mode 100644
index 00000000..84b9af32
--- /dev/null
+++ b/install/stylus-install.sh
@@ -0,0 +1,62 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 community-scripts ORG
+# Author: luismco
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://github.com/mmastrac/stylus
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Installing dependencies"
+$STD apt-get install -y \
+ build-essential \
+ openssl \
+ libssl-dev \
+ pkg-config
+msg_ok "Installed dependencies"
+
+msg_info "Installing Rust"
+$STD su -c "curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- -y"
+$STD . "$HOME/.cargo/env"
+$STD cargo install cargo-update
+msg_ok "Installed Rust"
+
+msg_info "Installing Stylus"
+$STD cargo install stylus
+$STD stylus init /opt/stylus/
+$STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > /opt/stylus/stylus_version.txt"
+msg_ok "Installed Stylus"
+
+msg_info "Creating service"
+
+cat >/etc/systemd/system/stylus.service <
Date: Fri, 5 Sep 2025 12:53:50 +0100
Subject: [PATCH 299/312] Added new check_for_gh_release function and changed
version file to new home. Config path now points to a file. Revisioned cat
command on install script.
---
ct/stylus.sh | 6 ++----
frontend/public/json/stylus.json | 4 ++--
install/stylus-install.sh | 7 ++++---
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/ct/stylus.sh b/ct/stylus.sh
index 8c3c5568..69ae4a2d 100644
--- a/ct/stylus.sh
+++ b/ct/stylus.sh
@@ -29,9 +29,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
-
- RELEASE=$(curl -fsSL https://api.github.com/repos/mmastrac/stylus/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
- if [[ ! -f /opt/stylus/stylus_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/stylus/stylus_version.txt)" ]]; then
+ if check_for_gh_release "stylus" "mmastrac/stylus"; then
msg_info "Stopping $APP"
systemctl stop stylus
msg_ok "Stopped $APP"
@@ -39,7 +37,7 @@ function update_script() {
msg_info "Updating $APP"
$STD rustup update
$STD cargo install-update -a
- $STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > /opt/stylus/stylus_version.txt"
+ $STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > ~/.stylus"
msg_ok "Updated $APP"
msg_info "Starting $APP"
diff --git a/frontend/public/json/stylus.json b/frontend/public/json/stylus.json
index 4a8efe03..94b2244d 100644
--- a/frontend/public/json/stylus.json
+++ b/frontend/public/json/stylus.json
@@ -12,7 +12,7 @@
"documentation": "https://mmastrac.github.io/stylus/",
"website": "https://github.com/mmastrac/stylus",
"logo": null,
- "config_path": "/opt/stylus/",
+ "config_path": "/opt/stylus/config.yaml",
"description": "Stylus (style + status) is a lightweight status page for infrastructure and networks. Configure a set of bash scripts that test the various parts of your infrastructure, set up visualizations with minimal configuration, and Stylus will generate you a dashboard for your system.",
"install_methods": [
{
@@ -33,7 +33,7 @@
},
"notes": [
{
- "text": "Configuration Path: `/opt/stylus/`",
+ "text": "Configuration Path: `/opt/stylus/config.yaml`",
"type": "info"
}
]
diff --git a/install/stylus-install.sh b/install/stylus-install.sh
index 84b9af32..c515ce28 100644
--- a/install/stylus-install.sh
+++ b/install/stylus-install.sh
@@ -30,20 +30,21 @@ msg_ok "Installed Rust"
msg_info "Installing Stylus"
$STD cargo install stylus
$STD stylus init /opt/stylus/
-$STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > /opt/stylus/stylus_version.txt"
+$STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > ~/.stylus"
msg_ok "Installed Stylus"
msg_info "Creating service"
-cat >/etc/systemd/system/stylus.service </etc/systemd/system/stylus.service
[Unit]
-Description=Stylus
+Description=Stylus Service
After=network.target
[Service]
Type=simple
ExecStart=$HOME/.cargo/bin/stylus run /opt/stylus
Restart=on-failure
+RestartSec=5
[Install]
WantedBy=multi-user.target
From 91fcd53a53f34c83658e1f46495751ed7e686b76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?=
Date: Fri, 5 Sep 2025 14:16:30 +0100
Subject: [PATCH 300/312] Small text change in the update msg_ok to remove
duplicate version number info
---
ct/stylus.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ct/stylus.sh b/ct/stylus.sh
index 69ae4a2d..fb1addb2 100644
--- a/ct/stylus.sh
+++ b/ct/stylus.sh
@@ -45,7 +45,7 @@ function update_script() {
msg_ok "Started $APP"
msg_ok "Update Successful"
else
- msg_ok "No update required. ${APP} is already at v${RELEASE}."
+ msg_ok "No update required. Latest version already installed."
fi
exit
}
From 3dbe49b6c21d4bdfd41b40f1ee6b6e571483dbcf Mon Sep 17 00:00:00 2001
From: vhsdream
Date: Fri, 5 Sep 2025 11:19:49 -0400
Subject: [PATCH 301/312] Autocaliweb: use new version helper
---
ct/autocaliweb.sh | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/ct/autocaliweb.sh b/ct/autocaliweb.sh
index e2aa9735..53cf7fc6 100644
--- a/ct/autocaliweb.sh
+++ b/ct/autocaliweb.sh
@@ -31,7 +31,7 @@ function update_script() {
setup_uv
RELEASE=$(curl -fsSL https://api.github.com/repos/gelbphoenix/autocaliweb/releases/latest | jq '.tag_name' | sed 's/^"v//;s/"$//')
- if [[ "${RELEASE}" != "$(cat ~/.autocaliweb 2>/dev/null)" ]] || [[ ! -f ~/.autocaliweb ]]; then
+ if check_for_gh_release "autocaliweb" "gelbphoenix/autocaliweb"; then
msg_info "Stopping Services"
systemctl stop autocaliweb metadata-change-detector acw-ingest-service acw-auto-zipper
msg_ok "Stopped Services"
@@ -61,6 +61,7 @@ function update_script() {
echo "${CALIBRE_RELEASE#v}" >/"$INSTALL_DIR"/CALIBRE_RELEASE
sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
chown -R acw:acw "$INSTALL_DIR"
+ rm ~/autocaliweb_bkp.tar
msg_ok "Updated $APP"
msg_info "Starting Services"
@@ -68,8 +69,6 @@ function update_script() {
msg_ok "Started Services"
msg_ok "Updated Successfully"
- else
- msg_ok "Already up to date"
fi
exit
}
From 923e721889a2d2695b9f2ad70c806596149ee7e4 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 5 Sep 2025 19:44:33 +0200
Subject: [PATCH 302/312] Update resilio-sync
---
install/resiliosync-install.sh | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/install/resiliosync-install.sh b/install/resiliosync-install.sh
index 8b03ff9e..d03b58d0 100644
--- a/install/resiliosync-install.sh
+++ b/install/resiliosync-install.sh
@@ -13,14 +13,17 @@ setting_up_container
network_check
update_os
-msg_info "Installing Resilio Sync"
+msg_info "Setting up Resilio Sync Repository"
curl -fsSL "https://linux-packages.resilio.com/resilio-sync/key.asc" >/etc/apt/trusted.gpg.d/resilio-sync.asc
echo "deb [signed-by=/etc/apt/trusted.gpg.d/resilio-sync.asc] http://linux-packages.resilio.com/resilio-sync/deb resilio-sync non-free" >/etc/apt/sources.list.d/resilio-sync.list
$STD apt-get update
+msg_ok "Resilio Sync Repository Setup"
+
+msg_info "Installing Resilio Sync"
$STD apt-get install -y resilio-sync
-sed -i 's/127.0.0.1:8888/0.0.0.0:8888/g' /etc/resilio-sync/config.json
-$STD systemctl enable resilio-sync
-$STD systemctl restart resilio-sync
+sed -i "s/127.0.0.1:8888/0.0.0.0:8888/g" /etc/resilio-sync/config.json
+systemctl enable -q resilio-sync
+systemctl restart resilio-sync
msg_ok "Installed Resilio Sync"
motd_ssh
From 99cac0486ca18db0dbcd5e90552d0c37ce0fc589 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 5 Sep 2025 20:00:49 +0200
Subject: [PATCH 303/312] Fix resiliosync icon
---
frontend/public/json/resiliosync.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/public/json/resiliosync.json b/frontend/public/json/resiliosync.json
index 222786e1..3dcc81e0 100644
--- a/frontend/public/json/resiliosync.json
+++ b/frontend/public/json/resiliosync.json
@@ -12,7 +12,7 @@
"interface_port": 8888,
"documentation": "https://help.resilio.com/",
"website": "https://www.resilio.com/sync",
- "logo": "https://www.resilio.com/images/sync-appicon-blue-bg.svg",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/resilio-sync.webp",
"description": "Fast, reliable, and simple file sync and share solution, powered by P2P technology. Sync files across all your devices without storing them in the cloud.",
"install_methods": [
{
From 480fe61ee39327b10887f3f9a7df52466a0ae26d Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 5 Sep 2025 20:07:39 +0200
Subject: [PATCH 304/312] Update resilio json
---
frontend/public/json/resiliosync.json | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/frontend/public/json/resiliosync.json b/frontend/public/json/resiliosync.json
index 3dcc81e0..a75ae70c 100644
--- a/frontend/public/json/resiliosync.json
+++ b/frontend/public/json/resiliosync.json
@@ -31,5 +31,10 @@
"username": null,
"password": null
},
- "notes": []
+ "notes": [
+ {
+ "text": "After free registration, you will receive a license keyfile to your email address. Upload it into any LXC directory and select on first run.",
+ "type": "info"
+ }
+ ]
}
From a761c097a3cd36766a49627685c956e68b0eceb6 Mon Sep 17 00:00:00 2001
From: tremor021
Date: Fri, 5 Sep 2025 20:10:46 +0200
Subject: [PATCH 305/312] Update resiliosync
---
ct/{resiliosync.sh => resilio-sync.sh} | 0
frontend/public/json/{resiliosync.json => resilio-sync.json} | 2 +-
install/{resiliosync-install.sh => resilio-sync-install.sh} | 0
3 files changed, 1 insertion(+), 1 deletion(-)
rename ct/{resiliosync.sh => resilio-sync.sh} (100%)
rename frontend/public/json/{resiliosync.json => resilio-sync.json} (96%)
rename install/{resiliosync-install.sh => resilio-sync-install.sh} (100%)
diff --git a/ct/resiliosync.sh b/ct/resilio-sync.sh
similarity index 100%
rename from ct/resiliosync.sh
rename to ct/resilio-sync.sh
diff --git a/frontend/public/json/resiliosync.json b/frontend/public/json/resilio-sync.json
similarity index 96%
rename from frontend/public/json/resiliosync.json
rename to frontend/public/json/resilio-sync.json
index a75ae70c..0b61fe3d 100644
--- a/frontend/public/json/resiliosync.json
+++ b/frontend/public/json/resilio-sync.json
@@ -17,7 +17,7 @@
"install_methods": [
{
"type": "default",
- "script": "ct/resiliosync.sh",
+ "script": "ct/resilio-sync.sh",
"resources": {
"cpu": 2,
"ram": 2048,
diff --git a/install/resiliosync-install.sh b/install/resilio-sync-install.sh
similarity index 100%
rename from install/resiliosync-install.sh
rename to install/resilio-sync-install.sh
From 791db5589a81a96a5a47351846f1f0993ef8c880 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?=
Date: Sat, 6 Sep 2025 09:56:35 +0100
Subject: [PATCH 306/312] Simplified install and update scripts with binaries
instead of building it from source. Added app icon. Updated app resources.
---
ct/stylus.sh | 11 +++++------
frontend/public/json/stylus.json | 10 +++++-----
install/stylus-install.sh | 24 +++++-------------------
3 files changed, 15 insertions(+), 30 deletions(-)
diff --git a/ct/stylus.sh b/ct/stylus.sh
index fb1addb2..9e8bd99b 100644
--- a/ct/stylus.sh
+++ b/ct/stylus.sh
@@ -7,9 +7,9 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVED/
APP="Stylus"
var_tags="${var_tags:-network}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-8}"
+var_cpu="${var_cpu:-1}"
+var_ram="${var_ram:-1024}"
+var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
@@ -35,9 +35,8 @@ function update_script() {
msg_ok "Stopped $APP"
msg_info "Updating $APP"
- $STD rustup update
- $STD cargo install-update -a
- $STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > ~/.stylus"
+ fetch_and_deploy_gh_release "stylus" "mmastrac/stylus" "singlefile" "latest" "/usr/bin/" "*_linux_amd64"
+
msg_ok "Updated $APP"
msg_info "Starting $APP"
diff --git a/frontend/public/json/stylus.json b/frontend/public/json/stylus.json
index 94b2244d..9ef41244 100644
--- a/frontend/public/json/stylus.json
+++ b/frontend/public/json/stylus.json
@@ -4,14 +4,14 @@
"categories": [
4
],
- "date_created": "2025-09-05",
+ "date_created": "2025-09-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://mmastrac.github.io/stylus/",
"website": "https://github.com/mmastrac/stylus",
- "logo": null,
+ "logo": "https: //cdn.jsdelivr.net/gh/selfhst/icons/webp/stylus.webp",
"config_path": "/opt/stylus/config.yaml",
"description": "Stylus (style + status) is a lightweight status page for infrastructure and networks. Configure a set of bash scripts that test the various parts of your infrastructure, set up visualizations with minimal configuration, and Stylus will generate you a dashboard for your system.",
"install_methods": [
@@ -19,9 +19,9 @@
"type": "default",
"script": "ct/stylus.sh",
"resources": {
- "cpu": 2,
- "ram": 2048,
- "hdd": 8,
+ "cpu": 1,
+ "ram": 1024,
+ "hdd": 2,
"os": "debian",
"version": "12"
}
diff --git a/install/stylus-install.sh b/install/stylus-install.sh
index c515ce28..d740fd3b 100644
--- a/install/stylus-install.sh
+++ b/install/stylus-install.sh
@@ -13,28 +13,14 @@ setting_up_container
network_check
update_os
-msg_info "Installing dependencies"
-$STD apt-get install -y \
- build-essential \
- openssl \
- libssl-dev \
- pkg-config
-msg_ok "Installed dependencies"
-
-msg_info "Installing Rust"
-$STD su -c "curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- -y"
-$STD . "$HOME/.cargo/env"
-$STD cargo install cargo-update
-msg_ok "Installed Rust"
-
msg_info "Installing Stylus"
-$STD cargo install stylus
+fetch_and_deploy_gh_release "stylus" "mmastrac/stylus" "singlefile" "latest" "/usr/bin/" "*_linux_amd64"
+
+msg_info "Configuring Stylus"
$STD stylus init /opt/stylus/
-$STD su -c "cargo install --list | grep 'stylus' | cut -d' ' -f2 | sed 's/^v//;s/:$//' > ~/.stylus"
-msg_ok "Installed Stylus"
+msg_ok "Configured Stylus"
msg_info "Creating service"
-
cat </etc/systemd/system/stylus.service
[Unit]
Description=Stylus Service
@@ -42,7 +28,7 @@ After=network.target
[Service]
Type=simple
-ExecStart=$HOME/.cargo/bin/stylus run /opt/stylus
+ExecStart=stylus run /opt/stylus/
Restart=on-failure
RestartSec=5
From 42588937730bd310a84a2834004f9339524492c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?=
Date: Sat, 6 Sep 2025 10:04:49 +0100
Subject: [PATCH 307/312] Small correction to the install script
---
install/stylus-install.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/install/stylus-install.sh b/install/stylus-install.sh
index d740fd3b..483b055f 100644
--- a/install/stylus-install.sh
+++ b/install/stylus-install.sh
@@ -13,7 +13,6 @@ setting_up_container
network_check
update_os
-msg_info "Installing Stylus"
fetch_and_deploy_gh_release "stylus" "mmastrac/stylus" "singlefile" "latest" "/usr/bin/" "*_linux_amd64"
msg_info "Configuring Stylus"
From 50e90457ea381793fcdf853e31243631584b9b7f Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Sat, 6 Sep 2025 16:00:05 +0200
Subject: [PATCH 308/312] Rename resilio-sync.json to resiliosync.json
---
frontend/public/json/{resilio-sync.json => resiliosync.json} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename frontend/public/json/{resilio-sync.json => resiliosync.json} (100%)
diff --git a/frontend/public/json/resilio-sync.json b/frontend/public/json/resiliosync.json
similarity index 100%
rename from frontend/public/json/resilio-sync.json
rename to frontend/public/json/resiliosync.json
From f5bebc286d7dee1b6fb51b7b300b3b60d472cac5 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Sat, 6 Sep 2025 16:11:08 +0200
Subject: [PATCH 309/312] Rename resilio-sync-install.sh to
resiliosync-install.sh
---
install/{resilio-sync-install.sh => resiliosync-install.sh} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename install/{resilio-sync-install.sh => resiliosync-install.sh} (100%)
diff --git a/install/resilio-sync-install.sh b/install/resiliosync-install.sh
similarity index 100%
rename from install/resilio-sync-install.sh
rename to install/resiliosync-install.sh
From d4d7ae6febc83cebb26e10505db1b5a589316406 Mon Sep 17 00:00:00 2001
From: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Date: Sat, 6 Sep 2025 16:11:32 +0200
Subject: [PATCH 310/312] Rename resilio-sync.sh to resiliosync.sh
---
ct/{resilio-sync.sh => resiliosync.sh} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename ct/{resilio-sync.sh => resiliosync.sh} (100%)
diff --git a/ct/resilio-sync.sh b/ct/resiliosync.sh
similarity index 100%
rename from ct/resilio-sync.sh
rename to ct/resiliosync.sh
From d2f1f4643a14e432a00dd4c42ffb8d4d6b71b5c0 Mon Sep 17 00:00:00 2001
From: Christian Benincasa
Date: Sat, 6 Sep 2025 11:20:04 -0400
Subject: [PATCH 311/312] Add Tunarr script (#871)
---
ct/headers/tunarr | 5 ++
ct/tunarr.sh | 76 ++++++++++++++++++++++++++++
frontend/public/json/tunarr.json | 35 +++++++++++++
install/tunarr-install.sh | 85 ++++++++++++++++++++++++++++++++
misc/build.func | 2 +-
5 files changed, 202 insertions(+), 1 deletion(-)
create mode 100644 ct/headers/tunarr
create mode 100644 ct/tunarr.sh
create mode 100644 frontend/public/json/tunarr.json
create mode 100644 install/tunarr-install.sh
diff --git a/ct/headers/tunarr b/ct/headers/tunarr
new file mode 100644
index 00000000..c802ed8e
--- /dev/null
+++ b/ct/headers/tunarr
@@ -0,0 +1,5 @@
+______
+/ _ __ / _ ______ ____ ___________
+ / / / / / / __ \/ __ `/ ___/ ___/
+ / / / /_/ / / / / /_/ / / / /
+/_/ \__, _/_/ /_/\__, _/_/ /_/
diff --git a/ct/tunarr.sh b/ct/tunarr.sh
new file mode 100644
index 00000000..a3941b1d
--- /dev/null
+++ b/ct/tunarr.sh
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
+# Copyright (c) 2021-2025 tteck
+# Author: chrisbenincasa
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://tunarr.com/
+
+APP="Tunarr"
+var_tags="${var_tags:-iptv}"
+var_cpu="${var_cpu:-2}"
+var_ram="${var_ram:-1024}"
+var_disk="${var_disk:-5}"
+var_os="${var_os:-debian}"
+var_version="${var_version:-12}"
+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/tunarr ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+ if check_for_gh_release "tunarr" "chrisbenincasa/tunarr"; then
+ msg_info "Stopping ${APP}"
+ systemctl stop tunarr
+ msg_ok "Stopped ${APP}"
+
+ msg_info "Creating Backup"
+ tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" /usr/.local/share/tunarr
+ msg_ok "Backup Created"
+
+ fetch_and_deploy_gh_release "tunarr" "chrisbenincasa/tunarr" "singlefile" "latest" "/opt/tunarr" "*linux-x64"
+
+ msg_info "Starting ${APP}"
+ systemctl start tunarr
+ msg_ok "Started ${APP}"
+
+ msg_ok "Updated Successfully"
+ fi
+
+ if check_for_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg"; then
+ msg_info "Stopping ${APP}"
+ systemctl stop tunarr
+ msg_ok "Stopped ${APP}"
+
+ fetch_and_deploy_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg" "prebuild" "latest" "/opt/ErsatzTV-ffmpeg" "*-linux64-gpl-7.1.tar.xz"
+
+ msg_info "Set ErsatzTV-ffmpeg links"
+ chmod +x /opt/ErsatzTV-ffmpeg/bin/*
+ ln -sf /opt/ErsatzTV-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg
+ ln -sf /opt/ErsatzTV-ffmpeg/bin/ffplay /usr/local/bin/ffplay
+ ln -sf /opt/ErsatzTV-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
+ msg_ok "ffmpeg links set"
+
+ msg_info "Starting ${APP}"
+ systemctl start tunarr
+ msg_ok "Started ${APP}"
+ msg_ok "Updated 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"
diff --git a/frontend/public/json/tunarr.json b/frontend/public/json/tunarr.json
new file mode 100644
index 00000000..d77f28d1
--- /dev/null
+++ b/frontend/public/json/tunarr.json
@@ -0,0 +1,35 @@
+{
+ "name": "Tunarr",
+ "slug": "tunarr",
+ "categories": [
+ 13
+ ],
+ "date_created": "2025-09-06",
+ "type": "ct",
+ "updateable": true,
+ "privileged": false,
+ "config_path": "/opt/tunarr/.env",
+ "interface_port": 8000,
+ "documentation": "https://tunarr.com/",
+ "website": "https://tunarr.com/",
+ "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/tunarr.png",
+ "description": "Create a classic TV experience using your own media - IPTV backed by Plex/Jellyfin/Emby.",
+ "install_methods": [
+ {
+ "type": "default",
+ "script": "ct/tunarr.sh",
+ "resources": {
+ "cpu": 2,
+ "ram": 1024,
+ "hdd": 5,
+ "os": "Debian",
+ "version": "12"
+ }
+ }
+ ],
+ "default_credentials": {
+ "username": null,
+ "password": null
+ },
+ "notes": []
+}
diff --git a/install/tunarr-install.sh b/install/tunarr-install.sh
new file mode 100644
index 00000000..854db713
--- /dev/null
+++ b/install/tunarr-install.sh
@@ -0,0 +1,85 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2021-2025 tteck
+# Author: chrisbenincasa
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://tunarr.com/
+
+source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+color
+verb_ip6
+catch_errors
+setting_up_container
+network_check
+update_os
+
+msg_info "Setting Up Hardware Acceleration"
+$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
+if [[ "$CTTYPE" == "0" ]]; then
+ chgrp video /dev/dri
+ chmod 755 /dev/dri
+ chmod 660 /dev/dri/*
+ $STD adduser $(id -u -n) video
+ $STD adduser $(id -u -n) render
+fi
+msg_ok "Set Up Hardware Acceleration"
+
+read -r -p "${TAB3}Do you need the intel-media-va-driver-non-free driver for HW encoding (Debian 12 only)? " prompt
+if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
+ msg_info "Installing Intel Hardware Acceleration (non-free)"
+ cat </etc/apt/sources.list.d/non-free.list
+
+deb http://deb.debian.org/debian bookworm non-free non-free-firmware
+deb-src http://deb.debian.org/debian bookworm non-free non-free-firmware
+
+deb http://deb.debian.org/debian-security bookworm-security non-free non-free-firmware
+deb-src http://deb.debian.org/debian-security bookworm-security non-free non-free-firmware
+
+deb http://deb.debian.org/debian bookworm-updates non-free non-free-firmware
+deb-src http://deb.debian.org/debian bookworm-updates non-free non-free-firmware
+EOF
+ $STD apt-get update
+ $STD apt-get -y install {intel-media-va-driver-non-free,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
+else
+ msg_info "Installing Intel Hardware Acceleration"
+ $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
+fi
+msg_ok "Installed and Set Up Intel Hardware Acceleration"
+
+fetch_and_deploy_gh_release "tunarr" "chrisbenincasa/tunarr" "singlefile" "latest" "/opt/tunarr" "*linux-x64"
+fetch_and_deploy_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg" "prebuild" "latest" "/opt/ErsatzTV-ffmpeg" "*-linux64-gpl-7.1.tar.xz"
+
+msg_info "Set ErsatzTV-ffmpeg links"
+chmod +x /opt/ErsatzTV-ffmpeg/bin/*
+ln -sf /opt/ErsatzTV-ffmpeg/bin/ffmpeg /usr/bin/ffmpeg
+ln -sf /opt/ErsatzTV-ffmpeg/bin/ffplay /usr/bin/ffplay
+ln -sf /opt/ErsatzTV-ffmpeg/bin/ffprobe /usr/bin/ffprobe
+msg_ok "ffmpeg links set"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/tunarr.service
+[Unit]
+Description=Tunarr Service
+After=multi-user.target
+
+[Service]
+Type=simple
+User=root
+WorkingDirectory=/opt/tunarr
+ExecStart=/opt/tunarr/tunarr
+Restart=always
+RestartSec=30
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now tunarr
+msg_ok "Created Service"
+
+motd_ssh
+customize
+
+msg_info "Cleaning up"
+$STD apt-get -y autoremove
+$STD apt-get -y autoclean
+msg_ok "Cleaned"
diff --git a/misc/build.func b/misc/build.func
index 766aab33..a9889913 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1715,7 +1715,7 @@ EOF
VAAPI_APPS=(
"immich" "Channels" "Emby" "ErsatzTV" "Frigate" "Jellyfin"
"Plex" "Scrypted" "Tdarr" "Unmanic" "Ollama" "FileFlows"
- "Open WebUI" "Debian"
+ "Open WebUI" "Debian" "Tunarr"
)
is_vaapi_app=false
From 9636683fa95a0a2a3c0fcfe1b51d61c433e5eb5c Mon Sep 17 00:00:00 2001
From: GitHub Actions
Date: Sat, 6 Sep 2025 15:20:23 +0000
Subject: [PATCH 312/312] Update .app files
---
ct/headers/stylus | 6 ++++++
ct/headers/tunarr | 9 +++++----
2 files changed, 11 insertions(+), 4 deletions(-)
create mode 100644 ct/headers/stylus
diff --git a/ct/headers/stylus b/ct/headers/stylus
new file mode 100644
index 00000000..bb8c5765
--- /dev/null
+++ b/ct/headers/stylus
@@ -0,0 +1,6 @@
+ _____ __ __
+ / ___// /___ __/ /_ _______
+ \__ \/ __/ / / / / / / / ___/
+ ___/ / /_/ /_/ / / /_/ (__ )
+/____/\__/\__, /_/\__,_/____/
+ /____/
diff --git a/ct/headers/tunarr b/ct/headers/tunarr
index c802ed8e..27f2a281 100644
--- a/ct/headers/tunarr
+++ b/ct/headers/tunarr
@@ -1,5 +1,6 @@
-______
-/ _ __ / _ ______ ____ ___________
+ ______
+ /_ __/_ ______ ____ ___________
/ / / / / / __ \/ __ `/ ___/ ___/
- / / / /_/ / / / / /_/ / / / /
-/_/ \__, _/_/ /_/\__, _/_/ /_/
+ / / / /_/ / / / / /_/ / / / /
+/_/ \__,_/_/ /_/\__,_/_/ /_/
+