Compare commits

..

42 Commits

Author SHA1 Message Date
github-actions[bot]
e02a2febe9 Update CHANGELOG.md 2026-02-28 13:52:18 +00:00
hraphael
fd498b0efb Update ombi.sh (#12412) 2026-02-28 14:52:01 +01:00
community-scripts-pr-app[bot]
cdbcf098d2 Update CHANGELOG.md (#12418)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 13:51:51 +00:00
CanbiZ (MickLesk)
fddc47064d core: read from /dev/tty in all interactive prompts | fix empty or cropped logs due build process (#12406) 2026-02-28 14:51:26 +01:00
community-scripts-pr-app[bot]
16ae89cd88 Update CHANGELOG.md (#12417)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 13:46:47 +00:00
community-scripts-pr-app[bot]
f2d88b7b4f Update CHANGELOG.md (#12416)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 13:46:27 +00:00
CanbiZ (MickLesk)
187c96f777 fix(dawarich): add missing build deps and handle seed failure (#12410) 2026-02-28 14:46:21 +01:00
CanbiZ (MickLesk)
f974ac4773 pangolin: increase hdd to 10G (#12409) 2026-02-28 14:45:59 +01:00
community-scripts-pr-app[bot]
869985dc60 chore: update github-versions.json (#12415)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 12:08:40 +00:00
CanbiZ (MickLesk)
1e391e22ce Add build-essential and python3 dependencies
Ensure build-essential and python3 are installed as prerequisites. ct/pangolin.sh now calls ensure_dependencies for these packages before setting up Node.js, and install/pangolin-install.sh adds them to the apt install list so build/runtime requirements are present during install.
2026-02-28 10:21:39 +01:00
community-scripts-pr-app[bot]
dae03cf80e Update .app files (#12407)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-28 09:04:07 +01:00
community-scripts-pr-app[bot]
1edcc106e3 Update CHANGELOG.md (#12408)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 08:03:37 +00:00
Chris
34eb094143 Delete Palmr (#12399) 2026-02-28 09:03:08 +01:00
community-scripts-pr-app[bot]
683c0d4e8b chore: update github-versions.json (#12405)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 06:10:08 +00:00
community-scripts-pr-app[bot]
9d8c544f83 Update CHANGELOG.md (#12403)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 00:18:45 +00:00
community-scripts-pr-app[bot]
5967d51769 chore: update github-versions.json (#12402)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-28 00:18:17 +00:00
community-scripts-pr-app[bot]
c37af920df chore: update github-versions.json (#12398)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 18:12:17 +00:00
community-scripts-pr-app[bot]
5f08bf2e98 Update CHANGELOG.md (#12393)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 13:40:05 +00:00
CanbiZ (MickLesk)
a2dc3f44d3 feat: graceful fallback for apt-get update failures (#12386)
Add apt_update_safe() function that warns instead of aborting when apt-get update fails (e.g. enterprise repo 401 Unauthorized). Shows a helpful hint about disabling the enterprise repo when no subscription is active. Replaces direct  apt-get update calls in build.func and install.func.
2026-02-27 14:39:39 +01:00
community-scripts-pr-app[bot]
9e9dfd6947 Update CHANGELOG.md (#12392)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 12:59:23 +00:00
CanbiZ (MickLesk)
774bbbc6d5 core: Improve error outputs across core functions (#12378)
* Improve error outputs across core functions

* Update tools.func
2026-02-27 13:59:02 +01:00
community-scripts-pr-app[bot]
c7a1d4bd13 Update .app files (#12389)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-27 13:55:59 +01:00
community-scripts-pr-app[bot]
a6d56700d9 Update CHANGELOG.md (#12391)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 12:55:33 +00:00
community-scripts-pr-app[bot]
ed22dc806d Update CHANGELOG.md (#12390)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 12:55:12 +00:00
community-scripts-pr-app[bot]
b129614679 Update date in json (#12388)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-27 12:55:05 +00:00
push-app-to-main[bot]
154374a2d1 Strapi (#12320)
* Add strapi (ct)

* Update strapi.sh

* Update date_created in strapi.json

* fix(strapi): use official upgrade tool instead of npm install

Replace 'npm install' with 'npx @strapi/upgrade minor --yes' which properly updates dependencies in package.json and runs codemods. See https://docs.strapi.io/cms/upgrade-tool

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-02-27 13:54:45 +01:00
community-scripts-pr-app[bot]
5ec5f980dc chore: update github-versions.json (#12385)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 12:11:22 +00:00
community-scripts-pr-app[bot]
b83c378667 Update CHANGELOG.md (#12384)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 08:45:20 +00:00
juronja
981e62d53d TrueNAS VM: filter out new nightlies with MASTER (#12355)
* filter out new nightlies with MASTER

* reversed the quotes
2026-02-27 09:44:57 +01:00
community-scripts-pr-app[bot]
03028a9a9b chore: update github-versions.json (#12382)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 06:18:51 +00:00
community-scripts-pr-app[bot]
c080821e31 Update CHANGELOG.md (#12381)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 00:23:31 +00:00
community-scripts-pr-app[bot]
2f546ec277 chore: update github-versions.json (#12380)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-27 00:23:06 +00:00
community-scripts-pr-app[bot]
56d8ed38b0 Update CHANGELOG.md (#12377)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-26 21:28:44 +00:00
Darkangeel_hd
c0fde54d73 Improves adguardhome-sync addon when running on alpine LXCs (#12362)
* Update adguardhome-sync.sh

Better handle edge case of `curl` not being installed on Alpine.
Install `jq`, required by `fetch_and_deploy_gh_release()`, which if not installed makes the script error out with confusing stuff
Rewritten `get_ip()` to make it also work on busybox environments (Alpine).

* Update adguardhome-sync.sh

`jq` is installed by some code inside of `fetch_and_deploy_gh_release` for debian
So it doesn't make much sense to install it here.
We only do so for alpine, as if its not installed it breaks the script
2026-02-26 22:28:22 +01:00
community-scripts-pr-app[bot]
95a7cb1242 Update CHANGELOG.md (#12376)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-26 21:28:14 +00:00
CanbiZ (MickLesk)
7d79a15ddf Fix missing libGL.so.1 in Nvidia LXC containers (#12372) 2026-02-26 22:27:46 +01:00
community-scripts-pr-app[bot]
86f54e3244 Update CHANGELOG.md (#12375)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-26 21:27:37 +00:00
CanbiZ (MickLesk)
06e81e1077 Add Alpine support and improve Tailscale install (#12370)
Detect Alpine inside the LXC container and install Tailscale via apk (add community repo if missing), enable/start the service. Preserve Debian/Ubuntu install path but improve DNS resolution checks, temporarily override /etc/resolv.conf if DNS appears blocked, and restore it afterwards. Switch pct exec to use sh -c, tighten command existence checks and redirections, ensure curl and keyring directory are present, add Tailscale apt source and install package. Overall robustness and error-handling improvements for installing Tailscale in containers.
2026-02-26 22:27:06 +01:00
community-scripts-pr-app[bot]
6c545e962a Update CHANGELOG.md (#12374)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-26 21:13:40 +00:00
Darkangeel_hd
9c4f82db66 fix wrong link on contributions README.md (#12363) 2026-02-26 22:13:14 +01:00
community-scripts-pr-app[bot]
1dd067924a Update CHANGELOG.md (#12373)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-26 21:12:43 +00:00
CanbiZ (MickLesk)
6565e20dc1 Add ffmpeg for booklore (ffprobe) (#12371) 2026-02-26 22:12:09 +01:00
27 changed files with 618 additions and 442 deletions

View File

@@ -407,6 +407,45 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-02-28
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Ombi: Add database.json [@hraphael](https://github.com/hraphael) ([#12412](https://github.com/community-scripts/ProxmoxVE/pull/12412))
- Dawarich: add missing build deps and handle seed failure [@MickLesk](https://github.com/MickLesk) ([#12410](https://github.com/community-scripts/ProxmoxVE/pull/12410))
- pangolin: increase hdd to 10G [@MickLesk](https://github.com/MickLesk) ([#12409](https://github.com/community-scripts/ProxmoxVE/pull/12409))
### 🗑️ Deleted Scripts
- Delete Palmr [@vhsdream](https://github.com/vhsdream) ([#12399](https://github.com/community-scripts/ProxmoxVE/pull/12399))
### 💾 Core
- #### 🐞 Bug Fixes
- core: read from /dev/tty in all interactive prompts | fix empty or cropped logs due build process [@MickLesk](https://github.com/MickLesk) ([#12406](https://github.com/community-scripts/ProxmoxVE/pull/12406))
## 2026-02-27
### 🆕 New Scripts
- Strapi ([#12320](https://github.com/community-scripts/ProxmoxVE/pull/12320))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- TrueNAS VM: filter out new nightlies with MASTER [@juronja](https://github.com/juronja) ([#12355](https://github.com/community-scripts/ProxmoxVE/pull/12355))
### 💾 Core
- #### ✨ New Features
- core: graceful fallback for apt-get update failures [@MickLesk](https://github.com/MickLesk) ([#12386](https://github.com/community-scripts/ProxmoxVE/pull/12386))
- core: Improve error outputs across core functions [@MickLesk](https://github.com/MickLesk) ([#12378](https://github.com/community-scripts/ProxmoxVE/pull/12378))
## 2026-02-26
### 🆕 New Scripts
@@ -417,12 +456,28 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes
- tools.func: update glx alternatives / nvidia alternative if nvidia glx are missing [@MickLesk](https://github.com/MickLesk) ([#12372](https://github.com/community-scripts/ProxmoxVE/pull/12372))
- hotfix: overseer version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12366](https://github.com/community-scripts/ProxmoxVE/pull/12366))
- #### ✨ New Features
- Add ffmpeg for booklore (ffprobe) [@MickLesk](https://github.com/MickLesk) ([#12371](https://github.com/community-scripts/ProxmoxVE/pull/12371))
- [QOL] Immich: add warning regarding library compilation time [@vhsdream](https://github.com/vhsdream) ([#12345](https://github.com/community-scripts/ProxmoxVE/pull/12345))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Improves adguardhome-sync addon when running on alpine LXCs [@Darkangeel-hd](https://github.com/Darkangeel-hd) ([#12362](https://github.com/community-scripts/ProxmoxVE/pull/12362))
- #### ✨ New Features
- Add Alpine support and improve Tailscale install [@MickLesk](https://github.com/MickLesk) ([#12370](https://github.com/community-scripts/ProxmoxVE/pull/12370))
### 📚 Documentation
- fix wrong link on contributions README.md [@Darkangeel-hd](https://github.com/Darkangeel-hd) ([#12363](https://github.com/community-scripts/ProxmoxVE/pull/12363))
### 📂 Github
- github: add workflow to autom. close unauthorized new-script PRs [@MickLesk](https://github.com/MickLesk) ([#12356](https://github.com/community-scripts/ProxmoxVE/pull/12356))

View File

@@ -34,6 +34,7 @@ function update_script() {
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
ensure_dependencies ffmpeg
msg_info "Stopping Service"
systemctl stop booklore

View File

@@ -29,6 +29,8 @@ function update_script() {
exit
fi
ensure_dependencies libgeos++-dev libxml2-dev libxslt-dev libjemalloc-dev
if check_for_gh_release "dawarich" "Freika/dawarich"; then
msg_info "Stopping Services"
systemctl stop dawarich-web dawarich-worker

View File

@@ -1,6 +0,0 @@
____ __
/ __ \____ _/ /___ ___ _____
/ /_/ / __ `/ / __ `__ \/ ___/
/ ____/ /_/ / / / / / / / /
/_/ \__,_/_/_/ /_/ /_/_/

6
ct/headers/strapi Normal file
View File

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

View File

@@ -36,6 +36,7 @@ function update_script() {
[[ -f /opt/ombi/Ombi.db ]] && mv /opt/ombi/Ombi.db /opt
[[ -f /opt/ombi/OmbiExternal.db ]] && mv /opt/ombi/OmbiExternal.db /opt
[[ -f /opt/ombi/OmbiSettings.db ]] && mv /opt/ombi/OmbiSettings.db /opt
[[ -f /opt/ombi/database.json ]] && mv /opt/ombi/database.json /opt
msg_ok "Backup created"
rm -rf /opt/ombi
@@ -43,6 +44,7 @@ function update_script() {
[[ -f /opt/Ombi.db ]] && mv /opt/Ombi.db /opt/ombi
[[ -f /opt/OmbiExternal.db ]] && mv /opt/OmbiExternal.db /opt/ombi
[[ -f /opt/OmbiSettings.db ]] && mv /opt/OmbiSettings.db /opt/ombi
[[ -f /opt/database.json ]] && mv /opt/database.json /opt/ombi
msg_info "Starting Service"
systemctl start ombi

View File

@@ -1,75 +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: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/kyantech/Palmr
APP="Palmr"
var_tags="${var_tags:-files}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-6144}"
var_disk="${var_disk:-6}"
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/palmr_data ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "palmr" "kyantech/Palmr"; then
msg_info "Stopping Services"
systemctl stop palmr-frontend palmr-backend
msg_ok "Stopped Services"
cp /opt/palmr/apps/server/.env /opt/palmr.env
rm -rf /opt/palmr
fetch_and_deploy_gh_release "Palmr" "kyantech/Palmr" "tarball" "latest" "/opt/palmr"
PNPM="$(jq -r '.packageManager' /opt/palmr/package.json)"
NODE_VERSION="24" NODE_MODULE="$PNPM" setup_nodejs
msg_info "Updating ${APP}"
cd /opt/palmr/apps/server
mv /opt/palmr.env /opt/palmr/apps/server/.env
$STD pnpm install
$STD npx prisma generate
$STD npx prisma migrate deploy
$STD npx prisma db push
$STD pnpm build
cd /opt/palmr/apps/web
export NODE_ENV=production
export NEXT_TELEMETRY_DISABLED=1
mv ./.env.example ./.env
$STD pnpm install
$STD pnpm build
chown -R palmr:palmr /opt/palmr_data /opt/palmr
msg_ok "Updated ${APP}"
msg_info "Starting Services"
systemctl start palmr-backend palmr-frontend
msg_ok "Started Services"
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}:3000${CL}"

View File

@@ -9,7 +9,7 @@ APP="Pangolin"
var_tags="${var_tags:-proxy}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-5}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
@@ -29,6 +29,8 @@ function update_script() {
exit
fi
ensure_dependencies build-essential python3
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "pangolin" "fosrl/pangolin"; then

61
ct/strapi.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/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: pespinel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://strapi.io/
APP="Strapi"
var_tags="${var_tags:-cms}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
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 [[ ! -f /etc/systemd/system/strapi.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
NODE_VERSION="24" setup_nodejs
msg_info "Stopping Strapi"
systemctl stop strapi
msg_ok "Stopped Strapi"
msg_info "Updating Strapi"
cd /opt/strapi
$STD npx @strapi/upgrade minor --yes
msg_ok "Updated Strapi"
msg_info "Building Strapi"
export NODE_OPTIONS="--max-old-space-size=3072"
$STD npm run build
msg_ok "Built Strapi"
msg_info "Starting Strapi"
systemctl start strapi
msg_ok "Started Strapi"
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}:1337${CL}"

View File

@@ -175,7 +175,7 @@ All scripts and configurations must follow our coding standards to ensure consis
### Available Guides
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Essential coding standards and best practices
- **[CODE_AUDIT.md](CODE_AUDIT.md)** - Code review checklist and audit procedures
- **[CODE-AUDIT.md](CODE-AUDIT.md)** - Code review checklist and audit procedures
- **[GUIDE.md](GUIDE.md)** - Comprehensive contribution guide
- **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions
- **Container Scripts** - `/ct/` templates and guidelines

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-26T18:16:20Z",
"generated": "2026-02-28T12:08:32Z",
"versions": [
{
"slug": "2fauth",
@@ -18,9 +18,9 @@
{
"slug": "adguardhome-sync",
"repo": "bakito/adguardhome-sync",
"version": "v0.8.2",
"version": "v0.9.0",
"pinned": false,
"date": "2025-10-24T17:13:47Z"
"date": "2026-02-27T18:37:37Z"
},
{
"slug": "adventurelog",
@@ -116,9 +116,9 @@
{
"slug": "bentopdf",
"repo": "alam00000/bentopdf",
"version": "v2.3.1",
"version": "v2.3.3",
"pinned": false,
"date": "2026-02-21T09:04:27Z"
"date": "2026-02-27T08:40:05Z"
},
{
"slug": "beszel",
@@ -144,23 +144,23 @@
{
"slug": "blocky",
"repo": "0xERR0R/blocky",
"version": "v0.28.2",
"version": "v0.29.0",
"pinned": false,
"date": "2025-11-18T05:51:46Z"
"date": "2026-02-27T15:48:56Z"
},
{
"slug": "booklore",
"repo": "booklore-app/BookLore",
"version": "v2.0.2",
"version": "v2.0.4",
"pinned": false,
"date": "2026-02-25T19:59:20Z"
"date": "2026-02-28T01:54:25Z"
},
{
"slug": "bookstack",
"repo": "BookStackApp/BookStack",
"version": "v25.12.7",
"version": "v25.12.8",
"pinned": false,
"date": "2026-02-19T23:36:55Z"
"date": "2026-02-27T10:33:14Z"
},
{
"slug": "byparr",
@@ -200,9 +200,9 @@
{
"slug": "cleanuparr",
"repo": "Cleanuparr/Cleanuparr",
"version": "v2.7.5",
"version": "v2.7.6",
"pinned": false,
"date": "2026-02-24T17:11:50Z"
"date": "2026-02-27T19:32:02Z"
},
{
"slug": "cloudreve",
@@ -214,9 +214,9 @@
{
"slug": "comfyui",
"repo": "comfyanonymous/ComfyUI",
"version": "v0.15.0",
"version": "v0.15.1",
"pinned": false,
"date": "2026-02-24T20:56:09Z"
"date": "2026-02-26T22:01:35Z"
},
{
"slug": "commafeed",
@@ -242,9 +242,9 @@
{
"slug": "cosmos",
"repo": "azukaar/Cosmos-Server",
"version": "v0.21.2",
"version": "v0.21.5",
"pinned": false,
"date": "2026-02-26T11:32:33Z"
"date": "2026-02-27T10:07:11Z"
},
{
"slug": "cronicle",
@@ -277,9 +277,9 @@
{
"slug": "dawarich",
"repo": "Freika/dawarich",
"version": "1.3.0",
"version": "1.3.1",
"pinned": false,
"date": "2026-02-25T19:30:25Z"
"date": "2026-02-27T19:47:40Z"
},
{
"slug": "discopanel",
@@ -291,9 +291,9 @@
{
"slug": "dispatcharr",
"repo": "Dispatcharr/Dispatcharr",
"version": "v0.19.0",
"version": "v0.20.1",
"pinned": false,
"date": "2026-02-10T21:18:10Z"
"date": "2026-02-26T21:38:19Z"
},
{
"slug": "docmost",
@@ -361,9 +361,9 @@
{
"slug": "endurain",
"repo": "endurain-project/endurain",
"version": "v0.17.5",
"version": "v0.17.6",
"pinned": false,
"date": "2026-02-24T14:51:03Z"
"date": "2026-02-27T23:08:50Z"
},
{
"slug": "ersatztv",
@@ -382,9 +382,9 @@
{
"slug": "firefly",
"repo": "firefly-iii/firefly-iii",
"version": "v6.5.0",
"version": "v6.5.1",
"pinned": false,
"date": "2026-02-23T19:19:00Z"
"date": "2026-02-27T20:55:55Z"
},
{
"slug": "fladder",
@@ -438,9 +438,9 @@
{
"slug": "ghostfolio",
"repo": "ghostfolio/ghostfolio",
"version": "2.243.0",
"version": "2.244.0",
"pinned": false,
"date": "2026-02-23T19:31:36Z"
"date": "2026-02-28T09:51:45Z"
},
{
"slug": "gitea",
@@ -452,9 +452,9 @@
{
"slug": "gitea-mirror",
"repo": "RayLabsHQ/gitea-mirror",
"version": "v3.9.5",
"version": "v3.9.6",
"pinned": false,
"date": "2026-02-26T05:32:12Z"
"date": "2026-02-27T07:15:42Z"
},
{
"slug": "glance",
@@ -494,9 +494,9 @@
{
"slug": "grist",
"repo": "gristlabs/grist-core",
"version": "v1.7.10",
"version": "v1.7.11",
"pinned": false,
"date": "2026-01-12T20:50:50Z"
"date": "2026-02-27T17:13:50Z"
},
{
"slug": "grocy",
@@ -550,9 +550,9 @@
{
"slug": "homarr",
"repo": "homarr-labs/homarr",
"version": "v1.53.2",
"version": "v1.54.0",
"pinned": false,
"date": "2026-02-20T19:41:55Z"
"date": "2026-02-27T19:38:50Z"
},
{
"slug": "homebox",
@@ -606,16 +606,16 @@
{
"slug": "invoiceninja",
"repo": "invoiceninja/invoiceninja",
"version": "v5.12.68",
"version": "v5.12.69",
"pinned": false,
"date": "2026-02-25T19:38:19Z"
"date": "2026-02-26T22:23:32Z"
},
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1218",
"version": "v0.24.1226",
"pinned": false,
"date": "2026-02-26T05:55:11Z"
"date": "2026-02-28T05:58:51Z"
},
{
"slug": "jellystat",
@@ -669,9 +669,9 @@
{
"slug": "kima-hub",
"repo": "Chevron7Locked/kima-hub",
"version": "v1.5.7",
"version": "v1.5.10",
"pinned": false,
"date": "2026-02-23T23:58:59Z"
"date": "2026-02-27T19:25:56Z"
},
{
"slug": "kimai",
@@ -718,9 +718,9 @@
{
"slug": "kubo",
"repo": "ipfs/kubo",
"version": "v0.40.0",
"version": "v0.40.1",
"pinned": false,
"date": "2026-02-25T23:16:17Z"
"date": "2026-02-27T17:58:22Z"
},
{
"slug": "kutt",
@@ -795,9 +795,9 @@
{
"slug": "lubelogger",
"repo": "hargata/lubelog",
"version": "v1.6.0",
"version": "v1.6.1",
"pinned": false,
"date": "2026-02-10T20:16:32Z"
"date": "2026-02-26T20:01:24Z"
},
{
"slug": "mafl",
@@ -872,9 +872,9 @@
{
"slug": "metube",
"repo": "alexta69/metube",
"version": "2026.02.22",
"version": "2026.02.27",
"pinned": false,
"date": "2026-02-22T00:58:45Z"
"date": "2026-02-27T11:47:02Z"
},
{
"slug": "miniflux",
@@ -956,9 +956,9 @@
{
"slug": "nodebb",
"repo": "NodeBB/NodeBB",
"version": "v4.8.1",
"version": "v4.9.0",
"pinned": false,
"date": "2026-01-28T14:19:11Z"
"date": "2026-02-27T19:20:51Z"
},
{
"slug": "nodecast-tv",
@@ -1037,19 +1037,12 @@
"pinned": false,
"date": "2025-02-24T19:47:06Z"
},
{
"slug": "palmr",
"repo": "kyantech/Palmr",
"version": "v3.3.2-beta",
"pinned": false,
"date": "2025-12-10T05:42:43Z"
},
{
"slug": "pangolin",
"repo": "fosrl/pangolin",
"version": "1.15.4",
"version": "1.16.1",
"pinned": false,
"date": "2026-02-13T23:01:29Z"
"date": "2026-02-27T21:18:53Z"
},
{
"slug": "paperless-ai",
@@ -1068,9 +1061,9 @@
{
"slug": "paperless-ngx",
"repo": "paperless-ngx/paperless-ngx",
"version": "v2.20.8",
"version": "v2.20.9",
"pinned": false,
"date": "2026-02-22T01:40:54Z"
"date": "2026-02-28T10:17:35Z"
},
{
"slug": "patchmon",
@@ -1222,9 +1215,9 @@
{
"slug": "pulse",
"repo": "rcourtman/Pulse",
"version": "v5.1.14",
"version": "v5.1.15",
"pinned": false,
"date": "2026-02-25T00:11:58Z"
"date": "2026-02-27T15:17:24Z"
},
{
"slug": "pve-scripts-local",
@@ -1376,16 +1369,16 @@
{
"slug": "seerr",
"repo": "seerr-team/seerr",
"version": "v3.0.1",
"version": "v3.1.0",
"pinned": false,
"date": "2026-02-14T19:30:24Z"
"date": "2026-02-27T17:25:29Z"
},
{
"slug": "semaphore",
"repo": "semaphoreui/semaphore",
"version": "v2.17.14",
"version": "v2.17.15",
"pinned": false,
"date": "2026-02-24T14:27:03Z"
"date": "2026-02-28T09:04:40Z"
},
{
"slug": "shelfmark",
@@ -1558,9 +1551,9 @@
{
"slug": "traccar",
"repo": "traccar/traccar",
"version": "v6.12.1",
"version": "v6.12.2",
"pinned": false,
"date": "2026-02-22T18:47:37Z"
"date": "2026-02-27T15:08:36Z"
},
{
"slug": "tracearr",
@@ -1607,9 +1600,9 @@
{
"slug": "tunarr",
"repo": "chrisbenincasa/tunarr",
"version": "v1.1.17",
"version": "v1.1.18",
"pinned": false,
"date": "2026-02-25T19:56:36Z"
"date": "2026-02-26T22:09:44Z"
},
{
"slug": "uhf",
@@ -1670,9 +1663,9 @@
{
"slug": "vikunja",
"repo": "go-vikunja/vikunja",
"version": "v2.0.0",
"version": "v2.1.0",
"pinned": false,
"date": "2026-02-25T13:58:47Z"
"date": "2026-02-27T14:26:53Z"
},
{
"slug": "wallabag",
@@ -1817,9 +1810,9 @@
{
"slug": "zoraxy",
"repo": "tobychui/zoraxy",
"version": "v3.3.2-rc1",
"version": "v3.3.2-rc2",
"pinned": false,
"date": "2026-02-15T02:16:17Z"
"date": "2026-02-27T03:31:25Z"
},
{
"slug": "zwave-js-ui",

View File

@@ -1,45 +0,0 @@
{
"name": "Palmr",
"slug": "palmr",
"categories": [
11
],
"date_created": "2025-08-08",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"disable": true,
"documentation": "https://palmr.kyantech.com.br/docs/3.1-beta",
"config_path": "/opt/palmr/apps/server/.env, /opt/palmr/apps/web/.env",
"website": "https://palmr.kyantech.com.br/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/palmr.webp",
"description": "Palmr is a fast and secure platform for sharing files, built with performance and privacy in mind.",
"install_methods": [
{
"type": "default",
"script": "ct/palmr.sh",
"resources": {
"cpu": 4,
"ram": 6144,
"hdd": 6,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "To use a bind mount for storage, create symlinks to your mount for both `uploads` and `temp-uploads` in `/opt/palmr_data`, and uncomment `CUSTOM_PATH` to add the path to your bind mount",
"type": "info"
},
{
"text": "To use Palmr with a reverse proxy, uncomment `SECURE_SITE` in `/opt/palmr/apps/server/.env`",
"type": "info"
}
]
}

View File

@@ -21,7 +21,7 @@
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 5,
"hdd": 10,
"os": "Debian",
"version": "13"
}

View File

@@ -0,0 +1,48 @@
{
"name": "Strapi",
"slug": "strapi",
"categories": [
12
],
"date_created": "2026-02-27",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 1337,
"documentation": "https://docs.strapi.io/",
"website": "https://strapi.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/strapi.webp",
"config_path": "/opt/strapi/.env",
"description": "Strapi is a leading open-source headless CMS that enables developers to build powerful APIs quickly. It features a flexible content structure with customizable content types, supporting both REST and GraphQL APIs. The intuitive admin panel allows non-technical users to manage content easily, while developers can extend functionality through plugins. Built on Node.js, Strapi offers role-based access control, media library management, and internationalization support out of the box.",
"install_methods": [
{
"type": "default",
"script": "ct/strapi.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "First-time setup requires creating an admin account at http://IP:1337/admin",
"type": "info"
},
{
"text": "Default installation uses SQLite. For production use, consider configuring PostgreSQL or MySQL.",
"type": "info"
},
{
"text": "Building the admin panel requires 4GB RAM. Container may take 10-15 minutes to fully initialize.",
"type": "warning"
}
]
}

View File

@@ -13,6 +13,10 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y ffmpeg
msg_ok "Installed Dependencies"
JAVA_VERSION="25" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb

View File

@@ -16,19 +16,23 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
git \
libpq-dev \
libgeos-dev \
libyaml-dev \
libffi-dev \
libssl-dev \
libjemalloc2 \
imagemagick \
libmagickwand-dev \
libvips-dev \
cmake \
redis-server \
nginx
git \
imagemagick \
libffi-dev \
libgeos-dev \
libgeos++-dev \
libjemalloc2 \
libjemalloc-dev \
libmagickwand-dev \
libpq-dev \
libssl-dev \
libvips-dev \
libxml2-dev \
libxslt-dev \
libyaml-dev \
nginx \
redis-server
msg_ok "Installed Dependencies"
PG_VERSION="17" PG_MODULES="postgis-3" setup_postgresql
@@ -82,7 +86,9 @@ elif [[ -f /opt/dawarich/app/package.json ]]; then
$STD npm install
fi
$STD bundle exec rake assets:precompile
$STD bundle exec rails db:prepare
$STD bundle exec rails db:create
$STD bundle exec rails db:schema:load
$STD bundle exec rails db:seed || msg_warn "Database seed failed (upstream rgeo-geojson issue), app will still work"
$STD bundle exec rake data:migrate
msg_ok "Installed Dawarich"

View File

@@ -1,91 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/kyantech/Palmr
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "Palmr" "kyantech/Palmr" "tarball" "latest" "/opt/palmr"
PNPM="$(jq -r '.packageManager' /opt/palmr/package.json)"
NODE_VERSION="24" NODE_MODULE="$PNPM" setup_nodejs
msg_info "Configuring palmr backend"
PALMR_DIR="/opt/palmr_data"
mkdir -p "$PALMR_DIR"
PALMR_DB="${PALMR_DIR}/palmr.db"
PALMR_KEY="$(openssl rand -hex 32)"
cd /opt/palmr/apps/server
sed -e 's/_ENCRYPTION=true/_ENCRYPTION=false/' \
-e '/^# ENC/s/# //' \
-e "s/ENCRYPTION_KEY=.*$/ENCRYPTION_KEY=$PALMR_KEY/" \
-e "s|file:.*$|file:$PALMR_DB\"|" \
-e "\|db\"$|a\\# Uncomment below when using a reverse proxy\\
# SECURE_SITE=true\\
# Uncomment and add your path if using symlinks for data storage\\
# CUSTOM_PATH=<path-to-your-bind-mount>" \
.env.example >./.env
$STD pnpm install
$STD npx prisma generate
$STD npx prisma migrate deploy
$STD npx prisma db push
$STD pnpm db:seed
$STD pnpm build
msg_ok "Configured palmr backend"
msg_info "Configuring palmr frontend"
cd /opt/palmr/apps/web
mv ./.env.example ./.env
export NODE_ENV=production
export NEXT_TELEMETRY_DISABLED=1
$STD pnpm install
$STD pnpm build
msg_ok "Configured palmr frontend"
msg_info "Creating service"
useradd -d "$PALMR_DIR" -M -s /usr/sbin/nologin -U palmr
chown -R palmr:palmr "$PALMR_DIR" /opt/palmr
cat <<EOF >/etc/systemd/system/palmr-backend.service
[Unit]
Description=palmr Backend Service
After=network.target
[Service]
Type=simple
User=palmr
Group=palmr
WorkingDirectory=/opt/palmr_data
ExecStart=/usr/bin/node /opt/palmr/apps/server/dist/server.js
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/palmr-frontend.service
[Unit]
Description=palmr Frontend Service
After=network.target palmr-backend.service
[Service]
Type=simple
User=palmr
Group=palmr
WorkingDirectory=/opt/palmr/apps/web
ExecStart=/usr/bin/pnpm start
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now palmr-backend palmr-frontend
msg_ok "Created service"
motd_ssh
customize
cleanup_lxc

View File

@@ -15,6 +15,8 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
python3 \
sqlite3 \
iptables
msg_ok "Installed Dependencies"

69
install/strapi-install.sh Executable file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: pespinel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://strapi.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 install -y \
build-essential \
python3 \
python3-setuptools \
libvips42
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
msg_info "Installing Strapi (Patience)"
mkdir -p /opt/strapi
cd /opt/strapi
$STD npx --yes create-strapi-app@latest . --quickstart --no-run --skip-cloud
msg_ok "Installed Strapi"
msg_info "Building Strapi"
cd /opt/strapi
export NODE_OPTIONS="--max-old-space-size=3072"
$STD npm run build
msg_ok "Built Strapi"
msg_info "Creating Service"
cat <<EOF >/opt/strapi/.env
HOST=0.0.0.0
PORT=1337
APP_KEYS=$(openssl rand -base64 32)
API_TOKEN_SALT=$(openssl rand -base64 32)
ADMIN_JWT_SECRET=$(openssl rand -base64 32)
TRANSFER_TOKEN_SALT=$(openssl rand -base64 32)
JWT_SECRET=$(openssl rand -base64 32)
EOF
cat <<EOF >/etc/systemd/system/strapi.service
[Unit]
Description=Strapi CMS
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/strapi
EnvironmentFile=/opt/strapi/.env
ExecStart=/usr/bin/npm run start
Restart=on-failure
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now strapi
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -3132,7 +3132,7 @@ check_container_resources() {
msg_warn "Under-provisioned: Required ${var_cpu} CPU/${var_ram}MB RAM, Current ${current_cpu} CPU/${current_ram}MB RAM"
echo -e "${YWB}Please ensure that the ${APP} LXC is configured with at least ${var_cpu} vCPU and ${var_ram} MB RAM for the build process.${CL}\n"
echo -ne "${INFO}${HOLD} May cause data loss! ${INFO} Continue update with under-provisioned LXC? <yes/No> "
read -r prompt
read -r prompt </dev/tty
if [[ ! ${prompt,,} =~ ^(yes)$ ]]; then
msg_error "Aborted: under-provisioned LXC (${current_cpu} CPU/${current_ram}MB RAM < ${var_cpu} CPU/${var_ram}MB RAM)"
exit 1
@@ -3155,7 +3155,7 @@ check_container_storage() {
if ((usage > 80)); then
msg_warn "Storage is dangerously low (${usage}% used on /boot)"
echo -ne "Continue anyway? <y/N> "
read -r prompt
read -r prompt </dev/tty
if [[ ! ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_error "Aborted: storage too low (${usage}% used)"
exit 1
@@ -3707,10 +3707,18 @@ $PCT_OPTIONS_STRING"
NVIDIA_DEVICES=()
# Store PCI info to avoid multiple calls
local pci_vga_info=$(lspci -nn 2>/dev/null | grep -E "VGA|Display|3D")
# grep returns exit 1 when no match — use || true to prevent ERR trap
local pci_vga_info
pci_vga_info=$(lspci -nn 2>/dev/null | grep -E "VGA|Display|3D" || true)
# No GPU-related PCI devices at all? Skip silently.
if [[ -z "$pci_vga_info" ]]; then
msg_debug "No VGA/Display/3D PCI devices found"
return 0
fi
# Check for Intel GPU - look for Intel vendor ID [8086]
if echo "$pci_vga_info" | grep -q "\[8086:"; then
if grep -q "\[8086:" <<<"$pci_vga_info"; then
msg_custom "🎮" "${BL}" "Detected Intel GPU"
if [[ -d /dev/dri ]]; then
for d in /dev/dri/renderD* /dev/dri/card*; do
@@ -3720,7 +3728,7 @@ $PCT_OPTIONS_STRING"
fi
# Check for AMD GPU - look for AMD vendor IDs [1002] (AMD/ATI) or [1022] (AMD)
if echo "$pci_vga_info" | grep -qE "\[1002:|\[1022:"; then
if grep -qE "\[1002:|\[1022:" <<<"$pci_vga_info"; then
msg_custom "🎮" "${RD}" "Detected AMD GPU"
if [[ -d /dev/dri ]]; then
# Only add if not already claimed by Intel
@@ -3733,7 +3741,7 @@ $PCT_OPTIONS_STRING"
fi
# Check for NVIDIA GPU - look for NVIDIA vendor ID [10de]
if echo "$pci_vga_info" | grep -q "\[10de:"; then
if grep -q "\[10de:" <<<"$pci_vga_info"; then
msg_custom "🎮" "${GN}" "Detected NVIDIA GPU"
# Simple passthrough - just bind /dev/nvidia* devices if they exist
@@ -3834,7 +3842,7 @@ EOF
for gpu in "${available_gpus[@]}"; do
echo " - $gpu"
done
read -rp "Which GPU type to passthrough? (${available_gpus[*]}): " selected_gpu
read -rp "Which GPU type to passthrough? (${available_gpus[*]}): " selected_gpu </dev/tty
selected_gpu="${selected_gpu^^}"
# Validate selection
@@ -4012,6 +4020,16 @@ EOF
# install_gpu_userland "NVIDIA"
# fi
# Disable error trap for entire customization & install phase.
# All errors are handled explicitly — recovery menu shown on failure.
# Without this, customization errors (e.g. container stopped during base package
# install) would trigger error_handler() with a simple "Remove broken container?"
# prompt instead of the full recovery menu with retry/repair options.
set +Eeuo pipefail
trap - ERR
local install_exit_code=0
# Continue with standard container setup
if [ "$var_os" == "alpine" ]; then
sleep 3
@@ -4019,9 +4037,9 @@ EOF
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
EOF'
pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses jq >/dev/null" || {
pct exec "$CTID" -- ash -c "apk add bash newt curl openssh nano mc ncurses jq" >>"$BUILD_LOG" 2>&1 || {
msg_error "Failed to install base packages in Alpine container"
exit 1
install_exit_code=1
}
else
sleep 3
@@ -4045,69 +4063,69 @@ EOF'
msg_warn "Skipping timezone setup zone '$tz' not found in container"
fi
pct exec "$CTID" -- bash -c "apt-get update >/dev/null && apt-get install -y sudo curl mc gnupg2 jq >/dev/null" || {
pct exec "$CTID" -- bash -c "apt-get update 2>&1 && apt-get install -y sudo curl mc gnupg2 jq 2>&1" >>"$BUILD_LOG" 2>&1 || {
msg_error "apt-get base packages installation failed"
exit 1
install_exit_code=1
}
fi
msg_ok "Customized LXC Container"
# Only continue with installation if customization succeeded
if [[ $install_exit_code -eq 0 ]]; then
msg_ok "Customized LXC Container"
# Optional DNS override for retry scenarios (inside LXC, never on host)
if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then
msg_info "Applying DNS retry override in LXC (8.8.8.8, 1.1.1.1)"
pct exec "$CTID" -- bash -c "printf 'nameserver 8.8.8.8\nnameserver 1.1.1.1\n' >/etc/resolv.conf" >/dev/null 2>&1 || true
msg_ok "DNS override applied in LXC"
fi
# Install SSH keys
install_ssh_keys_into_ct
# Start timer for duration tracking
start_install_timer
# Run application installer
# Disable error trap - container errors are handled internally via flag file
set +Eeuo pipefail # Disable ALL error handling temporarily
trap - ERR # Remove ERR trap completely
# Signal handlers use this flag to stop the container on abort (SIGHUP/SIGINT/SIGTERM)
# Without this, SSH disconnects leave the container running as an orphan process
# that sends "configuring" status AFTER the host already reported "failed"
export CONTAINER_INSTALLING=true
# Capture lxc-attach terminal output to host-side log via tee.
# This is the ONLY reliable way to get install output when:
# - install.func fails to load (DNS error) → no container-side logging
# - install script crashes before logging starts
# - $STD/silent() not used for some commands
# PIPESTATUS[0] gets the real exit code from lxc-attach (not from tee).
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
local lxc_exit=${PIPESTATUS[0]}
unset CONTAINER_INSTALLING
# Keep error handling DISABLED during failure detection and recovery
# Re-enabling it here would cause any pct exec/pull failure to trigger
# error_handler() on the host, bypassing the recovery menu entirely
# Check for error flag file in container (more reliable than lxc-attach exit code)
local install_exit_code=0
if [[ -n "${SESSION_ID:-}" ]]; then
local error_flag="/root/.install-${SESSION_ID}.failed"
if pct exec "$CTID" -- test -f "$error_flag" 2>/dev/null; then
install_exit_code=$(pct exec "$CTID" -- cat "$error_flag" 2>/dev/null || echo "1")
pct exec "$CTID" -- rm -f "$error_flag" 2>/dev/null || true
# Optional DNS override for retry scenarios (inside LXC, never on host)
if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then
msg_info "Applying DNS retry override in LXC (8.8.8.8, 1.1.1.1)"
pct exec "$CTID" -- bash -c "printf 'nameserver 8.8.8.8\nnameserver 1.1.1.1\n' >/etc/resolv.conf" >/dev/null 2>&1 || true
msg_ok "DNS override applied in LXC"
fi
fi
# Fallback to lxc-attach exit code if no flag file
if [[ $install_exit_code -eq 0 && $lxc_exit -ne 0 ]]; then
install_exit_code=$lxc_exit
fi
# Install SSH keys
install_ssh_keys_into_ct
# Installation failed?
# Start timer for duration tracking
start_install_timer
# Run application installer
# Error handling already disabled above (before customization phase)
# Signal handlers use this flag to stop the container on abort (SIGHUP/SIGINT/SIGTERM)
# Without this, SSH disconnects leave the container running as an orphan process
# that sends "configuring" status AFTER the host already reported "failed"
export CONTAINER_INSTALLING=true
# Capture lxc-attach terminal output to host-side log via tee.
# This is the ONLY reliable way to get install output when:
# - install.func fails to load (DNS error) → no container-side logging
# - install script crashes before logging starts
# - $STD/silent() not used for some commands
# PIPESTATUS[0] gets the real exit code from lxc-attach (not from tee).
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)" 2>&1 | tee "$_LXC_CAPTURE_LOG"
local lxc_exit=${PIPESTATUS[0]}
unset CONTAINER_INSTALLING
# Keep error handling DISABLED during failure detection and recovery
# Re-enabling it here would cause any pct exec/pull failure to trigger
# error_handler() on the host, bypassing the recovery menu entirely
# Check for error flag file in container (more reliable than lxc-attach exit code)
if [[ -n "${SESSION_ID:-}" ]]; then
local error_flag="/root/.install-${SESSION_ID}.failed"
if pct exec "$CTID" -- test -f "$error_flag" 2>/dev/null; then
install_exit_code=$(pct exec "$CTID" -- cat "$error_flag" 2>/dev/null || echo "1")
pct exec "$CTID" -- rm -f "$error_flag" 2>/dev/null || true
fi
fi
# Fallback to lxc-attach exit code if no flag file
if [[ $install_exit_code -eq 0 && ${lxc_exit:-0} -ne 0 ]]; then
install_exit_code=${lxc_exit:-0}
fi
fi # end: if [[ $install_exit_code -eq 0 ]] (customization succeeded)
# Installation or customization failed?
if [[ $install_exit_code -ne 0 ]]; then
# Prevent job-control signals from suspending the script during recovery.
# In non-interactive shells (bash -c), background processes (spinner) can
@@ -4219,7 +4237,7 @@ EOF'
pct enter "$CTID"
echo ""
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
if read -r response && [[ "$response" =~ ^[Yy]$ ]]; then
if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then
pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true
msg_ok "Container ${CTID} removed"
@@ -4369,7 +4387,7 @@ EOF'
echo ""
echo -en "${YW}Select option [1-${max_option}] (default: 1, auto-remove in 60s): ${CL}"
if read -t 60 -r response; then
if read -t 60 -r response </dev/tty; then
case "${response:-1}" in
1)
# Remove container
@@ -4586,7 +4604,7 @@ destroy_lxc() {
trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT
local prompt
if ! read -rp "Remove this Container? <y/N> " prompt; then
if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then
# read returns non-zero on Ctrl-D/ESC
msg_error "Aborted input (Ctrl-D/ESC)"
return 130
@@ -4923,11 +4941,12 @@ create_lxc_container() {
echo " pve-container: installed=${_pvec_i:-n/a} candidate=${_pvec_c:-n/a}"
echo " lxc-pve : installed=${_lxcp_i:-n/a} candidate=${_lxcp_c:-n/a}"
echo
read -rp "Do you want to upgrade now? [y/N] " _ans
read -rp "Do you want to upgrade now? [y/N] " _ans </dev/tty
case "${_ans,,}" in
y | yes)
msg_info "Upgrading Proxmox LXC stack (pve-container, lxc-pve)"
if $STD apt-get update && $STD apt-get install -y --only-upgrade pve-container lxc-pve; then
apt_update_safe
if $STD apt-get install -y --only-upgrade pve-container lxc-pve; then
msg_ok "LXC stack upgraded."
if [[ "$do_retry" == "yes" ]]; then
msg_info "Retrying container creation after upgrade"
@@ -5154,7 +5173,7 @@ create_lxc_container() {
echo " [$((i + 1))] ${AVAILABLE_VERSIONS[$i]}"
done
echo ""
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or press Enter to cancel: " choice
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or press Enter to cancel: " choice </dev/tty
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then
PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}"
@@ -5217,7 +5236,7 @@ create_lxc_container() {
done
echo ""
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or Enter to exit: " choice
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or Enter to exit: " choice </dev/tty
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then
export var_version="${AVAILABLE_VERSIONS[$((choice - 1))]}"
@@ -5327,7 +5346,7 @@ create_lxc_container() {
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
for attempt in {1..3}; do
msg_info "Attempt $attempt: Downloading template $TEMPLATE to $TEMPLATE_STORAGE"
if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1; then
if pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >>"${BUILD_LOG:-/dev/null}" 2>&1; then
msg_ok "Template download successful."
break
fi
@@ -5404,11 +5423,23 @@ create_lxc_container() {
LOGFILE="/tmp/pct_create_${CTID}_$(date +%Y%m%d_%H%M%S)_${SESSION_ID}.log"
# Helper: append pct_create log to BUILD_LOG before exit so combined log has full context
_flush_pct_log() {
if [[ -s "${LOGFILE:-}" && -n "${BUILD_LOG:-}" ]]; then
{
echo ""
echo "--- pct create output (${LOGFILE}) ---"
cat "$LOGFILE"
echo "--- end pct create output ---"
} >>"$BUILD_LOG" 2>/dev/null || true
fi
}
# 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 || {
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >>"${BUILD_LOG:-/dev/null}" 2>&1 || {
msg_error "Failed to download template '$TEMPLATE' to storage '$TEMPLATE_STORAGE'"
exit 222
}
@@ -5417,7 +5448,7 @@ create_lxc_container() {
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 || {
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >>"${BUILD_LOG:-/dev/null}" 2>&1 || {
msg_error "Failed to re-download template '$TEMPLATE'"
exit 222
}
@@ -5441,7 +5472,7 @@ create_lxc_container() {
if grep -qiE 'unable to open|corrupt|invalid' "$LOGFILE"; then
msg_info "Template may be corrupted re-downloading"
rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null 2>&1
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >>"${BUILD_LOG:-/dev/null}" 2>&1
msg_ok "Template re-downloaded"
fi
@@ -5454,7 +5485,7 @@ create_lxc_container() {
if [[ ! -f "$LOCAL_TEMPLATE_PATH" ]]; then
msg_ok "Trying local storage fallback"
msg_info "Downloading template to local"
pveam download local "$TEMPLATE" >/dev/null 2>&1
pveam download local "$TEMPLATE" >>"${BUILD_LOG:-/dev/null}" 2>&1
msg_ok "Template downloaded to local"
else
msg_ok "Trying local storage fallback"
@@ -5469,10 +5500,12 @@ create_lxc_container() {
0) : ;; # success - container created, continue
2)
msg_error "Upgrade declined. Please update and re-run: apt update && apt install --only-upgrade pve-container lxc-pve"
_flush_pct_log
exit 231
;;
3)
msg_error "Upgrade and/or retry failed. Please inspect: $LOGFILE"
_flush_pct_log
exit 231
;;
esac
@@ -5483,6 +5516,7 @@ create_lxc_container() {
pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS 2>&1 | tee -a "$LOGFILE"
set +x
fi
_flush_pct_log
exit 209
fi
else
@@ -5498,10 +5532,12 @@ create_lxc_container() {
0) : ;; # success - container created, continue
2)
msg_error "Upgrade declined. Please update and re-run: apt update && apt install --only-upgrade pve-container lxc-pve"
_flush_pct_log
exit 231
;;
3)
msg_error "Upgrade and/or retry failed. Please inspect: $LOGFILE"
_flush_pct_log
exit 231
;;
esac
@@ -5512,6 +5548,7 @@ create_lxc_container() {
pct create "$CTID" "local:vztmpl/${TEMPLATE}" $PCT_OPTIONS 2>&1 | tee -a "$LOGFILE"
set +x
fi
_flush_pct_log
exit 209
fi
fi
@@ -5523,16 +5560,28 @@ create_lxc_container() {
# Verify container exists
pct list | awk '{print $1}' | grep -qx "$CTID" || {
msg_error "Container ID $CTID not listed in 'pct list'. See $LOGFILE"
_flush_pct_log
exit 215
}
# Verify config rootfs
grep -q '^rootfs:' "/etc/pve/lxc/$CTID.conf" || {
msg_error "RootFS entry missing in container config. See $LOGFILE"
_flush_pct_log
exit 216
}
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
# Append pct create log to BUILD_LOG for combined log visibility
if [[ -s "$LOGFILE" && -n "${BUILD_LOG:-}" ]]; then
{
echo ""
echo "--- pct create output ---"
cat "$LOGFILE"
echo "--- end pct create output ---"
} >>"$BUILD_LOG" 2>/dev/null || true
fi
}
# ==============================================================================

View File

@@ -552,6 +552,53 @@ silent() {
fi
}
# ------------------------------------------------------------------------------
# apt_update_safe()
#
# - Runs apt-get update with graceful error handling
# - On failure: shows warning with common causes instead of aborting
# - Logs full output to active log file
# - Returns 0 even on failure so the caller can continue
# - Typical cause: enterprise repos returning 401 Unauthorized
#
# Usage:
# apt_update_safe # Warn on failure, continue without aborting
# ------------------------------------------------------------------------------
apt_update_safe() {
local logfile
logfile="$(get_active_logfile)"
local _restore_errexit=false
[[ "$-" == *e* ]] && _restore_errexit=true
set +Eeuo pipefail
trap - ERR
apt-get update >>"$logfile" 2>&1
local rc=$?
if $_restore_errexit; then
set -Eeuo pipefail
trap 'error_handler' ERR
fi
if [[ $rc -ne 0 ]]; then
msg_warn "apt-get update exited with code ${rc} — some repositories may have failed."
# Check log for common 401/403 enterprise repo issues
if grep -qiE '401\s*Unauthorized|403\s*Forbidden|enterprise\.proxmox\.com' "$logfile" 2>/dev/null; then
echo -e "${TAB}${INFO} ${YWB}Hint: Proxmox enterprise repository returned an auth error.${CL}"
echo -e "${TAB} If you don't have a subscription, you can disable the enterprise"
echo -e "${TAB} repo and use the no-subscription repo instead."
fi
echo -e "${TAB}${INFO} ${YWB}Continuing despite partial update failure — packages may still be installable.${CL}"
echo ""
fi
return 0
}
# ------------------------------------------------------------------------------
# spinner()
#

View File

@@ -286,7 +286,7 @@ error_handler() {
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
fi
if read -t 60 -r response; then
if read -t 60 -r response </dev/tty; then
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
echo ""
if declare -f msg_info >/dev/null 2>&1; then

View File

@@ -233,7 +233,7 @@ fi
EOF
chmod +x /usr/local/bin/apt-proxy-detect.sh
fi
$STD apt-get update
apt_update_safe
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Updated Container OS"

View File

@@ -4260,6 +4260,18 @@ NVIDIA_PIN
# VA-API for hybrid setups (Intel + NVIDIA)
$STD apt-get -y install va-driver-all vainfo 2>/dev/null || true
# Fix GLX alternatives: nvidia-alternative diverts mesa libs but in LXC
# containers the nvidia GLX libs are typically missing, leaving libGL.so.1
# pointing nowhere. Fall back to mesa if nvidia GLX dir is empty/missing.
if command -v update-glx &>/dev/null; then
local nvidia_glx_dir="/usr/lib/nvidia"
if [[ ! -f "${nvidia_glx_dir}/libGL.so.1" ]] && [[ -d /usr/lib/mesa-diverted ]]; then
msg_info "NVIDIA GLX libs missing in container - falling back to mesa"
$STD update-glx --set glx /usr/lib/mesa-diverted 2>/dev/null || true
ldconfig 2>/dev/null || true
fi
fi
msg_ok "NVIDIA GPU configured"
}

View File

@@ -76,70 +76,90 @@ grep -q "lxc.mount.entry: /dev/net/tun" "$CTID_CONFIG_PATH" || echo "lxc.mount.e
header_info
msg_info "Installing Tailscale in CT $CTID"
pct exec "$CTID" -- bash -c '
pct exec "$CTID" -- sh -c '
set -e
export DEBIAN_FRONTEND=noninteractive
# Source os-release properly (handles quoted values)
source /etc/os-release
# Detect OS inside container
if [ -f /etc/alpine-release ]; then
# ── Alpine Linux ──
echo "[INFO] Alpine Linux detected, installing Tailscale via apk..."
# Fallback if DNS is poisoned or blocked
ORIG_RESOLV="/etc/resolv.conf"
BACKUP_RESOLV="/tmp/resolv.conf.backup"
# Enable community repo if not already enabled
if ! grep -q "^[^#].*community" /etc/apk/repositories 2>/dev/null; then
ALPINE_VERSION=$(cat /etc/alpine-release | cut -d. -f1,2)
echo "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community" >> /etc/apk/repositories
fi
apk update
apk add --no-cache tailscale
# Enable and start Tailscale service
rc-update add tailscale default 2>/dev/null || true
rc-service tailscale start 2>/dev/null || true
# Check DNS resolution using multiple methods (dig may not be installed)
dns_check_failed=true
if command -v dig &>/dev/null; then
if dig +short pkgs.tailscale.com 2>/dev/null | grep -qvE "^127\.|^0\.0\.0\.0$|^$"; then
dns_check_failed=false
fi
elif command -v host &>/dev/null; then
if host pkgs.tailscale.com 2>/dev/null | grep -q "has address"; then
dns_check_failed=false
fi
elif command -v nslookup &>/dev/null; then
if nslookup pkgs.tailscale.com 2>/dev/null | grep -q "Address:"; then
dns_check_failed=false
fi
elif command -v getent &>/dev/null; then
if getent hosts pkgs.tailscale.com &>/dev/null; then
dns_check_failed=false
fi
else
# No DNS tools available, try curl directly and assume DNS works
dns_check_failed=false
fi
# ── Debian / Ubuntu ──
export DEBIAN_FRONTEND=noninteractive
if $dns_check_failed; then
echo "[INFO] DNS resolution for pkgs.tailscale.com failed (blocked or redirected)."
echo "[INFO] Temporarily overriding /etc/resolv.conf with Cloudflare DNS (1.1.1.1)"
cp "$ORIG_RESOLV" "$BACKUP_RESOLV"
echo "nameserver 1.1.1.1" >"$ORIG_RESOLV"
fi
# Source os-release properly (handles quoted values)
. /etc/os-release
# Fallback if DNS is poisoned or blocked
ORIG_RESOLV="/etc/resolv.conf"
BACKUP_RESOLV="/tmp/resolv.conf.backup"
# Check DNS resolution using multiple methods (dig may not be installed)
dns_check_failed=true
if command -v dig >/dev/null 2>&1; then
if dig +short pkgs.tailscale.com 2>/dev/null | grep -qvE "^127\.|^0\.0\.0\.0$|^$"; then
dns_check_failed=false
fi
elif command -v host >/dev/null 2>&1; then
if host pkgs.tailscale.com 2>/dev/null | grep -q "has address"; then
dns_check_failed=false
fi
elif command -v nslookup >/dev/null 2>&1; then
if nslookup pkgs.tailscale.com 2>/dev/null | grep -q "Address:"; then
dns_check_failed=false
fi
elif command -v getent >/dev/null 2>&1; then
if getent hosts pkgs.tailscale.com >/dev/null 2>&1; then
dns_check_failed=false
fi
else
# No DNS tools available, try curl directly and assume DNS works
dns_check_failed=false
fi
if $dns_check_failed; then
echo "[INFO] DNS resolution for pkgs.tailscale.com failed (blocked or redirected)."
echo "[INFO] Temporarily overriding /etc/resolv.conf with Cloudflare DNS (1.1.1.1)"
cp "$ORIG_RESOLV" "$BACKUP_RESOLV"
echo "nameserver 1.1.1.1" >"$ORIG_RESOLV"
fi
if ! command -v curl >/dev/null 2>&1; then
echo "[INFO] curl not found, installing..."
apt-get update -qq
apt-get install -y curl >/dev/null
fi
# Ensure keyrings directory exists
mkdir -p /usr/share/keyrings
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \
>/etc/apt/sources.list.d/tailscale.list
if ! command -v curl &>/dev/null; then
echo "[INFO] curl not found, installing..."
apt-get update -qq
apt update -qq
apt install -y curl >/dev/null
fi
apt-get install -y tailscale >/dev/null
# Ensure keyrings directory exists
mkdir -p /usr/share/keyrings
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \
>/etc/apt/sources.list.d/tailscale.list
apt-get update -qq
apt update -qq
apt install -y tailscale >/dev/null
if [[ -f /tmp/resolv.conf.backup ]]; then
echo "[INFO] Restoring original /etc/resolv.conf"
mv /tmp/resolv.conf.backup /etc/resolv.conf
if [ -f /tmp/resolv.conf.backup ]; then
echo "[INFO] Restoring original /etc/resolv.conf"
mv /tmp/resolv.conf.backup /etc/resolv.conf
fi
fi
'

View File

@@ -7,8 +7,12 @@
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
if [[ -f "/etc/alpine-release" ]]; then
apk -U add curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -51,7 +55,7 @@ EOF
# HELPER FUNCTIONS
# ==============================================================================
get_ip() {
hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1"
ifconfig | grep -v '127.0.0.1' | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -m1 -Eo '([0-9]*\.){3}[0-9]*' || echo "127.0.0.1"
}
# ==============================================================================
@@ -68,6 +72,16 @@ else
exit 1
fi
# ==============================================================================
# DEPENDENCY CHECK
# ==============================================================================
if ! command -v jq &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Installing jq \033[m' >&2
if [[ "$OS" == "Alpine" ]]; then
apk -U add jq >/dev/null 2>&1
fi
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================

View File

@@ -88,7 +88,7 @@ function truenas_iso_lookup() {
curl -sL "$BASE_URL" |
grep -oE 'href="[^"]+\.iso"' |
sed 's/href="//; s/"$//' |
grep -vE '(nightly|ALPHA)' |
grep -vE '(MASTER|ALPHA)' |
grep -E "$year_pattern"
)