Compare commits

..

1 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
e3446b6367 fix(homepage): preserve config directory during updates
Fixes #10985 - The update script was deleting user config files due to
CLEAN_INSTALL=1 flag. Now backs up and restores both .env and config/
directory to preserve user configurations.
2026-01-20 13:06:52 +01:00
16 changed files with 383 additions and 1104 deletions

View File

@@ -10,57 +10,8 @@
> [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2026-01-22
## 2026-01-21
### 🆕 New Scripts
- Byparr ([#11039](https://github.com/community-scripts/ProxmoxVE/pull/11039))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: Snipe-IT update missing all user uploads (#11032) [@ruanmed](https://github.com/ruanmed) ([#11033](https://github.com/community-scripts/ProxmoxVE/pull/11033))
- yubal: fix for v0.2 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11006](https://github.com/community-scripts/ProxmoxVE/pull/11006))
- Joplin-Server: use yarn workspaces focus for faster builds [@MickLesk](https://github.com/MickLesk) ([#11027](https://github.com/community-scripts/ProxmoxVE/pull/11027))
### 💾 Core
- #### ✨ New Features
- tools: add ubuntu PHP repository setup [@MickLesk](https://github.com/MickLesk) ([#11034](https://github.com/community-scripts/ProxmoxVE/pull/11034))
- #### 🔧 Refactor
- core: allow empty tags & improve template search [@MickLesk](https://github.com/MickLesk) ([#11020](https://github.com/community-scripts/ProxmoxVE/pull/11020))
### 🌐 Website
- #### 📝 Script Information
- Joplin Server: Set disable flag to true in joplin-server.json [@tremor021](https://github.com/tremor021) ([#11008](https://github.com/community-scripts/ProxmoxVE/pull/11008))
## 2026-01-20
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- dolibarr: switch mirror [@MickLesk](https://github.com/MickLesk) ([#11004](https://github.com/community-scripts/ProxmoxVE/pull/11004))
- checkmk: reordner base function [@MickLesk](https://github.com/MickLesk) ([#10990](https://github.com/community-scripts/ProxmoxVE/pull/10990))
- Homepage: preserve config directory during updates [@MickLesk](https://github.com/MickLesk) ([#10993](https://github.com/community-scripts/ProxmoxVE/pull/10993))
- DiscoPanel: add go for update build process [@miausalvaje](https://github.com/miausalvaje) ([#10991](https://github.com/community-scripts/ProxmoxVE/pull/10991))
### 💾 Core
- #### ✨ New Features
- core: add retry logic for template lock in LXC container creation [@MickLesk](https://github.com/MickLesk) ([#11002](https://github.com/community-scripts/ProxmoxVE/pull/11002))
- core: implement ensure_profile_loaded function [@MickLesk](https://github.com/MickLesk) ([#10999](https://github.com/community-scripts/ProxmoxVE/pull/10999))
- core: add input validations for several functions [@MickLesk](https://github.com/MickLesk) ([#10995](https://github.com/community-scripts/ProxmoxVE/pull/10995))
## 2026-01-19
### 🆕 New Scripts

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: luismco
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/ThePhaseless/Byparr
APP="Byparr"
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:-13}"
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/Byparr ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "Byparr" "ThePhaseless/Byparr"; then
msg_info "Stopping Service"
systemctl stop byparr
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
msg_info "Starting Service"
systemctl start byparr
msg_ok "Started Service"
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}:8191${CL}"

View File

@@ -54,14 +54,9 @@ function update_script() {
cd /opt/discopanel/web/discopanel
$STD npm install
$STD npm run build
msg_ok "Built Web Interface"
setup_go
msg_info "Building DiscoPanel"
cd /opt/discopanel
$STD go build -o discopanel cmd/discopanel/main.go
msg_ok "Built DiscoPanel"
msg_ok "Setup DiscoPanel"
msg_info "Restoring Data"
mkdir -p /opt/discopanel/data

View File

@@ -1,6 +0,0 @@
____
/ __ )__ ______ ____ ___________
/ __ / / / / __ \/ __ `/ ___/ ___/
/ /_/ / /_/ / /_/ / /_/ / / / /
/_____/\__, / .___/\__,_/_/ /_/
/____/_/

View File

@@ -44,9 +44,7 @@ function update_script() {
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
export BUILD_SEQUENCIAL=1
$STD yarn workspaces focus @joplin/server
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run build
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run tsc
$STD yarn install --inline-builds
msg_ok "Updated Joplin-Server"
msg_info "Starting Services"

View File

@@ -50,8 +50,8 @@ function update_script() {
$STD apt update
$STD apt -y upgrade
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
cp -r /opt/snipe-it-backup/public/uploads/. /opt/snipe-it/public/uploads/
cp -r /opt/snipe-it-backup/storage/private_uploads/. /opt/snipe-it/storage/private_uploads/
cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
cd /opt/snipe-it/
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev --optimize-autoloader --no-interaction

View File

@@ -1,35 +0,0 @@
{
"name": "Byparr",
"slug": "byparr",
"categories": [
14
],
"date_created": "2026-01-21",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8191,
"documentation": "https://github.com/ThePhaseless/Byparr/blob/master/README.md",
"website": "https://github.com/ThePhaseless/Byparr",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/byparr.webp",
"config_path": "",
"description": "Byparr is a proxy server to bypass Cloudflare and DDoS-GUARD protection.",
"install_methods": [
{
"type": "default",
"script": "ct/byparr.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,284 +1,4 @@
[
{
"name": "Stirling-Tools/Stirling-PDF",
"version": "v2.3.0",
"date": "2026-01-15T19:29:02Z"
},
{
"name": "ollama/ollama",
"version": "v0.14.3-rc3",
"date": "2026-01-20T20:20:53Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.81.0.rc.4",
"date": "2026-01-21T21:43:55Z"
},
{
"name": "Infisical/infisical",
"version": "v0.156.2",
"date": "2026-01-21T21:02:11Z"
},
{
"name": "runtipi/runtipi",
"version": "nightly",
"date": "2026-01-20T21:10:15Z"
},
{
"name": "Comfy-Org/ComfyUI",
"version": "v0.10.0",
"date": "2026-01-21T19:22:04Z"
},
{
"name": "fccview/jotty",
"version": "1.18.1",
"date": "2026-01-21T19:16:44Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.16",
"date": "2026-01-17T07:54:15Z"
},
{
"name": "metabase/metabase",
"version": "v0.57.x",
"date": "2026-01-21T17:54:29Z"
},
{
"name": "openobserve/openobserve",
"version": "v0.50.2",
"date": "2026-01-21T17:02:52Z"
},
{
"name": "LimeSurvey/LimeSurvey",
"version": "7.0.0-beta1+260113",
"date": "2026-01-21T15:14:45Z"
},
{
"name": "jenkinsci/jenkins",
"version": "jenkins-2.541.1",
"date": "2026-01-21T15:09:10Z"
},
{
"name": "dedicatedcode/reitti",
"version": "v3.4.0",
"date": "2026-01-21T14:29:46Z"
},
{
"name": "node-red/node-red",
"version": "4.1.3",
"date": "2026-01-07T16:24:23Z"
},
{
"name": "prometheus/prometheus",
"version": "v3.5.1",
"date": "2026-01-21T13:28:57Z"
},
{
"name": "apache/tomcat",
"version": "10.1.51",
"date": "2026-01-21T13:19:21Z"
},
{
"name": "semaphoreui/semaphore",
"version": "v2.17.0-rc7",
"date": "2026-01-21T12:12:33Z"
},
{
"name": "evcc-io/evcc",
"version": "0.300.5",
"date": "2026-01-21T11:35:44Z"
},
{
"name": "javedh-dev/tracktor",
"version": "1.2.1",
"date": "2026-01-21T11:12:28Z"
},
{
"name": "endurain-project/endurain",
"version": "v0.17.0",
"date": "2026-01-21T10:55:33Z"
},
{
"name": "emqx/emqx",
"version": "e5.10.3-rc.2",
"date": "2026-01-21T08:57:16Z"
},
{
"name": "docker/compose",
"version": "v5.0.2",
"date": "2026-01-21T07:42:38Z"
},
{
"name": "SigNoz/signoz",
"version": "v0.108.0",
"date": "2026-01-21T06:45:16Z"
},
{
"name": "rabbitmq/rabbitmq-server",
"version": "v4.2.2",
"date": "2025-12-15T18:25:36Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.898",
"date": "2026-01-21T05:50:19Z"
},
{
"name": "9001/copyparty",
"version": "v1.20.3",
"date": "2026-01-21T05:39:57Z"
},
{
"name": "donetick/donetick",
"version": "v0.1.70-beta.1",
"date": "2026-01-21T05:35:05Z"
},
{
"name": "esphome/esphome",
"version": "2026.1.0",
"date": "2026-01-21T03:43:09Z"
},
{
"name": "jeedom/core",
"version": "4.5.2",
"date": "2026-01-21T00:27:05Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "paperless-ngx/paperless-ngx",
"version": "v2.20.5",
"date": "2026-01-21T00:12:33Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.8",
"date": "2026-01-15T13:52:29Z"
},
{
"name": "ZoeyVid/NPMplus",
"version": "2026-01-20-r2",
"date": "2026-01-20T22:28:54Z"
},
{
"name": "seerr-team/seerr",
"version": "preview-availability-sync-fix",
"date": "2026-01-20T22:11:24Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v1.2.0-dev.1",
"date": "2026-01-20T21:46:14Z"
},
{
"name": "rcourtman/Pulse",
"version": "v5.0.17",
"date": "2026-01-20T19:07:30Z"
},
{
"name": "netbox-community/netbox",
"version": "v4.5.1",
"date": "2026-01-20T19:45:05Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.24",
"date": "2026-01-20T18:31:20Z"
},
{
"name": "mysql/mysql-server",
"version": "mysql-cluster-8.0.45",
"date": "2026-01-20T18:27:03Z"
},
{
"name": "element-hq/synapse",
"version": "v1.145.0",
"date": "2026-01-13T16:49:51Z"
},
{
"name": "chrisvel/tududi",
"version": "v0.88.4",
"date": "2026-01-20T16:02:12Z"
},
{
"name": "gtsteffaniak/filebrowser",
"version": "v1.1.1-stable",
"date": "2026-01-12T23:25:10Z"
},
{
"name": "mattermost/mattermost",
"version": "@mattermost/client@11.3.0",
"date": "2026-01-20T15:26:31Z"
},
{
"name": "theonedev/onedev",
"version": "v14.0.8",
"date": "2026-01-20T15:10:44Z"
},
{
"name": "meilisearch/meilisearch",
"version": "latest",
"date": "2026-01-20T14:25:19Z"
},
{
"name": "sysadminsmedia/homebox",
"version": "v0.23.0-rc.1",
"date": "2026-01-20T14:19:56Z"
},
{
"name": "n8n-io/n8n",
"version": "n8n@2.3.6",
"date": "2026-01-16T15:00:42Z"
},
{
"name": "dgtlmoon/changedetection.io",
"version": "0.52.8",
"date": "2026-01-20T12:36:05Z"
},
{
"name": "lazy-media/reactive-resume",
"version": "v1.2.7",
"date": "2026-01-20T11:59:40Z"
},
{
"name": "cloudflare/cloudflared",
"version": "2026.1.1",
"date": "2026-01-20T11:22:06Z"
},
{
"name": "passbolt/passbolt_api",
"version": "v5.9.0-test.1",
"date": "2026-01-20T10:34:53Z"
},
{
"name": "Luligu/matterbridge",
"version": "3.5.0",
"date": "2026-01-20T08:53:52Z"
},
{
"name": "nzbgetcom/nzbget",
"version": "v25.4",
"date": "2025-10-09T10:27:01Z"
},
{
"name": "HydroshieldMKII/Guardian",
"version": "v1.3.4",
"date": "2026-01-20T06:20:36Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.4",
"date": "2026-01-04T22:41:00Z"
},
{
"name": "diced/zipline",
"version": "v4.4.1",
"date": "2026-01-20T01:29:01Z"
},
{
"name": "binwiederhier/ntfy",
"version": "v2.16.0",
@@ -290,9 +10,29 @@
"date": "2026-01-19T20:51:19Z"
},
{
"name": "livebook-dev/livebook",
"version": "nightly",
"date": "2026-01-19T18:03:38Z"
"name": "ollama/ollama",
"version": "v0.14.3-rc2",
"date": "2026-01-19T20:48:34Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.16",
"date": "2026-01-17T07:54:15Z"
},
{
"name": "metabase/metabase",
"version": "v0.58.x",
"date": "2026-01-19T18:21:04Z"
},
{
"name": "apache/tomcat",
"version": "11.0.16",
"date": "2026-01-19T18:15:05Z"
},
{
"name": "paperless-ngx/paperless-ngx",
"version": "v2.20.5",
"date": "2026-01-19T17:55:57Z"
},
{
"name": "ghostfolio/ghostfolio",
@@ -304,6 +44,16 @@
"version": "server-v3.5.2",
"date": "2025-12-19T21:28:55Z"
},
{
"name": "meilisearch/meilisearch",
"version": "prototype-v1.33.0-hannoy-better-linear-scanning.4",
"date": "2026-01-19T16:37:18Z"
},
{
"name": "Infisical/infisical",
"version": "v0.155.6",
"date": "2026-01-19T16:35:03Z"
},
{
"name": "bunkerity/bunkerweb",
"version": "v1.6.7",
@@ -319,6 +69,11 @@
"version": "pmm-6401-v1.134.0",
"date": "2026-01-19T13:31:08Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.8",
"date": "2026-01-15T13:52:29Z"
},
{
"name": "crowdsecurity/crowdsec",
"version": "v1.7.4",
@@ -339,11 +94,36 @@
"version": "v1.9.14",
"date": "2026-01-19T09:16:56Z"
},
{
"name": "dgtlmoon/changedetection.io",
"version": "0.52.7",
"date": "2026-01-19T08:38:05Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.4",
"date": "2026-01-04T22:41:00Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.887",
"date": "2026-01-19T05:55:24Z"
},
{
"name": "gethomepage/homepage",
"version": "v1.9.0",
"date": "2026-01-19T05:46:09Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.23",
"date": "2026-01-19T05:14:43Z"
},
{
"name": "9001/copyparty",
"version": "v1.20.2",
"date": "2026-01-19T02:20:10Z"
},
{
"name": "jellyfin/jellyfin",
"version": "v10.11.6",
@@ -354,6 +134,16 @@
"version": "2.1.0rc1",
"date": "2026-01-19T00:48:21Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5.2",
"date": "2026-01-19T00:27:05Z"
},
{
"name": "Kareadita/Kavita",
"version": "v0.8.9.1",
@@ -374,6 +164,16 @@
"version": "v2.5.0",
"date": "2026-01-18T22:16:38Z"
},
{
"name": "seerr-team/seerr",
"version": "preview-remonitor-sonarr-episodes",
"date": "2026-01-18T20:33:38Z"
},
{
"name": "fccview/jotty",
"version": "1.18.0",
"date": "2026-01-18T19:00:48Z"
},
{
"name": "Brandawg93/PeaNUT",
"version": "v5.21.2",
@@ -394,6 +194,11 @@
"version": "2.4",
"date": "2026-01-18T12:12:02Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.81.0-nightly",
"date": "2026-01-18T04:06:15Z"
},
{
"name": "hyperion-project/hyperion.ng",
"version": "2.1.1",
@@ -404,11 +209,26 @@
"version": "v7.14.2",
"date": "2026-01-18T00:26:09Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v1.1.1",
"date": "2026-01-17T22:35:09Z"
},
{
"name": "ZoeyVid/NPMplus",
"version": "2026-01-17-r3",
"date": "2026-01-17T21:45:17Z"
},
{
"name": "outline/outline",
"version": "v1.3.0",
"date": "2026-01-17T16:28:04Z"
},
{
"name": "evcc-io/evcc",
"version": "0.300.4",
"date": "2026-01-17T14:11:01Z"
},
{
"name": "LogicLabs-OU/OpenArchiver",
"version": "v0.4.1",
@@ -424,6 +244,11 @@
"version": "v6.13.6",
"date": "2025-11-04T13:35:35Z"
},
{
"name": "esphome/esphome",
"version": "2025.12.7",
"date": "2026-01-17T03:49:29Z"
},
{
"name": "coder/code-server",
"version": "v4.108.1",
@@ -444,6 +269,26 @@
"version": "v1.50.1",
"date": "2026-01-16T19:27:38Z"
},
{
"name": "livebook-dev/livebook",
"version": "v0.18.3",
"date": "2026-01-14T21:50:55Z"
},
{
"name": "cloudflare/cloudflared",
"version": "2026.1.0",
"date": "2026-01-16T17:48:15Z"
},
{
"name": "n8n-io/n8n",
"version": "n8n@2.3.6",
"date": "2026-01-16T15:00:42Z"
},
{
"name": "emqx/emqx",
"version": "6.0.2",
"date": "2026-01-16T13:52:11Z"
},
{
"name": "silverbulletmd/silverbullet",
"version": "2.4.1",
@@ -474,11 +319,31 @@
"version": "v0.13.6",
"date": "2026-01-15T23:34:51Z"
},
{
"name": "semaphoreui/semaphore",
"version": "v2.17.0-rc3",
"date": "2026-01-15T21:30:26Z"
},
{
"name": "azukaar/Cosmos-Server",
"version": "v0.20.0",
"date": "2026-01-15T20:59:44Z"
},
{
"name": "runtipi/runtipi",
"version": "nightly",
"date": "2026-01-15T20:03:50Z"
},
{
"name": "Stirling-Tools/Stirling-PDF",
"version": "v2.3.0",
"date": "2026-01-15T19:29:02Z"
},
{
"name": "Comfy-Org/ComfyUI",
"version": "v0.9.2",
"date": "2026-01-15T17:55:40Z"
},
{
"name": "zwave-js/zwave-js-ui",
"version": "v11.10.1",
@@ -494,11 +359,26 @@
"version": "0.24.3",
"date": "2026-01-15T14:40:15Z"
},
{
"name": "openobserve/openobserve",
"version": "v0.50.0-rc3",
"date": "2026-01-15T13:57:37Z"
},
{
"name": "readeck/readeck",
"version": "0.21.6",
"date": "2026-01-15T11:18:58Z"
},
{
"name": "mattermost/mattermost",
"version": "v10.11.10",
"date": "2026-01-15T10:36:07Z"
},
{
"name": "SigNoz/signoz",
"version": "v0.107.0",
"date": "2026-01-15T06:50:08Z"
},
{
"name": "zitadel/zitadel",
"version": "v4.9.1",
@@ -549,6 +429,11 @@
"version": "v3.3.1-rc2",
"date": "2026-01-14T12:29:28Z"
},
{
"name": "dedicatedcode/reitti",
"version": "v3.3.0",
"date": "2026-01-14T11:06:59Z"
},
{
"name": "cloudreve/cloudreve",
"version": "4.11.1",
@@ -589,6 +474,31 @@
"version": "v0.5.5",
"date": "2026-01-13T17:03:32Z"
},
{
"name": "element-hq/synapse",
"version": "v1.145.0",
"date": "2026-01-13T16:49:51Z"
},
{
"name": "LimeSurvey/LimeSurvey",
"version": "6.16.3+251215",
"date": "2026-01-13T10:36:10Z"
},
{
"name": "endurain-project/endurain",
"version": "v0.16.6",
"date": "2026-01-13T10:28:14Z"
},
{
"name": "jenkinsci/jenkins",
"version": "jenkins-2.546",
"date": "2026-01-13T10:08:09Z"
},
{
"name": "Luligu/matterbridge",
"version": "3.4.7",
"date": "2026-01-13T07:28:02Z"
},
{
"name": "henrygd/beszel",
"version": "v0.18.2",
@@ -604,6 +514,11 @@
"version": "26.1.1",
"date": "2026-01-12T23:26:02Z"
},
{
"name": "gtsteffaniak/filebrowser",
"version": "v1.1.1-stable",
"date": "2026-01-12T23:25:10Z"
},
{
"name": "influxdata/influxdb",
"version": "v2.8.0",
@@ -619,6 +534,11 @@
"version": "v1.7.10",
"date": "2026-01-12T20:50:50Z"
},
{
"name": "rcourtman/Pulse",
"version": "v5.0.16",
"date": "2026-01-12T20:18:34Z"
},
{
"name": "release-argus/Argus",
"version": "0.29.2",
@@ -704,6 +624,11 @@
"version": "v0.14.1",
"date": "2024-08-29T22:32:51Z"
},
{
"name": "theonedev/onedev",
"version": "v14.0.7",
"date": "2026-01-10T10:31:47Z"
},
{
"name": "Kozea/Radicale",
"version": "v3.6.0",
@@ -784,11 +709,21 @@
"version": "5.2.7",
"date": "2026-01-07T23:48:00Z"
},
{
"name": "prometheus/prometheus",
"version": "v0.309.1",
"date": "2026-01-07T19:20:52Z"
},
{
"name": "leiweibau/Pi.Alert",
"version": "v2026-01-07",
"date": "2026-01-07T18:50:28Z"
},
{
"name": "node-red/node-red",
"version": "4.1.3",
"date": "2026-01-07T16:24:23Z"
},
{
"name": "MDeLuise/plant-it",
"version": "1.0.1",
@@ -824,6 +759,11 @@
"version": "2.46.0",
"date": "2026-01-07T00:19:31Z"
},
{
"name": "netbox-community/netbox",
"version": "v4.5.0",
"date": "2026-01-06T21:14:27Z"
},
{
"name": "caddyserver/caddy",
"version": "v2.10.2",
@@ -882,7 +822,7 @@
{
"name": "mealie-recipes/mealie",
"version": "v3.9.2",
"date": "2026-01-02T19:40:19Z"
"date": "2026-01-02T19:40:09Z"
},
{
"name": "gotify/server",
@@ -909,6 +849,11 @@
"version": "v25.12.1",
"date": "2025-12-30T17:25:57Z"
},
{
"name": "javedh-dev/tracktor",
"version": "1.1.0",
"date": "2025-12-30T04:42:18Z"
},
{
"name": "ArchiveBox/ArchiveBox",
"version": "v0.8.6rc1",
@@ -929,6 +874,16 @@
"version": "v4.7.0",
"date": "2025-12-27T20:37:54Z"
},
{
"name": "sysadminsmedia/homebox",
"version": "v0.22.3",
"date": "2025-12-26T22:31:20Z"
},
{
"name": "HydroshieldMKII/Guardian",
"version": "v1.3.3",
"date": "2025-12-25T20:19:52Z"
},
{
"name": "matze/wastebin",
"version": "3.4.0",
@@ -964,6 +919,11 @@
"version": "v5.7",
"date": "2025-12-23T14:53:51Z"
},
{
"name": "nzbgetcom/nzbget",
"version": "v25.4",
"date": "2025-10-09T10:27:01Z"
},
{
"name": "itsmng/itsm-ng",
"version": "v1.6.11",
@@ -984,6 +944,16 @@
"version": "v4.0.16.2944",
"date": "2025-11-05T01:56:48Z"
},
{
"name": "chrisvel/tududi",
"version": "v0.88.2",
"date": "2025-12-22T14:36:59Z"
},
{
"name": "passbolt/passbolt_api",
"version": "v5.8.0",
"date": "2025-12-22T10:12:48Z"
},
{
"name": "benjaminjonard/koillection",
"version": "1.7.1",
@@ -1039,6 +1009,11 @@
"version": "v1.25.3",
"date": "2025-12-18T18:11:48Z"
},
{
"name": "docker/compose",
"version": "v5.0.1",
"date": "2025-12-18T14:22:38Z"
},
{
"name": "juanfont/headscale",
"version": "v0.27.1",
@@ -1059,6 +1034,11 @@
"version": "v4.1.0",
"date": "2025-12-15T18:53:25Z"
},
{
"name": "rabbitmq/rabbitmq-server",
"version": "v4.2.2",
"date": "2025-12-15T18:25:36Z"
},
{
"name": "docmost/docmost",
"version": "v0.24.1",
@@ -1079,6 +1059,11 @@
"version": "v1.13.2",
"date": "2025-12-13T22:59:03Z"
},
{
"name": "diced/zipline",
"version": "v4.4.0",
"date": "2025-12-13T22:49:07Z"
},
{
"name": "WGDashboard/WGDashboard",
"version": "v4.3.1",
@@ -1439,16 +1424,31 @@
"version": "v2.2.2",
"date": "2025-10-06T21:31:07Z"
},
{
"name": "mysql/mysql-server",
"version": "mysql-cluster-7.6.36",
"date": "2025-10-06T15:19:49Z"
},
{
"name": "jordan-dalby/ByteStash",
"version": "v1.5.9",
"date": "2025-10-06T08:34:01Z"
},
{
"name": "donetick/donetick",
"version": "v0.1.64",
"date": "2025-10-03T05:18:24Z"
},
{
"name": "thomiceli/opengist",
"version": "v1.11.1",
"date": "2025-09-30T00:24:16Z"
},
{
"name": "lazy-media/Reactive-Resume",
"version": "v1.2.6",
"date": "2025-09-28T18:09:21Z"
},
{
"name": "Pf2eToolsOrg/Pf2eTools",
"version": "v0.10.1",

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: luismco
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/ThePhaseless/Byparr
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt -y install \
xauth \
xvfb \
scrot \
chromium \
chromium-driver \
ca-certificates
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
setup_uv
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/byparr.service
[Unit]
Description=Byparr
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/Byparr
ExecStart=/usr/local/bin/uv run python3 main.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now byparr
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -21,6 +21,9 @@ rm -rf /opt/checkmk.deb
echo "${RELEASE}" >"/opt/checkmk_version.txt"
msg_ok "Installed Checkmk"
motd_ssh
customize
msg_info "Creating Service"
SITE_NAME="monitoring"
$STD omd create "$SITE_NAME"
@@ -39,5 +42,3 @@ $STD omd start "$SITE_NAME"
msg_ok "Created Service"
cleanup_lxc
motd_ssh
customize

View File

@@ -34,7 +34,7 @@ msg_info "Setup Dolibarr"
BASE="https://sourceforge.net/projects/dolibarr/files/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/"
RELEASE=$(curl -fsSL "$BASE" | grep -oP '(?<=/Dolibarr%20installer%20for%20Debian-Ubuntu%20%28DoliDeb%29/)\d+(\.\d+)+(?=/)' | sort -V | tail -n1)
FILE=$(curl -fsSL "${BASE}${RELEASE}/" | grep -oP 'dolibarr_[^"]+_all.deb' | head -n1)
curl -fsSL "https://altushost-swe.dl.sourceforge.net/project/dolibarr/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/${RELEASE}/${FILE}?viasf=1" -o ""$FILE""
curl -fsSL "https://netcologne.dl.sourceforge.net/project/dolibarr/Dolibarr%20installer%20for%20Debian-Ubuntu%20(DoliDeb)/${RELEASE}/${FILE}?viasf=1" -o ""$FILE""
echo "dolibarr dolibarr/reconfigure-webserver multiselect apache2" | debconf-set-selections
$STD apt-get install ./$FILE -y
$STD apt install -f

View File

@@ -36,9 +36,8 @@ cd /opt/joplin-server
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
export BUILD_SEQUENCIAL=1
$STD yarn workspaces focus @joplin/server
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run build
$STD yarn workspaces foreach -R --topological-dev --from @joplin/server run tsc
$STD yarn install --inline-builds
cat <<EOF >/opt/joplin-server/.env
PM2_HOME=/opt/pm2
NODE_ENV=production

View File

@@ -59,7 +59,7 @@ msg_ok "Installed Python Dependencies"
msg_info "Creating Service"
cat <<EOF >/opt/yubal.env
YUBAL_HOST=0.0.0.0
YUBAL_PORT=8000
YUBAL_PORT=8001
YUBAL_DATA=/opt/yubal_data
YUBAL_CONFIG=/opt/yubal_config
YUBAL_ROOT=/opt/yubal
@@ -76,7 +76,7 @@ User=root
WorkingDirectory=/opt/yubal
EnvironmentFile=/opt/yubal.env
Environment="PATH=/opt/yubal/.venv/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=/opt/yubal/.venv/bin/python -m yubal_api
ExecStart=/opt/yubal/.venv/bin/python -m yubal
Restart=always
RestartSec=5

View File

@@ -357,268 +357,6 @@ validate_hostname() {
return 0
}
# ------------------------------------------------------------------------------
# validate_mac_address()
#
# - Validates MAC address format (XX:XX:XX:XX:XX:XX)
# - Empty value is allowed (auto-generated)
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_mac_address() {
local mac="$1"
[[ -z "$mac" ]] && return 0
if [[ ! "$mac" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_vlan_tag()
#
# - Validates VLAN tag (1-4094)
# - Empty value is allowed (no VLAN)
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_vlan_tag() {
local vlan="$1"
[[ -z "$vlan" ]] && return 0
if ! [[ "$vlan" =~ ^[0-9]+$ ]] || ((vlan < 1 || vlan > 4094)); then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_mtu()
#
# - Validates MTU size (576-65535, common values: 1500, 9000)
# - Empty value is allowed (default 1500)
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_mtu() {
local mtu="$1"
[[ -z "$mtu" ]] && return 0
if ! [[ "$mtu" =~ ^[0-9]+$ ]] || ((mtu < 576 || mtu > 65535)); then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_ipv6_address()
#
# - Validates IPv6 address with optional CIDR notation
# - Supports compressed (::) and full notation
# - Empty value is allowed
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_ipv6_address() {
local ipv6="$1"
[[ -z "$ipv6" ]] && return 0
# Extract address and CIDR
local addr="${ipv6%%/*}"
local cidr="${ipv6##*/}"
# Validate CIDR if present (1-128)
if [[ "$ipv6" == */* ]]; then
if ! [[ "$cidr" =~ ^[0-9]+$ ]] || ((cidr < 1 || cidr > 128)); then
return 1
fi
fi
# Basic IPv6 validation - check for valid characters and structure
# Must contain only hex digits and colons
if [[ ! "$addr" =~ ^[0-9a-fA-F:]+$ ]]; then
return 1
fi
# Must contain at least one colon
if [[ ! "$addr" == *:* ]]; then
return 1
fi
# Check for valid double-colon usage (only one :: allowed)
if [[ "$addr" == *::*::* ]]; then
return 1
fi
# Check that no segment exceeds 4 hex chars
local IFS=':'
local -a segments
read -ra segments <<< "$addr"
for seg in "${segments[@]}"; do
if [[ ${#seg} -gt 4 ]]; then
return 1
fi
done
return 0
}
# ------------------------------------------------------------------------------
# validate_bridge()
#
# - Validates that network bridge exists and is active
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_bridge() {
local bridge="$1"
[[ -z "$bridge" ]] && return 1
# Check if bridge interface exists
if ! ip link show "$bridge" &>/dev/null; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_gateway_in_subnet()
#
# - Validates that gateway IP is in the same subnet as static IP
# - Arguments: static_ip (with CIDR), gateway_ip
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_gateway_in_subnet() {
local static_ip="$1"
local gateway="$2"
[[ -z "$static_ip" || -z "$gateway" ]] && return 0
# Extract IP and CIDR
local ip="${static_ip%%/*}"
local cidr="${static_ip##*/}"
# Convert CIDR to netmask bits
local mask=$((0xFFFFFFFF << (32 - cidr) & 0xFFFFFFFF))
# Convert IPs to integers
local IFS='.'
read -r i1 i2 i3 i4 <<< "$ip"
read -r g1 g2 g3 g4 <<< "$gateway"
local ip_int=$(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))
local gw_int=$(( (g1 << 24) + (g2 << 16) + (g3 << 8) + g4 ))
# Check if both are in same network
if (( (ip_int & mask) != (gw_int & mask) )); then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_ip_address()
#
# - Validates IPv4 address with CIDR notation
# - Checks each octet is 0-255
# - Checks CIDR is 1-32
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_ip_address() {
local ip="$1"
[[ -z "$ip" ]] && return 1
# Check format with CIDR
if [[ ! "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$ ]]; then
return 1
fi
local o1="${BASH_REMATCH[1]}"
local o2="${BASH_REMATCH[2]}"
local o3="${BASH_REMATCH[3]}"
local o4="${BASH_REMATCH[4]}"
local cidr="${BASH_REMATCH[5]}"
# Validate octets (0-255)
for octet in "$o1" "$o2" "$o3" "$o4"; do
if ((octet > 255)); then
return 1
fi
done
# Validate CIDR (1-32)
if ((cidr < 1 || cidr > 32)); then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_gateway_ip()
#
# - Validates gateway IPv4 address (without CIDR)
# - Checks each octet is 0-255
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_gateway_ip() {
local ip="$1"
[[ -z "$ip" ]] && return 0
# Check format without CIDR
if [[ ! "$ip" =~ ^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$ ]]; then
return 1
fi
local o1="${BASH_REMATCH[1]}"
local o2="${BASH_REMATCH[2]}"
local o3="${BASH_REMATCH[3]}"
local o4="${BASH_REMATCH[4]}"
# Validate octets (0-255)
for octet in "$o1" "$o2" "$o3" "$o4"; do
if ((octet > 255)); then
return 1
fi
done
return 0
}
# ------------------------------------------------------------------------------
# validate_timezone()
#
# - Validates timezone string against system zoneinfo
# - Empty value or "host" is allowed
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_timezone() {
local tz="$1"
[[ -z "$tz" || "$tz" == "host" ]] && return 0
# Check if timezone file exists
if [[ ! -f "/usr/share/zoneinfo/$tz" ]]; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# validate_tags()
#
# - Validates Proxmox tags format
# - Only alphanumeric, hyphens, underscores, and semicolons allowed
# - Empty value is allowed
# - Returns 0 if valid, 1 if invalid
# ------------------------------------------------------------------------------
validate_tags() {
local tags="$1"
[[ -z "$tags" ]] && return 0
# Tags can only contain alphanumeric, -, _, and ; (separator)
if [[ ! "$tags" =~ ^[a-zA-Z0-9_\;-]+$ ]]; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# find_host_ssh_keys()
#
@@ -1034,119 +772,6 @@ load_vars_file() {
# Trim trailing whitespace
var_val="${var_val%"${var_val##*[![:space:]]}"}"
# Validate values before setting (skip empty values - they use defaults)
if [[ -n "$var_val" ]]; then
case "$var_key" in
var_mac)
if ! validate_mac_address "$var_val"; then
msg_warn "Invalid MAC address '$var_val' in $file, ignoring"
continue
fi
;;
var_vlan)
if ! validate_vlan_tag "$var_val"; then
msg_warn "Invalid VLAN tag '$var_val' in $file (must be 1-4094), ignoring"
continue
fi
;;
var_mtu)
if ! validate_mtu "$var_val"; then
msg_warn "Invalid MTU '$var_val' in $file (must be 576-65535), ignoring"
continue
fi
;;
var_tags)
if ! validate_tags "$var_val"; then
msg_warn "Invalid tags '$var_val' in $file (alphanumeric, -, _, ; only), ignoring"
continue
fi
;;
var_timezone)
if ! validate_timezone "$var_val"; then
msg_warn "Invalid timezone '$var_val' in $file, ignoring"
continue
fi
;;
var_brg)
if ! validate_bridge "$var_val"; then
msg_warn "Bridge '$var_val' not found in $file, ignoring"
continue
fi
;;
var_gateway)
if ! validate_gateway_ip "$var_val"; then
msg_warn "Invalid gateway IP '$var_val' in $file, ignoring"
continue
fi
;;
var_hostname)
if ! validate_hostname "$var_val"; then
msg_warn "Invalid hostname '$var_val' in $file, ignoring"
continue
fi
;;
var_cpu)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1 || var_val > 128)); then
msg_warn "Invalid CPU count '$var_val' in $file (must be 1-128), ignoring"
continue
fi
;;
var_ram)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 256)); then
msg_warn "Invalid RAM '$var_val' in $file (must be >= 256 MiB), ignoring"
continue
fi
;;
var_disk)
if ! [[ "$var_val" =~ ^[0-9]+$ ]] || ((var_val < 1)); then
msg_warn "Invalid disk size '$var_val' in $file (must be >= 1 GB), ignoring"
continue
fi
;;
var_unprivileged)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid unprivileged value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_nesting)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid nesting value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_keyctl)
if [[ "$var_val" != "0" && "$var_val" != "1" ]]; then
msg_warn "Invalid keyctl value '$var_val' in $file (must be 0 or 1), ignoring"
continue
fi
;;
var_net)
# var_net can be: dhcp, static IP/CIDR, or IP range
if [[ "$var_val" != "dhcp" ]]; then
if is_ip_range "$var_val"; then
: # IP range is valid, will be resolved at runtime
elif ! validate_ip_address "$var_val"; then
msg_warn "Invalid network '$var_val' in $file (must be dhcp or IP/CIDR), ignoring"
continue
fi
fi
;;
var_fuse|var_tun|var_gpu|var_ssh|var_verbose|var_protection)
if [[ "$var_val" != "yes" && "$var_val" != "no" ]]; then
msg_warn "Invalid boolean '$var_val' for $var_key in $file (must be yes/no), ignoring"
continue
fi
;;
var_ipv6_method)
if [[ "$var_val" != "auto" && "$var_val" != "dhcp" && "$var_val" != "static" && "$var_val" != "none" ]]; then
msg_warn "Invalid IPv6 method '$var_val' in $file (must be auto/dhcp/static/none), ignoring"
continue
fi
;;
esac
fi
# Set variable: force mode overrides existing, otherwise only set if empty
if [[ "$force" == "yes" ]]; then
export "${var_key}=${var_val}"
@@ -1987,14 +1612,8 @@ advanced_settings() {
# ═══════════════════════════════════════════════════════════════════════════
8)
if [[ ${#BRIDGE_MENU_OPTIONS[@]} -eq 0 ]]; then
# Validate default bridge exists
if validate_bridge "vmbr0"; then
_bridge="vmbr0"
((STEP++))
else
whiptail --msgbox "Default bridge 'vmbr0' not found!\n\nPlease configure a network bridge in Proxmox first." 10 58
exit 1
fi
_bridge="vmbr0"
((STEP++))
else
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "NETWORK BRIDGE" \
@@ -2002,13 +1621,8 @@ advanced_settings() {
--menu "\nSelect network bridge:" 16 58 6 \
"${BRIDGE_MENU_OPTIONS[@]}" \
3>&1 1>&2 2>&3); then
local bridge_test="${result:-vmbr0}"
if validate_bridge "$bridge_test"; then
_bridge="$bridge_test"
((STEP++))
else
whiptail --msgbox "Bridge '$bridge_test' is not available or not active." 8 58
fi
_bridge="${result:-vmbr0}"
((STEP++))
else
((STEP--))
fi
@@ -2036,7 +1650,7 @@ advanced_settings() {
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nEnter Static IPv4 CIDR Address\n(e.g. 192.168.1.100/24)" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_ip_address "$static_ip"; then
if [[ "$static_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then
# Get gateway
local gateway_ip
if gateway_ip=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
@@ -2044,21 +1658,16 @@ advanced_settings() {
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nEnter Gateway IP address" 10 58 "" \
3>&1 1>&2 2>&3); then
if validate_gateway_ip "$gateway_ip"; then
# Validate gateway is in same subnet
if validate_gateway_in_subnet "$static_ip" "$gateway_ip"; then
_net="$static_ip"
_gate=",gw=$gateway_ip"
((STEP++))
else
whiptail --msgbox "Gateway is not in the same subnet as the static IP.\n\nStatic IP: $static_ip\nGateway: $gateway_ip" 10 58
fi
if [[ "$gateway_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
_net="$static_ip"
_gate=",gw=$gateway_ip"
((STEP++))
else
whiptail --msgbox "Invalid Gateway IP format.\n\nEach octet must be 0-255.\nExample: 192.168.1.1" 10 58
whiptail --msgbox "Invalid Gateway IP format." 8 58
fi
fi
else
whiptail --msgbox "Invalid IPv4 CIDR format.\n\nEach octet must be 0-255.\nCIDR must be 1-32.\nExample: 192.168.1.100/24" 12 58
whiptail --msgbox "Invalid IPv4 CIDR format.\nExample: 192.168.1.100/24" 8 58
fi
fi
elif [[ "$result" == "range" ]]; then
@@ -2082,17 +1691,12 @@ advanced_settings() {
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nFound free IP: $NET_RESOLVED\n\nEnter Gateway IP address" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_gateway_ip "$gateway_ip"; then
# Validate gateway is in same subnet
if validate_gateway_in_subnet "$NET_RESOLVED" "$gateway_ip"; then
_net="$NET_RESOLVED"
_gate=",gw=$gateway_ip"
((STEP++))
else
whiptail --msgbox "Gateway is not in the same subnet as the IP.\n\nIP: $NET_RESOLVED\nGateway: $gateway_ip" 10 58
fi
if [[ "$gateway_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
_net="$NET_RESOLVED"
_gate=",gw=$gateway_ip"
((STEP++))
else
whiptail --msgbox "Invalid Gateway IP format.\n\nEach octet must be 0-255.\nExample: 192.168.1.1" 10 58
whiptail --msgbox "Invalid Gateway IP format." 8 58
fi
fi
else
@@ -2135,33 +1739,16 @@ advanced_settings() {
--title "STATIC IPv6 ADDRESS" \
--inputbox "\nEnter IPv6 CIDR address\n(e.g. 2001:db8::1/64)" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_ipv6_address "$ipv6_addr"; then
if [[ "$ipv6_addr" =~ ^([0-9a-fA-F:]+:+)+[0-9a-fA-F]+(/[0-9]{1,3})$ ]]; then
_ipv6_addr="$ipv6_addr"
# Optional gateway - loop until valid or empty
local ipv6_gw_valid=false
while [[ "$ipv6_gw_valid" == "false" ]]; do
local ipv6_gw
ipv6_gw=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "IPv6 GATEWAY" \
--inputbox "\nEnter IPv6 gateway (optional, leave blank for none)" 10 58 "" \
3>&1 1>&2 2>&3) || true
# Validate gateway if provided
if [[ -n "$ipv6_gw" ]]; then
if validate_ipv6_address "$ipv6_gw"; then
_ipv6_gate="$ipv6_gw"
ipv6_gw_valid=true
((STEP++))
else
whiptail --msgbox "Invalid IPv6 gateway format.\n\nExample: 2001:db8::1" 8 58
fi
else
_ipv6_gate=""
ipv6_gw_valid=true
((STEP++))
fi
done
# Optional gateway
_ipv6_gate=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "IPv6 GATEWAY" \
--inputbox "\nEnter IPv6 gateway (optional, leave blank for none)" 10 58 "" \
3>&1 1>&2 2>&3) || true
((STEP++))
else
whiptail --msgbox "Invalid IPv6 CIDR format.\n\nExample: 2001:db8::1/64\nCIDR must be 1-128." 10 58
whiptail --msgbox "Invalid IPv6 CIDR format." 8 58
fi
fi
;;
@@ -2194,14 +1781,10 @@ advanced_settings() {
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "MTU SIZE" \
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet Interface MTU Size\n(leave blank for default 1500, common values: 1500, 9000)" 12 62 "" \
--inputbox "\nSet Interface MTU Size\n(leave blank for default 1500)" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_mtu "$result"; then
_mtu="$result"
((STEP++))
else
whiptail --msgbox "Invalid MTU size.\n\nMTU must be between 576 and 65535.\nCommon values: 1500 (default), 9000 (jumbo frames)" 10 58
fi
_mtu="$result"
((STEP++))
else
((STEP--))
fi
@@ -2246,14 +1829,10 @@ advanced_settings() {
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "MAC ADDRESS" \
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet MAC Address\n(leave blank for auto-generated, format: XX:XX:XX:XX:XX:XX)" 12 62 "" \
--inputbox "\nSet MAC Address\n(leave blank for auto-generated)" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_mac_address "$result"; then
_mac="$result"
((STEP++))
else
whiptail --msgbox "Invalid MAC address format.\n\nRequired format: XX:XX:XX:XX:XX:XX\nExample: 02:00:00:00:00:01" 10 58
fi
_mac="$result"
((STEP++))
else
((STEP--))
fi
@@ -2266,14 +1845,10 @@ advanced_settings() {
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "VLAN TAG" \
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet VLAN Tag (1-4094)\n(leave blank for no VLAN)" 12 58 "" \
--inputbox "\nSet VLAN Tag\n(leave blank for no VLAN)" 12 58 "" \
3>&1 1>&2 2>&3); then
if validate_vlan_tag "$result"; then
_vlan="$result"
((STEP++))
else
whiptail --msgbox "Invalid VLAN tag.\n\nVLAN must be a number between 1 and 4094." 8 58
fi
_vlan="$result"
((STEP++))
else
((STEP--))
fi
@@ -2286,16 +1861,11 @@ advanced_settings() {
if result=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "CONTAINER TAGS" \
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet Custom Tags (semicolon-separated)\n(alphanumeric, hyphens, underscores only)" 12 58 "$_tags" \
--inputbox "\nSet Custom Tags (semicolon-separated)\n(remove all for no tags)" 12 58 "$_tags" \
3>&1 1>&2 2>&3); then
local tags_test="${result:-}"
tags_test=$(echo "$tags_test" | tr -d '[:space:]')
if validate_tags "$tags_test"; then
_tags="$tags_test"
((STEP++))
else
whiptail --msgbox "Invalid tag format.\n\nTags can only contain:\n- Letters (a-z, A-Z)\n- Numbers (0-9)\n- Hyphens (-)\n- Underscores (_)\n- Semicolons (;) as separator" 14 58
fi
_tags="${result:-;}"
_tags=$(echo "$_tags" | tr -d '[:space:]')
((STEP++))
else
((STEP--))
fi
@@ -2474,14 +2044,9 @@ advanced_settings() {
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet container timezone.\n\nExamples: Europe/Berlin, America/New_York, Asia/Tokyo\n\nHost timezone: ${_host_timezone:-unknown}\n\nLeave empty to inherit from host." 16 62 "$_ct_timezone" \
3>&1 1>&2 2>&3); then
local tz_test="$result"
[[ "${tz_test:-}" == Etc/* ]] && tz_test="host" # pct doesn't accept Etc/* zones
if validate_timezone "$tz_test"; then
_ct_timezone="$tz_test"
((STEP++))
else
whiptail --msgbox "Invalid timezone: '$result'\n\nTimezone must exist in /usr/share/zoneinfo/\n\nExamples:\n- Europe/Berlin\n- America/New_York\n- Asia/Tokyo\n- UTC" 14 58
fi
_ct_timezone="$result"
[[ "${_ct_timezone:-}" == Etc/* ]] && _ct_timezone="host" # pct doesn't accept Etc/* zones
((STEP++))
else
((STEP--))
fi
@@ -3278,7 +2843,6 @@ start() {
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
VERBOSE="no"
set_std_mode
ensure_profile_loaded
update_script
cleanup_lxc
else
@@ -3304,7 +2868,6 @@ start() {
exit
;;
esac
ensure_profile_loaded
update_script
cleanup_lxc
fi
@@ -3442,13 +3005,8 @@ build_container() {
export DEV_MODE_DRYRUN="${DEV_MODE_DRYRUN:-false}"
# Build PCT_OPTIONS as multi-line string
PCT_OPTIONS_STRING=" -hostname $HN"
# Only add -tags if TAGS is not empty
if [ -n "$TAGS" ]; then
PCT_OPTIONS_STRING="$PCT_OPTIONS_STRING
PCT_OPTIONS_STRING=" -hostname $HN
-tags $TAGS"
fi
# Only add -features if FEATURES is not empty
if [ -n "$FEATURES" ]; then
@@ -4478,42 +4036,37 @@ create_lxc_container() {
msg_info "Searching for template '$TEMPLATE_SEARCH'"
# Initialize variables
ONLINE_TEMPLATE=""
ONLINE_TEMPLATES=()
# Step 1: Check local templates first (instant)
mapfile -t LOCAL_TEMPLATES < <(
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
sed 's|.*/||' | sort -t - -k 2 -V
)
# Step 2: If local template found, use it immediately (skip pveam update)
pveam update >/dev/null 2>&1 || msg_warn "Could not update template catalog (pveam update failed)."
msg_ok "Template search completed"
set +u
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
set -u
ONLINE_TEMPLATE=""
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
if [[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]]; then
count=0
for idx in "${!ONLINE_TEMPLATES[@]}"; do
((count++))
[[ $count -ge 3 ]] && break
done
fi
if [[ ${#LOCAL_TEMPLATES[@]} -gt 0 ]]; then
TEMPLATE="${LOCAL_TEMPLATES[-1]}"
TEMPLATE_SOURCE="local"
msg_ok "Template search completed"
else
# Step 3: No local template - need to check online (this may be slow)
msg_info "No local template found, checking online catalog..."
# Update catalog with timeout to prevent long hangs
if command -v timeout &>/dev/null; then
if ! timeout 30 pveam update >/dev/null 2>&1; then
msg_warn "Template catalog update timed out (possible network/DNS issue). Run 'pveam update' manually to diagnose."
fi
else
pveam update >/dev/null 2>&1 || msg_warn "Could not update template catalog (pveam update failed)"
fi
ONLINE_TEMPLATES=()
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
TEMPLATE="$ONLINE_TEMPLATE"
TEMPLATE_SOURCE="online"
msg_ok "Template search completed"
fi
# If still no template, try to find alternatives
@@ -4522,7 +4075,6 @@ create_lxc_container() {
echo "[DEBUG] No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}, searching for alternatives..."
# Get all available versions for this OS type
AVAILABLE_VERSIONS=()
mapfile -t AVAILABLE_VERSIONS < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
@@ -4545,7 +4097,6 @@ create_lxc_container() {
PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}"
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION}"
ONLINE_TEMPLATES=()
mapfile -t ONLINE_TEMPLATES < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
@@ -4755,88 +4306,50 @@ create_lxc_container() {
-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}"
fi
# Lock by template file (avoid concurrent template downloads/validation)
# Lock by template file (avoid concurrent downloads/creates)
lockfile="/tmp/template.${TEMPLATE}.lock"
# Cleanup stale lock files (older than 1 hour - likely from crashed processes)
if [[ -f "$lockfile" ]]; then
local lock_age=$(($(date +%s) - $(stat -c %Y "$lockfile" 2>/dev/null || echo 0)))
if [[ $lock_age -gt 3600 ]]; then
msg_warn "Removing stale template lock file (age: ${lock_age}s)"
rm -f "$lockfile"
fi
fi
exec 9>"$lockfile" || {
msg_error "Failed to create lock file '$lockfile'."
exit 200
}
# Retry logic for template lock (another container creation may be running)
local lock_attempts=0
local max_lock_attempts=10
local lock_wait_time=30
while ! flock -w "$lock_wait_time" 9; do
lock_attempts=$((lock_attempts + 1))
if [[ $lock_attempts -ge $max_lock_attempts ]]; then
msg_error "Timeout while waiting for template lock after ${max_lock_attempts} attempts."
msg_custom "💡" "${YW}" "Another container creation may be stuck. Check running processes or remove: $lockfile"
exit 211
fi
msg_custom "⏳" "${YW}" "Another container is being created with this template. Waiting... (attempt ${lock_attempts}/${max_lock_attempts})"
done
flock -w 60 9 || {
msg_error "Timeout while waiting for template lock."
exit 211
}
LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log"
# Validate template before pct create (while holding lock)
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH" 2>/dev/null || echo 0)" -lt 1000000 ]]; then
msg_info "Template file missing or too small downloading"
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template downloaded"
elif ! tar -tf "$TEMPLATE_PATH" &>/dev/null; then
if [[ -n "$ONLINE_TEMPLATE" ]]; then
msg_info "Template appears corrupted re-downloading"
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template re-downloaded"
else
msg_warn "Template appears corrupted, but no online version exists. Skipping re-download."
fi
fi
# Release lock after template validation - pct create has its own internal locking
exec 9>&-
msg_debug "pct create command: pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} $PCT_OPTIONS"
msg_debug "Logfile: $LOGFILE"
# First attempt (PCT_OPTIONS is a multi-line string, use it directly)
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >"$LOGFILE" 2>&1; then
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Checking error..."
msg_debug "Container creation failed on ${TEMPLATE_STORAGE}. Validating template..."
# Check if template issue - retry with fresh download
if grep -qiE 'unable to open|corrupt|invalid' "$LOGFILE"; then
msg_info "Template may be corrupted re-downloading"
# Validate template file
if [[ ! -s "$TEMPLATE_PATH" || "$(stat -c%s "$TEMPLATE_PATH")" -lt 1000000 ]]; then
msg_warn "Template file too small or missing re-downloading."
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template re-downloaded"
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
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
# Fallback to local storage if not already on local
if [[ "$TEMPLATE_STORAGE" != "local" ]]; then
msg_info "Retrying container creation with fallback to local storage"
msg_info "Retrying container creation with fallback to local storage..."
LOCAL_TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if [[ ! -f "$LOCAL_TEMPLATE_PATH" ]]; then
msg_ok "Trying local storage fallback"
msg_info "Downloading template to local"
msg_info "Downloading template to local..."
pveam download local "$TEMPLATE" >/dev/null 2>&1
msg_ok "Template downloaded to local"
else
msg_ok "Trying local storage fallback"
fi
if ! pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS >>"$LOGFILE" 2>&1; then
# Local fallback also failed - check for LXC stack version issue

View File

@@ -38,6 +38,8 @@ load_functions() {
icons
default_vars
set_std_mode
# Note: get_lxc_ip() is NOT called here automatically
# Call it explicitly when you need LOCAL_IP variable
}
# ------------------------------------------------------------------------------
@@ -127,34 +129,6 @@ icons() {
HOURGLASS="${TAB}${TAB}"
}
# ------------------------------------------------------------------------------
# ensure_profile_loaded()
#
# - Sources /etc/profile.d/*.sh scripts if not already loaded
# - Fixes PATH issues when running via pct enter/exec (non-login shells)
# - Safe to call multiple times (uses guard variable)
# - Should be called in update_script() or any script running inside LXC
# ------------------------------------------------------------------------------
ensure_profile_loaded() {
# Skip if already loaded or running on Proxmox host
[[ -n "${_PROFILE_LOADED:-}" ]] && return
command -v pveversion &>/dev/null && return
# Source all profile.d scripts to ensure PATH is complete
if [[ -d /etc/profile.d ]]; then
for script in /etc/profile.d/*.sh; do
[[ -r "$script" ]] && source "$script"
done
fi
# Also ensure /usr/local/bin is in PATH (common install location)
if [[ ":$PATH:" != *":/usr/local/bin:"* ]]; then
export PATH="/usr/local/bin:$PATH"
fi
export _PROFILE_LOADED=1
}
# ------------------------------------------------------------------------------
# default_vars()
#

View File

@@ -4387,19 +4387,11 @@ EOF
return 1
}
# Use different repository based on OS
if [[ "$DISTRO_ID" == "ubuntu" ]]; then
# Ubuntu: Use ondrej/php PPA
msg_info "Adding ondrej/php PPA for Ubuntu"
$STD apt install -y software-properties-common
$STD add-apt-repository -y ppa:ondrej/php
else
# Debian: Use Sury repository
manage_tool_repository "php" "$PHP_VERSION" "" "https://packages.sury.org/debsuryorg-archive-keyring.deb" || {
msg_error "Failed to setup PHP repository"
return 1
}
fi
manage_tool_repository "php" "$PHP_VERSION" "" "https://packages.sury.org/debsuryorg-archive-keyring.deb" || {
msg_error "Failed to setup PHP repository"
return 1
}
ensure_apt_working || return 1
$STD apt update