Compare commits

..

22 Commits

Author SHA1 Message Date
github-actions[bot]
7000d426aa chore: update github-versions.json 2026-02-05 06:22:20 +00:00
community-scripts-pr-app[bot]
ddd130dbe3 Update CHANGELOG.md (#11558)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 00:22:45 +00:00
community-scripts-pr-app[bot]
93c52abebd chore: update github-versions.json (#11557)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 00:22:22 +00:00
community-scripts-pr-app[bot]
a74f6ee3c3 Update CHANGELOG.md (#11555)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 22:00:07 +00:00
Alessandro Del Pex
b36051375b Add log directory and permissions for koillection (#11553)
Create log directory and set ownership for www-data
2026-02-04 22:59:43 +01:00
community-scripts-pr-app[bot]
7b8a3a111d Update .app files (#11550)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-02-04 21:06:58 +01:00
community-scripts-pr-app[bot]
be994ce84f Update CHANGELOG.md (#11551)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 19:58:23 +00:00
Chris
4bd5c7b54b [FIX] Scanopy: ensure Scanopy Daemon update (#11541)
- It wasn't updating due to it having the same name as the server
- Changed it to 'Scanopy Daemon'
- Other small fixes
2026-02-04 20:57:52 +01:00
community-scripts-pr-app[bot]
868446a4b6 Update CHANGELOG.md (#11545)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 19:21:53 +00:00
Chris
5f31954d91 [FIX] Immich Public Proxy docs link (#11543) 2026-02-04 20:21:30 +01:00
community-scripts-pr-app[bot]
b025fd049c chore: update github-versions.json (#11544)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 18:17:43 +00:00
community-scripts-pr-app[bot]
3046eb000d Update CHANGELOG.md (#11542)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 15:20:23 +00:00
Chris
472439ce6e [ADDON] Immich Public Proxy addon (#11518)
* [ADDON] Immich Public Proxy

* prompt to add Immich IP or domain

* fix path

* fix immich port

* allow localhost

* add JSON

* Update tools/addon/immich-public-proxy.sh

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>

* NodeJS things

---------

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-02-04 16:19:53 +01:00
community-scripts-pr-app[bot]
43044c60f0 Update CHANGELOG.md (#11540)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 13:48:50 +00:00
Chris
36bf5cb57e Immich: pin version to 2.5.3 (#11515)
* Immich: pin version to 2.5.3

[FIX] Immich: only show OpenVINO menu if `/dev/dri` detected

* Grab pnpm version from release package.json
2026-02-04 14:48:18 +01:00
CanbiZ (MickLesk)
338c054112 action: prevent duplicate History section in changelog-archive workflow 2026-02-04 14:04:34 +01:00
community-scripts-pr-app[bot]
17ac4f5ae7 Archive old changelog entries (#11537)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 13:00:42 +00:00
CanbiZ (MickLesk)
5210d1bb71 fix sorting in changelog-archive.yml 2026-02-04 13:59:57 +01:00
CanbiZ (MickLesk)
c599fd7551 fix github - changelog double history 2026-02-04 13:58:19 +01:00
community-scripts-pr-app[bot]
0644bef572 Update CHANGELOG.md (#11536)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 12:28:08 +00:00
ls-root
27ab446926 fix(frontend): implement weighted search scoring for command menu (#11534)
* fix(frontend): implement weighted search scoring for command menu

The previous cmdk search was filtered correctly but then sorted by category
order rather than match strength. This caused "Dokpoly" to appear above
"Traefik", if you searched for Traefik, simply because its category (Containers) comes before Traefik's
category alphabetically.

- Flatten search results into a single "Search Results" group.
- Implement scoring to prioritize name matches over descriptions.
- Revert to category grouping only when the search query is empty.

* perf(frontend): optimize search logic

Limiting the results to 20 helps a lot.
2026-02-04 13:27:42 +01:00
community-scripts-pr-app[bot]
81abf70851 chore: update github-versions.json (#11535)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 12:12:03 +00:00
16 changed files with 901 additions and 1270 deletions

310
.github/changelogs/2026/01.md generated vendored
View File

@@ -1,14 +1,156 @@
## 2026-01-27 ## 2026-01-31
### 🆕 New Scripts
- shelfmark ([#11371](https://github.com/community-scripts/ProxmoxVE/pull/11371))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: yubal: add git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11394](https://github.com/community-scripts/ProxmoxVE/pull/11394))
## 2026-01-30
### 🆕 New Scripts
- languagetool ([#11370](https://github.com/community-scripts/ProxmoxVE/pull/11370))
- Ampache ([#11369](https://github.com/community-scripts/ProxmoxVE/pull/11369))
### 🚀 Updated Scripts
- #### 🔧 Refactor
- Refactor: remove redundant PHP_MODULE entries in several scripts [@MickLesk](https://github.com/MickLesk) ([#11362](https://github.com/community-scripts/ProxmoxVE/pull/11362))
- Refactor: Koillection [@MickLesk](https://github.com/MickLesk) ([#11361](https://github.com/community-scripts/ProxmoxVE/pull/11361))
### 💾 Core
- #### 🐞 Bug Fixes
- core: meilisearch - add data migration for version upgrades [@MickLesk](https://github.com/MickLesk) ([#11356](https://github.com/community-scripts/ProxmoxVE/pull/11356))
- #### ✨ New Features
- [tools] Add `fetch_and_deploy_from_url()` [@tremor021](https://github.com/tremor021) ([#11376](https://github.com/community-scripts/ProxmoxVE/pull/11376))
- core: php - improve module handling and prevent installation failures [@MickLesk](https://github.com/MickLesk) ([#11358](https://github.com/community-scripts/ProxmoxVE/pull/11358))
## 2026-01-29
### 🆕 New Scripts
- Alpine-Valkey [@MickLesk](https://github.com/MickLesk) ([#11320](https://github.com/community-scripts/ProxmoxVE/pull/11320))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Pin version to 2.5.2 [@vhsdream](https://github.com/vhsdream) ([#11335](https://github.com/community-scripts/ProxmoxVE/pull/11335))
- Kollection: Update to php 8.5 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11315](https://github.com/community-scripts/ProxmoxVE/pull/11315))
- Notifiarr: change installation check from apt to systemd service [@MickLesk](https://github.com/MickLesk) ([#11319](https://github.com/community-scripts/ProxmoxVE/pull/11319))
- #### ✨ New Features
- [FEAT] Immich: Enable Maintenance Mode before update [@vhsdream](https://github.com/vhsdream) ([#11342](https://github.com/community-scripts/ProxmoxVE/pull/11342))
- jellyfin: add logrotate instead of reducing log level [@MickLesk](https://github.com/MickLesk) ([#11326](https://github.com/community-scripts/ProxmoxVE/pull/11326))
- core: Add config file handling options | Fix Vikunja update with interactive overwrite [@MickLesk](https://github.com/MickLesk) ([#11317](https://github.com/community-scripts/ProxmoxVE/pull/11317))
- Immich: v2.5.0 [@vhsdream](https://github.com/vhsdream) ([#11240](https://github.com/community-scripts/ProxmoxVE/pull/11240))
- #### 💥 Breaking Changes
- fix: vikunja v1 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11308](https://github.com/community-scripts/ProxmoxVE/pull/11308))
- #### 🔧 Refactor
- Refactor: Byparr [@vhsdream](https://github.com/vhsdream) ([#11338](https://github.com/community-scripts/ProxmoxVE/pull/11338))
- cloudflare: Remove deprecated DNS-over-HTTPS proxy option [@MickLesk](https://github.com/MickLesk) ([#11068](https://github.com/community-scripts/ProxmoxVE/pull/11068))
### 💾 Core
- #### 🐞 Bug Fixes
- build.func: Replace storage variable with searchdomain variable [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11322](https://github.com/community-scripts/ProxmoxVE/pull/11322))
### 📂 Github
- Add workflow to lock closed issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11316](https://github.com/community-scripts/ProxmoxVE/pull/11316))
## 2026-01-28
### 🆕 New Scripts
- nodecast-tv ([#11287](https://github.com/community-scripts/ProxmoxVE/pull/11287))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Ubuntu 25.04 VM - Change default start from yes to no [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11292](https://github.com/community-scripts/ProxmoxVE/pull/11292))
- #### ✨ New Features
- various scripts: use setup_meilisearch function [@MickLesk](https://github.com/MickLesk) ([#11259](https://github.com/community-scripts/ProxmoxVE/pull/11259))
- #### 🔧 Refactor
- Refactor: NPMPlus / Default Login [@MickLesk](https://github.com/MickLesk) ([#11262](https://github.com/community-scripts/ProxmoxVE/pull/11262))
### 💾 Core
- #### 🐞 Bug Fixes
- core: sed patch for ram [@lavacano](https://github.com/lavacano) ([#11285](https://github.com/community-scripts/ProxmoxVE/pull/11285))
- Fix installer loop caused by invalid whiptail menu separator [@Mesteriis](https://github.com/Mesteriis) ([#11237](https://github.com/community-scripts/ProxmoxVE/pull/11237))
- core: fix Debian 13 LXC template root ownership bug [@MickLesk](https://github.com/MickLesk) ([#11277](https://github.com/community-scripts/ProxmoxVE/pull/11277))
- tools.func: prevent systemd-tmpfiles failure in unprivileged LXC during deb install [@MickLesk](https://github.com/MickLesk) ([#11271](https://github.com/community-scripts/ProxmoxVE/pull/11271))
- tools.func: fix php "wait_for" hint [@MickLesk](https://github.com/MickLesk) ([#11254](https://github.com/community-scripts/ProxmoxVE/pull/11254))
- #### ✨ New Features
- core: update dynamic values in LXC profile on update_motd_ip [@MickLesk](https://github.com/MickLesk) ([#11268](https://github.com/community-scripts/ProxmoxVE/pull/11268))
- tools.func: add new function - setup_meilisearch [@MickLesk](https://github.com/MickLesk) ([#11258](https://github.com/community-scripts/ProxmoxVE/pull/11258))
### 📂 Github
- github: add GitHub-based versions.json updater [@MickLesk](https://github.com/MickLesk) ([#10021](https://github.com/community-scripts/ProxmoxVE/pull/10021))
### 🌐 Website
- #### ✨ New Features
- Frontend: use github-versions.json for version display [@MickLesk](https://github.com/MickLesk) ([#11281](https://github.com/community-scripts/ProxmoxVE/pull/11281))
- #### 📝 Script Information
- fix: homarr: conf location [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11253](https://github.com/community-scripts/ProxmoxVE/pull/11253))
## 2026-01-27
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- [FIX] Jotty: backup and restore custom config [@vhsdream](https://github.com/vhsdream) ([#11212](https://github.com/community-scripts/ProxmoxVE/pull/11212)) - [FIX] Jotty: backup and restore custom config [@vhsdream](https://github.com/vhsdream) ([#11212](https://github.com/community-scripts/ProxmoxVE/pull/11212))
- Immich: update libraw [@vhsdream](https://github.com/vhsdream) ([#11233](https://github.com/community-scripts/ProxmoxVE/pull/11233))
- #### ✨ New Features
- grist: enable optional enterprise features toggle [@MickLesk](https://github.com/MickLesk) ([#11239](https://github.com/community-scripts/ProxmoxVE/pull/11239))
- #### 🔧 Refactor
- Termix: use nginx.conf from upstream repo [@MickLesk](https://github.com/MickLesk) ([#11228](https://github.com/community-scripts/ProxmoxVE/pull/11228))
### 💾 Core
- #### ✨ New Features
- feat: add NVIDIA driver install prompt for GPU-enabled containers [@devdecrux](https://github.com/devdecrux) ([#11184](https://github.com/community-scripts/ProxmoxVE/pull/11184))
### 📚 Documentation ### 📚 Documentation
- doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215)) - doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215))
- changelog: archive old entries to year/month files [@MickLesk](https://github.com/MickLesk) ([#11225](https://github.com/community-scripts/ProxmoxVE/pull/11225))
## 2026-01-26 ## 2026-01-26
@@ -100,7 +242,7 @@
### 🆕 New Scripts ### 🆕 New Scripts
- Tracearr ([#11079](https://github.com/community-scripts/ProxmoxVE/pull/11079)) - Tracearr ([#11079](https://github.com/community-scripts/ProxmoxVE/pull/11079))
- Dawarich ([#11075](https://github.com/community-scripts/ProxmoxVE/pull/11075)) - Dawarich ([#11075](https://github.com/community-scripts/ProxmoxVE/pull/11075))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
@@ -250,7 +392,7 @@
### 🆕 New Scripts ### 🆕 New Scripts
- Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887)) - Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887))
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904)) - ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
@@ -319,7 +461,7 @@
### 🆕 New Scripts ### 🆕 New Scripts
- Flatnotes ([#10857](https://github.com/community-scripts/ProxmoxVE/pull/10857)) - Flatnotes ([#10857](https://github.com/community-scripts/ProxmoxVE/pull/10857))
- Unifi OS Server ([#10856](https://github.com/community-scripts/ProxmoxVE/pull/10856)) - Unifi OS Server ([#10856](https://github.com/community-scripts/ProxmoxVE/pull/10856))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
@@ -385,7 +527,7 @@
### 🆕 New Scripts ### 🆕 New Scripts
- Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774)) - Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774))
- Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768)) - Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
@@ -574,7 +716,7 @@
### 📚 Documentation ### 📚 Documentation
- [gh] New Script template update [@tremor021](https://github.com/tremor021) ([#10607](https://github.com/community-scripts/ProxmoxVE/pull/10607)) - [gh] New Script template update [@tremor021](https://github.com/tremor021) ([#10607](https://github.com/community-scripts/ProxmoxVE/pull/10607))
- chore: bump copyright to 2026 - happy new year [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10585](https://github.com/community-scripts/ProxmoxVE/pull/10585)) - chore: bump copyright to 2026 - happy new year [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10585](https://github.com/community-scripts/ProxmoxVE/pull/10585))
### 📂 Github ### 📂 Github
@@ -655,7 +797,7 @@
### ❔ Uncategorized ### ❔ Uncategorized
- Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496)) - Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496))
- InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497)) - InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497))
## 2026-01-02 ## 2026-01-02
@@ -684,157 +826,3 @@
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- Fix MariaDB runtime directory persistence on container reboot [@Copilot](https://github.com/Copilot) ([#10468](https://github.com/community-scripts/ProxmoxVE/pull/10468)) - Fix MariaDB runtime directory persistence on container reboot [@Copilot](https://github.com/Copilot) ([#10468](https://github.com/community-scripts/ProxmoxVE/pull/10468))
## 2026-01-31
### 🆕 New Scripts
- shelfmark ([#11371](https://github.com/community-scripts/ProxmoxVE/pull/11371))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: yubal: add git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11394](https://github.com/community-scripts/ProxmoxVE/pull/11394))
## 2026-01-30
### 🆕 New Scripts
- languagetool ([#11370](https://github.com/community-scripts/ProxmoxVE/pull/11370))
- Ampache ([#11369](https://github.com/community-scripts/ProxmoxVE/pull/11369))
### 🚀 Updated Scripts
- #### 🔧 Refactor
- Refactor: remove redundant PHP_MODULE entries in several scripts [@MickLesk](https://github.com/MickLesk) ([#11362](https://github.com/community-scripts/ProxmoxVE/pull/11362))
- Refactor: Koillection [@MickLesk](https://github.com/MickLesk) ([#11361](https://github.com/community-scripts/ProxmoxVE/pull/11361))
### 💾 Core
- #### 🐞 Bug Fixes
- core: meilisearch - add data migration for version upgrades [@MickLesk](https://github.com/MickLesk) ([#11356](https://github.com/community-scripts/ProxmoxVE/pull/11356))
- #### ✨ New Features
- [tools] Add `fetch_and_deploy_from_url()` [@tremor021](https://github.com/tremor021) ([#11376](https://github.com/community-scripts/ProxmoxVE/pull/11376))
- core: php - improve module handling and prevent installation failures [@MickLesk](https://github.com/MickLesk) ([#11358](https://github.com/community-scripts/ProxmoxVE/pull/11358))
## 2026-01-29
### 🆕 New Scripts
- Alpine-Valkey [@MickLesk](https://github.com/MickLesk) ([#11320](https://github.com/community-scripts/ProxmoxVE/pull/11320))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Pin version to 2.5.2 [@vhsdream](https://github.com/vhsdream) ([#11335](https://github.com/community-scripts/ProxmoxVE/pull/11335))
- Kollection: Update to php 8.5 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11315](https://github.com/community-scripts/ProxmoxVE/pull/11315))
- Notifiarr: change installation check from apt to systemd service [@MickLesk](https://github.com/MickLesk) ([#11319](https://github.com/community-scripts/ProxmoxVE/pull/11319))
- #### ✨ New Features
- [FEAT] Immich: Enable Maintenance Mode before update [@vhsdream](https://github.com/vhsdream) ([#11342](https://github.com/community-scripts/ProxmoxVE/pull/11342))
- jellyfin: add logrotate instead of reducing log level [@MickLesk](https://github.com/MickLesk) ([#11326](https://github.com/community-scripts/ProxmoxVE/pull/11326))
- core: Add config file handling options | Fix Vikunja update with interactive overwrite [@MickLesk](https://github.com/MickLesk) ([#11317](https://github.com/community-scripts/ProxmoxVE/pull/11317))
- Immich: v2.5.0 [@vhsdream](https://github.com/vhsdream) ([#11240](https://github.com/community-scripts/ProxmoxVE/pull/11240))
- #### 💥 Breaking Changes
- fix: vikunja v1 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11308](https://github.com/community-scripts/ProxmoxVE/pull/11308))
- #### 🔧 Refactor
- Refactor: Byparr [@vhsdream](https://github.com/vhsdream) ([#11338](https://github.com/community-scripts/ProxmoxVE/pull/11338))
- cloudflare: Remove deprecated DNS-over-HTTPS proxy option [@MickLesk](https://github.com/MickLesk) ([#11068](https://github.com/community-scripts/ProxmoxVE/pull/11068))
### 💾 Core
- #### 🐞 Bug Fixes
- build.func: Replace storage variable with searchdomain variable [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11322](https://github.com/community-scripts/ProxmoxVE/pull/11322))
### 📂 Github
- Add workflow to lock closed issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11316](https://github.com/community-scripts/ProxmoxVE/pull/11316))
## 2026-01-28
### 🆕 New Scripts
- nodecast-tv ([#11287](https://github.com/community-scripts/ProxmoxVE/pull/11287))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Ubuntu 25.04 VM - Change default start from yes to no [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11292](https://github.com/community-scripts/ProxmoxVE/pull/11292))
- #### ✨ New Features
- various scripts: use setup_meilisearch function [@MickLesk](https://github.com/MickLesk) ([#11259](https://github.com/community-scripts/ProxmoxVE/pull/11259))
- #### 🔧 Refactor
- Refactor: NPMPlus / Default Login [@MickLesk](https://github.com/MickLesk) ([#11262](https://github.com/community-scripts/ProxmoxVE/pull/11262))
### 💾 Core
- #### 🐞 Bug Fixes
- core: sed patch for ram [@lavacano](https://github.com/lavacano) ([#11285](https://github.com/community-scripts/ProxmoxVE/pull/11285))
- Fix installer loop caused by invalid whiptail menu separator [@Mesteriis](https://github.com/Mesteriis) ([#11237](https://github.com/community-scripts/ProxmoxVE/pull/11237))
- core: fix Debian 13 LXC template root ownership bug [@MickLesk](https://github.com/MickLesk) ([#11277](https://github.com/community-scripts/ProxmoxVE/pull/11277))
- tools.func: prevent systemd-tmpfiles failure in unprivileged LXC during deb install [@MickLesk](https://github.com/MickLesk) ([#11271](https://github.com/community-scripts/ProxmoxVE/pull/11271))
- tools.func: fix php "wait_for" hint [@MickLesk](https://github.com/MickLesk) ([#11254](https://github.com/community-scripts/ProxmoxVE/pull/11254))
- #### ✨ New Features
- core: update dynamic values in LXC profile on update_motd_ip [@MickLesk](https://github.com/MickLesk) ([#11268](https://github.com/community-scripts/ProxmoxVE/pull/11268))
- tools.func: add new function - setup_meilisearch [@MickLesk](https://github.com/MickLesk) ([#11258](https://github.com/community-scripts/ProxmoxVE/pull/11258))
### 📂 Github
- github: add GitHub-based versions.json updater [@MickLesk](https://github.com/MickLesk) ([#10021](https://github.com/community-scripts/ProxmoxVE/pull/10021))
### 🌐 Website
- #### ✨ New Features
- Frontend: use github-versions.json for version display [@MickLesk](https://github.com/MickLesk) ([#11281](https://github.com/community-scripts/ProxmoxVE/pull/11281))
- #### 📝 Script Information
- fix: homarr: conf location [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11253](https://github.com/community-scripts/ProxmoxVE/pull/11253))
## 2026-01-27
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: update libraw [@vhsdream](https://github.com/vhsdream) ([#11233](https://github.com/community-scripts/ProxmoxVE/pull/11233))
- #### ✨ New Features
- grist: enable optional enterprise features toggle [@MickLesk](https://github.com/MickLesk) ([#11239](https://github.com/community-scripts/ProxmoxVE/pull/11239))
- #### 🔧 Refactor
- Termix: use nginx.conf from upstream repo [@MickLesk](https://github.com/MickLesk) ([#11228](https://github.com/community-scripts/ProxmoxVE/pull/11228))
### 💾 Core
- #### ✨ New Features
- feat: add NVIDIA driver install prompt for GPU-enabled containers [@devdecrux](https://github.com/devdecrux) ([#11184](https://github.com/community-scripts/ProxmoxVE/pull/11184))
### 📚 Documentation
- doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215))
- changelog: archive old entries to year/month files [@MickLesk](https://github.com/MickLesk) ([#11225](https://github.com/community-scripts/ProxmoxVE/pull/11225))

121
.github/changelogs/2026/02.md generated vendored Normal file
View File

@@ -0,0 +1,121 @@
## 2026-02-04
### 🆕 New Scripts
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
### 💾 Core
- #### ✨ New Features
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
## 2026-02-03
### 🆕 New Scripts
- Wealthfolio ([#11511](https://github.com/community-scripts/ProxmoxVE/pull/11511))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [FIX] Shelfmark: unpin Chromium version [@vhsdream](https://github.com/vhsdream) ([#11505](https://github.com/community-scripts/ProxmoxVE/pull/11505))
- #### ✨ New Features
- [FEAT] Scanopy: automatically update integrated daemon [@vhsdream](https://github.com/vhsdream) ([#11506](https://github.com/community-scripts/ProxmoxVE/pull/11506))
### 💾 Core
- #### 🐞 Bug Fixes
- [FIX] tools.func: trim spaces in app_lc when checking for gh release [@vhsdream](https://github.com/vhsdream) ([#11512](https://github.com/community-scripts/ProxmoxVE/pull/11512))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): decouple table pagination from summary fetching [@ls-root](https://github.com/ls-root) ([#11495](https://github.com/community-scripts/ProxmoxVE/pull/11495))
## 2026-02-02
### 🆕 New Scripts
- rustypaste | Alpine-rustypaste ([#11457](https://github.com/community-scripts/ProxmoxVE/pull/11457))
- KitchenOwl ([#11453](https://github.com/community-scripts/ProxmoxVE/pull/11453))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grist: Update dependencies [@tremor021](https://github.com/tremor021) ([#11489](https://github.com/community-scripts/ProxmoxVE/pull/11489))
- Allow "downgrade" of libigdgmm12 [@vhsdream](https://github.com/vhsdream) ([#11478](https://github.com/community-scripts/ProxmoxVE/pull/11478))
- Disable NPM install and update due to OpenResty SHA-1 signature issues [@MickLesk](https://github.com/MickLesk) ([#11471](https://github.com/community-scripts/ProxmoxVE/pull/11471))
- #### ✨ New Features
- Refactor: Forgejo & readeck - migrate to codeberg functions [@MickLesk](https://github.com/MickLesk) ([#11460](https://github.com/community-scripts/ProxmoxVE/pull/11460))
- #### 💥 Breaking Changes
- [FIX] Scanopy: remove daemon build [@vhsdream](https://github.com/vhsdream) ([#11444](https://github.com/community-scripts/ProxmoxVE/pull/11444))
- #### 🔧 Refactor
- Refactor: Vaultwarden [@MickLesk](https://github.com/MickLesk) ([#11445](https://github.com/community-scripts/ProxmoxVE/pull/11445))
- various scripts: use ensure_dependencies instead of apt [@MickLesk](https://github.com/MickLesk) ([#11463](https://github.com/community-scripts/ProxmoxVE/pull/11463))
### 🌐 Website
- cleanup(frontend): remove unused /category-view route [@ls-root](https://github.com/ls-root) ([#11461](https://github.com/community-scripts/ProxmoxVE/pull/11461))
- #### ✨ New Features
- feat(frontend): preview tab [@ls-root](https://github.com/ls-root) ([#11475](https://github.com/community-scripts/ProxmoxVE/pull/11475))
## 2026-02-01
### 🚀 Updated Scripts
- fix headers [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11422](https://github.com/community-scripts/ProxmoxVE/pull/11422))
- #### 🐞 Bug Fixes
- 2fauth: export PHP_VERSION for nginx config [@MickLesk](https://github.com/MickLesk) ([#11441](https://github.com/community-scripts/ProxmoxVE/pull/11441))
- Prometheus Paperless NGX Exporter: Set correct binary path in systemd unit file [@andygrunwald](https://github.com/andygrunwald) ([#11438](https://github.com/community-scripts/ProxmoxVE/pull/11438))
- tracearr: install/update new prestart script from upstream [@durzo](https://github.com/durzo) ([#11433](https://github.com/community-scripts/ProxmoxVE/pull/11433))
- n8n: Fix dependencies [@tremor021](https://github.com/tremor021) ([#11429](https://github.com/community-scripts/ProxmoxVE/pull/11429))
- [Hotfix] Bunkerweb update [@vhsdream](https://github.com/vhsdream) ([#11402](https://github.com/community-scripts/ProxmoxVE/pull/11402))
- [Hotfix] Immich: revert healthcheck feature [@vhsdream](https://github.com/vhsdream) ([#11427](https://github.com/community-scripts/ProxmoxVE/pull/11427))
- #### ✨ New Features
- tools.func: add codeberg functions & autocaliweb: migrate from GitHub to Codeberg [@MickLesk](https://github.com/MickLesk) ([#11440](https://github.com/community-scripts/ProxmoxVE/pull/11440))
- Immich Refactor #2 [@vhsdream](https://github.com/vhsdream) ([#11375](https://github.com/community-scripts/ProxmoxVE/pull/11375))
- #### 🔧 Refactor
- WordPress: Refactor [@tremor021](https://github.com/tremor021) ([#11408](https://github.com/community-scripts/ProxmoxVE/pull/11408))
- Refactor: Whisparr [@tremor021](https://github.com/tremor021) ([#11411](https://github.com/community-scripts/ProxmoxVE/pull/11411))
### 💾 Core
- #### ✨ New Features
- [tools]: Update `fetch_and_deply_from_url()` [@tremor021](https://github.com/tremor021) ([#11410](https://github.com/community-scripts/ProxmoxVE/pull/11410))
### 🌐 Website
- feat(frontend): implement UX refinements and syntax highlighting [@ls-root](https://github.com/ls-root) ([#11423](https://github.com/community-scripts/ProxmoxVE/pull/11423))
- #### ✨ New Features
- feat(frontend): add contribution CTA to empty search state [@ls-root](https://github.com/ls-root) ([#11412](https://github.com/community-scripts/ProxmoxVE/pull/11412))

View File

@@ -54,8 +54,9 @@ jobs:
console.log(`Cutoff date: ${cutoffDate.toISOString().split('T')[0]}`); console.log(`Cutoff date: ${cutoffDate.toISOString().split('T')[0]}`);
// Read changelog // Read changelog and normalize line endings
const content = await fs.readFile(CHANGELOG_PATH, 'utf-8'); let content = await fs.readFile(CHANGELOG_PATH, 'utf-8');
content = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
const lines = content.split('\n'); const lines = content.split('\n');
// Parse entries // Parse entries
@@ -66,9 +67,39 @@ jobs:
let currentDate = null; let currentDate = null;
let currentContent = []; let currentContent = [];
let inHeader = true; let inHeader = true;
let inOldHistory = false;
let historyDetailsDepth = 0;
for (const line of lines) { for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const match = line.match(datePattern); const match = line.match(datePattern);
// Detect the start of History section: <details> followed by line with 📜 History
if (inHeader && !inOldHistory && line.trim() === '<details>') {
// Look ahead to see if this is the History section
const nextLine = lines[i + 1] || '';
if (nextLine.includes('📜 History')) {
inOldHistory = true;
historyDetailsDepth = 1;
continue;
}
}
// Track nested details tags to find the end of History section
if (inOldHistory) {
if (line.trim() === '<details>') {
historyDetailsDepth++;
}
if (line.trim() === '</details>') {
historyDetailsDepth--;
if (historyDetailsDepth === 0) {
// We've closed the main History details tag
inOldHistory = false;
}
}
continue;
}
if (match) { if (match) {
inHeader = false; inHeader = false;
@@ -148,30 +179,55 @@ jobs:
let existingContent = ''; let existingContent = '';
try { try {
existingContent = await fs.readFile(monthPath, 'utf-8'); existingContent = await fs.readFile(monthPath, 'utf-8');
// Normalize line endings to prevent regex issues
existingContent = existingContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
} catch (e) { } catch (e) {
// File doesn't exist // File doesn't exist
} }
// Merge new entries with existing (avoid duplicates) // Parse existing entries into a Map (date -> content) for deduplication
const existingDates = new Set(); const allEntries = new Map();
const existingDatePattern = /^## (\d{4}-\d{2}-\d{2})$/gm;
let match; // Helper function to parse entries from content
while ((match = existingDatePattern.exec(existingContent)) !== null) { const parseEntries = (content) => {
existingDates.add(match[1]); const entries = new Map();
const parts = content.split(/(?=^## \d{4}-\d{2}-\d{2}$)/m);
for (const part of parts) {
const trimmed = part.trim();
if (!trimmed) continue;
const dateMatch = trimmed.match(/^## (\d{4}-\d{2}-\d{2})/);
if (dateMatch) {
entries.set(dateMatch[1], trimmed);
}
}
return entries;
};
// Parse existing content
if (existingContent) {
const existingEntries = parseEntries(existingContent);
for (const [date, content] of existingEntries) {
allEntries.set(date, content);
}
} }
const newEntries = archiveData[year][month].filter(entry => { // Add new entries (existing entries take precedence to avoid overwriting)
let addedCount = 0;
for (const entry of archiveData[year][month]) {
const dateMatch = entry.match(/^## (\d{4}-\d{2}-\d{2})/); const dateMatch = entry.match(/^## (\d{4}-\d{2}-\d{2})/);
return dateMatch && !existingDates.has(dateMatch[1]); if (dateMatch && !allEntries.has(dateMatch[1])) {
}); allEntries.set(dateMatch[1], entry.trim());
addedCount++;
}
}
if (newEntries.length > 0) { // Sort entries by date (newest first) and write
const allContent = existingContent const sortedDates = [...allEntries.keys()].sort().reverse();
? existingContent + '\n\n' + newEntries.join('\n\n') const sortedContent = sortedDates.map(date => allEntries.get(date)).join('\n\n');
: newEntries.join('\n\n');
await fs.writeFile(monthPath, allContent, 'utf-8'); if (addedCount > 0 || !existingContent) {
console.log(`Updated: ${monthPath} (+${newEntries.length} entries)`); await fs.writeFile(monthPath, sortedContent + '\n', 'utf-8');
console.log(`Updated: ${monthPath} (${allEntries.size} total entries, +${addedCount} new)`);
} }
} }
} }
@@ -218,7 +274,8 @@ jobs:
// Count entries in month file // Count entries in month file
let entryCount = 0; let entryCount = 0;
try { try {
const monthContent = await fs.readFile(monthPath, 'utf-8'); let monthContent = await fs.readFile(monthPath, 'utf-8');
monthContent = monthContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
entryCount = (monthContent.match(/^## \d{4}-\d{2}-\d{2}$/gm) || []).length; entryCount = (monthContent.match(/^## \d{4}-\d{2}-\d{2}$/gm) || []).length;
} catch (e) { } catch (e) {
entryCount = (archiveData[year]?.[month] || []).length; entryCount = (archiveData[year]?.[month] || []).length;

View File

@@ -21,7 +21,14 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
<details> <details>
<summary><h4>January - 27 entries</h4></summary> <summary><h4>February (4 entries)</h4></summary>
[View February 2026 Changelog](.github/changelogs/2026/02.md)
</details>
<details>
<summary><h4>January (31 entries)</h4></summary>
[View January 2026 Changelog](.github/changelogs/2026/01.md) [View January 2026 Changelog](.github/changelogs/2026/01.md)
@@ -391,386 +398,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details> </details>
## 2026-02-05
<details>
<summary><h2>📜 History</h2></summary>
<details>
<summary><h3>2026</h3></summary>
<details>
<summary><h4>January (31 entries)</h4></summary>
[View January 2026 Changelog](.github/changelogs/2026/01.md)
</details>
</details>
<details>
<summary><h3>2025</h3></summary>
<details>
<summary><h4>December (31 entries)</h4></summary>
[View December 2025 Changelog](.github/changelogs/2025/12.md)
</details>
<details>
<summary><h4>November (29 entries)</h4></summary>
[View November 2025 Changelog](.github/changelogs/2025/11.md)
</details>
<details>
<summary><h4>October (30 entries)</h4></summary>
[View October 2025 Changelog](.github/changelogs/2025/10.md)
</details>
<details>
<summary><h4>September (29 entries)</h4></summary>
[View September 2025 Changelog](.github/changelogs/2025/09.md)
</details>
<details>
<summary><h4>August (30 entries)</h4></summary>
[View August 2025 Changelog](.github/changelogs/2025/08.md)
</details>
<details>
<summary><h4>July (29 entries)</h4></summary>
[View July 2025 Changelog](.github/changelogs/2025/07.md)
</details>
<details>
<summary><h4>June (29 entries)</h4></summary>
[View June 2025 Changelog](.github/changelogs/2025/06.md)
</details>
<details>
<summary><h4>May (30 entries)</h4></summary>
[View May 2025 Changelog](.github/changelogs/2025/05.md)
</details>
<details>
<summary><h4>April (25 entries)</h4></summary>
[View April 2025 Changelog](.github/changelogs/2025/04.md)
</details>
<details>
<summary><h4>March (30 entries)</h4></summary>
[View March 2025 Changelog](.github/changelogs/2025/03.md)
</details>
<details>
<summary><h4>February (26 entries)</h4></summary>
[View February 2025 Changelog](.github/changelogs/2025/02.md)
</details>
<details>
<summary><h4>January (27 entries)</h4></summary>
[View January 2025 Changelog](.github/changelogs/2025/01.md)
</details>
</details>
<details>
<summary><h3>2024</h3></summary>
<details>
<summary><h4>December (22 entries)</h4></summary>
[View December 2024 Changelog](.github/changelogs/2024/12.md)
</details>
<details>
<summary><h4>November (15 entries)</h4></summary>
[View November 2024 Changelog](.github/changelogs/2024/11.md)
</details>
<details>
<summary><h4>October (9 entries)</h4></summary>
[View October 2024 Changelog](.github/changelogs/2024/10.md)
</details>
<details>
<summary><h4>September (1 entries)</h4></summary>
[View September 2024 Changelog](.github/changelogs/2024/09.md)
</details>
<details>
<summary><h4>August (2 entries)</h4></summary>
[View August 2024 Changelog](.github/changelogs/2024/08.md)
</details>
<details>
<summary><h4>July (0 entries)</h4></summary>
[View July 2024 Changelog](.github/changelogs/2024/07.md)
</details>
<details>
<summary><h4>June (8 entries)</h4></summary>
[View June 2024 Changelog](.github/changelogs/2024/06.md)
</details>
<details>
<summary><h4>May (16 entries)</h4></summary>
[View May 2024 Changelog](.github/changelogs/2024/05.md)
</details>
<details>
<summary><h4>April (14 entries)</h4></summary>
[View April 2024 Changelog](.github/changelogs/2024/04.md)
</details>
<details>
<summary><h4>March (5 entries)</h4></summary>
[View March 2024 Changelog](.github/changelogs/2024/03.md)
</details>
<details>
<summary><h4>February (9 entries)</h4></summary>
[View February 2024 Changelog](.github/changelogs/2024/02.md)
</details>
<details>
<summary><h4>January (9 entries)</h4></summary>
[View January 2024 Changelog](.github/changelogs/2024/01.md)
</details>
</details>
<details>
<summary><h3>2023</h3></summary>
<details>
<summary><h4>December (3 entries)</h4></summary>
[View December 2023 Changelog](.github/changelogs/2023/12.md)
</details>
<details>
<summary><h4>November (3 entries)</h4></summary>
[View November 2023 Changelog](.github/changelogs/2023/11.md)
</details>
<details>
<summary><h4>October (7 entries)</h4></summary>
[View October 2023 Changelog](.github/changelogs/2023/10.md)
</details>
<details>
<summary><h4>September (10 entries)</h4></summary>
[View September 2023 Changelog](.github/changelogs/2023/09.md)
</details>
<details>
<summary><h4>August (7 entries)</h4></summary>
[View August 2023 Changelog](.github/changelogs/2023/08.md)
</details>
<details>
<summary><h4>July (5 entries)</h4></summary>
[View July 2023 Changelog](.github/changelogs/2023/07.md)
</details>
<details>
<summary><h4>June (5 entries)</h4></summary>
[View June 2023 Changelog](.github/changelogs/2023/06.md)
</details>
<details>
<summary><h4>May (8 entries)</h4></summary>
[View May 2023 Changelog](.github/changelogs/2023/05.md)
</details>
<details>
<summary><h4>April (8 entries)</h4></summary>
[View April 2023 Changelog](.github/changelogs/2023/04.md)
</details>
<details>
<summary><h4>March (8 entries)</h4></summary>
[View March 2023 Changelog](.github/changelogs/2023/03.md)
</details>
<details>
<summary><h4>February (6 entries)</h4></summary>
[View February 2023 Changelog](.github/changelogs/2023/02.md)
</details>
<details>
<summary><h4>January (15 entries)</h4></summary>
[View January 2023 Changelog](.github/changelogs/2023/01.md)
</details>
</details>
<details>
<summary><h3>2022</h3></summary>
<details>
<summary><h4>December (7 entries)</h4></summary>
[View December 2022 Changelog](.github/changelogs/2022/12.md)
</details>
<details>
<summary><h4>November (7 entries)</h4></summary>
[View November 2022 Changelog](.github/changelogs/2022/11.md)
</details>
<details>
<summary><h4>October (2 entries)</h4></summary>
[View October 2022 Changelog](.github/changelogs/2022/10.md)
</details>
<details>
<summary><h4>September (9 entries)</h4></summary>
[View September 2022 Changelog](.github/changelogs/2022/09.md)
</details>
<details>
<summary><h4>August (7 entries)</h4></summary>
[View August 2022 Changelog](.github/changelogs/2022/08.md)
</details>
<details>
<summary><h4>July (10 entries)</h4></summary>
[View July 2022 Changelog](.github/changelogs/2022/07.md)
</details>
<details>
<summary><h4>June (1 entries)</h4></summary>
[View June 2022 Changelog](.github/changelogs/2022/06.md)
</details>
<details>
<summary><h4>May (8 entries)</h4></summary>
[View May 2022 Changelog](.github/changelogs/2022/05.md)
</details>
<details>
<summary><h4>April (13 entries)</h4></summary>
[View April 2022 Changelog](.github/changelogs/2022/04.md)
</details>
<details>
<summary><h4>March (20 entries)</h4></summary>
[View March 2022 Changelog](.github/changelogs/2022/03.md)
</details>
<details>
<summary><h4>February (15 entries)</h4></summary>
[View February 2022 Changelog](.github/changelogs/2022/02.md)
</details>
<details>
<summary><h4>January (3 entries)</h4></summary>
[View January 2022 Changelog](.github/changelogs/2022/01.md)
</details>
</details>
</details>
## 2026-02-04 ## 2026-02-04
@@ -779,12 +407,37 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527)) - Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524)) - WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
### 🚀 Updated Scripts
- Add log directory and permissions for koillection [@shineangelic](https://github.com/shineangelic) ([#11553](https://github.com/community-scripts/ProxmoxVE/pull/11553))
- #### 🐞 Bug Fixes
- [FIX] Scanopy: ensure Scanopy Daemon update [@vhsdream](https://github.com/vhsdream) ([#11541](https://github.com/community-scripts/ProxmoxVE/pull/11541))
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
### 💾 Core ### 💾 Core
- #### ✨ New Features - #### ✨ New Features
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528)) - core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
### 🧰 Tools
- #### ✨ New Features
- [ADDON] Immich Public Proxy addon [@vhsdream](https://github.com/vhsdream) ([#11518](https://github.com/community-scripts/ProxmoxVE/pull/11518))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
### ❔ Uncategorized
- [FIX] Immich Public Proxy docs link [@vhsdream](https://github.com/vhsdream) ([#11543](https://github.com/community-scripts/ProxmoxVE/pull/11543))
## 2026-02-03 ## 2026-02-03
### 🆕 New Scripts ### 🆕 New Scripts
@@ -1638,64 +1291,3 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🔧 Refactor - #### 🔧 Refactor
- Refactor: IP-Tag (Multiple IP / Performance / Execution Time) [@MickLesk](https://github.com/MickLesk) ([#10558](https://github.com/community-scripts/ProxmoxVE/pull/10558)) - Refactor: IP-Tag (Multiple IP / Performance / Execution Time) [@MickLesk](https://github.com/MickLesk) ([#10558](https://github.com/community-scripts/ProxmoxVE/pull/10558))
## 2026-01-04
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- PocketID: Update PocketID for 2.x [@tremor021](https://github.com/tremor021) ([#10506](https://github.com/community-scripts/ProxmoxVE/pull/10506))
- fix: reitti: nginx [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10511](https://github.com/community-scripts/ProxmoxVE/pull/10511))
- MagicMirror: bump to nodejs 24 [@MickLesk](https://github.com/MickLesk) ([#10534](https://github.com/community-scripts/ProxmoxVE/pull/10534))
- #### 🔧 Refactor
- Refactor: SFTPGo [@tremor021](https://github.com/tremor021) ([#10518](https://github.com/community-scripts/ProxmoxVE/pull/10518))
- Refactor: Pelican Wings [@tremor021](https://github.com/tremor021) ([#10517](https://github.com/community-scripts/ProxmoxVE/pull/10517))
- Refactor: Pelican Panel [@tremor021](https://github.com/tremor021) ([#10516](https://github.com/community-scripts/ProxmoxVE/pull/10516))
- Refactor: Audiobookshelf [@tremor021](https://github.com/tremor021) ([#10519](https://github.com/community-scripts/ProxmoxVE/pull/10519))
### 💾 Core
- #### 🐞 Bug Fixes
- Export IPV6_METHOD to trigger verb_ip6() function [@remz1337](https://github.com/remz1337) ([#10538](https://github.com/community-scripts/ProxmoxVE/pull/10538))
### 🌐 Website
- #### 📝 Script Information
- Prowlarr: Update config_path [@tremor021](https://github.com/tremor021) ([#10504](https://github.com/community-scripts/ProxmoxVE/pull/10504))
## 2026-01-03
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Fix ownership and permissions for InvoiceNinja setup [@twinzdragonz](https://github.com/twinzdragonz) ([#10298](https://github.com/community-scripts/ProxmoxVE/pull/10298))
- Fix headscale Caddyfile to pass non-API URLs [@IlyaSemenov](https://github.com/IlyaSemenov) ([#10493](https://github.com/community-scripts/ProxmoxVE/pull/10493))
### 💾 Core
- #### 🔧 Refactor
- [core]: Preserve log files [@tremor021](https://github.com/tremor021) ([#10509](https://github.com/community-scripts/ProxmoxVE/pull/10509))
### ❔ Uncategorized
- Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496))
- InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497))
## 2026-01-02
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Fix Intel Level Zero package conflict on Debian 13 [@Copilot](https://github.com/Copilot) ([#10467](https://github.com/community-scripts/ProxmoxVE/pull/10467))
### ❔ Uncategorized
- Extend guidance for changing the immich upload location for #10447 [@jshprentz](https://github.com/jshprentz) ([#10475](https://github.com/community-scripts/ProxmoxVE/pull/10475))

View File

@@ -36,10 +36,6 @@ function update_script() {
exit exit
fi fi
setup_uv
PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/package.json" | jq -r '.packageManager | split("@")[1]')"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
if [[ ! -f /etc/apt/preferences.d/preferences ]]; then if [[ ! -f /etc/apt/preferences.d/preferences ]]; then
msg_info "Adding Debian Testing repo" msg_info "Adding Debian Testing repo"
sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources
@@ -109,7 +105,7 @@ EOF
msg_ok "Image-processing libraries up to date" msg_ok "Image-processing libraries up to date"
fi fi
RELEASE="2.5.2" RELEASE="2.5.3"
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode" msg_info "Enabling Maintenance Mode"
@@ -164,7 +160,10 @@ EOF
rm -rf "${APP_DIR:?}"/* rm -rf "${APP_DIR:?}"/*
) )
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
msg_info "Updating Immich web and microservices" msg_info "Updating Immich web and microservices"
cd "$SRC_DIR"/server cd "$SRC_DIR"/server

View File

@@ -59,6 +59,8 @@ function update_script() {
$STD yarn install $STD yarn install
$STD yarn build $STD yarn build
mkdir -p /opt/koillection/public/uploads mkdir -p /opt/koillection/public/uploads
mkdir -p /opt/koillection/var/log
chown -R www-data:www-data /opt/koillection/var/log
chown -R www-data:www-data /opt/koillection/public/uploads chown -R www-data:www-data /opt/koillection/public/uploads
rm -r /opt/koillection-backup rm -r /opt/koillection-backup

View File

@@ -29,7 +29,7 @@ function update_script() {
exit exit
fi fi
if check_for_gh_release "scanopy" "scanopy/scanopy"; then if check_for_gh_release "Scanopy" "scanopy/scanopy"; then
msg_info "Stopping services" msg_info "Stopping services"
systemctl stop scanopy-server systemctl stop scanopy-server
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon [[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
@@ -40,7 +40,7 @@ function update_script() {
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml [[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
msg_ok "Backed up configurations" msg_ok "Backed up configurations"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
ensure_dependencies pkg-config libssl-dev ensure_dependencies pkg-config libssl-dev
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')" TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
@@ -61,19 +61,22 @@ function update_script() {
$STD npm run build $STD npm run build
msg_ok "Created frontend UI" msg_ok "Created frontend UI"
msg_info "Building scanopy-server (patience)" msg_info "Building Scanopy Server (patience)"
cd /opt/scanopy/backend cd /opt/scanopy/backend
$STD cargo build --release --bin server $STD cargo build --release --bin server
mv ./target/release/server /usr/bin/scanopy-server mv ./target/release/server /usr/bin/scanopy-server
msg_ok "Built scanopy-server" msg_ok "Built Scanopy Server"
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && if [[ -f /etc/systemd/system/scanopy-daemon.service ]]; then
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64" && fetch_and_deploy_gh_release "Scanopy Daemon" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64"
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh && mv "/usr/local/bin/Scanopy Daemon" /usr/local/bin/scanopy-daemon
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh
sed -i -e 's|usr/bin|usr/local/bin|' \ sed -i -e 's|usr/bin|usr/local/bin|' \
-e 's/push/daemon_poll/' \ -e 's/push/daemon_poll/' \
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service && -e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service
systemctl daemon-reload systemctl daemon-reload
msg_ok "Updated Scanopy Daemon"
fi
msg_info "Starting services" msg_info "Starting services"
systemctl start scanopy-server systemctl start scanopy-server

View File

@@ -1,5 +1,5 @@
{ {
"generated": "2026-02-04T06:18:03Z", "generated": "2026-02-05T06:22:20Z",
"versions": [ "versions": [
{ {
"slug": "2fauth", "slug": "2fauth",
@@ -221,9 +221,9 @@
{ {
"slug": "cronicle", "slug": "cronicle",
"repo": "jhuckaby/Cronicle", "repo": "jhuckaby/Cronicle",
"version": "v0.9.102", "version": "v0.9.103",
"pinned": false, "pinned": false,
"date": "2025-12-19T03:45:13Z" "date": "2026-02-05T03:09:04Z"
}, },
{ {
"slug": "cryptpad", "slug": "cryptpad",
@@ -256,9 +256,9 @@
{ {
"slug": "docmost", "slug": "docmost",
"repo": "docmost/docmost", "repo": "docmost/docmost",
"version": "v0.25.0", "version": "v0.25.1",
"pinned": false, "pinned": false,
"date": "2026-02-04T00:33:45Z" "date": "2026-02-04T15:19:51Z"
}, },
{ {
"slug": "domain-locker", "slug": "domain-locker",
@@ -445,9 +445,9 @@
{ {
"slug": "headscale", "slug": "headscale",
"repo": "juanfont/headscale", "repo": "juanfont/headscale",
"version": "v0.27.1", "version": "v0.28.0",
"pinned": false, "pinned": false,
"date": "2025-11-11T19:32:29Z" "date": "2026-02-04T20:40:23Z"
}, },
{ {
"slug": "healthchecks", "slug": "healthchecks",
@@ -494,9 +494,9 @@
{ {
"slug": "homepage", "slug": "homepage",
"repo": "gethomepage/homepage", "repo": "gethomepage/homepage",
"version": "v1.9.0", "version": "v1.10.0",
"pinned": false, "pinned": false,
"date": "2026-01-19T05:46:09Z" "date": "2026-02-05T06:17:32Z"
}, },
{ {
"slug": "homer", "slug": "homer",
@@ -515,9 +515,9 @@
{ {
"slug": "huntarr", "slug": "huntarr",
"repo": "plexguide/Huntarr.io", "repo": "plexguide/Huntarr.io",
"version": "9.1.9.1", "version": "9.2.0",
"pinned": false, "pinned": false,
"date": "2026-02-04T01:08:22Z" "date": "2026-02-05T04:18:08Z"
}, },
{ {
"slug": "inspircd", "slug": "inspircd",
@@ -536,16 +536,16 @@
{ {
"slug": "invoiceninja", "slug": "invoiceninja",
"repo": "invoiceninja/invoiceninja", "repo": "invoiceninja/invoiceninja",
"version": "v5.12.53", "version": "v5.12.55",
"pinned": false, "pinned": false,
"date": "2026-02-04T00:52:01Z" "date": "2026-02-05T01:06:15Z"
}, },
{ {
"slug": "jackett", "slug": "jackett",
"repo": "Jackett/Jackett", "repo": "Jackett/Jackett",
"version": "v0.24.1027", "version": "v0.24.1032",
"pinned": false, "pinned": false,
"date": "2026-02-04T05:56:22Z" "date": "2026-02-05T05:55:27Z"
}, },
{ {
"slug": "joplin-server", "slug": "joplin-server",
@@ -746,9 +746,9 @@
{ {
"slug": "mealie", "slug": "mealie",
"repo": "mealie-recipes/mealie", "repo": "mealie-recipes/mealie",
"version": "v3.10.1", "version": "v3.10.2",
"pinned": false, "pinned": false,
"date": "2026-02-03T01:04:38Z" "date": "2026-02-04T23:32:32Z"
}, },
{ {
"slug": "mediamanager", "slug": "mediamanager",
@@ -781,9 +781,9 @@
{ {
"slug": "metube", "slug": "metube",
"repo": "alexta69/metube", "repo": "alexta69/metube",
"version": "2026.02.03", "version": "2026.02.04",
"pinned": false, "pinned": false,
"date": "2026-02-03T21:49:49Z" "date": "2026-02-04T20:01:18Z"
}, },
{ {
"slug": "miniflux", "slug": "miniflux",
@@ -1096,9 +1096,9 @@
{ {
"slug": "pulse", "slug": "pulse",
"repo": "rcourtman/Pulse", "repo": "rcourtman/Pulse",
"version": "v5.0.17", "version": "v5.1.2",
"pinned": false, "pinned": false,
"date": "2026-01-20T19:07:30Z" "date": "2026-02-05T00:18:57Z"
}, },
{ {
"slug": "pve-scripts-local", "slug": "pve-scripts-local",
@@ -1271,9 +1271,9 @@
{ {
"slug": "speedtest-tracker", "slug": "speedtest-tracker",
"repo": "alexjustesen/speedtest-tracker", "repo": "alexjustesen/speedtest-tracker",
"version": "v1.13.6", "version": "v1.13.8",
"pinned": false, "pinned": false,
"date": "2026-02-03T21:20:51Z" "date": "2026-02-04T19:24:23Z"
}, },
{ {
"slug": "spoolman", "slug": "spoolman",
@@ -1292,9 +1292,9 @@
{ {
"slug": "stirling-pdf", "slug": "stirling-pdf",
"repo": "Stirling-Tools/Stirling-PDF", "repo": "Stirling-Tools/Stirling-PDF",
"version": "v2.4.3", "version": "v2.4.4",
"pinned": false, "pinned": false,
"date": "2026-01-31T22:19:14Z" "date": "2026-02-05T00:15:53Z"
}, },
{ {
"slug": "streamlink-webui", "slug": "streamlink-webui",
@@ -1369,9 +1369,9 @@
{ {
"slug": "tianji", "slug": "tianji",
"repo": "msgbyte/tianji", "repo": "msgbyte/tianji",
"version": "v1.31.9", "version": "v1.31.10",
"pinned": false, "pinned": false,
"date": "2026-01-31T18:22:40Z" "date": "2026-02-04T17:21:04Z"
}, },
{ {
"slug": "traccar", "slug": "traccar",
@@ -1411,9 +1411,9 @@
{ {
"slug": "trip", "slug": "trip",
"repo": "itskovacs/TRIP", "repo": "itskovacs/TRIP",
"version": "1.38.0", "version": "1.38.1",
"pinned": false, "pinned": false,
"date": "2026-01-31T15:56:30Z" "date": "2026-02-04T18:10:15Z"
}, },
{ {
"slug": "tududi", "slug": "tududi",
@@ -1562,6 +1562,13 @@
"pinned": false, "pinned": false,
"date": "2026-01-08T09:50:00Z" "date": "2026-01-08T09:50:00Z"
}, },
{
"slug": "wishlist",
"repo": "cmintey/wishlist",
"version": "v0.59.0",
"pinned": false,
"date": "2026-01-19T16:42:14Z"
},
{ {
"slug": "wizarr", "slug": "wizarr",
"repo": "wizarrrr/wizarr", "repo": "wizarrrr/wizarr",
@@ -1569,6 +1576,13 @@
"pinned": false, "pinned": false,
"date": "2025-12-09T14:30:23Z" "date": "2025-12-09T14:30:23Z"
}, },
{
"slug": "writefreely",
"repo": "writefreely/writefreely",
"version": "v0.16.0",
"pinned": false,
"date": "2025-08-29T19:30:02Z"
},
{ {
"slug": "yt-dlp-webui", "slug": "yt-dlp-webui",
"repo": "marcopiovanello/yt-dlp-web-ui", "repo": "marcopiovanello/yt-dlp-web-ui",

View File

@@ -0,0 +1,44 @@
{
"name": "Immich Public Proxy",
"slug": "immich-public-proxy",
"categories": [
21
],
"date_created": "2026-02-04",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://github.com/alangrainger/immich-public-proxy/tree/main/docs",
"website": "https://github.com/alangrainger/immich-public-proxy",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/immich-public-proxy.webp",
"config_path": "/opt/immich-proxy/app/.env",
"description": "Share your Immich photos and albums in a safe way without exposing your Immich instance to the public.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/immich-public-proxy.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Requires Node.js 24+",
"type": "info"
},
{
"text": "Update with: update_immich-public-proxy",
"type": "info"
}
]
}

View File

@@ -1,84 +0,0 @@
{
"name": "PVE LXC Apps Updater",
"slug": "update-apps",
"categories": [
1
],
"date_created": "2025-02-04",
"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": "Only containers with `community-script` or `proxmox-helper-scripts` tags are listed for update.",
"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

@@ -23,6 +23,34 @@ import { Button } from "./ui/button";
import { Badge } from "./ui/badge"; import { Badge } from "./ui/badge";
import Link from "next/link"; import Link from "next/link";
function search(scripts: Script[], query: string): Script[] {
const queryLower = query.toLowerCase().trim();
const searchWords = queryLower.split(/\s+/).filter(Boolean);
return scripts
.map(script => {
const nameLower = script.name.toLowerCase();
const descriptionLower = (script.description || "").toLowerCase();
let score = 0;
for (const word of searchWords) {
if (nameLower.includes(word)) {
score += 10;
}
if (descriptionLower.includes(word)) {
score += 5;
}
}
return { script, score };
})
.filter(({ score }) => score > 0)
.sort((a, b) => b.score - a.score)
.slice(0, 20)
.map(({ script }) => script);
}
export function formattedBadge(type: string) { export function formattedBadge(type: string) {
switch (type) { switch (type) {
case "vm": case "vm":
@@ -51,9 +79,11 @@ function getRandomScript(categories: Category[], previouslySelected: Set<string>
} }
function CommandMenu() { function CommandMenu() {
const [query, setQuery] = React.useState("");
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [links, setLinks] = React.useState<Category[]>([]); const [links, setLinks] = React.useState<Category[]>([]);
const [isLoading, setIsLoading] = React.useState(false); const [isLoading, setIsLoading] = React.useState(false);
const [results, setResults] = React.useState<Script[]>([]);
const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set()); const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set());
const router = useRouter(); const router = useRouter();
@@ -70,6 +100,27 @@ function CommandMenu() {
}); });
}; };
React.useEffect(() => {
if (query.trim() === "") {
fetchSortedCategories();
}
else {
const scriptMap = new Map<string, Script>();
for (const category of links) {
for (const script of category.scripts || []) {
if (!scriptMap.has(script.slug)) {
scriptMap.set(script.slug, script);
}
}
}
const uniqueScripts = Array.from(scriptMap.values());
const filteredResults = search(uniqueScripts, query);
setResults(filteredResults);
}
}, [query]);
React.useEffect(() => { React.useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => { const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) { if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
@@ -197,20 +248,20 @@ function CommandMenu() {
<CommandDialog <CommandDialog
open={open} open={open}
onOpenChange={setOpen} onOpenChange={(open) => {
filter={(value: string, search: string) => { setOpen(open);
const searchLower = search.toLowerCase().trim(); if (open) {
if (!searchLower) setQuery("");
return 1; setResults([]);
const valueLower = value.toLowerCase(); }
const searchWords = searchLower.split(/\s+/).filter(Boolean);
// All search words must appear somewhere in the value (name + description)
const allWordsMatch = searchWords.every((word: string) => valueLower.includes(word));
return allWordsMatch ? 1 : 0;
}} }}
> >
<DialogTitle className="sr-only">Search scripts</DialogTitle> <DialogTitle className="sr-only">Search scripts</DialogTitle>
<CommandInput placeholder="Search for a script..." /> <CommandInput
placeholder="Search for a script..."
onValueChange={setQuery}
value={query}
/>
<CommandList> <CommandList>
<CommandEmpty> <CommandEmpty>
{isLoading ? ( {isLoading ? (
@@ -233,9 +284,10 @@ function CommandMenu() {
</div> </div>
)} )}
</CommandEmpty> </CommandEmpty>
{Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
<CommandGroup key={`category:${categoryName}`} heading={categoryName}> {results.length > 0 ? (
{scripts.map(script => ( <CommandGroup heading="Search Results">
{results.map(script => (
<CommandItem <CommandItem
key={`script:${script.slug}`} key={`script:${script.slug}`}
value={`${script.name} ${script.type} ${script.description || ""}`} value={`${script.name} ${script.type} ${script.description || ""}`}
@@ -268,7 +320,44 @@ function CommandMenu() {
</CommandItem> </CommandItem>
))} ))}
</CommandGroup> </CommandGroup>
))} ) : ( // When no search results, show all scripts grouped by category
Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
<CommandGroup key={`category:${categoryName}`} heading={categoryName}>
{scripts.map(script => (
<CommandItem
key={`script:${script.slug}`}
value={`${script.name} ${script.type} ${script.description || ""}`}
onSelect={() => {
setOpen(false);
router.push(`/scripts?id=${script.slug}`);
}}
tabIndex={0}
aria-label={`Open script ${script.name}`}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setOpen(false);
router.push(`/scripts?id=${script.slug}`);
}
}}
>
<div className="flex gap-2" onClick={() => setOpen(false)}>
<Image
src={script.logo || `/${basePath}/logo.png`}
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
unoptimized
width={16}
height={16}
alt=""
className="h-5 w-5"
/>
<span>{script.name}</span>
<span>{formattedBadge(script.type)}</span>
</div>
</CommandItem>
))}
</CommandGroup>
))
)}
</CommandList> </CommandList>
</CommandDialog> </CommandDialog>
</> </>

View File

@@ -13,44 +13,44 @@ setting_up_container
network_check network_check
update_os update_os
echo "" if [ -d /dev/dri ]; then
echo "" echo ""
echo -e "🤖 ${BL}Immich Machine Learning Options${CL}" echo ""
echo "─────────────────────────────────────────" echo -e "🤖 ${BL}Immich Machine Learning Options${CL}"
echo "Please choose your machine-learning type:" echo "─────────────────────────────────────────"
echo "" echo "Please choose your machine-learning type:"
echo " 1) CPU only (default)" echo ""
echo " 2) Intel OpenVINO (requires GPU passthrough)" echo " 1) CPU only (default)"
echo "" echo " 2) Intel OpenVINO (requires GPU passthrough)"
echo ""
read -r -p "${TAB3}Select machine-learning type [1]: " ML_TYPE read -r -p "${TAB3}Select machine-learning type [1]: " ML_TYPE
ML_TYPE="${ML_TYPE:-1}" ML_TYPE="${ML_TYPE:-1}"
if [[ "$ML_TYPE" == "2" ]]; then if [[ "$ML_TYPE" == "2" ]]; then
msg_info "Installing OpenVINO dependencies" msg_info "Installing OpenVINO dependencies"
touch ~/.openvino touch ~/.openvino
$STD apt install -y --no-install-recommends patchelf $STD apt install -y --no-install-recommends patchelf
tmp_dir=$(mktemp -d) tmp_dir=$(mktemp -d)
$STD pushd "$tmp_dir" $STD pushd "$tmp_dir"
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
readarray -t INTEL_URLS < <( readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}' sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}' sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
) )
for url in "${INTEL_URLS[@]}"; do for url in "${INTEL_URLS[@]}"; do
curl -fsSLO "$url" curl -fsSLO "$url"
done done
$STD apt install -y ./libigdgmm12*.deb $STD apt install -y ./libigdgmm12*.deb
rm ./libigdgmm12*.deb rm ./libigdgmm12*.deb
$STD apt install -y ./*.deb $STD apt install -y ./*.deb
$STD apt-mark hold libigdgmm12 $STD apt-mark hold libigdgmm12
$STD popd $STD popd
rm -rf "$tmp_dir" rm -rf "$tmp_dir"
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
msg_ok "Installed OpenVINO dependencies" msg_ok "Installed OpenVINO dependencies"
fi
fi fi
setup_uv
msg_info "Installing dependencies" msg_info "Installing dependencies"
$STD apt install --no-install-recommends -y \ $STD apt install --no-install-recommends -y \
git \ git \
@@ -144,8 +144,7 @@ msg_info "Installing packages from Debian Testing repo"
$STD apt install -t testing --no-install-recommends -yqq libmimalloc3 libde265-dev $STD apt install -t testing --no-install-recommends -yqq libmimalloc3 libde265-dev
msg_ok "Installed packages from Debian Testing repo" msg_ok "Installed packages from Debian Testing repo"
PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/package.json" | jq -r '.packageManager | split("@")[1]')" setup_uv
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
VCHORD_RELEASE="0.5.3" VCHORD_RELEASE="0.5.3"
@@ -290,7 +289,9 @@ ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata" GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache} mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.2" "$SRC_DIR" fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.3" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
msg_info "Installing Immich (patience)" msg_info "Installing Immich (patience)"

View File

@@ -23,7 +23,7 @@ msg_ok "Installed Dependencies"
PG_VERSION=17 setup_postgresql PG_VERSION=17 setup_postgresql
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy" fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')" TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
@@ -35,11 +35,11 @@ $STD npm ci --no-fund --no-audit
$STD npm run build $STD npm run build
msg_ok "Created frontend UI" msg_ok "Created frontend UI"
msg_info "Building scanopy-server (patience)" msg_info "Building Scanopy Server (patience)"
cd /opt/scanopy/backend cd /opt/scanopy/backend
$STD cargo build --release --bin server $STD cargo build --release --bin server
mv ./target/release/server /usr/bin/scanopy-server mv ./target/release/server /usr/bin/scanopy-server
msg_ok "Built scanopy-server" msg_ok "Built Scanopy Server"
msg_info "Configuring server for first-run" msg_info "Configuring server for first-run"
cat <<EOF >/opt/scanopy/.env cat <<EOF >/opt/scanopy/.env

View File

@@ -0,0 +1,264 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/alangrainger/immich-public-proxy
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# ==============================================================================
# CONFIGURATION
# ==============================================================================
APP="Immich Public Proxy"
APP_TYPE="addon"
INSTALL_PATH="/opt/immich-proxy"
CONFIG_PATH="/opt/immich-proxy/app"
DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
____ _ __ ____
/ _/___ ___ ____ ___ (_)____/ /_ / __ \_________ _ ____ __
/ // __ `__ \/ __ `__ \/ / ___/ __ \______/ /_/ / ___/ __ \| |/_/ / / /
_/ // / / / / / / / / / / / /__/ / / /_____/ ____/ / / /_/ /> </ /_/ /
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ /_/ \____/_/|_|\__, /
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
msg_error "Alpine is not supported for ${APP}. Use Debian."
exit 1
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now immich-proxy.service &>/dev/null || true
rm -f "$SERVICE_PATH"
rm -rf "$INSTALL_PATH"
rm -f "/usr/local/bin/update_immich-public-proxy"
rm -f "$HOME/.immichpublicproxy"
msg_ok "${APP} has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy"; then
msg_info "Stopping service"
systemctl stop immich-proxy.service &>/dev/null || true
msg_ok "Stopped service"
msg_info "Backing up configuration"
cp "$CONFIG_PATH"/.env /tmp/ipp.env.bak 2>/dev/null || true
cp "$CONFIG_PATH"/config.json /tmp/ipp.config.json.bak 2>/dev/null || true
msg_ok "Backed up configuration"
NODE_VERSION="24" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
msg_info "Restoring configuration"
cp /tmp/ipp.env.bak "$CONFIG_PATH"/.env 2>/dev/null || true
cp /tmp/ipp.config.json.bak "$CONFIG_PATH"/config.json 2>/dev/null || true
rm -f /tmp/ipp.*.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies"
cd "$CONFIG_PATH"
$STD npm install
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
msg_info "Starting service"
systemctl start immich-proxy
msg_ok "Started service"
msg_ok "Updated successfully"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
NODE_VERSION="24" setup_nodejs
# Force fresh download by removing version cache
rm -f "$HOME/.immichpublicproxy"
fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
msg_info "Installing dependencies"
cd "$CONFIG_PATH"
$STD npm install
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
MAX_ATTEMPTS=3
attempt=0
while true; do
attempt=$((attempt + 1))
read -rp "${TAB3}Enter your LOCAL Immich IP or domain (ex. 192.168.1.100 or immich.local.lan): " DOMAIN
if [[ -z "$DOMAIN" ]]; then
if ((attempt >= MAX_ATTEMPTS)); then
DOMAIN="${LOCAL_IP:-localhost}"
msg_warn "Using fallback: $DOMAIN"
break
fi
msg_warn "Domain cannot be empty! (Attempt $attempt/$MAX_ATTEMPTS)"
elif [[ "$DOMAIN" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
valid_ip=true
IFS='.' read -ra octets <<<"$DOMAIN"
for octet in "${octets[@]}"; do
if ((octet > 255)); then
valid_ip=false
break
fi
done
if $valid_ip; then
break
else
msg_warn "Invalid IP address!"
fi
elif [[ "$DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$ || "$DOMAIN" == "localhost" ]]; then
break
else
msg_warn "Invalid domain format!"
fi
done
msg_info "Creating configuration"
cat <<EOF >"$CONFIG_PATH"/.env
NODE_ENV=production
IMMICH_URL=http://${DOMAIN}:2283
EOF
chmod 600 "$CONFIG_PATH"/.env
msg_ok "Created configuration"
msg_info "Creating service"
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=Immich Public Proxy
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_PATH}
EnvironmentFile=${CONFIG_PATH}/.env
ExecStart=/usr/bin/node ${INSTALL_PATH}/app/server.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now immich-proxy
msg_ok "Created and started service"
# Create update script (simple wrapper that calls this addon with type=update)
msg_info "Creating update script"
cat <<'UPDATEEOF' >/usr/local/bin/update_immich-public-proxy
#!/usr/bin/env bash
# Immich Public Proxy Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/immich-public-proxy.sh)"
UPDATEEOF
chmod +x /usr/local/bin/update_immich-public-proxy
msg_ok "Created update script (/usr/local/bin/update_immich-public-proxy)"
echo ""
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
echo ""
msg_warn "Additional configuration is available at '/opt/immich-proxy/app/config.json'"
}
# ==============================================================================
# MAIN
# ==============================================================================
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
header_info
if [[ -d "$INSTALL_PATH" && -f "$SERVICE_PATH" ]]; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 1
fi
exit 0
fi
header_info
get_lxc_ip
# Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$SERVICE_PATH" ]]; then
msg_warn "${APP} is already installed."
echo ""
echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
# Fresh installation
msg_warn "${APP} is not installed."
echo ""
echo -e "${TAB}${INFO} This will install:"
echo -e "${TAB} - Node.js 24"
echo -e "${TAB} - Immich Public Proxy"
echo ""
echo -n "${TAB}Install ${APP}? (y/N): "
read -r install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
install
else
msg_warn "Installation cancelled. Exiting."
exit 0
fi

View File

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

View File

@@ -1,465 +0,0 @@
#!/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:-}"
# =============================================================================
# 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}"
}
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)
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 Container Update" --yesno "This will update LXC container. Proceed?" 10 58 || exit
fi
msg_info "Loading all possible LXC containers from Proxmox VE. 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="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:.*(${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"
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