Compare commits

...

51 Commits

Author SHA1 Message Date
github-actions[bot]
037d977c4a Update CHANGELOG.md 2026-02-07 19:44:37 +00:00
CanbiZ (MickLesk)
173aaeeb06 NocoDB: pin to v0.301.1 (#11655)
* Pin NocoDB to version 0.301.1 due to ipaddr.js module error in 0.301.2

* Pin NocoDB version to 0.301.1 in github-versions.json

* Remove version pin note from nocodb.json (handled in github-versions.json)

* Add version pin to check_for_gh_release in NocoDB CT

Prevents the update check from looking for versions newer than 0.301.1
2026-02-07 20:44:17 +01:00
community-scripts-pr-app[bot]
b900f90bab Update CHANGELOG.md (#11666)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 19:38:18 +00:00
CanbiZ (MickLesk)
e70de7d95f feat(tools): fallback to previous release when asset is missing (#11660)
When fetch_and_deploy_gh_release fails to find a matching asset in the
target release (binary/prebuild/singlefile modes), scan up to 15 older
releases for a compatible asset. Prompts the user with a 60s timeout
(default: yes) before using the fallback version.

Addresses issues like SigNoz #11652 where the latest release has no
matching OTel collector binary.
2026-02-07 20:37:50 +01:00
community-scripts-pr-app[bot]
493371423e Update CHANGELOG.md (#11664)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 18:45:07 +00:00
ls-root
e27dc1cebb fix(setup): correctly auto-detect username when using --full (#11650)
Argument parsing prevented auto-detection from running when --full
was supplied without an explicit username. After shifting --full,
no positional arguments remained, but the script had already skipped
the auto-detection branch, leaving USERNAME empty and causing the
script to abort.
2026-02-07 19:44:47 +01:00
community-scripts-pr-app[bot]
fd7095a133 Update CHANGELOG.md (#11663)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 18:42:21 +00:00
community-scripts-pr-app[bot]
f752bebad3 Update CHANGELOG.md (#11662)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 18:41:58 +00:00
CanbiZ (MickLesk)
263cbbeb86 Pin Memos to v0.25.3 - last version with release binaries (#11658)
* Pin Memos to v0.25.3 - last version with release binaries

v0.26.0 removed release binaries (issue usememos/memos#5552)
Pinning to v0.25.3 (Nov 25, 2025) which has 7 binary assets available

This is a temporary solution until v0.27.0 releases with binaries
as indicated by MickLesk in issue #11474

* Pin Memos scripts to v0.25.3 instead of latest

Both CT update script and install script now explicitly use v0.25.3
instead of 'latest' to ensure binaries are available

* Add version pin to check_for_gh_release in Memos CT

Prevents the update check from looking for versions newer than v0.25.3
2026-02-07 19:41:55 +01:00
CanbiZ (MickLesk)
48d743910a Downgrade: OpenProject | NginxProxyManager | Semaphore to Debian 12 due to persistent SHA1 issues (#11654)
* Downgrade OpenProject and NginxProxyManager to Debian 12 due to SHA1 signature issues

* Downgrade Semaphore to Debian 12 due to SHA1 signature issues in Ansible PPA
2026-02-07 19:41:37 +01:00
community-scripts-pr-app[bot]
2763664e08 Update CHANGELOG.md (#11661)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 18:36:54 +00:00
ls-root
a524431c0e feat(frontend): add JSON script import functionality (#11563)
Allow users to import scripts into the JSON editor via local file
upload or by selecting from the existing script library.

- Dropdown toggle for 'Local' and 'Library' import sources.
- Script selection dialog with category and search filters.
- Global search using the existing command menu logic.
2026-02-07 19:36:32 +01:00
community-scripts-pr-app[bot]
2c39cab0c1 chore: update github-versions.json (#11659)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 18:08:11 +00:00
community-scripts-pr-app[bot]
8dca8d2041 chore: update github-versions.json (#11649)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 12:07:47 +00:00
community-scripts-pr-app[bot]
ee599030cf chore: update github-versions.json (#11647)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 06:14:04 +00:00
community-scripts-pr-app[bot]
599eb4652f Update CHANGELOG.md (#11645)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 00:21:31 +00:00
community-scripts-pr-app[bot]
84bfd4549e chore: update github-versions.json (#11644)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-07 00:21:11 +00:00
community-scripts-pr-app[bot]
6175e7af57 Update CHANGELOG.md (#11641)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 19:58:07 +00:00
Chris
aa1350d126 Immich: supress startup messages for immich-admin (#11635) 2026-02-06 20:57:43 +01:00
community-scripts-pr-app[bot]
5965023d16 Update CHANGELOG.md (#11640)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 19:55:58 +00:00
Chris
bb0188b38c [Fix] build.func: QOL grammar adjustment for Creating LXC message (#11633) 2026-02-06 20:55:35 +01:00
community-scripts-pr-app[bot]
46cf374426 Update .app files (#11637)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-06 20:48:18 +01:00
community-scripts-pr-app[bot]
2eb263c314 Update CHANGELOG.md (#11639)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 19:44:28 +00:00
community-scripts-pr-app[bot]
5d95a35980 Update CHANGELOG.md (#11638)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 19:44:09 +00:00
community-scripts-pr-app[bot]
ccb27cd7ab Update date in json (#11636)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-06 19:44:03 +00:00
push-app-to-main[bot]
523ece1558 Nightscout (#11621)
* Add nightscout (ct)

* Change fetch_and_deploy_gh_release to use tarball

* Modify date_created and logo in nightscout.json

Updated the creation date and logo URL for Nightscout.

* Change fetch method from source to tarball

* Update nightscout.json

---------

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>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-02-06 20:43:40 +01:00
community-scripts-pr-app[bot]
d3d2b0d85e chore: update github-versions.json (#11634)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 18:16:41 +00:00
community-scripts-pr-app[bot]
650ef64649 Update CHANGELOG.md (#11632)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:59:13 +00:00
ls-root
ef8449e4da fix(core): spinner misalignment (#11627) 2026-02-06 17:58:50 +01:00
community-scripts-pr-app[bot]
d6b6057cdc Update CHANGELOG.md (#11631)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:58:32 +00:00
CanbiZ (MickLesk)
9c9771f684 Semaphore: Change Ubuntu release from 'jammy' to 'noble' (#11625) 2026-02-06 17:58:03 +01:00
community-scripts-pr-app[bot]
465af25e00 Update CHANGELOG.md (#11630)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:57:49 +00:00
community-scripts-pr-app[bot]
e39ac43553 Update CHANGELOG.md (#11629)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:57:21 +00:00
Chris
da0dfc9c7e Update LXC App Updater JSON to reflect tag override option (#11626) 2026-02-06 17:56:45 +01:00
community-scripts-pr-app[bot]
f96892bf1d Update CHANGELOG.md (#11628)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:28:39 +00:00
Chris
7973216438 Immich: pin to v2.5.5 (#11598)
* Use uppercase

* Immich: pin version to 2.5.4

* Restart immich-proxy service after update if found

* Pin version to 2.5.5
2026-02-06 17:28:15 +01:00
community-scripts-pr-app[bot]
5b01899434 Update CHANGELOG.md (#11624)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 15:02:17 +00:00
Chris
c20923136c Shelfmark: remove Chromedriver dep, add URL_BASE env (#11619) 2026-02-06 16:01:48 +01:00
community-scripts-pr-app[bot]
b8f4a722cb Update CHANGELOG.md (#11623)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 15:01:44 +00:00
Chris
c296b9d985 Opencloud: fix JSON (#11617) 2026-02-06 16:01:16 +01:00
community-scripts-pr-app[bot]
3eadc02a3d Update CHANGELOG.md (#11618)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 13:26:15 +00:00
CanbiZ (MickLesk)
70c9df24d9 Pangolin: replace build:sqlite with db:generate + build (#11616)
* Replace build:sqlite with db:generate + build

Update build flow in ct/pangolin.sh and install/pangolin-install.sh to use `npm run db:generate` followed by `npm run build` instead of the old `npm run build:sqlite`. Also normalize a DB generation invocation by replacing `npm run db:sqlite:generate` with `npm run db:generate` in the installer. These changes consolidate DB generation and use the standard build step.

* Update pangolin-install.sh

* db push on update
2026-02-06 14:25:44 +01:00
community-scripts-pr-app[bot]
15397e1bbe chore: update github-versions.json (#11615)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 12:12:05 +00:00
community-scripts-pr-app[bot]
bb561172cf Update CHANGELOG.md (#11614)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 11:12:20 +00:00
Slaviša Arežina
eecff9db6b [gh] Update to the New Script request template (#11612) 2026-02-06 12:11:51 +01:00
community-scripts-pr-app[bot]
f5558638b0 Update CHANGELOG.md (#11609)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 07:56:10 +00:00
Tobias
f233c476b6 refactor: homepage (#11605) 2026-02-06 08:55:47 +01:00
community-scripts-pr-app[bot]
bdd7c0f6f1 Update CHANGELOG.md (#11608)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 07:55:12 +00:00
community-scripts-pr-app[bot]
c67a5a157c Update CHANGELOG.md (#11607)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 07:54:50 +00:00
community-scripts-pr-app[bot]
ac3732db2f Update date in json (#11606)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-06 07:54:44 +00:00
CanbiZ (MickLesk)
2af418c729 PVE LXC Apps Updater (#11533)
* Add PVE LXC Apps Updater script and metadata

Add a new Proxmox LXC Apps Updater: frontend/public/json/update-apps.json registers the app for the UI (install script points to tools/pve/update-apps.sh) and provides documentation/notes for usage and environment variables. Add tools/pve/update-apps.sh (MIT, authors noted) — a full-featured updater for community-scripts managed LXC containers that supports interactive Whiptail selection or environment-driven automation (var_backup, var_backup_storage, var_container, var_unattended, var_skip_confirm, var_auto_reboot). Features include exportable JSON config, optional vzdump backups, detection of service/update script from the community repo, temporary CPU/RAM adjustments for build requirements, unattended update mode, restore-from-backup on failure, and reporting/optional reboot of containers that require it.

* Fix source command syntax in update-apps.sh

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

* Update tools/pve/update-apps.sh

Co-authored-by: Chris <punk.sand7393@fastmail.com>

---------

Co-authored-by: Chris <punk.sand7393@fastmail.com>
2026-02-06 08:54:21 +01:00
35 changed files with 1230 additions and 78 deletions

View File

@@ -32,6 +32,8 @@ body:
required: true
- label: "The application requested has 600+ stars on Github (if applicable), is older than 6 months, actively maintained and has release tarballs published."
required: true
- label: "I understand that not all applications will be accepted due to various reasons and criteria by the community-scripts ORG."
required: true
- type: markdown
attributes:
value: "Thanks for submitting your request! The team will review it and reach out if we need more information."

View File

@@ -398,15 +398,82 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-02-06
## 2026-02-07
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- NocoDB: pin to v0.301.1 [@MickLesk](https://github.com/MickLesk) ([#11655](https://github.com/community-scripts/ProxmoxVE/pull/11655))
- Pin Memos to v0.25.3 - last version with release binaries [@MickLesk](https://github.com/MickLesk) ([#11658](https://github.com/community-scripts/ProxmoxVE/pull/11658))
- Downgrade: OpenProject | NginxProxyManager | Semaphore to Debian 12 due to persistent SHA1 issues [@MickLesk](https://github.com/MickLesk) ([#11654](https://github.com/community-scripts/ProxmoxVE/pull/11654))
### 💾 Core
- #### ✨ New Features
- tools: fallback to previous release when asset is missing [@MickLesk](https://github.com/MickLesk) ([#11660](https://github.com/community-scripts/ProxmoxVE/pull/11660))
### 📚 Documentation
- fix(setup): correctly auto-detect username when using --full [@ls-root](https://github.com/ls-root) ([#11650](https://github.com/community-scripts/ProxmoxVE/pull/11650))
### 🌐 Website
- #### ✨ New Features
- feat(frontend): add JSON script import functionality [@ls-root](https://github.com/ls-root) ([#11563](https://github.com/community-scripts/ProxmoxVE/pull/11563))
## 2026-02-06
### 🆕 New Scripts
- Nightscout ([#11621](https://github.com/community-scripts/ProxmoxVE/pull/11621))
- PVE LXC Apps Updater [@MickLesk](https://github.com/MickLesk) ([#11533](https://github.com/community-scripts/ProxmoxVE/pull/11533))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: supress startup messages for immich-admin [@vhsdream](https://github.com/vhsdream) ([#11635](https://github.com/community-scripts/ProxmoxVE/pull/11635))
- Semaphore: Change Ubuntu release from 'jammy' to 'noble' [@MickLesk](https://github.com/MickLesk) ([#11625](https://github.com/community-scripts/ProxmoxVE/pull/11625))
- Pangolin: replace build:sqlite with db:generate + build [@MickLesk](https://github.com/MickLesk) ([#11616](https://github.com/community-scripts/ProxmoxVE/pull/11616))
- [FIX] OpenCloud: path issues [@vhsdream](https://github.com/vhsdream) ([#11593](https://github.com/community-scripts/ProxmoxVE/pull/11593))
- [FIX] Homepage: preserve public/images & public/icons if they exist [@vhsdream](https://github.com/vhsdream) ([#11594](https://github.com/community-scripts/ProxmoxVE/pull/11594))
- #### ✨ New Features
- Shelfmark: remove Chromedriver dep, add URL_BASE env [@vhsdream](https://github.com/vhsdream) ([#11619](https://github.com/community-scripts/ProxmoxVE/pull/11619))
- Immich: pin to v2.5.5 [@vhsdream](https://github.com/vhsdream) ([#11598](https://github.com/community-scripts/ProxmoxVE/pull/11598))
- #### 🔧 Refactor
- refactor: homepage [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11605](https://github.com/community-scripts/ProxmoxVE/pull/11605))
### 💾 Core
- #### 🐞 Bug Fixes
- fix(core): spinner misalignment [@ls-root](https://github.com/ls-root) ([#11627](https://github.com/community-scripts/ProxmoxVE/pull/11627))
- #### 🔧 Refactor
- [Fix] build.func: QOL grammar adjustment for Creating LXC message [@vhsdream](https://github.com/vhsdream) ([#11633](https://github.com/community-scripts/ProxmoxVE/pull/11633))
### 📚 Documentation
- [gh] Update to the New Script request template [@tremor021](https://github.com/tremor021) ([#11612](https://github.com/community-scripts/ProxmoxVE/pull/11612))
### 🌐 Website
- #### 📝 Script Information
- Update LXC App Updater JSON to reflect tag override option [@vhsdream](https://github.com/vhsdream) ([#11626](https://github.com/community-scripts/ProxmoxVE/pull/11626))
### ❔ Uncategorized
- Opencloud: fix JSON [@vhsdream](https://github.com/vhsdream) ([#11617](https://github.com/community-scripts/ProxmoxVE/pull/11617))
## 2026-02-05
### 🆕 New Scripts

6
ct/headers/nightscout Normal file
View File

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

View File

@@ -28,7 +28,6 @@ function update_script() {
exit
fi
get_lxc_ip
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
ensure_dependencies jq
@@ -37,14 +36,20 @@ function update_script() {
systemctl stop homepage
msg_ok "Stopped service"
msg_info "Creating Backup"
cp /opt/homepage/.env /opt/homepage.env
cp -r /opt/homepage/config /opt/homepage_config_backup
[[ -d /opt/homepage/public/images ]] && cp -r /opt/homepage/public/images /opt/homepage_images_backup
[[ -d /opt/homepage/public/icons ]] && cp -r /opt/homepage/public/icons /opt/homepage_icons_backup
msg_ok "Created Backup"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homepage" "gethomepage/homepage" "tarball"
msg_info "Restoring Backup"
mv /opt/homepage.env /opt/homepage
rm -rf /opt/homepage/config
mv /opt/homepage_config_backup /opt/homepage/config
msg_ok "Restored Backup"
msg_info "Updating Homepage (Patience)"
RELEASE=$(get_latest_github_release "gethomepage/homepage")

View File

@@ -105,8 +105,8 @@ EOF
msg_ok "Image-processing libraries up to date"
fi
RELEASE="2.5.3"
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
RELEASE="2.5.5"
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
cd /opt/immich/app/bin
@@ -140,7 +140,7 @@ EOF
GEO_DIR="${INSTALL_DIR}/geodata"
[[ -f "$ML_DIR"/ml_start.sh ]] && cp "$ML_DIR"/ml_start.sh "$INSTALL_DIR"
if grep -qs "set -a" "$APP_DIR"/bin/start.sh; then
if grep -qs "set -a" "$APP_DIR"/bin/start.sh && grep -qs "warnings" "$APP_DIR"/bin/start.sh; then
cp "$APP_DIR"/bin/start.sh "$INSTALL_DIR"
else
cat <<EOF >"$INSTALL_DIR"/start.sh
@@ -150,7 +150,7 @@ set -a
. ${INSTALL_DIR}/.env
set +a
/usr/bin/node ${APP_DIR}/dist/main.js "\$@"
/usr/bin/node --no-warnings ${APP_DIR}/dist/main.js "\$@"
EOF
chmod +x "$INSTALL_DIR"/start.sh
fi
@@ -161,7 +161,7 @@ EOF
)
setup_uv
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v${RELEASE}" "$SRC_DIR"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v${RELEASE}" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
@@ -248,6 +248,7 @@ EOF
msg_ok "Disabled Maintenance Mode"
fi
systemctl restart immich-ml immich-web
[[ -f /etc/systemd/system/immich-proxy.service ]] && systemctl restart immich-proxy
msg_ok "Updated successfully!"
fi
exit

View File

@@ -27,12 +27,12 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "memos" "usememos/memos"; then
if check_for_gh_release "memos" "usememos/memos" "v0.25.3"; then
msg_info "Stopping service"
systemctl stop memos
msg_ok "Service stopped"
fetch_and_deploy_gh_release "memos" "usememos/memos" "prebuild" "latest" "/opt/memos" "memos*linux_amd64.tar.gz"
fetch_and_deploy_gh_release "memos" "usememos/memos" "prebuild" "v0.25.3" "/opt/memos" "memos*linux_amd64.tar.gz"
msg_info "Starting service"
systemctl start memos

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"

58
ct/nightscout.sh Normal file
View File

@@ -0,0 +1,58 @@
#!/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: aendel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/nightscout/cgm-remote-monitor
APP="Nightscout"
var_tags="${var_tags:-health}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
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/nightscout ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "nightscout" "nightscout/cgm-remote-monitor"; then
msg_info "Stopping Service"
systemctl stop nightscout
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "nightscout" "nightscout/cgm-remote-monitor" "tarball"
msg_info "Updating Nightscout"
cd /opt/nightscout
$STD npm install
msg_ok "Updated Nightscout"
msg_info "Starting Service"
systemctl start nightscout
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:1337${CL}"

View File

@@ -27,12 +27,12 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "nocodb" "nocodb/nocodb"; then
if check_for_gh_release "nocodb" "nocodb/nocodb" "0.301.1"; then
msg_info "Stopping Service"
systemctl stop nocodb
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "latest" "/opt/nocodb/" "Noco-linux-x64"
fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "0.301.1" "/opt/nocodb/" "Noco-linux-x64"
msg_info "Starting Service"
systemctl start nocodb

View File

@@ -11,7 +11,7 @@ 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_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"

View File

@@ -48,8 +48,10 @@ function update_script() {
$STD npm run set:sqlite
$STD npm run set:oss
rm -rf server/private
$STD npm run build:sqlite
$STD npm run db:generate
$STD npm run build
$STD npm run build:cli
$STD npm run db:sqlite:push
cp -R .next/standalone ./
chmod +x ./dist/cli.mjs
cp server/db/names.json ./dist/names.json

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"

View File

@@ -42,16 +42,19 @@ function update_script() {
msg_info "Stopping FlareSolverr service"
systemctl stop flaresolverr
msg_ok "Stopped FlareSolverr service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "prebuild" "latest" "/opt/flaresolverr" "flaresolverr_linux_x64.tar.gz"
msg_info "Starting FlareSolverr Service"
systemctl start flaresolverr
msg_ok "Started FlareSolverr Service"
msg_ok "Updated FlareSolverr"
fi
cp /opt/shelfmark/start.sh /opt/start.sh.bak
if command -v chromedriver &>/dev/null; then
$STD apt remove -y chromium-driver
fi
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "shelfmark" "calibrain/shelfmark" "tarball" "latest" "/opt/shelfmark"
RELEASE_VERSION=$(cat "$HOME/.shelfmark")

View File

@@ -237,7 +237,6 @@ if [[ $# -gt 0 ]]; then
# Check for --full flag
if [[ "$1" == "--full" ]]; then
UPDATE_ALL=true
AUTO_DETECT=true
shift # Remove --full from arguments
fi
@@ -250,8 +249,10 @@ if [[ $# -gt 0 ]]; then
REPO_NAME="$2"
fi
fi
else
# Try auto-detection
fi
# Try auto-detection
if [[ -z "$USERNAME" ]]; then
if username=$(detect_username); then
USERNAME="$username"
print_success "Detected GitHub username: $USERNAME"
@@ -261,14 +262,15 @@ else
echo " ./setup-fork.sh YOUR_USERNAME"
exit 1
fi
fi
if repo_name=$(detect_repo_name); then
REPO_NAME="$repo_name"
if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then
print_info "Detected custom repo name: $REPO_NAME"
else
print_success "Using default repo name: ProxmoxVE"
fi
# Auto-detect repo name if needed
if repo_name=$(detect_repo_name); then
REPO_NAME="$repo_name"
if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then
print_info "Detected custom repo name: $REPO_NAME"
else
print_success "Using default repo name: ProxmoxVE"
fi
fi

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-06T06:19:41Z",
"generated": "2026-02-07T18:08:02Z",
"versions": [
{
"slug": "2fauth",
@@ -256,9 +256,9 @@
{
"slug": "docmost",
"repo": "docmost/docmost",
"version": "v0.25.1",
"version": "v0.25.2",
"pinned": false,
"date": "2026-02-04T15:19:51Z"
"date": "2026-02-06T19:50:55Z"
},
{
"slug": "domain-locker",
@@ -326,9 +326,9 @@
{
"slug": "firefly",
"repo": "firefly-iii/firefly-iii",
"version": "v6.4.16",
"version": "v6.4.17",
"pinned": false,
"date": "2026-01-17T07:54:15Z"
"date": "2026-02-07T06:56:00Z"
},
{
"slug": "fladder",
@@ -480,9 +480,9 @@
{
"slug": "homarr",
"repo": "homarr-labs/homarr",
"version": "v1.52.0",
"version": "v1.53.0",
"pinned": false,
"date": "2026-01-30T19:41:22Z"
"date": "2026-02-06T19:42:58Z"
},
{
"slug": "homebox",
@@ -515,9 +515,9 @@
{
"slug": "huntarr",
"repo": "plexguide/Huntarr.io",
"version": "9.2.1",
"version": "9.2.3",
"pinned": false,
"date": "2026-02-05T16:39:35Z"
"date": "2026-02-07T04:44:20Z"
},
{
"slug": "inspircd",
@@ -543,9 +543,9 @@
{
"slug": "jackett",
"repo": "Jackett/Jackett",
"version": "v0.24.1044",
"version": "v0.24.1060",
"pinned": false,
"date": "2026-02-06T05:55:31Z"
"date": "2026-02-07T05:55:27Z"
},
{
"slug": "joplin-server",
@@ -774,16 +774,16 @@
{
"slug": "memos",
"repo": "usememos/memos",
"version": "v0.26.0",
"pinned": false,
"date": "2026-01-31T15:28:09Z"
"version": "v0.25.3",
"pinned": true,
"date": "2025-11-25T00:00:00Z"
},
{
"slug": "metube",
"repo": "alexta69/metube",
"version": "2026.02.04",
"version": "2026.02.07",
"pinned": false,
"date": "2026-02-04T20:01:18Z"
"date": "2026-02-07T16:24:37Z"
},
{
"slug": "miniflux",
@@ -841,11 +841,18 @@
"pinned": false,
"date": "2025-12-09T09:47:15Z"
},
{
"slug": "nightscout",
"repo": "nightscout/cgm-remote-monitor",
"version": "15.0.3",
"pinned": false,
"date": "2025-05-08T22:12:34Z"
},
{
"slug": "nocodb",
"repo": "nocodb/nocodb",
"version": "0.301.2",
"pinned": false,
"version": "0.301.1",
"pinned": true,
"date": "2026-01-21T16:23:04Z"
},
{
@@ -1110,9 +1117,9 @@
{
"slug": "pulse",
"repo": "rcourtman/Pulse",
"version": "v5.1.2",
"version": "v5.1.3",
"pinned": false,
"date": "2026-02-05T00:18:57Z"
"date": "2026-02-07T14:59:29Z"
},
{
"slug": "pve-scripts-local",
@@ -1250,9 +1257,9 @@
{
"slug": "signoz",
"repo": "SigNoz/signoz-otel-collector",
"version": "v0.129.13",
"version": "v0.142.0",
"pinned": false,
"date": "2026-01-27T15:43:00Z"
"date": "2026-02-06T11:40:30Z"
},
{
"slug": "silverbullet",
@@ -1306,9 +1313,9 @@
{
"slug": "stirling-pdf",
"repo": "Stirling-Tools/Stirling-PDF",
"version": "v2.4.4",
"version": "v2.4.5",
"pinned": false,
"date": "2026-02-05T00:15:53Z"
"date": "2026-02-06T23:12:20Z"
},
{
"slug": "streamlink-webui",
@@ -1425,9 +1432,9 @@
{
"slug": "trip",
"repo": "itskovacs/TRIP",
"version": "1.38.1",
"version": "1.39.0",
"pinned": false,
"date": "2026-02-04T18:10:15Z"
"date": "2026-02-07T16:59:51Z"
},
{
"slug": "tududi",
@@ -1481,9 +1488,9 @@
{
"slug": "uptimekuma",
"repo": "louislam/uptime-kuma",
"version": "2.0.2",
"version": "2.1.0",
"pinned": false,
"date": "2025-10-22T17:03:54Z"
"date": "2026-02-07T02:31:49Z"
},
{
"slug": "vaultwarden",
@@ -1607,9 +1614,9 @@
{
"slug": "yubal",
"repo": "guillevc/yubal",
"version": "v4.0.0",
"version": "v0.4.0",
"pinned": false,
"date": "2026-02-05T22:42:02Z"
"date": "2026-02-06T21:25:24Z"
},
{
"slug": "zigbee2mqtt",

View File

@@ -25,7 +25,7 @@
"ram": 2048,
"hdd": 8,
"os": "debian",
"version": "13"
"version": "12"
}
}
],

View File

@@ -0,0 +1,52 @@
{
"name": "Nightscout",
"slug": "nightscout",
"categories": [
0
],
"date_created": "2026-02-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 1337,
"documentation": "https://nightscout.github.io/",
"website": "http://www.nightscout.info/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/nightscout.webp",
"config_path": "/opt/nightscout/my.env",
"description": "Nightscout is an open source, DIY project that allows real time access to a CGM data via personal website, smartwatch watchers, or apps and widgets available for smartphones.",
"install_methods": [
{
"type": "default",
"script": "ct/nightscout.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 10,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Nightscout requires configuring `my.env` with your Mongo connection string. API_SECRET has been generated and saved to `~/nightscout.creds`.",
"type": "info"
},
{
"text": "Edit `/opt/nightscout/my.env` to configure your CGM source (Dexcom/CareLink). Then run: `systemctl restart nightscout`",
"type": "info"
},
{
"text": "Official Configuration Guide: https://nightscout.github.io/nightscout/setup_variables/",
"type": "info"
},
{
"text": "Nightscout requires HTTPS for many features (security, tokens, PWA). Usage of a reverse proxy (e.g. Nginx Proxy Manager, Traefik, Caddy) is highly recommended.",
"type": "warning"
}
]
}

View File

@@ -41,15 +41,15 @@
"type": "info"
},
{
"text": "**Optional External Apps**: extract zip archives from App Store to `/etc/opencloud/assets/apps`",
"text": "**Optional External Apps**: extract zip archives from App Store to `/etc/opencloud/web/assets/apps`",
"type": "info"
},
{
"text": "**Optional CalDAV and CardDAV**: requires separate Radicale install. Edit and rename `/opt/opencloud/proxy.yaml.bak` and change your Radicale config to use `http_x_remote_user` as the auth method",
"text": "**Optional CalDAV and CardDAV**: requires separate Radicale install. Edit and rename `/etc/opencloud/proxy.yaml.bak` and change your Radicale config to use `http_x_remote_user` as the auth method",
"type": "info"
},
{
"text": "**Optional OpenID**: Authelia and PocketID supported. Uncomment relevant lines in `/opt/opencloud/opencloud.env` and consult OpenCloud GitHub discussions for configuration tips",
"text": "**Optional OpenID**: Authelia and PocketID supported. Uncomment relevant lines in `/etc/opencloud/opencloud.env` and consult OpenCloud GitHub discussions for configuration tips",
"type": "info"
},
{

View File

@@ -23,7 +23,7 @@
"ram": 4096,
"hdd": 8,
"os": "Debian",
"version": "13"
"version": "12"
}
}
],

View File

@@ -23,7 +23,7 @@
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
"version": "12"
}
}
],

View File

@@ -35,6 +35,10 @@
{
"text": "The configuration at `/etc/shelfmark/.env` is for bootstrapping the initial install. Customize the configuration via the Shelfmark UI.",
"type": "info"
},
{
"text": "This version of the application does not support routing through Tor (the `USING_TOR` env var).",
"type": "info"
}
]
}

View File

@@ -0,0 +1,84 @@
{
"name": "PVE LXC Apps Updater",
"slug": "update-apps",
"categories": [
1
],
"date_created": "2026-02-06",
"type": "pve",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://github.com/community-scripts/ProxmoxVE/discussions/11532",
"website": null,
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/proxmox.webp",
"config_path": "",
"description": "This script updates community-scripts managed LXC containers on a Proxmox VE node. It detects the installed service, verifies available update scripts, and applies updates interactively or unattended. Optionally, containers can be backed up before the update process. If additional build resources (CPU/RAM) are required, the script adjusts container resources temporarily and restores them after the update. Containers requiring a reboot will be listed at the end of the process.",
"install_methods": [
{
"type": "default",
"script": "tools/pve/update-apps.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Execute within the Proxmox shell.",
"type": "info"
},
{
"text": "Full Guide can be found here: `https://github.com/community-scripts/ProxmoxVE/discussions/11532`",
"type": "info"
},
{
"text": "By default, only containers with `community-script` or `proxmox-helper-scripts` tags are listed for update. You can override this by using `var_tags='custom-tag|othertag'`.",
"type": "info"
},
{
"text": "Optionally performs a vzdump backup before updating containers.",
"type": "warning"
},
{
"text": "If required, the script will temporarily increase container CPU/RAM resources for the build process and restore them after completion.",
"type": "info"
},
{
"text": "At the end of the update, containers requiring a reboot will be listed, and you may choose to reboot them directly.",
"type": "info"
},
{
"text": "Use `var_backup=yes|no` to enable/disable backup (skip prompt).",
"type": "info"
},
{
"text": "Use `var_backup_storage=<name>` to set backup storage location.",
"type": "info"
},
{
"text": "Use `var_container=all|all_running|all_stopped|101,102,...` to select containers.",
"type": "info"
},
{
"text": "Use `var_unattended=yes|no` to run updates without interaction.",
"type": "info"
},
{
"text": "Use `var_skip_confirm=yes` to skip initial confirmation dialog.",
"type": "info"
},
{
"text": "Use `var_auto_reboot=yes|no` to auto-reboot containers after update.",
"type": "info"
}
]
}

View File

@@ -32,6 +32,11 @@ import Note from "./_components/note";
import { githubGist, nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
import SyntaxHighlighter from "react-syntax-highlighter";
import { ScriptItem } from "../scripts/_components/script-item";
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { search } from "@/components/command-menu";
import { basePath } from "@/config/site-config";
import Image from "next/image";
import { useTheme } from "next-themes";
const initialScript: Script = {
@@ -65,8 +70,35 @@ export default function JSONGenerator() {
const [isValid, setIsValid] = useState(false);
const [categories, setCategories] = useState<Category[]>([]);
const [currentTab, setCurrentTab] = useState<"json" | "preview">("json");
const [selectedCategory, setSelectedCategory] = useState<string>("");
const [searchQuery, setSearchQuery] = useState<string>("");
const [isImportDialogOpen, setIsImportDialogOpen] = useState(false);
const [zodErrors, setZodErrors] = useState<z.ZodError | null>(null);
const selectedCategoryObj = useMemo(
() => categories.find(cat => cat.id.toString() === selectedCategory),
[categories, selectedCategory]
);
const allScripts = useMemo(
() => categories.flatMap(cat => cat.scripts || []),
[categories]
);
const scripts = useMemo(() => {
const query = searchQuery.trim()
if (query) {
return search(allScripts, query)
}
if (selectedCategoryObj) {
return selectedCategoryObj.scripts || []
}
return []
}, [allScripts, selectedCategoryObj, searchQuery]);
useEffect(() => {
fetchCategories()
.then(setCategories)
@@ -120,6 +152,53 @@ export default function JSONGenerator() {
if (isValid) toast.success("Copied metadata to clipboard");
}, [script]);
const importScript = (script: Script) => {
try {
const result = ScriptSchema.safeParse(script);
if (!result.success) {
setIsValid(false);
setZodErrors(result.error);
toast.error("Imported JSON is invalid according to the schema.");
return;
}
setScript(result.data);
setIsValid(true);
setZodErrors(null);
toast.success("Imported JSON successfully");
} catch (error) {
toast.error("Failed to read or parse the JSON file.");
}
}
const handleFileImport = useCallback(() => {
const input = document.createElement("input");
input.type = "file";
input.accept = "application/json";
input.onchange = (e: Event) => {
const target = e.target as HTMLInputElement;
const file = target.files?.[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
try {
const content = event.target?.result as string;
const parsed = JSON.parse(content);
importScript(parsed);
toast.success("Imported JSON successfully");
} catch (error) {
toast.error("Failed to read the JSON file.");
}
};
reader.readAsText(file);
};
input.click();
}, [setScript]);
const handleDownload = useCallback(() => {
if (isValid === false) {
toast.error("Cannot download invalid JSON");
@@ -177,7 +256,94 @@ export default function JSONGenerator() {
return (
<div className="flex h-screen mt-20">
<div className="w-1/2 p-4 overflow-y-auto">
<h2 className="text-2xl font-bold mb-4">JSON Generator</h2>
<div className="flex justify-between items-center mb-4">
<h2 className="text-2xl font-bold">JSON Generator</h2>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button>Import</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-52" align="start">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={handleFileImport}>Import local JSON file</DropdownMenuItem>
<Dialog
open={isImportDialogOpen}
onOpenChange={setIsImportDialogOpen}
>
<DialogTrigger asChild>
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
Import existing script
</DropdownMenuItem>
</DialogTrigger>
<DialogContent className="sm:max-w-md w-full">
<DialogHeader>
<DialogTitle>Import existing script</DialogTitle>
<DialogDescription>
Select one of the puplished scripts to import its metadata.
</DialogDescription>
</DialogHeader>
<div className="flex items-center gap-2">
<div className="grid flex-1 gap-2">
<Select
value={selectedCategory}
onValueChange={setSelectedCategory}
>
<SelectTrigger>
<SelectValue placeholder="Category" />
</SelectTrigger>
<SelectContent>
{categories.map((category) => (
<SelectItem key={category.id} value={category.id.toString()}>
{category.name}
</SelectItem>
))}
</SelectContent>
</Select>
<Input
placeholder="Search for a script..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
{!selectedCategory && !searchQuery ? (
<p className="text-muted-foreground text-sm text-center">
Select a category or search for a script
</p>
) : scripts.length === 0 ? (
<p className="text-muted-foreground text-sm text-center">
No scripts found
</p>
) : (
<div className="grid grid-cols-3 auto-rows-min h-64 overflow-y-auto gap-4">
{scripts.map(script => (
<div
key={script.slug}
className="p-2 border rounded cursor-pointer hover:bg-accent hover:text-accent-foreground"
onClick={() => {
importScript(script);
setIsImportDialogOpen(false);
}}
>
<Image
src={script.logo || `/${basePath}/logo.png`}
alt={script.name}
className="w-full h-12 object-contain mb-2"
width={16}
height={16}
unoptimized
/>
<p className="text-sm text-center">{script.name}</p>
</div>
))}
</div>
)}
</div>
</div>
</DialogContent>
</Dialog>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</div>
<form className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>

View File

@@ -23,7 +23,7 @@ import { Button } from "./ui/button";
import { Badge } from "./ui/badge";
import Link from "next/link";
function search(scripts: Script[], query: string): Script[] {
export function search(scripts: Script[], query: string): Script[] {
const queryLower = query.toLowerCase().trim();
const searchWords = queryLower.split(/\s+/).filter(Boolean);

View File

@@ -289,7 +289,7 @@ ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.3" "$SRC_DIR"
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v2.5.5" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
@@ -424,7 +424,7 @@ set -a
. ${INSTALL_DIR}/.env
set +a
/usr/bin/node ${APP_DIR}/dist/main.js "\$@"
/usr/bin/node --no-warnings ${APP_DIR}/dist/main.js "\$@"
EOF
chmod +x "$ML_DIR"/ml_start.sh "$APP_DIR"/bin/start.sh
ln -sf "$APP_DIR"/cli/bin/immich /usr/bin/immich

View File

@@ -14,7 +14,7 @@ setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "memos" "usememos/memos" "prebuild" "latest" "/opt/memos" "memos*linux_amd64.tar.gz"
fetch_and_deploy_gh_release "memos" "usememos/memos" "prebuild" "v0.25.3" "/opt/memos" "memos*linux_amd64.tar.gz"
mkdir -p /opt/memos_data
msg_info "Creating Service"

View File

@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: aendel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/nightscout/cgm-remote-monitor
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 \
libssl-dev \
openssl
msg_ok "Installed Dependencies"
MONGO_VERSION="8.0" setup_mongodb
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "nightscout" "nightscout/cgm-remote-monitor" "tarball"
msg_info "Installing Nightscout"
$STD npm install --prefix /opt/nightscout
msg_ok "Installed Nightscout"
msg_info "Creating Service"
useradd -s /bin/bash -m nightscout
chown -R nightscout:nightscout /opt/nightscout
API_SECRET=$(openssl rand -hex 16)
cat <<EOF >/opt/nightscout/my.env
MONGO_CONNECTION=mongodb://127.0.0.1:27017/nightscout
BASE_URL=http://localhost:1337
API_SECRET=${API_SECRET}
DISPLAY_UNITS=mg/dl
ENABLE=careportal boluscalc food bwp cage sage iage iob cob basal ar2 rawbg pushover bgi pump openaps pvb linear custom
INSECURE_USE_HTTP=true
EOF
chown nightscout:nightscout /opt/nightscout/my.env
cat <<EOF >/etc/systemd/system/nightscout.service
[Unit]
Description=Nightscout CGM Service
After=network.target mongodb.service
[Service]
Type=simple
User=nightscout
WorkingDirectory=/opt/nightscout
EnvironmentFile=/opt/nightscout/my.env
ExecStart=/usr/bin/npm start
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nightscout
msg_ok "Created Service"
{
echo "Nightscout Credentials"
echo "API_SECRET: ${API_SECRET}"
} >> ~/nightscout.creds
motd_ssh
customize
cleanup_lxc

View File

@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "latest" "/opt/nocodb/" "Noco-linux-x64"
fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "0.301.1" "/opt/nocodb/" "Noco-linux-x64"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/nocodb.service

View File

@@ -36,7 +36,8 @@ $STD npm ci
$STD npm run set:sqlite
$STD npm run set:oss
rm -rf server/private
$STD npm run build:sqlite
$STD npm run db:generate
$STD npm run build
$STD npm run build:cli
cp -R .next/standalone ./
@@ -177,7 +178,6 @@ http:
servers:
- url: "http://$LOCAL_IP:3000"
EOF
$STD npm run db:sqlite:generate
$STD npm run db:sqlite:push
. /etc/os-release

View File

@@ -19,7 +19,7 @@ setup_deb822_repo \
"ansible" \
"https://keyserver.ubuntu.com/pks/lookup?fingerprint=on&op=get&search=0x6125E2A8C77F2818FB7BD15B93C4A3FD7BB9C367" \
"http://ppa.launchpad.net/ansible/ansible/ubuntu" \
"jammy"
"noble"
$STD apt install -y ansible
msg_ok "Installed Dependencies"

View File

@@ -14,14 +14,14 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
unrar-free
$STD apt install -y unrar-free
ln -sf /usr/bin/unrar-free /usr/bin/unrar
msg_ok "Installed Dependencies"
mkdir -p /etc/shelfmark
cat <<EOF >/etc/shelfmark/.env
DOCKERMODE=false
URL_BASE=""
CONFIG_DIR=/etc/shelfmark
TMP_DIR=/tmp/shelfmark
ENABLE_LOGGING=true
@@ -111,7 +111,6 @@ else
ffmpeg \
chromium-common \
chromium \
chromium-driver \
python3-tk
msg_ok "Installed internal bypasser dependencies"
fi

View File

@@ -2763,7 +2763,7 @@ Advanced:
[[ -n "${CT_TIMEZONE:-}" ]] && echo -e "${INFO}${BOLD}${DGN}Timezone: ${BGN}$CT_TIMEZONE${CL}"
[[ "$APT_CACHER" == "yes" ]] && echo -e "${INFO}${BOLD}${DGN}APT Cacher: ${BGN}$APT_CACHER_IP${CL}"
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}"
echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}"
echo -e "${CREATING}${BOLD}${RD}Creating an LXC of ${APP} using the above advanced settings${CL}"
}
# ==============================================================================

View File

@@ -488,7 +488,7 @@ spinner() {
local i=0
while true; do
local index=$((i++ % ${#chars[@]}))
printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${msg}${CS_CL}"
printf "\r\033[2K%s %b" "${CS_YWB}${TAB}${chars[$index]}${TAB}${CS_CL}" "${CS_YWB}${msg}${CS_CL}"
sleep 0.1
done
}

View File

@@ -2317,8 +2317,106 @@ function fetch_and_deploy_codeberg_release() {
#
# # 4. Single binary (chmod +x) like Argus, Promtail etc.
# fetch_and_deploy_gh_release "argus" "release-argus/Argus" "singlefile" "0.26.3" "/opt/argus" "Argus-.*linux-amd64"
#
# Notes:
# - For binary/prebuild/singlefile modes: if the target release has no
# matching asset, the function scans older releases and prompts the user
# (60s timeout, default yes) to use a previous version that has the asset.
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Scans older GitHub releases for a matching asset when the latest release
# is missing the expected file. Used internally by fetch_and_deploy_gh_release.
#
# Arguments:
# $1 - GitHub repo (owner/repo)
# $2 - mode (binary|prebuild|singlefile)
# $3 - asset_pattern (glob pattern for asset filename)
# $4 - tag to skip (the already-checked release)
#
# Output:
# Prints the release JSON of the first older release that has a matching asset.
# Returns 0 on success, 1 if no matching release found or user declined.
# ------------------------------------------------------------------------------
_gh_scan_older_releases() {
local repo="$1"
local mode="$2"
local asset_pattern="$3"
local skip_tag="$4"
local header=()
[[ -n "${GITHUB_TOKEN:-}" ]] && header=(-H "Authorization: token $GITHUB_TOKEN")
local releases_list
releases_list=$(curl --connect-timeout 10 --max-time 30 -fsSL \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
"${header[@]}" \
"https://api.github.com/repos/${repo}/releases?per_page=15" 2>/dev/null) || return 1
local count
count=$(echo "$releases_list" | jq 'length')
for ((i = 0; i < count; i++)); do
local rel_tag rel_draft rel_prerelease
rel_tag=$(echo "$releases_list" | jq -r ".[$i].tag_name")
rel_draft=$(echo "$releases_list" | jq -r ".[$i].draft")
rel_prerelease=$(echo "$releases_list" | jq -r ".[$i].prerelease")
# Skip drafts, prereleases, and the tag we already checked
[[ "$rel_draft" == "true" || "$rel_prerelease" == "true" ]] && continue
[[ "$rel_tag" == "$skip_tag" ]] && continue
local has_match=false
if [[ "$mode" == "binary" ]]; then
local arch
arch=$(dpkg --print-architecture 2>/dev/null || uname -m)
[[ "$arch" == "x86_64" ]] && arch="amd64"
[[ "$arch" == "aarch64" ]] && arch="arm64"
# Check with explicit pattern first, then arch heuristic, then any .deb
if [[ -n "$asset_pattern" ]]; then
has_match=$(echo "$releases_list" | jq -r --arg pat "$asset_pattern" ".[$i].assets[].name" | while read -r name; do
case "$name" in $asset_pattern) echo true; break ;; esac
done)
fi
if [[ "$has_match" != "true" ]]; then
has_match=$(echo "$releases_list" | jq -r ".[$i].assets[].browser_download_url" | grep -qE "($arch|amd64|x86_64|aarch64|arm64).*\.deb$" && echo true)
fi
if [[ "$has_match" != "true" ]]; then
has_match=$(echo "$releases_list" | jq -r ".[$i].assets[].browser_download_url" | grep -qE '\.deb$' && echo true)
fi
elif [[ "$mode" == "prebuild" || "$mode" == "singlefile" ]]; then
has_match=$(echo "$releases_list" | jq -r ".[$i].assets[].name" | while read -r name; do
case "$name" in $asset_pattern) echo true; break ;; esac
done)
fi
if [[ "$has_match" == "true" ]]; then
local rel_version="$rel_tag"
[[ "$rel_tag" =~ ^v ]] && rel_version="${rel_tag:1}"
local use_fallback="y"
if [[ -t 0 ]]; then
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y"
use_fallback="${use_fallback:-y}"
fi
if [[ "${use_fallback,,}" == "y" || "${use_fallback,,}" == "yes" ]]; then
echo "$releases_list" | jq ".[$i]"
return 0
else
return 1
fi
fi
done
return 1
}
function fetch_and_deploy_gh_release() {
local app="$1"
local repo="$2"
@@ -2458,6 +2556,33 @@ function fetch_and_deploy_gh_release() {
done
fi
# Fallback: scan older releases for a matching .deb asset
if [[ -z "$url_match" ]]; then
local fallback_json
if fallback_json=$(_gh_scan_older_releases "$repo" "binary" "$asset_pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
[[ "$tag_name" =~ ^v ]] && version="${tag_name:1}" || version="$tag_name"
msg_info "Fetching GitHub release: $app ($version)"
assets=$(echo "$json" | jq -r '.assets[].browser_download_url')
if [[ -n "$asset_pattern" ]]; then
for u in $assets; do
case "${u##*/}" in $asset_pattern) url_match="$u"; break ;; esac
done
fi
if [[ -z "$url_match" ]]; then
for u in $assets; do
if [[ "$u" =~ ($arch|amd64|x86_64|aarch64|arm64).*\.deb$ ]]; then url_match="$u"; break; fi
done
fi
if [[ -z "$url_match" ]]; then
for u in $assets; do
[[ "$u" =~ \.deb$ ]] && url_match="$u" && break
done
fi
fi
fi
if [[ -z "$url_match" ]]; then
msg_error "No suitable .deb asset found for $app"
rm -rf "$tmpdir"
@@ -2506,6 +2631,21 @@ function fetch_and_deploy_gh_release() {
esac
done
# Fallback: scan older releases for a matching asset
if [[ -z "$asset_url" ]]; then
local fallback_json
if fallback_json=$(_gh_scan_older_releases "$repo" "prebuild" "$pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
[[ "$tag_name" =~ ^v ]] && version="${tag_name:1}" || version="$tag_name"
msg_info "Fetching GitHub release: $app ($version)"
for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do
filename_candidate="${u##*/}"
case "$filename_candidate" in $pattern) asset_url="$u"; break ;; esac
done
fi
fi
[[ -z "$asset_url" ]] && {
msg_error "No asset matching '$pattern' found"
rm -rf "$tmpdir"
@@ -2603,6 +2743,20 @@ function fetch_and_deploy_gh_release() {
esac
done
# Fallback: scan older releases for a matching asset
if [[ -z "$asset_url" ]]; then
local fallback_json
if fallback_json=$(_gh_scan_older_releases "$repo" "singlefile" "$pattern" "$tag_name"); then
json="$fallback_json"
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
[[ "$tag_name" =~ ^v ]] && version="${tag_name:1}" || version="$tag_name"
msg_info "Fetching GitHub release: $app ($version)"
for u in $(echo "$json" | jq -r '.assets[].browser_download_url'); do
filename_candidate="${u##*/}"
case "$filename_candidate" in $pattern) asset_url="$u"; break ;; esac
done
fi
fi
[[ -z "$asset_url" ]] && {
msg_error "No asset matching '$pattern' found"
rm -rf "$tmpdir"

471
tools/pve/update-apps.sh Normal file
View File

@@ -0,0 +1,471 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: BvdBerg01 | Co-Author: remz1337
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/core.func)
# =============================================================================
# CONFIGURATION VARIABLES
# Set these variables to skip interactive prompts (Whiptail dialogs)
# =============================================================================
# var_backup: Enable/disable backup before update
# Options: "yes" | "no" | "" (empty = interactive prompt)
var_backup="${var_backup:-}"
# var_backup_storage: Storage location for backups (only used if var_backup=yes)
# Options: Storage name from /etc/pve/storage.cfg (e.g., "local", "nas-backup")
# Leave empty for interactive selection
var_backup_storage="${var_backup_storage:-}"
# var_container: Which containers to update
# Options:
# - "all" : All containers with community-scripts tags
# - "all_running" : Only running containers with community-scripts tags
# - "all_stopped" : Only stopped containers with community-scripts tags
# - "101,102,109" : Comma-separated list of specific container IDs
# - "" : Interactive selection via Whiptail
var_container="${var_container:-}"
# var_unattended: Run updates without user interaction inside containers
# Options: "yes" | "no" | "" (empty = interactive prompt)
var_unattended="${var_unattended:-}"
# var_skip_confirm: Skip initial confirmation dialog
# Options: "yes" | "no" (default: no)
var_skip_confirm="${var_skip_confirm:-no}"
# var_auto_reboot: Automatically reboot containers that require it after update
# Options: "yes" | "no" | "" (empty = interactive prompt)
var_auto_reboot="${var_auto_reboot:-}"
# var_tags: Optionally override the tags used for auto-detection
# Options: "community-script|proxmox-helper-scripts" (default)
var_tags="${var_tags:-community-script|proxmox-helper-scripts}"
# =============================================================================
# JSON CONFIG EXPORT
# Run with --export-config to output current configuration as JSON
# =============================================================================
function export_config_json() {
cat <<EOF
{
"var_backup": "${var_backup}",
"var_backup_storage": "${var_backup_storage}",
"var_container": "${var_container}",
"var_unattended": "${var_unattended}",
"var_skip_confirm": "${var_skip_confirm}",
"var_auto_reboot": "${var_auto_reboot}",
"var_tags": "${var_tags}"
}
EOF
}
function print_usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]
Update LXC containers created with community-scripts.
Options:
--help Show this help message
--export-config Export current configuration as JSON
Environment Variables:
var_backup Enable backup before update (yes/no)
var_backup_storage Storage location for backups
var_container Container selection (all/all_running/all_stopped/101,102,...)
var_unattended Run updates unattended (yes/no)
var_skip_confirm Skip initial confirmation (yes/no)
var_auto_reboot Auto-reboot containers if required (yes/no)
var_tags Optionally override auto-detection tags ("prod|smb|community-script")
Examples:
# Run interactively
$(basename "$0")
# Update all running containers unattended with backup
var_backup=yes var_backup_storage=local var_container=all_running var_unattended=yes var_skip_confirm=yes $(basename "$0")
# Update specific containers without backup
var_backup=no var_container=101,102,105 var_unattended=yes var_skip_confirm=yes $(basename "$0")
# Export current configuration
$(basename "$0") --export-config
EOF
}
# Handle command line arguments
case "${1:-}" in
--help|-h)
print_usage
exit 0
;;
--export-config)
export_config_json
exit 0
;;
esac
# =============================================================================
function header_info {
clear
cat <<"EOF"
__ _ ________ __ __ __ __
/ / | |/ / ____/ / / / /___ ____/ /___ _/ /____
/ / | / / / / / / __ \/ __ / __ `/ __/ _ \
/ /___/ / /___ / /_/ / /_/ / /_/ / /_/ / /_/ __/
/_____/_/|_\____/ \____/ .___/\__,_/\__,_/\__/\___/
/_/
EOF
}
function detect_service() {
pushd $(mktemp -d) >/dev/null
pct pull "$1" /usr/bin/update update 2>/dev/null
service=$(cat update | sed 's|.*/ct/||g' | sed 's|\.sh).*||g')
popd >/dev/null
}
function backup_container() {
msg_info "Creating backup for container $1"
vzdump $1 --compress zstd --storage $STORAGE_CHOICE -notes-template "community-scripts backup updater" >/dev/null 2>&1
status=$?
if [ $status -eq 0 ]; then
msg_ok "Backup created"
else
msg_error "Backup failed for container $1"
exit 1
fi
}
function get_backup_storages() {
STORAGES=$(awk '
/^[a-z]+:/ {
if (name != "") {
if (has_backup || (!has_content && type == "dir")) print name
}
split($0, a, ":")
type = a[1]
name = a[2]
sub(/^ +/, "", name)
has_content = 0
has_backup = 0
}
/^ +content/ {
has_content = 1
if ($0 ~ /backup/) has_backup = 1
}
END {
if (name != "") {
if (has_backup || (!has_content && type == "dir")) print name
}
}
' /etc/pve/storage.cfg)
}
header_info
# Skip confirmation if var_skip_confirm is set to yes
if [[ "$var_skip_confirm" != "yes" ]]; then
whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC App Update" --yesno "This will update apps in LXCs installed by Helper-Scripts. Proceed?" 10 58 || exit
fi
tags_formatted="${var_tags//|/, }"
msg_info "Loading all possible LXC containers from Proxmox VE with tags: ${tags_formatted}. This may take a few seconds..."
NODE=$(hostname)
containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}')
if [ -z "$containers" ]; then
whiptail --title "LXC Container Update" --msgbox "No LXC containers available!" 10 60
exit 1
fi
menu_items=()
FORMAT="%-10s %-15s %-10s"
TAGS="${var_tags:-community-script|proxmox-helper-scripts}"
while read -r container; do
container_id=$(echo $container | awk '{print $1}')
container_name=$(echo $container | awk '{print $2}')
container_status=$(echo $container | awk '{print $3}')
formatted_line=$(printf "$FORMAT" "$container_name" "$container_status")
if pct config "$container_id" | grep -qE "[^-][; ](${TAGS}).*"; then
menu_items+=("$container_id" "$formatted_line" "OFF")
fi
done <<<"$containers"
msg_ok "Loaded ${#menu_items[@]} containers"
# Determine container selection based on var_container
if [[ -n "$var_container" ]]; then
case "$var_container" in
all)
# Select all containers with matching tags
CHOICE=""
for ((i=0; i<${#menu_items[@]}; i+=3)); do
CHOICE="$CHOICE ${menu_items[$i]}"
done
CHOICE=$(echo "$CHOICE" | xargs)
;;
all_running)
# Select only running containers with matching tags
CHOICE=""
for ((i=0; i<${#menu_items[@]}; i+=3)); do
cid="${menu_items[$i]}"
if pct status "$cid" 2>/dev/null | grep -q "running"; then
CHOICE="$CHOICE $cid"
fi
done
CHOICE=$(echo "$CHOICE" | xargs)
;;
all_stopped)
# Select only stopped containers with matching tags
CHOICE=""
for ((i=0; i<${#menu_items[@]}; i+=3)); do
cid="${menu_items[$i]}"
if pct status "$cid" 2>/dev/null | grep -q "stopped"; then
CHOICE="$CHOICE $cid"
fi
done
CHOICE=$(echo "$CHOICE" | xargs)
;;
*)
# Assume comma-separated list of container IDs
CHOICE=$(echo "$var_container" | tr ',' ' ')
;;
esac
if [[ -z "$CHOICE" ]]; then
msg_error "No containers matched the selection criteria: $var_container ${var_tags:-community-script|proxmox-helper-scripts}"
exit 1
fi
msg_ok "Selected containers: $CHOICE"
else
CHOICE=$(whiptail --title "LXC Container Update" \
--checklist "Select LXC containers to update:" 25 60 13 \
"${menu_items[@]}" 3>&2 2>&1 1>&3 | tr -d '"')
if [ -z "$CHOICE" ]; then
whiptail --title "LXC Container Update" \
--msgbox "No containers selected!" 10 60
exit 1
fi
fi
header_info
# Determine backup choice based on var_backup
if [[ -n "$var_backup" ]]; then
BACKUP_CHOICE="$var_backup"
else
BACKUP_CHOICE="no"
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Do you want to backup your containers before update?" 10 58); then
BACKUP_CHOICE="yes"
fi
fi
# Determine unattended update based on var_unattended
if [[ -n "$var_unattended" ]]; then
UNATTENDED_UPDATE="$var_unattended"
else
UNATTENDED_UPDATE="no"
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Run updates unattended?" 10 58); then
UNATTENDED_UPDATE="yes"
fi
fi
if [ "$BACKUP_CHOICE" == "yes" ]; then
get_backup_storages
if [ -z "$STORAGES" ]; then
msg_error "No storage with 'backup' support found!"
exit 1
fi
# Determine storage based on var_backup_storage
if [[ -n "$var_backup_storage" ]]; then
# Validate that the specified storage exists and supports backups
if echo "$STORAGES" | grep -qw "$var_backup_storage"; then
STORAGE_CHOICE="$var_backup_storage"
msg_ok "Using backup storage: $STORAGE_CHOICE"
else
msg_error "Specified backup storage '$var_backup_storage' not found or doesn't support backups!"
msg_info "Available storages: $(echo $STORAGES | tr '\n' ' ')"
exit 1
fi
else
MENU_ITEMS=()
for STORAGE in $STORAGES; do
MENU_ITEMS+=("$STORAGE" "")
done
STORAGE_CHOICE=$(whiptail --title "Select storage device" --menu "Select a storage device (Only storage devices with 'backup' support are listed):" 15 50 5 "${MENU_ITEMS[@]}" 3>&1 1>&2 2>&3)
if [ -z "$STORAGE_CHOICE" ]; then
msg_error "No storage selected!"
exit 1
fi
fi
fi
UPDATE_CMD="update;"
if [ "$UNATTENDED_UPDATE" == "yes" ]; then
UPDATE_CMD="export PHS_SILENT=1;update;"
fi
containers_needing_reboot=()
for container in $CHOICE; do
echo -e "${BL}[INFO]${CL} Updating container $container"
if [ "$BACKUP_CHOICE" == "yes" ]; then
backup_container $container
fi
os=$(pct config "$container" | awk '/^ostype/ {print $2}')
status=$(pct status $container)
template=$(pct config $container | grep -q "template:" && echo "true" || echo "false")
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n"
pct start $container
echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n"
sleep 5
fi
#1) Detect service using the service name in the update command
detect_service $container
#1.1) If update script not detected, return
if [ -z "${service}" ]; then
echo -e "${YW}[WARN]${CL} Update script not found. Skipping to next container"
continue
else
echo -e "${BL}[INFO]${CL} Detected service: ${GN}${service}${CL}"
fi
#2) Extract service build/update resource requirements from config/installation file
script=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${service}.sh)
#2.1) Check if the script downloaded successfully
if [ $? -ne 0 ]; then
echo -e "${RD}[ERROR]${CL} Issue while downloading install script."
echo -e "${YW}[WARN]${CL} Unable to assess build resource requirements. Proceeding with current resources."
fi
config=$(pct config "$container")
build_cpu=$(echo "$script" | { grep -m 1 "var_cpu" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_cpu:-||g' | sed 's|}||g')
build_ram=$(echo "$script" | { grep -m 1 "var_ram" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_ram:-||g' | sed 's|}||g')
run_cpu=$(echo "$script" | { grep -m 1 "pct set \$CTID -cores" || test $? = 1; } | sed 's|.*cores ||g')
run_ram=$(echo "$script" | { grep -m 1 "pct set \$CTID -memory" || test $? = 1; } | sed 's|.*memory ||g')
current_cpu=$(echo "$config" | grep -m 1 "cores:" | sed 's|cores: ||g')
current_ram=$(echo "$config" | grep -m 1 "memory:" | sed 's|memory: ||g')
#Test if all values are valid (>0)
if [ -z "${run_cpu}" ] || [ "$run_cpu" -le 0 ]; then
#echo "No valid value found for run_cpu. Assuming same as current configuration."
run_cpu=$current_cpu
fi
if [ -z "${run_ram}" ] || [ "$run_ram" -le 0 ]; then
#echo "No valid value found for run_ram. Assuming same as current configuration."
run_ram=$current_ram
fi
if [ -z "${build_cpu}" ] || [ "$build_cpu" -le 0 ]; then
#echo "No valid value found for build_cpu. Assuming same as current configuration."
build_cpu=$current_cpu
fi
if [ -z "${build_ram}" ] || [ "$build_ram" -le 0 ]; then
#echo "No valid value found for build_ram. Assuming same as current configuration."
build_ram=$current_ram
fi
UPDATE_BUILD_RESOURCES=0
if [ "$build_cpu" -gt "$run_cpu" ] || [ "$build_ram" -gt "$run_ram" ]; then
UPDATE_BUILD_RESOURCES=1
fi
#3) if build resources are different than run resources, then:
if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then
pct set "$container" --cores "$build_cpu" --memory "$build_ram"
fi
#4) Update service, using the update command
case "$os" in
alpine) pct exec "$container" -- ash -c "$UPDATE_CMD" ;;
archlinux) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
fedora | rocky | centos | alma) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
ubuntu | debian | devuan) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
opensuse) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
esac
exit_code=$?
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n"
pct shutdown $container &
fi
#5) if build resources are different than run resources, then:
if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then
pct set "$container" --cores "$run_cpu" --memory "$run_ram"
fi
if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then
# Get the container's hostname and add it to the list
container_hostname=$(pct exec "$container" hostname)
containers_needing_reboot+=("$container ($container_hostname)")
fi
if [ $exit_code -eq 0 ]; then
msg_ok "Updated container $container"
elif [ "$BACKUP_CHOICE" == "yes" ]; then
msg_info "Restoring LXC from backup"
pct stop $container
LXC_STORAGE=$(pct config $container | awk -F '[:,]' '/rootfs/ {print $2}')
pct restore $container /var/lib/vz/dump/vzdump-lxc-${container}-*.tar.zst --storage $LXC_STORAGE --force >/dev/null 2>&1
pct start $container
restorestatus=$?
if [ $restorestatus -eq 0 ]; then
msg_ok "Restored LXC from backup"
else
msg_error "Restored LXC from backup failed"
exit 1
fi
else
msg_error "Update failed for container $container. Exiting"
exit 1
fi
done
wait
header_info
echo -e "${GN}The process is complete, and the containers have been successfully updated.${CL}\n"
if [ "${#containers_needing_reboot[@]}" -gt 0 ]; then
echo -e "${RD}The following containers require a reboot:${CL}"
for container_name in "${containers_needing_reboot[@]}"; do
echo "$container_name"
done
# Determine reboot choice based on var_auto_reboot
REBOOT_CHOICE="no"
if [[ -n "$var_auto_reboot" ]]; then
REBOOT_CHOICE="$var_auto_reboot"
else
echo -ne "${INFO} Do you wish to reboot these containers? <yes/No> "
read -r prompt
if [[ ${prompt,,} =~ ^(yes)$ ]]; then
REBOOT_CHOICE="yes"
fi
fi
if [[ "$REBOOT_CHOICE" == "yes" ]]; then
echo -e "${CROSS}${HOLD} ${YWB}Rebooting containers.${CL}"
for container_name in "${containers_needing_reboot[@]}"; do
container=$(echo $container_name | cut -d " " -f 1)
pct reboot ${container}
done
fi
fi