Compare commits

..

2 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
07b53369ae memos: unpin version due new release artifacts
Updated fetch_and_deploy_gh_release to use 'latest' version instead of specific version 'v0.25.3'.
2026-02-23 16:39:25 +01:00
CanbiZ (MickLesk)
4a96dc4f39 memos: unpin version due new release artifacts 2026-02-23 16:39:01 +01:00
29 changed files with 237 additions and 669 deletions

111
.github/workflows/stale_pr_close.yml generated vendored
View File

@@ -1,111 +0,0 @@
name: Stale PR Management
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
pull_request_target:
types:
- labeled
jobs:
stale-prs:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
contents: read
steps:
- name: Handle stale PRs
uses: actions/github-script@v7
with:
script: |
const now = new Date();
const owner = context.repo.owner;
const repo = context.repo.repo;
// --- When stale label is added, comment immediately ---
if (context.eventName === "pull_request_target" && context.payload.action === "labeled") {
const label = context.payload.label?.name;
if (label === "stale") {
const author = context.payload.pull_request.user.login;
await github.rest.issues.createComment({
owner,
repo,
issue_number: context.payload.pull_request.number,
body: `@${author} This PR has been marked as stale. It will be closed if no new commits are added in 7 days.`
});
}
return;
}
// --- Scheduled run: check all stale PRs ---
const { data: prs } = await github.rest.pulls.list({
owner,
repo,
state: "open",
per_page: 100
});
for (const pr of prs) {
const hasStale = pr.labels.some(l => l.name === "stale");
if (!hasStale) continue;
// Get timeline events to find when stale label was added
const { data: events } = await github.rest.issues.listEvents({
owner,
repo,
issue_number: pr.number,
per_page: 100
});
// Find the most recent time the stale label was added
const staleLabelEvents = events
.filter(e => e.event === "labeled" && e.label?.name === "stale")
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
if (staleLabelEvents.length === 0) continue;
const staleLabelDate = new Date(staleLabelEvents[0].created_at);
const daysSinceStale = (now - staleLabelDate) / (1000 * 60 * 60 * 24);
// Check for new commits since stale label was added
const { data: commits } = await github.rest.pulls.listCommits({
owner,
repo,
pull_number: pr.number
});
const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date);
const author = pr.user.login;
// If there are new commits after the stale label, remove it
if (lastCommitDate > staleLabelDate) {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: pr.number,
name: "stale"
});
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr.number,
body: `@${author} Recent activity detected. Removing stale label.`
});
}
// If 7 days have passed since stale label, close the PR
else if (daysSinceStale > 7) {
await github.rest.pulls.update({
owner,
repo,
pull_number: pr.number,
state: "closed"
});
await github.rest.issues.createComment({
owner,
repo,
issue_number: pr.number,
body: `@${author} Closing stale PR due to inactivity (no commits for 7 days after stale label).`
});
}
}

View File

@@ -407,48 +407,19 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-02-24
### 🚀 Updated Scripts
- adds further documentation during the installation script. [@d12rio](https://github.com/d12rio) ([#12248](https://github.com/community-scripts/ProxmoxVE/pull/12248))
- #### 🐞 Bug Fixes
- Firefly: PHP bump [@tremor021](https://github.com/tremor021) ([#12247](https://github.com/community-scripts/ProxmoxVE/pull/12247))
- #### ✨ New Features
- make searxng updateable [@shtefko](https://github.com/shtefko) ([#12207](https://github.com/community-scripts/ProxmoxVE/pull/12207))
### 📂 Github
- add: workflow to close stale PRs [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12243](https://github.com/community-scripts/ProxmoxVE/pull/12243))
## 2026-02-23
### 🆕 New Scripts
- SeaweedFS ([#12220](https://github.com/community-scripts/ProxmoxVE/pull/12220))
- Sonobarr ([#12221](https://github.com/community-scripts/ProxmoxVE/pull/12221))
- SparkyFitness ([#12185](https://github.com/community-scripts/ProxmoxVE/pull/12185))
- SparkyFitness ([#12185](https://github.com/community-scripts/ProxmoxVE/pull/12185))
- Frigate v16.4 [@MickLesk](https://github.com/MickLesk) ([#11887](https://github.com/community-scripts/ProxmoxVE/pull/11887))
### 🚀 Updated Scripts
- #### ✨ New Features
- memos: unpin version due new release artifacts [@MickLesk](https://github.com/MickLesk) ([#12224](https://github.com/community-scripts/ProxmoxVE/pull/12224))
- core: Enhance signal handling, reported "status" and logs [@MickLesk](https://github.com/MickLesk) ([#12216](https://github.com/community-scripts/ProxmoxVE/pull/12216))
- #### 🔧 Refactor
- booklore v2: embed frontend, bump Java to 25, remove nginx [@MickLesk](https://github.com/MickLesk) ([#12223](https://github.com/community-scripts/ProxmoxVE/pull/12223))
### 🗑️ Deleted Scripts
- Remove: Huntarr (deprecated & Security) [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12226](https://github.com/community-scripts/ProxmoxVE/pull/12226))
### 💾 Core
- #### 🔧 Refactor

View File

@@ -30,7 +30,7 @@ function update_script() {
fi
if check_for_gh_release "booklore" "booklore-app/BookLore"; then
JAVA_VERSION="25" setup_java
JAVA_VERSION="21" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
@@ -60,16 +60,11 @@ function update_script() {
$STD npm run build --configuration=production
msg_ok "Built Frontend"
msg_info "Embedding Frontend into Backend"
mkdir -p /opt/booklore/booklore-api/src/main/resources/static
cp -r /opt/booklore/booklore-ui/dist/booklore/browser/* /opt/booklore/booklore-api/src/main/resources/static/
msg_ok "Embedded Frontend into Backend"
msg_info "Building Backend"
cd /opt/booklore/booklore-api
APP_VERSION=$(get_latest_github_release "booklore-app/BookLore")
yq eval ".app.version = \"${APP_VERSION}\"" -i src/main/resources/application.yaml
$STD ./gradlew clean build -x test --no-daemon
$STD ./gradlew clean build --no-daemon
mkdir -p /opt/booklore/dist
JAR_PATH=$(find /opt/booklore/booklore-api/build/libs -maxdepth 1 -type f -name "booklore-api-*.jar" ! -name "*plain*" | head -n1)
if [[ -z "$JAR_PATH" ]]; then
@@ -79,22 +74,9 @@ function update_script() {
cp "$JAR_PATH" /opt/booklore/dist/app.jar
msg_ok "Built Backend"
if systemctl is-active --quiet nginx 2>/dev/null; then
msg_info "Removing Nginx (no longer needed)"
systemctl disable --now nginx
$STD apt-get purge -y nginx nginx-common
msg_ok "Removed Nginx"
fi
if ! grep -q "^SERVER_PORT=" /opt/booklore_storage/.env 2>/dev/null; then
echo "SERVER_PORT=6060" >>/opt/booklore_storage/.env
fi
sed -i 's|ExecStart=/usr/bin/java -jar|ExecStart=/usr/bin/java -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+UseCompactObjectHeaders -jar|' /etc/systemd/system/booklore.service
systemctl daemon-reload
msg_info "Starting Service"
systemctl start booklore
systemctl reload nginx
rm -rf /opt/booklore_bak
msg_ok "Started Service"
msg_ok "Updated successfully!"

View File

@@ -28,10 +28,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
setup_mariadb
PHP_VERSION="8.5" PHP_APACHE="YES" setup_php
if check_for_gh_release "firefly" "firefly-iii/firefly-iii"; then
systemctl stop apache2
cp /opt/firefly/.env /opt/.env

6
ct/headers/huntarr Normal file
View File

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

View File

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

View File

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

View File

@@ -1,19 +1,18 @@
#!/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: MickLesk (CanbiZ)
# Author: BiluliB
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/seaweedfs/seaweedfs
# Source: https://github.com/plexguide/Huntarr.io
APP="SeaweedFS"
var_tags="${var_tags:-storage;s3;filesystem}"
APP="huntarr"
var_tags="${var_tags:-arr}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-16}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-yes}"
header_info "$APP"
variables
@@ -25,20 +24,28 @@ function update_script() {
check_container_storage
check_container_resources
if [[ ! -f /opt/seaweedfs/weed ]]; then
if [[ ! -f /opt/huntarr/main.py ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "seaweedfs" "seaweedfs/seaweedfs"; then
msg_info "Stopping Service"
systemctl stop seaweedfs
msg_ok "Stopped Service"
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "seaweedfs" "seaweedfs/seaweedfs" "prebuild" "latest" "/opt/seaweedfs" "linux_amd64.tar.gz"
if check_for_gh_release "huntarr" "plexguide/Huntarr.io"; then
msg_info "Stopping Service"
systemctl stop huntarr
msg_ok "Stopped Service"
ensure_dependencies build-essential
fetch_and_deploy_gh_release "huntarr" "plexguide/Huntarr.io" "tarball"
msg_info "Updating Huntarr"
cd /opt/huntarr
$STD uv pip install -r requirements.txt --python /opt/huntarr/.venv/bin/python
msg_ok "Updated Huntarr"
msg_info "Starting Service"
systemctl start seaweedfs
systemctl start huntarr
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
@@ -49,7 +56,7 @@ start
build_container
description
msg_ok "Completed Successfully!\n"
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}:9333${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9705${CL}"

View File

@@ -27,11 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
ensure_dependencies graphicsmagick
NODE_VERSION="24" setup_nodejs
msg_info "Updating n8n"
ensure_dependencies graphicsmagick
if [ ! -f /opt/n8n.env ]; then
sed -i 's|^Environment="N8N_SECURE_COOKIE=false"$|EnvironmentFile=/opt/n8n.env|' /etc/systemd/system/n8n.service
mkdir -p /opt
@@ -41,12 +37,14 @@ N8N_PORT=5678
N8N_PROTOCOL=http
N8N_HOST=$LOCAL_IP
EOF
systemctl daemon-reload
fi
NODE_VERSION="22" setup_nodejs
$STD npm update -g n8n
msg_info "Updating ${APP} LXC"
rm -rf /usr/lib/node_modules/.n8n-* /usr/lib/node_modules/n8n
$STD npm install -g n8n --force
systemctl restart n8n
msg_ok "Updated n8n"
msg_ok "Updated successfully!"
exit
}

View File

@@ -27,33 +27,12 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
chown -R searxng:searxng /usr/local/searxng/searxng-src
if su -s /bin/bash -c "git -C /usr/local/searxng/searxng-src pull" searxng | grep -q 'Already up to date'; then
msg_ok "There is currently no update available."
exit
fi
msg_info "Updating SearXNG installation"
msg_info "Stopping Service"
systemctl stop searxng
msg_ok "Stopped Service"
msg_info "Updating SearXNG"
$STD su -s /bin/bash searxng -c '
python3 -m venv /usr/local/searxng/searx-pyenv &&
. /usr/local/searxng/searx-pyenv/bin/activate &&
pip install -U pip setuptools wheel pyyaml lxml msgspec typing_extensions &&
pip install --use-pep517 --no-build-isolation -e /usr/local/searxng/searxng-src
'
msg_ok "Updated SearXNG"
msg_info "Starting Services"
systemctl start searxng
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
exit
msg_ok "There is currently no update available."
# sed -i 's/^\([[:space:]]*limiter:\)[[:space:]]*true/\1 false/' /etc/searxng/settings.yml
# if cd /usr/local/searxng/searxng-src && git pull | grep -q 'Already up to date'; then
# msg_ok "There is currently no update available."
# fi
exit
}
start
build_container

View File

@@ -1,63 +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: GoldenSpringness
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Dodelidoo-Labs/sonobarr
APP="sonobarr"
var_tags="${var_tags:-music;discovery}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-20}"
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/sonobarr" ]]; then
msg_error "No sonobarr Installation Found!"
exit
fi
PYTHON_VERSION="3.12" setup_uv
if check_for_gh_release "sonobarr" "Dodelidoo-Labs/sonobarr"; then
msg_info "Stopping Service"
systemctl stop sonobarr
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "sonobarr" "Dodelidoo-Labs/sonobarr" "tarball"
msg_info "Updating sonobarr"
$STD uv venv -c /opt/sonobarr/venv
$STD source /opt/sonobarr/venv/bin/activate
$STD uv pip install --no-cache-dir -r /opt/sonobarr/requirements.txt
sed -i "/release_version/s/=.*/=$(cat ~/.sonobarr)/" /etc/sonobarr/.env
msg_ok "Updated sonobarr"
msg_info "Starting Service"
systemctl start sonobarr
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}sonobarr setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5000${CL}"

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-24T06:23:39Z",
"generated": "2026-02-23T12:14:19Z",
"versions": [
{
"slug": "2fauth",
@@ -25,9 +25,9 @@
{
"slug": "adventurelog",
"repo": "seanmorley15/adventurelog",
"version": "v0.12.0",
"version": "v0.11.0",
"pinned": false,
"date": "2026-02-23T14:06:45Z"
"date": "2025-09-01T16:19:38Z"
},
{
"slug": "alpine-redlib",
@@ -151,9 +151,9 @@
{
"slug": "booklore",
"repo": "booklore-app/BookLore",
"version": "v2.0.1",
"version": "v1.18.5",
"pinned": false,
"date": "2026-02-24T04:15:33Z"
"date": "2026-01-24T17:15:32Z"
},
{
"slug": "bookstack",
@@ -200,9 +200,9 @@
{
"slug": "cleanuparr",
"repo": "Cleanuparr/Cleanuparr",
"version": "v2.7.4",
"version": "v2.7.1",
"pinned": false,
"date": "2026-02-23T18:41:16Z"
"date": "2026-02-23T09:58:13Z"
},
{
"slug": "cloudreve",
@@ -228,9 +228,9 @@
{
"slug": "configarr",
"repo": "raydak-labs/configarr",
"version": "v1.23.0",
"version": "v1.22.0",
"pinned": false,
"date": "2026-02-23T12:28:13Z"
"date": "2026-02-20T21:55:46Z"
},
{
"slug": "convertx",
@@ -249,9 +249,9 @@
{
"slug": "cronicle",
"repo": "jhuckaby/Cronicle",
"version": "v0.9.107",
"version": "v0.9.106",
"pinned": false,
"date": "2026-02-23T17:48:27Z"
"date": "2026-02-11T17:11:46Z"
},
{
"slug": "cronmaster",
@@ -382,9 +382,9 @@
{
"slug": "firefly",
"repo": "firefly-iii/firefly-iii",
"version": "v6.5.0",
"version": "v6.4.23",
"pinned": false,
"date": "2026-02-23T19:19:00Z"
"date": "2026-02-20T07:02:05Z"
},
{
"slug": "fladder",
@@ -438,9 +438,9 @@
{
"slug": "ghostfolio",
"repo": "ghostfolio/ghostfolio",
"version": "2.243.0",
"version": "2.242.0",
"pinned": false,
"date": "2026-02-23T19:31:36Z"
"date": "2026-02-22T10:01:44Z"
},
{
"slug": "gitea",
@@ -452,9 +452,9 @@
{
"slug": "gitea-mirror",
"repo": "RayLabsHQ/gitea-mirror",
"version": "v3.9.4",
"version": "v3.9.2",
"pinned": false,
"date": "2026-02-24T06:17:56Z"
"date": "2025-11-08T05:36:48Z"
},
{
"slug": "glance",
@@ -582,6 +582,13 @@
"pinned": false,
"date": "2025-12-23T14:53:51Z"
},
{
"slug": "huntarr",
"repo": "plexguide/Huntarr.io",
"version": "9.4.1",
"pinned": false,
"date": "2026-02-23T08:46:37Z"
},
{
"slug": "immich-public-proxy",
"repo": "alangrainger/immich-public-proxy",
@@ -613,9 +620,9 @@
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1193",
"version": "v0.24.1184",
"pinned": false,
"date": "2026-02-24T05:58:04Z"
"date": "2026-02-23T05:55:36Z"
},
{
"slug": "jellystat",
@@ -858,9 +865,9 @@
{
"slug": "memos",
"repo": "usememos/memos",
"version": "v0.26.2",
"pinned": false,
"date": "2026-02-23T13:28:34Z"
"version": "v0.25.3",
"pinned": true,
"date": "2025-11-25T15:40:41Z"
},
{
"slug": "metube",
@@ -1117,9 +1124,9 @@
{
"slug": "planka",
"repo": "plankanban/planka",
"version": "v2.0.2",
"version": "v2.0.1",
"pinned": false,
"date": "2026-02-23T17:47:15Z"
"date": "2026-02-17T15:26:55Z"
},
{
"slug": "plant-it",
@@ -1138,9 +1145,9 @@
{
"slug": "pocketid",
"repo": "pocket-id/pocket-id",
"version": "v2.3.0",
"version": "v2.2.0",
"pinned": false,
"date": "2026-02-23T19:50:48Z"
"date": "2026-01-11T15:01:07Z"
},
{
"slug": "privatebin",
@@ -1243,9 +1250,9 @@
{
"slug": "qui",
"repo": "autobrr/qui",
"version": "v1.14.1",
"version": "v1.14.0",
"pinned": false,
"date": "2026-02-23T13:13:31Z"
"date": "2026-02-21T22:23:46Z"
},
{
"slug": "radarr",
@@ -1271,9 +1278,9 @@
{
"slug": "rdtclient",
"repo": "rogerfar/rdt-client",
"version": "v2.0.124",
"version": "v2.0.123",
"pinned": false,
"date": "2026-02-24T03:18:03Z"
"date": "2026-02-21T23:08:13Z"
},
{
"slug": "reactive-resume",
@@ -1345,13 +1352,6 @@
"pinned": false,
"date": "2026-02-12T14:20:56Z"
},
{
"slug": "seaweedfs",
"repo": "seaweedfs/seaweedfs",
"version": "4.13",
"pinned": false,
"date": "2026-02-17T01:09:45Z"
},
{
"slug": "seelf",
"repo": "YuukanOO/seelf",
@@ -1404,16 +1404,16 @@
{
"slug": "snipeit",
"repo": "grokability/snipe-it",
"version": "v8.4.0",
"version": "v8.3.7",
"pinned": false,
"date": "2026-02-23T20:59:43Z"
"date": "2025-12-12T09:13:40Z"
},
{
"slug": "snowshare",
"repo": "TuroYT/snowshare",
"version": "v1.3.7",
"version": "v1.3.6",
"pinned": false,
"date": "2026-02-23T15:51:39Z"
"date": "2026-02-19T11:06:29Z"
},
{
"slug": "sonarr",
@@ -1422,13 +1422,6 @@
"pinned": false,
"date": "2025-11-05T01:56:48Z"
},
{
"slug": "sonobarr",
"repo": "Dodelidoo-Labs/sonobarr",
"version": "0.11.0",
"pinned": false,
"date": "2026-01-21T19:07:21Z"
},
{
"slug": "speedtest-tracker",
"repo": "alexjustesen/speedtest-tracker",
@@ -1453,9 +1446,9 @@
{
"slug": "stirling-pdf",
"repo": "Stirling-Tools/Stirling-PDF",
"version": "v2.5.3",
"version": "v2.5.2",
"pinned": false,
"date": "2026-02-23T23:23:39Z"
"date": "2026-02-20T23:20:20Z"
},
{
"slug": "streamlink-webui",
@@ -1565,9 +1558,9 @@
{
"slug": "traefik",
"repo": "traefik/traefik",
"version": "v3.6.9",
"version": "v3.6.8",
"pinned": false,
"date": "2026-02-23T17:21:17Z"
"date": "2026-02-11T16:44:37Z"
},
{
"slug": "trilium",
@@ -1579,9 +1572,9 @@
{
"slug": "trip",
"repo": "itskovacs/TRIP",
"version": "1.41.0",
"version": "1.40.0",
"pinned": false,
"date": "2026-02-23T17:57:31Z"
"date": "2026-02-10T20:12:53Z"
},
{
"slug": "tududi",
@@ -1593,9 +1586,9 @@
{
"slug": "tunarr",
"repo": "chrisbenincasa/tunarr",
"version": "v1.1.16",
"version": "v1.1.15",
"pinned": false,
"date": "2026-02-23T21:24:47Z"
"date": "2026-02-19T23:51:17Z"
},
{
"slug": "uhf",
@@ -1642,9 +1635,9 @@
{
"slug": "vaultwarden",
"repo": "dani-garcia/vaultwarden",
"version": "1.35.4",
"version": "1.35.3",
"pinned": false,
"date": "2026-02-23T21:43:25Z"
"date": "2026-02-10T20:37:03Z"
},
{
"slug": "victoriametrics",
@@ -1740,16 +1733,16 @@
{
"slug": "wishlist",
"repo": "cmintey/wishlist",
"version": "v0.60.1",
"version": "v0.60.0",
"pinned": false,
"date": "2026-02-24T04:01:37Z"
"date": "2026-02-10T04:05:26Z"
},
{
"slug": "wizarr",
"repo": "wizarrrr/wizarr",
"version": "v2026.2.0",
"version": "v2025.12.0",
"pinned": false,
"date": "2026-02-23T19:25:28Z"
"date": "2025-12-09T14:30:23Z"
},
{
"slug": "writefreely",

View File

@@ -0,0 +1,36 @@
{
"name": "Huntarr",
"slug": "huntarr",
"categories": [
14
],
"date_created": "2025-06-18",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9705,
"documentation": "https://github.com/plexguide/Huntarr.io/wiki",
"config_path": "/opt/huntarr",
"website": "https://github.com/plexguide/Huntarr.io",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/huntarr.webp",
"description": "Huntarr is a tool that automates the search for missing or low-quality media content in your collection. It works seamlessly with applications like Sonarr, Radarr, Lidarr, Readarr, and Whisparr, enhancing their functionality with continuous background scans to identify and update missed or outdated content. Through a user-friendly web interface accessible on port 9705, Huntarr provides real-time statistics, log views, and extensive configuration options. The software is especially useful for users who want to keep their media library up to date by automatically searching for missing episodes or higher-quality versions. Huntarr is well-suited for self-hosted environments and can easily run in LXC containers or Docker setups.",
"disable": false,
"install_methods": [
{
"type": "default",
"script": "ct/huntarr.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -6,7 +6,7 @@
],
"date_created": "2025-08-26",
"type": "ct",
"updateable": true,
"updateable": false,
"privileged": false,
"interface_port": 8888,
"documentation": "https://docs.searxng.org/",

View File

@@ -1,48 +0,0 @@
{
"name": "SeaweedFS",
"slug": "seaweedfs",
"categories": [
11
],
"date_created": "2026-02-23",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9333,
"documentation": "https://github.com/seaweedfs/seaweedfs/wiki",
"website": "https://seaweedfs.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/seaweedfs.webp",
"config_path": "",
"description": "SeaweedFS is a fast distributed storage system for blobs, objects, files, and data lakes, with O(1) disk seek, S3 API, FUSE mount, WebDAV, and cloud tiering support.",
"install_methods": [
{
"type": "default",
"script": "ct/seaweedfs.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 16,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Master UI available at port 9333, Filer UI at port 8888, S3 API at port 8333.",
"type": "info"
},
{
"text": "Data is stored in /opt/seaweedfs-data.",
"type": "info"
},
{
"text": "FUSE mounting requires fuse3 (pre-installed).",
"type": "info"
}
]
}

View File

@@ -1,40 +0,0 @@
{
"name": "Sonobarr",
"slug": "sonobarr",
"categories": [
14
],
"date_created": "2026-02-23",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 5000,
"documentation": "https://github.com/Dodelidoo-Labs/sonobarr",
"config_path": "/etc/sonobarr/.env",
"website": "https://github.com/Dodelidoo-Labs/sonobarr",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/sonobarr.webp",
"description": "Sonobarr marries your existing Lidarr library with Last.fms discovery graph to surface artists you'll actually like. It runs as a Flask + Socket.IO application, ships with a polished Bootstrap UI, and includes admin tooling so folks can share a single instance safely.",
"install_methods": [
{
"type": "default",
"script": "ct/sonobarr.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 20,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Default generated admin password is in the env file (sonobarr_superadmin_password)",
"type": "info"
}
]
}

View File

@@ -13,7 +13,11 @@ setting_up_container
network_check
update_os
JAVA_VERSION="25" setup_java
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
JAVA_VERSION="21" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
@@ -26,11 +30,6 @@ $STD npm install --force
$STD npm run build --configuration=production
msg_ok "Built Frontend"
msg_info "Embedding Frontend into Backend"
mkdir -p /opt/booklore/booklore-api/src/main/resources/static
cp -r /opt/booklore/booklore-ui/dist/booklore/browser/* /opt/booklore/booklore-api/src/main/resources/static/
msg_ok "Embedded Frontend into Backend"
msg_info "Creating Environment"
mkdir -p /opt/booklore_storage/{data,books,bookdrop}
cat <<EOF >/opt/booklore_storage/.env
@@ -42,7 +41,6 @@ DATABASE_PASSWORD=${MARIADB_DB_PASS}
# App Configuration (Spring Boot mapping from app.* properties)
APP_PATH_CONFIG=/opt/booklore_storage/data
APP_BOOKDROP_FOLDER=/opt/booklore_storage/bookdrop
SERVER_PORT=6060
EOF
msg_ok "Created Environment"
@@ -50,7 +48,7 @@ msg_info "Building Backend"
cd /opt/booklore/booklore-api
APP_VERSION=$(get_latest_github_release "booklore-app/BookLore")
yq eval ".app.version = \"${APP_VERSION}\"" -i src/main/resources/application.yaml
$STD ./gradlew clean build -x test --no-daemon
$STD ./gradlew clean build --no-daemon
mkdir -p /opt/booklore/dist
JAR_PATH=$(find /opt/booklore/booklore-api/build/libs -maxdepth 1 -type f -name "booklore-api-*.jar" ! -name "*plain*" | head -n1)
if [[ -z "$JAR_PATH" ]]; then
@@ -60,6 +58,16 @@ fi
cp "$JAR_PATH" /opt/booklore/dist/app.jar
msg_ok "Built Backend"
msg_info "Configuring Nginx"
rm -rf /usr/share/nginx/html
ln -s /opt/booklore/booklore-ui/dist/booklore/browser /usr/share/nginx/html
rm -f /etc/nginx/sites-enabled/default
cp /opt/booklore/nginx.conf /etc/nginx/nginx.conf
sed -i 's/listen \${BOOKLORE_PORT};/listen 6060;/' /etc/nginx/nginx.conf
sed -i 's/listen \[::\]:${BOOKLORE_PORT};/listen [::]:6060;/' /etc/nginx/nginx.conf
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/booklore.service
[Unit]
@@ -70,7 +78,7 @@ After=network.target mariadb.service
Type=simple
User=root
WorkingDirectory=/opt/booklore/dist
ExecStart=/usr/bin/java -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+UseCompactObjectHeaders -jar /opt/booklore/dist/app.jar
ExecStart=/usr/bin/java -jar /opt/booklore/dist/app.jar
EnvironmentFile=/opt/booklore_storage/.env
SuccessExitStatus=143
TimeoutStopSec=10

View File

@@ -21,8 +21,6 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
echo "${TAB3}It is important to choose the name for your server before you install Synapse, because it cannot be changed later."
echo "${TAB3}The server name determines the “domain” part of user-ids for users on your server: these will all be of the format @user:my.domain.name. It also determines how other matrix servers will reach yours for federation."
read -p "${TAB3}Please enter the name for your server: " servername
msg_info "Installing Element Synapse"

View File

@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
PHP_VERSION="8.5" PHP_APACHE="YES" setup_php
PHP_VERSION="8.4" PHP_APACHE="YES" setup_php
setup_composer
setup_mariadb
MARIADB_DB_NAME="firefly" MARIADB_DB_USER="firefly" setup_mariadb_db

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: BiluliB
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/plexguide/Huntarr.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
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "huntarr" "plexguide/Huntarr.io" "tarball"
msg_info "Configure Huntarr"
$STD uv venv --clear /opt/huntarr/.venv
$STD uv pip install --python /opt/huntarr/.venv/bin/python -r /opt/huntarr/requirements.txt
msg_ok "Configured Huntrarr"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/huntarr.service
[Unit]
Description=Huntarr Service
After=network.target
[Service]
WorkingDirectory=/opt/huntarr
ExecStart=/opt/huntarr/.venv/bin/python /opt/huntarr/main.py
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now huntarr
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -15,19 +15,22 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
ca-certificates \
build-essential \
python3 \
python3-setuptools \
graphicsmagick
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
NODE_VERSION="22" setup_nodejs
msg_info "Installing n8n (Patience)"
$STD npm install -g n8n
$STD npm install --global patch-package
$STD npm install --global n8n
msg_ok "Installed n8n"
msg_info "Creating Service"
mkdir -p /opt
cat <<EOF >/opt/n8n.env
N8N_SECURE_COOKIE=false
N8N_PORT=5678

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/seaweedfs/seaweedfs
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 fuse3
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "seaweedfs" "seaweedfs/seaweedfs" "prebuild" "latest" "/opt/seaweedfs" "linux_amd64.tar.gz"
msg_info "Setting up SeaweedFS"
mkdir -p /opt/seaweedfs-data
ln -sf /opt/seaweedfs/weed /usr/local/bin/weed
msg_ok "Set up SeaweedFS"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/seaweedfs.service
[Unit]
Description=SeaweedFS Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/seaweedfs
ExecStart=/opt/seaweedfs/weed server -dir=/opt/seaweedfs-data -master.port=9333 -volume.port=8080 -filer -s3
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now seaweedfs
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -1,52 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: GoldenSpringness
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Dodelidoo-Labs/sonobarr
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "sonobarr" "Dodelidoo-Labs/sonobarr" "tarball"
PYTHON_VERSION="3.12" setup_uv
msg_info "Setting up sonobarr"
$STD uv venv -c /opt/sonobarr/venv
source /opt/sonobarr/venv/bin/activate
$STD uv pip install --no-cache-dir -r /opt/sonobarr/requirements.txt
mkdir -p /etc/sonobarr
mv /opt/sonobarr/.sample-env /etc/sonobarr/.env
sed -i "s/^secret_key=.*/secret_key=$(openssl rand -hex 16)/" /etc/sonobarr/.env
sed -i "s/^sonobarr_superadmin_password=.*/sonobarr_superadmin_password=$(openssl rand -hex 16)/" /etc/sonobarr/.env
echo "release_version=$(cat ~/.sonobarr)" >>/etc/sonobarr/.env
echo "sonobarr_config_dir=/etc/sonobarr" >>/etc/sonobarr.env
msg_ok "Set up sonobarr"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/sonobarr.service
[Unit]
Description=sonobarr Service
After=network.target
[Service]
WorkingDirectory=/opt/sonobarr/src
EnvironmentFile=/etc/sonobarr/.env
Environment="PATH=/opt/sonobarr/venv/bin"
ExecStart=/bin/bash -c 'gunicorn Sonobarr:app -c ../gunicorn_config.py'
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now sonobarr
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -25,9 +25,7 @@ get_lxc_ip
# post_progress_to_api()
#
# - Lightweight progress ping from inside the container
# - Updates the existing telemetry record status
# - Arguments:
# * $1: status (optional, default: "configuring")
# - Updates the existing telemetry record status from "installing" to "configuring"
# - Signals that the installation is actively progressing (not stuck)
# - Fire-and-forget: never blocks or fails the script
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
@@ -37,11 +35,9 @@ post_progress_to_api() {
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
local progress_status="${1:-configuring}"
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\"}" &>/dev/null || true
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
}
# This function enables IPv6 if it's not disabled and sets verbose mode

View File

@@ -35,11 +35,7 @@
TELEMETRY_URL="https://telemetry.community-scripts.org/telemetry"
# Timeout for telemetry requests (seconds)
# Progress pings (validation/configuring) use the short timeout
TELEMETRY_TIMEOUT=5
# Final status updates (success/failed) use the longer timeout
# PocketBase may need more time under load (FindRecord + UpdateRecord)
STATUS_TIMEOUT=10
# ==============================================================================
# SECTION 0: REPOSITORY SOURCE DETECTION
@@ -745,10 +741,7 @@ EOF
# post_progress_to_api()
#
# - Lightweight progress ping from host or container
# - Updates the existing telemetry record status
# - Arguments:
# * $1: status (optional, default: "configuring")
# Valid values: "validation", "configuring"
# - Updates the existing telemetry record status to "configuring"
# - Signals that the installation is actively progressing (not stuck)
# - Fire-and-forget: never blocks or fails the script
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
@@ -759,13 +752,12 @@ post_progress_to_api() {
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
local progress_status="${1:-configuring}"
local app_name="${NSAPP:-${app:-unknown}}"
local telemetry_type="${TELEMETRY_TYPE:-lxc}"
curl -fsS -m 5 -X POST "${TELEMETRY_URL:-https://telemetry.community-scripts.org/telemetry}" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${telemetry_type}\",\"nsapp\":\"${app_name}\",\"status\":\"${progress_status}\"}" &>/dev/null || true
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${telemetry_type}\",\"nsapp\":\"${app_name}\",\"status\":\"configuring\"}" &>/dev/null || true
}
# ------------------------------------------------------------------------------
@@ -901,7 +893,7 @@ post_update_to_api() {
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${STATUS_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
@@ -944,7 +936,7 @@ EOF
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${STATUS_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$RETRY_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
@@ -972,18 +964,12 @@ EOF
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${STATUS_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$MINIMAL_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
-d "$MINIMAL_PAYLOAD" -o /dev/null 2>/dev/null || true
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# All 3 attempts failed — do NOT set POST_UPDATE_DONE=true.
# This allows the EXIT trap (api_exit_script) to retry with 3 fresh attempts.
# No infinite loop risk: EXIT trap fires exactly once.
# Tried 3 times - mark as done regardless to prevent infinite loops
POST_UPDATE_DONE=true
}
# ==============================================================================
@@ -1359,27 +1345,9 @@ post_update_to_api_extended() {
EOF
)
local http_code
http_code=$(curl -sS -w "%{http_code}" -m "${STATUS_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
curl -fsS -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
-d "$JSON_PAYLOAD" &>/dev/null || true
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# Retry with minimal payload
sleep 1
http_code=$(curl -sS -w "%{http_code}" -m "${STATUS_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-unknown}\",\"status\":\"${pb_status}\",\"exit_code\":${exit_code},\"install_duration\":${duration:-0}}" \
-o /dev/null 2>/dev/null) || http_code="000"
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# Do NOT set POST_UPDATE_DONE=true — let EXIT trap retry
POST_UPDATE_DONE=true
}

View File

@@ -3671,9 +3671,6 @@ $PCT_OPTIONS_STRING"
create_lxc_container || exit $?
# Transition to 'configuring' — container created, now setting up OS/userland
post_progress_to_api "configuring"
LXC_CONFIG="/etc/pve/lxc/${CTID}.conf"
# ============================================================================
@@ -3915,6 +3912,7 @@ EOF
for i in {1..10}; do
if pct status "$CTID" | grep -q "status: running"; then
msg_ok "Started LXC Container"
post_progress_to_api # Signal container is running
break
fi
sleep 1
@@ -3969,6 +3967,7 @@ EOF
echo -e "${YW}Container may have limited internet access. Installation will continue...${CL}"
else
msg_ok "Network in LXC is reachable (ping)"
post_progress_to_api # Signal network is ready
fi
fi
# Function to get correct GID inside container
@@ -4040,6 +4039,7 @@ EOF'
fi
msg_ok "Customized LXC Container"
post_progress_to_api # Signal ready for app installation
# Optional DNS override for retry scenarios (inside LXC, never on host)
if [[ "${DNS_RETRY_OVERRIDE:-false}" == "true" ]]; then
@@ -4064,15 +4064,8 @@ EOF'
# 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]}
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
local lxc_exit=$?
unset CONTAINER_INSTALLING
@@ -4130,17 +4123,7 @@ EOF'
# Copy and append INSTALL_LOG from container (with timeout to prevent hangs)
local temp_install_log="/tmp/.install-temp-${SESSION_ID}.log"
local container_log_ok=false
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log" "$temp_install_log" 2>/dev/null; then
# Only use container log if it has meaningful content (>100 bytes)
if [[ -s "$temp_install_log" ]] && [[ $(stat -c%s "$temp_install_log" 2>/dev/null || echo 0) -gt 100 ]]; then
container_log_ok=true
fi
fi
# PHASE 2: Use container-side log if available, otherwise use host-captured tee output
local _LXC_CAPTURE_LOG="/tmp/.install-capture-${SESSION_ID}.log"
if [[ "$container_log_ok" == true ]]; then
{
echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container)"
@@ -4148,25 +4131,9 @@ EOF'
cat "$temp_install_log"
echo ""
} >>"$combined_log"
rm -f "$temp_install_log"
install_log_copied=true
elif [[ -s "$_LXC_CAPTURE_LOG" ]]; then
# Fallback: host-captured terminal output from lxc-attach
# This captures everything the user saw, including errors when install.func
# failed to load (DNS issues, etc.) and no container-side logging was set up.
{
echo "================================================================================"
echo "PHASE 2: APPLICATION INSTALLATION (Container - captured from terminal)"
echo "================================================================================"
# Strip ANSI escape codes from terminal capture
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' "$_LXC_CAPTURE_LOG" | sed 's/\r$//'
echo ""
} >>"$combined_log"
install_log_copied=true
fi
rm -f "$temp_install_log"
if [[ "$install_log_copied" == true ]]; then
# Point INSTALL_LOG to combined log so get_full_log() finds it
# Point INSTALL_LOG to combined log so get_error_text() finds it
INSTALL_LOG="$combined_log"
fi
fi
@@ -4426,9 +4393,8 @@ EOF'
# Re-run install script in existing container (don't destroy/recreate)
set +Eeuo pipefail
trap - ERR
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 apt_retry_exit=${PIPESTATUS[0]}
lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/install/${var_install}.sh)"
local apt_retry_exit=$?
set -Eeuo pipefail
trap 'error_handler' ERR
@@ -4534,9 +4500,6 @@ EOF'
exit $install_exit_code
fi
# Clean up host-side capture log (not needed on success, already in combined_log on failure)
rm -f "/tmp/.install-capture-${SESSION_ID}.log" 2>/dev/null
# Re-enable error handling after successful install or recovery menu completion
set -Eeuo pipefail
trap 'error_handler' ERR
@@ -4947,9 +4910,6 @@ create_lxc_container() {
# Report installation start to API early - captures failures in storage/template/create
post_to_api
# Transition to 'validation' — Proxmox-internal checks (storage, template, cluster)
post_progress_to_api "validation"
# Storage capability check
check_storage_support "rootdir" || {
msg_error "No valid storage found for 'rootdir' [Container]"
@@ -5479,6 +5439,7 @@ create_lxc_container() {
}
msg_ok "LXC Container ${BL}$CTID${CL} ${GN}was successfully created."
post_progress_to_api # Signal container creation complete
}
# ==============================================================================

View File

@@ -488,7 +488,7 @@ log_section() {
# silent()
#
# - Executes command with output redirected to active log file
# - On error: displays last 20 lines of log and exits with original exit code
# - On error: displays last 10 lines of log and exits with original exit code
# - Temporarily disables error trap to capture exit code correctly
# - Sources explain_exit_code() for detailed error messages
# ------------------------------------------------------------------------------
@@ -530,8 +530,8 @@ silent() {
msg_custom "→" "${YWB}" "${cmd}"
if [[ -s "$logfile" ]]; then
echo -e "\n${TAB}--- Last 20 lines of log ---"
tail -n 20 "$logfile"
echo -e "\n${TAB}--- Last 10 lines of log ---"
tail -n 10 "$logfile"
echo -e "${TAB}-----------------------------------"
echo -e "${TAB}📋 Full log: ${logfile}\n"
fi
@@ -1505,7 +1505,7 @@ cleanup_lxc() {
fi
msg_ok "Cleaned"
# Send progress ping if available (defined in install.func)
if declare -f post_progress_to_api &>/dev/null; then
post_progress_to_api

View File

@@ -51,9 +51,7 @@ get_lxc_ip
# post_progress_to_api()
#
# - Lightweight progress ping from inside the container
# - Updates the existing telemetry record status
# - Arguments:
# * $1: status (optional, default: "configuring")
# - Updates the existing telemetry record status from "installing" to "configuring"
# - Signals that the installation is actively progressing (not stuck)
# - Fire-and-forget: never blocks or fails the script
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
@@ -63,11 +61,9 @@ post_progress_to_api() {
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
local progress_status="${1:-configuring}"
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
-H "Content-Type: application/json" \
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\"}" &>/dev/null || true
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
}
# ==============================================================================

View File

@@ -169,7 +169,7 @@ get_active_logfile() {
# silent()
#
# - Executes command with output redirected to active log file
# - On error: displays last 20 lines of log and exits with original exit code
# - On error: displays last 10 lines of log and exits with original exit code
# - Temporarily disables error trap to capture exit code correctly
# - Sources explain_exit_code() for detailed error messages
# ------------------------------------------------------------------------------
@@ -207,8 +207,8 @@ silent() {
msg_custom "→" "${YWB}" "${cmd}"
if [[ -s "$logfile" ]]; then
echo -e "\n${TAB}--- Last 20 lines of log ---"
tail -n 20 "$logfile"
echo -e "\n${TAB}--- Last 10 lines of log ---"
tail -n 10 "$logfile"
echo -e "${TAB}----------------------------\n"
fi