Compare commits

..

1 Commits

Author SHA1 Message Date
Michel Roegl-Brunner
0925e14c26 Fix PBS microcode naming 2026-03-12 16:03:37 +01:00
345 changed files with 30389 additions and 11285 deletions

18
.gitattributes vendored
View File

@@ -4,29 +4,35 @@
*.sh linguist-detectable=true *.sh linguist-detectable=true
*.bash linguist-language=Shell *.bash linguist-language=Shell
*.func linguist-language=Shell *.func linguist-language=Shell
*.func linguist-detectable=true
*.install linguist-language=Shell *.install linguist-language=Shell
# --------------------------------------- # ---------------------------------------
# Exclude header art from stats # Treat Golang files as Go (for /api/)
api/**/*.go linguist-language=Go
# --------------------------------------- # ---------------------------------------
ct/headers/* linguist-documentation # Treat frontend as JavaScript/TypeScript (optional)
frontend/**/*.ts linguist-language=TypeScript
frontend/**/*.js linguist-language=JavaScript
# --------------------------------------- # ---------------------------------------
# Exclude documentation from stats # Exclude documentation from stats
# ---------------------------------------
*.md linguist-documentation *.md linguist-documentation
docs/** linguist-documentation
README.md linguist-documentation README.md linguist-documentation
CONTRIBUTING.md linguist-documentation CONTRIBUTING.md linguist-documentation
SECURITY.md linguist-documentation SECURITY.md linguist-documentation
# --------------------------------------- # ---------------------------------------
# Exclude generated/config files # Exclude generated/config files
# --------------------------------------- *.json linguist-generated
frontend/public/json/*.json linguist-generated=false
*.lock linguist-generated
*.yml linguist-generated
*.yaml linguist-generated
.github/** linguist-generated .github/** linguist-generated
.vscode/** linguist-generated .vscode/** linguist-generated
# --------------------------------------- # ---------------------------------------
# Standard text handling # Standard text handling
# ---------------------------------------
* text=auto eol=lf * text=auto eol=lf

3
.github/CODEOWNERS generated vendored
View File

@@ -12,3 +12,6 @@
# Set default reviewers # Set default reviewers
* @community-scripts/Contributor * @community-scripts/Contributor
# All changes in frontend
/frontend/ @community-scripts/Frontend-Dev

528
.github/changelogs/2026/03.md generated vendored
View File

@@ -1,531 +1,3 @@
## 2026-03-31
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Graylog: set vm.max_map_count on host for OpenSearch [@MickLesk](https://github.com/MickLesk) ([#13441](https://github.com/community-scripts/ProxmoxVE/pull/13441))
- Koillection: ensure newline before appending to .env.local [@MickLesk](https://github.com/MickLesk) ([#13440](https://github.com/community-scripts/ProxmoxVE/pull/13440))
### 💾 Core
- #### 🔧 Refactor
- core: skip empty gateway value in network config [@MickLesk](https://github.com/MickLesk) ([#13442](https://github.com/community-scripts/ProxmoxVE/pull/13442))
## 2026-03-30
### 🆕 New Scripts
- Bambuddy ([#13411](https://github.com/community-scripts/ProxmoxVE/pull/13411))
### 🚀 Updated Scripts
- #### 💥 Breaking Changes
- Rename: BirdNET > BirdNET-Go [@MickLesk](https://github.com/MickLesk) ([#13410](https://github.com/community-scripts/ProxmoxVE/pull/13410))
## 2026-03-29
### 🆕 New Scripts
- YOURLS ([#13379](https://github.com/community-scripts/ProxmoxVE/pull/13379))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(victoriametrics): use jq to filter releases [@Joery-M](https://github.com/Joery-M) ([#13393](https://github.com/community-scripts/ProxmoxVE/pull/13393))
- Ollama: add error handling for Intel GPG key imports [@MickLesk](https://github.com/MickLesk) ([#13397](https://github.com/community-scripts/ProxmoxVE/pull/13397))
- Immich: ignore Redis connection error on maintenance mode disable [@MickLesk](https://github.com/MickLesk) ([#13398](https://github.com/community-scripts/ProxmoxVE/pull/13398))
- NPM: unmask openresty after migration from package [@MickLesk](https://github.com/MickLesk) ([#13399](https://github.com/community-scripts/ProxmoxVE/pull/13399))
## 2026-03-28
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Fix: Update gokapi binary name for v2.2.4+ and add migration step [@krazos](https://github.com/krazos) ([#13377](https://github.com/community-scripts/ProxmoxVE/pull/13377))
- Fix: update gokapi asset matching for v2.2.4+ naming convention [@krazos](https://github.com/krazos) ([#13369](https://github.com/community-scripts/ProxmoxVE/pull/13369))
- Tandoor Recipes: Add missing env variable [@tremor021](https://github.com/tremor021) ([#13365](https://github.com/community-scripts/ProxmoxVE/pull/13365))
- #### ✨ New Features
- FileFlows: add option to install Node [@tremor021](https://github.com/tremor021) ([#13368](https://github.com/community-scripts/ProxmoxVE/pull/13368))
## 2026-03-27
### 🆕 New Scripts
- Matter-Server ([#13355](https://github.com/community-scripts/ProxmoxVE/pull/13355))
- GeoPulse ([#13320](https://github.com/community-scripts/ProxmoxVE/pull/13320))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- RevealJS: Switch from gulp to vite [@tremor021](https://github.com/tremor021) ([#13336](https://github.com/community-scripts/ProxmoxVE/pull/13336))
- #### ✨ New Features
- Dispatcharr add custom Postgres port support for upgrade [@MickLesk](https://github.com/MickLesk) ([#13347](https://github.com/community-scripts/ProxmoxVE/pull/13347))
- Immich: bump to v2.6.3 [@MickLesk](https://github.com/MickLesk) ([#13324](https://github.com/community-scripts/ProxmoxVE/pull/13324))
### 🧰 Tools
- #### ✨ New Features
- Refactor/Feature-Bump/Security: Update-Cron-LXCs (Now Local Mode!) [@MickLesk](https://github.com/MickLesk) ([#13339](https://github.com/community-scripts/ProxmoxVE/pull/13339))
## 2026-03-26
### 🆕 New Scripts
- BirdNET ([#13313](https://github.com/community-scripts/ProxmoxVE/pull/13313))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Bump to 2.6.2 | use start.sh in service, ensure DB_HOSTNAME in .env | Fix Rights Issue with ZFS Shares [@MickLesk](https://github.com/MickLesk) ([#13199](https://github.com/community-scripts/ProxmoxVE/pull/13199))
- #### ✨ New Features
- SparkyFitness: add garmin microservice as addon [@tomfrenzel](https://github.com/tomfrenzel) ([#12642](https://github.com/community-scripts/ProxmoxVE/pull/12642))
- Frigate: bump to v0.17.1 & change build order [@MickLesk](https://github.com/MickLesk) ([#13304](https://github.com/community-scripts/ProxmoxVE/pull/13304))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: pin npm to 11.11.0 to work around Node.js 22.22.2 regression [@MickLesk](https://github.com/MickLesk) ([#13296](https://github.com/community-scripts/ProxmoxVE/pull/13296))
- #### ✨ New Features
- core: APT/APK Mirror Fallback for CDN Failures [@MickLesk](https://github.com/MickLesk) ([#13316](https://github.com/community-scripts/ProxmoxVE/pull/13316))
- core/tools: replace generic return 1 exit_codes with more specific exit_codes [@MickLesk](https://github.com/MickLesk) ([#13311](https://github.com/community-scripts/ProxmoxVE/pull/13311))
- #### 🔧 Refactor
- core: use /usr/bin/install to prevent function shadowing [@MickLesk](https://github.com/MickLesk) ([#13299](https://github.com/community-scripts/ProxmoxVE/pull/13299))
### 🧰 Tools
- #### 🐞 Bug Fixes
- SparkyFitness-Garmin: fix app name [@tomfrenzel](https://github.com/tomfrenzel) ([#13325](https://github.com/community-scripts/ProxmoxVE/pull/13325))
## 2026-03-25
### 🚀 Updated Scripts
- #### ✨ New Features
- Komodo v2: migrate env vars to v2 and update source [@MickLesk](https://github.com/MickLesk) ([#13262](https://github.com/community-scripts/ProxmoxVE/pull/13262))
### 💾 Core
- #### 🔧 Refactor
- core: make shell command substitutions safe with || true [@MickLesk](https://github.com/MickLesk) ([#13279](https://github.com/community-scripts/ProxmoxVE/pull/13279))
## 2026-03-24
### 🆕 New Scripts
- Homebrew (Addon) ([#13249](https://github.com/community-scripts/ProxmoxVE/pull/13249))
- NextExplorer ([#13252](https://github.com/community-scripts/ProxmoxVE/pull/13252))
### 🚀 Updated Scripts
- #### ✨ New Features
- Turnkey: modernize turnkey.sh with shared libraries [@MickLesk](https://github.com/MickLesk) ([#13242](https://github.com/community-scripts/ProxmoxVE/pull/13242))
- #### 🔧 Refactor
- chore: replace helper-scripts.com with community-scripts.com [@MickLesk](https://github.com/MickLesk) ([#13244](https://github.com/community-scripts/ProxmoxVE/pull/13244))
### 🗑️ Deleted Scripts
- Remove: Booklore [@MickLesk](https://github.com/MickLesk) ([#13265](https://github.com/community-scripts/ProxmoxVE/pull/13265))
## 2026-03-23
### 🚀 Updated Scripts
- #### 🔧 Refactor
- core: harden shell scripts against injection and insecure permissions [@MickLesk](https://github.com/MickLesk) ([#13239](https://github.com/community-scripts/ProxmoxVE/pull/13239))
## 2026-03-22
### 🆕 New Scripts
- versitygw ([#13180](https://github.com/community-scripts/ProxmoxVE/pull/13180))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Adventurelog: pin DRF <3.15 to fix coreapi module removal [@MickLesk](https://github.com/MickLesk) ([#13194](https://github.com/community-scripts/ProxmoxVE/pull/13194))
- #### ✨ New Features
- ConvertX: add libreoffice-writer for ODT/document conversions [@MickLesk](https://github.com/MickLesk) ([#13196](https://github.com/community-scripts/ProxmoxVE/pull/13196))
- #### 🔧 Refactor
- iSponsorblockTV: add AVX CPU check before installation [@MickLesk](https://github.com/MickLesk) ([#13197](https://github.com/community-scripts/ProxmoxVE/pull/13197))
### 💾 Core
- #### 🐞 Bug Fixes
- core: guard against empty IPv6 address in static mode [@MickLesk](https://github.com/MickLesk) ([#13195](https://github.com/community-scripts/ProxmoxVE/pull/13195))
## 2026-03-21
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Anytype-server: wait for MongoDB readiness before rs.initiate() [@MickLesk](https://github.com/MickLesk) ([#13165](https://github.com/community-scripts/ProxmoxVE/pull/13165))
- Frigate: use correct CPU model fallback path [@MickLesk](https://github.com/MickLesk) ([#13164](https://github.com/community-scripts/ProxmoxVE/pull/13164))
- iSponsorBlockTV: Fix release fetching [@tremor021](https://github.com/tremor021) ([#13157](https://github.com/community-scripts/ProxmoxVE/pull/13157))
- Isponsorblocktv: use quoted heredoc to prevent unbound variable error during CLI wrapper creation [@Copilot](https://github.com/Copilot) ([#13146](https://github.com/community-scripts/ProxmoxVE/pull/13146))
- #### ✨ New Features
- Headscale: Enable TUN [@tremor021](https://github.com/tremor021) ([#13158](https://github.com/community-scripts/ProxmoxVE/pull/13158))
### 💾 Core
- #### 🐞 Bug Fixes
- core: add missing -searchdomain/-nameserver prefix in base_settings [@MickLesk](https://github.com/MickLesk) ([#13166](https://github.com/community-scripts/ProxmoxVE/pull/13166))
## 2026-03-20
### 🆕 New Scripts
- iSponsorBlockTV ([#13123](https://github.com/community-scripts/ProxmoxVE/pull/13123))
- Alpine-Wakapi ([#13119](https://github.com/community-scripts/ProxmoxVE/pull/13119))
- teleport ([#13086](https://github.com/community-scripts/ProxmoxVE/pull/13086))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Reactive-Resume: add git dependency for v5.0.13+ [@MickLesk](https://github.com/MickLesk) ([#13133](https://github.com/community-scripts/ProxmoxVE/pull/13133))
- Scanopy: increase default CPU, RAM, and HDD to prevent OOM during Rust build [@Copilot](https://github.com/Copilot) ([#13130](https://github.com/community-scripts/ProxmoxVE/pull/13130))
- #### ✨ New Features
- Immich: v2.6.1 [@vhsdream](https://github.com/vhsdream) ([#13111](https://github.com/community-scripts/ProxmoxVE/pull/13111))
- VM's: add input validation and hostname sanitization to all VM scripts [@MickLesk](https://github.com/MickLesk) ([#12973](https://github.com/community-scripts/ProxmoxVE/pull/12973))
### 🧰 Tools
- #### 🔧 Refactor
- Harden code-server addon install script [@MickLesk](https://github.com/MickLesk) ([#13116](https://github.com/community-scripts/ProxmoxVE/pull/13116))
## 2026-03-19
### 🚀 Updated Scripts
- Owncast: increase default disk size from 2GB to 10GB [@Copilot](https://github.com/Copilot) ([#13079](https://github.com/community-scripts/ProxmoxVE/pull/13079))
- #### 🐞 Bug Fixes
- fix: remove extra backslash to match single quoted here-doc [@Zelnes](https://github.com/Zelnes) ([#13108](https://github.com/community-scripts/ProxmoxVE/pull/13108))
- Reactive-Resume: Upgrade Node to 24 and enable Corepack [@MickLesk](https://github.com/MickLesk) ([#13093](https://github.com/community-scripts/ProxmoxVE/pull/13093))
- Increase Tracearr RAM; derive APP_VERSION [@MickLesk](https://github.com/MickLesk) ([#13087](https://github.com/community-scripts/ProxmoxVE/pull/13087))
- ProjectSend: Update application access URL [@tremor021](https://github.com/tremor021) ([#13078](https://github.com/community-scripts/ProxmoxVE/pull/13078))
- Dispatcharr: use npm install --no-audit --progress=false [@MickLesk](https://github.com/MickLesk) ([#13074](https://github.com/community-scripts/ProxmoxVE/pull/13074))
- core: reorder hwaccel setup and adjust GPU group usermod [@MickLesk](https://github.com/MickLesk) ([#13072](https://github.com/community-scripts/ProxmoxVE/pull/13072))
- #### ✨ New Features
- tools.func: display pin reason in release-check messages [@MickLesk](https://github.com/MickLesk) ([#13095](https://github.com/community-scripts/ProxmoxVE/pull/13095))
- NocoDB: Unpin Version to latest [@MickLesk](https://github.com/MickLesk) ([#13094](https://github.com/community-scripts/ProxmoxVE/pull/13094))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: use dpkg-query for reliable JDK version detection [@MickLesk](https://github.com/MickLesk) ([#13101](https://github.com/community-scripts/ProxmoxVE/pull/13101))
### 📚 Documentation
- Update link from helper-scripts.com to community-scripts.org [@adnanvaldes](https://github.com/adnanvaldes) ([#13098](https://github.com/community-scripts/ProxmoxVE/pull/13098))
- github: add PocketBase bot workflow [@MickLesk](https://github.com/MickLesk) ([#13075](https://github.com/community-scripts/ProxmoxVE/pull/13075))
## 2026-03-18
### 🆕 New Scripts
- Alpine-Ntfy [@MickLesk](https://github.com/MickLesk) ([#13048](https://github.com/community-scripts/ProxmoxVE/pull/13048))
- Split-Pro ([#12975](https://github.com/community-scripts/ProxmoxVE/pull/12975))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Tdarr: use curl_with_retry and correct exit code [@MickLesk](https://github.com/MickLesk) ([#13060](https://github.com/community-scripts/ProxmoxVE/pull/13060))
- reitti: fix: v4 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13039](https://github.com/community-scripts/ProxmoxVE/pull/13039))
- Paperless-NGX: increase default RAM to 3GB [@MickLesk](https://github.com/MickLesk) ([#13018](https://github.com/community-scripts/ProxmoxVE/pull/13018))
- Plex: restart service after update to apply new version [@MickLesk](https://github.com/MickLesk) ([#13017](https://github.com/community-scripts/ProxmoxVE/pull/13017))
- #### ✨ New Features
- tools: centralize GPU group setup via setup_hwaccel [@MickLesk](https://github.com/MickLesk) ([#13044](https://github.com/community-scripts/ProxmoxVE/pull/13044))
- Termix: add guacd build and systemd integration [@MickLesk](https://github.com/MickLesk) ([#12999](https://github.com/community-scripts/ProxmoxVE/pull/12999))
- #### 🔧 Refactor
- Podman: replace deprecated commands with Quadlets [@MickLesk](https://github.com/MickLesk) ([#13052](https://github.com/community-scripts/ProxmoxVE/pull/13052))
- Refactor: Jellyfin repo, ffmpeg package and symlinks [@MickLesk](https://github.com/MickLesk) ([#13045](https://github.com/community-scripts/ProxmoxVE/pull/13045))
- pve-scripts-local: Increase default disk size from 4GB to 10GB [@MickLesk](https://github.com/MickLesk) ([#13009](https://github.com/community-scripts/ProxmoxVE/pull/13009))
### 💾 Core
- #### ✨ New Features
- tools.func Implement pg_cron setup for setup_postgresql [@MickLesk](https://github.com/MickLesk) ([#13053](https://github.com/community-scripts/ProxmoxVE/pull/13053))
- tools.func: Implement check_for_gh_tag function [@MickLesk](https://github.com/MickLesk) ([#12998](https://github.com/community-scripts/ProxmoxVE/pull/12998))
- tools.func: Implement fetch_and_deploy_gh_tag function [@MickLesk](https://github.com/MickLesk) ([#13000](https://github.com/community-scripts/ProxmoxVE/pull/13000))
## 2026-03-17
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Gluetun: add OpenVPN process user and cleanup stale config [@MickLesk](https://github.com/MickLesk) ([#13016](https://github.com/community-scripts/ProxmoxVE/pull/13016))
- Frigate: check OpenVino model files exist before configuring detector and use curl_with_retry instead of default wget [@MickLesk](https://github.com/MickLesk) ([#13019](https://github.com/community-scripts/ProxmoxVE/pull/13019))
### 💾 Core
- #### 🔧 Refactor
- tools.func: Update `create_self_signed_cert()` [@tremor021](https://github.com/tremor021) ([#13008](https://github.com/community-scripts/ProxmoxVE/pull/13008))
## 2026-03-16
### 🆕 New Scripts
- Gluetun ([#12976](https://github.com/community-scripts/ProxmoxVE/pull/12976))
- Anytype-Server ([#12974](https://github.com/community-scripts/ProxmoxVE/pull/12974))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: use gcc-13 for compilation & add uv python pre-install with retry logic [@MickLesk](https://github.com/MickLesk) ([#12935](https://github.com/community-scripts/ProxmoxVE/pull/12935))
- Tautulli: add setuptools<81 constraint to update script [@MickLesk](https://github.com/MickLesk) ([#12959](https://github.com/community-scripts/ProxmoxVE/pull/12959))
- Seerr: add missing build deps [@MickLesk](https://github.com/MickLesk) ([#12960](https://github.com/community-scripts/ProxmoxVE/pull/12960))
- fix: yubal update [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12961](https://github.com/community-scripts/ProxmoxVE/pull/12961))
### 💾 Core
- #### 🐞 Bug Fixes
- hwaccel: remove ROCm install from AMD APU setup [@MickLesk](https://github.com/MickLesk) ([#12958](https://github.com/community-scripts/ProxmoxVE/pull/12958))
## 2026-03-15
### 🆕 New Scripts
- Yamtrack ([#12936](https://github.com/community-scripts/ProxmoxVE/pull/12936))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Wishlist: use --frozen-lockfile for pnpm install [@MickLesk](https://github.com/MickLesk) ([#12892](https://github.com/community-scripts/ProxmoxVE/pull/12892))
- SparkyFitness: use --legacy-peer-deps for npm install [@MickLesk](https://github.com/MickLesk) ([#12888](https://github.com/community-scripts/ProxmoxVE/pull/12888))
- Frigate: add fallback for OpenVino labelmap file [@MickLesk](https://github.com/MickLesk) ([#12889](https://github.com/community-scripts/ProxmoxVE/pull/12889))
- #### 🔧 Refactor
- Refactor: ITSM-NG [@MickLesk](https://github.com/MickLesk) ([#12918](https://github.com/community-scripts/ProxmoxVE/pull/12918))
- core: unify RELEASE variable for check_for_gh_release and fetch_and_deploy [@MickLesk](https://github.com/MickLesk) ([#12917](https://github.com/community-scripts/ProxmoxVE/pull/12917))
- Standardize NSAPP names across VM scripts [@MickLesk](https://github.com/MickLesk) ([#12924](https://github.com/community-scripts/ProxmoxVE/pull/12924))
### 💾 Core
- #### ✨ New Features
- core: retry downloads with exponential backoff [@MickLesk](https://github.com/MickLesk) ([#12896](https://github.com/community-scripts/ProxmoxVE/pull/12896))
### ❔ Uncategorized
- [go2rtc] Add ffmpeg dependency to install script [@Copilot](https://github.com/Copilot) ([#12944](https://github.com/community-scripts/ProxmoxVE/pull/12944))
## 2026-03-14
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Patchmon: remove v prefix from pinned version [@MickLesk](https://github.com/MickLesk) ([#12891](https://github.com/community-scripts/ProxmoxVE/pull/12891))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: don't abort on AMD repo apt update failure [@MickLesk](https://github.com/MickLesk) ([#12890](https://github.com/community-scripts/ProxmoxVE/pull/12890))
## 2026-03-13
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Hotfix: Removed clean install usage from original script. [@nickheyer](https://github.com/nickheyer) ([#12870](https://github.com/community-scripts/ProxmoxVE/pull/12870))
- #### 🔧 Refactor
- Discopanel: V2 Support + Script rewrite [@nickheyer](https://github.com/nickheyer) ([#12763](https://github.com/community-scripts/ProxmoxVE/pull/12763))
### 🧰 Tools
- update-apps: fix restore path, add PBS support and improve restore messages [@omertahaoztop](https://github.com/omertahaoztop) ([#12528](https://github.com/community-scripts/ProxmoxVE/pull/12528))
- #### 🐞 Bug Fixes
- fix(pve-privilege-converter): handle already stopped container in manage_states [@liuqitoday](https://github.com/liuqitoday) ([#12765](https://github.com/community-scripts/ProxmoxVE/pull/12765))
### 📚 Documentation
- Update: Docs/website metadata workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12858](https://github.com/community-scripts/ProxmoxVE/pull/12858))
## 2026-03-12
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- manyfold: fix incorrect port in upstream requests by forwarding original host [@anlopo](https://github.com/anlopo) ([#12812](https://github.com/community-scripts/ProxmoxVE/pull/12812))
- SparkyFitness: install pnpm dependencies from workspace root [@MickLesk](https://github.com/MickLesk) ([#12792](https://github.com/community-scripts/ProxmoxVE/pull/12792))
- n8n: add build-essential to update dependencies [@MickLesk](https://github.com/MickLesk) ([#12795](https://github.com/community-scripts/ProxmoxVE/pull/12795))
- Frigate openvino labelmap patch [@semtex1987](https://github.com/semtex1987) ([#12751](https://github.com/community-scripts/ProxmoxVE/pull/12751))
- #### 🔧 Refactor
- Pin Patchmon to 1.4.2 [@vhsdream](https://github.com/vhsdream) ([#12789](https://github.com/community-scripts/ProxmoxVE/pull/12789))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: correct PATH escaping in ROCm profile script [@MickLesk](https://github.com/MickLesk) ([#12793](https://github.com/community-scripts/ProxmoxVE/pull/12793))
- #### ✨ New Features
- core: add mode=generated for unattended frontend installs [@MickLesk](https://github.com/MickLesk) ([#12807](https://github.com/community-scripts/ProxmoxVE/pull/12807))
- core: validate storage availability when loading defaults [@MickLesk](https://github.com/MickLesk) ([#12794](https://github.com/community-scripts/ProxmoxVE/pull/12794))
- #### 🔧 Refactor
- tools.func: support older NVIDIA driver versions with 2 segments (xxx.xxx) [@MickLesk](https://github.com/MickLesk) ([#12796](https://github.com/community-scripts/ProxmoxVE/pull/12796))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Fix PBS microcode naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12834](https://github.com/community-scripts/ProxmoxVE/pull/12834))
### 📂 Github
- Cleanup: remove old workflow files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12818](https://github.com/community-scripts/ProxmoxVE/pull/12818))
- Cleanup: remove frontend, move JSONs to json/ top-level [@MickLesk](https://github.com/MickLesk) ([#12813](https://github.com/community-scripts/ProxmoxVE/pull/12813))
### ❔ Uncategorized
- Remove json files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12830](https://github.com/community-scripts/ProxmoxVE/pull/12830))
## 2026-03-11
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: Init telemetry in addon scripts [@MickLesk](https://github.com/MickLesk) ([#12777](https://github.com/community-scripts/ProxmoxVE/pull/12777))
- Tracearr: Increase default disk variable from 5 to 10 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12762](https://github.com/community-scripts/ProxmoxVE/pull/12762))
- Fix Wireguard Dashboard update [@odin568](https://github.com/odin568) ([#12767](https://github.com/community-scripts/ProxmoxVE/pull/12767))
### 🧰 Tools
- #### ✨ New Features
- Coder-Code-Server: Check if config file exists [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12758](https://github.com/community-scripts/ProxmoxVE/pull/12758))
## 2026-03-10
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [Fix] Immich: Pin libvips to 8.17.3 [@vhsdream](https://github.com/vhsdream) ([#12744](https://github.com/community-scripts/ProxmoxVE/pull/12744))
## 2026-03-09
### 🚀 Updated Scripts
- Pin Opencloud to 5.2.0 [@vhsdream](https://github.com/vhsdream) ([#12721](https://github.com/community-scripts/ProxmoxVE/pull/12721))
- #### 🐞 Bug Fixes
- [Hotfix] qBittorrent: Disable UPnP port forwarding by default [@vhsdream](https://github.com/vhsdream) ([#12728](https://github.com/community-scripts/ProxmoxVE/pull/12728))
- [Quickfix] Opencloud: ensure correct case for binary [@vhsdream](https://github.com/vhsdream) ([#12729](https://github.com/community-scripts/ProxmoxVE/pull/12729))
- Omada: Bump libssl [@MickLesk](https://github.com/MickLesk) ([#12724](https://github.com/community-scripts/ProxmoxVE/pull/12724))
- openwebui: Ensure required dependencies [@MickLesk](https://github.com/MickLesk) ([#12717](https://github.com/community-scripts/ProxmoxVE/pull/12717))
- Frigate: try an OpenVino model build fallback [@MickLesk](https://github.com/MickLesk) ([#12704](https://github.com/community-scripts/ProxmoxVE/pull/12704))
- Change cronjob setup to use www-data user [@opastorello](https://github.com/opastorello) ([#12695](https://github.com/community-scripts/ProxmoxVE/pull/12695))
- RustDesk Server: Fix check_for_gh_release function call [@tremor021](https://github.com/tremor021) ([#12694](https://github.com/community-scripts/ProxmoxVE/pull/12694))
- #### ✨ New Features
- feat: improve zigbee2mqtt backup handler [@MickLesk](https://github.com/MickLesk) ([#12714](https://github.com/community-scripts/ProxmoxVE/pull/12714))
- #### 💥 Breaking Changes
- Reactive Resume: rewrite for v5 using original repo amruthpilla/reactive-resume [@MickLesk](https://github.com/MickLesk) ([#12705](https://github.com/community-scripts/ProxmoxVE/pull/12705))
### 💾 Core
- #### ✨ New Features
- tools: add Alpine (apk) support to ensure_dependencies and is_package_installed [@MickLesk](https://github.com/MickLesk) ([#12703](https://github.com/community-scripts/ProxmoxVE/pull/12703))
- tools.func: extend hwaccel with ROCm [@MickLesk](https://github.com/MickLesk) ([#12707](https://github.com/community-scripts/ProxmoxVE/pull/12707))
### 🌐 Website
- #### ✨ New Features
- feat: add CopycatWarningToast component for user warnings [@BramSuurdje](https://github.com/BramSuurdje) ([#12733](https://github.com/community-scripts/ProxmoxVE/pull/12733))
## 2026-03-08
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [Fix] Immich: chown install dir before machine-learning update [@vhsdream](https://github.com/vhsdream) ([#12684](https://github.com/community-scripts/ProxmoxVE/pull/12684))
- [Fix] Scanopy: Build generate-fixtures [@vhsdream](https://github.com/vhsdream) ([#12686](https://github.com/community-scripts/ProxmoxVE/pull/12686))
- fix: rustdeskserver: use correct repo string [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12682](https://github.com/community-scripts/ProxmoxVE/pull/12682))
- NZBGet: Fixes for RAR5 handling [@tremor021](https://github.com/tremor021) ([#12675](https://github.com/community-scripts/ProxmoxVE/pull/12675))
### 🌐 Website
- #### 🐞 Bug Fixes
- LXC-Execute: Fix slug [@tremor021](https://github.com/tremor021) ([#12681](https://github.com/community-scripts/ProxmoxVE/pull/12681))
## 2026-03-07 ## 2026-03-07
### 🆕 New Scripts ### 🆕 New Scripts

197
.github/changelogs/2026/04.md generated vendored
View File

@@ -1,197 +0,0 @@
## 2026-04-11
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Ensure newline before appending IMMICH_HELMET_FILE to .env [@MickLesk](https://github.com/MickLesk) ([#13667](https://github.com/community-scripts/ProxmoxVE/pull/13667))
- #### ✨ New Features
- BentoPDF: replace http-server with nginx to fix WASM initialization timeout [@MickLesk](https://github.com/MickLesk) ([#13625](https://github.com/community-scripts/ProxmoxVE/pull/13625))
- Element Synapse: Add MatrixRTC configuration for Element Call support [@MickLesk](https://github.com/MickLesk) ([#13665](https://github.com/community-scripts/ProxmoxVE/pull/13665))
- RomM: Use ROMM_BASE_PATH from .env for symlinks and nginx config [@MickLesk](https://github.com/MickLesk) ([#13666](https://github.com/community-scripts/ProxmoxVE/pull/13666))
- Immich: Pin version to 2.7.4 [@vhsdream](https://github.com/vhsdream) ([#13661](https://github.com/community-scripts/ProxmoxVE/pull/13661))
- #### 🔧 Refactor
- Crafty Controller: Wait for credentials file instead of fixed sleep [@MickLesk](https://github.com/MickLesk) ([#13670](https://github.com/community-scripts/ProxmoxVE/pull/13670))
- Refactor: Alpine-Wakapi [@tremor021](https://github.com/tremor021) ([#13656](https://github.com/community-scripts/ProxmoxVE/pull/13656))
## 2026-04-10
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: ensure trailing newline in redis.conf before appending bind directive [@Copilot](https://github.com/Copilot) ([#13647](https://github.com/community-scripts/ProxmoxVE/pull/13647))
- #### ✨ New Features
- Immich: Pin version to 2.7.3 [@vhsdream](https://github.com/vhsdream) ([#13631](https://github.com/community-scripts/ProxmoxVE/pull/13631))
- Homarr: bind Redis to localhost only [@MickLesk](https://github.com/MickLesk) ([#13552](https://github.com/community-scripts/ProxmoxVE/pull/13552))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: prevent script crash when entering GitHub token after rate limit [@MickLesk](https://github.com/MickLesk) ([#13638](https://github.com/community-scripts/ProxmoxVE/pull/13638))
### 🧰 Tools
- #### 🔧 Refactor
- addons: Filebrowser & Filebrowser-Quantum get warning if host install [@MickLesk](https://github.com/MickLesk) ([#13639](https://github.com/community-scripts/ProxmoxVE/pull/13639))
## 2026-04-09
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- boostack: add: git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13620](https://github.com/community-scripts/ProxmoxVE/pull/13620))
- #### ✨ New Features
- Update OPNsense version from 25.7 to 26.1 [@tdn131](https://github.com/tdn131) ([#13626](https://github.com/community-scripts/ProxmoxVE/pull/13626))
- CheckMK: Bump Default OS to 13 (trixie) + dynamic codename + fix RELEASE-Tag Fetching [@MickLesk](https://github.com/MickLesk) ([#13610](https://github.com/community-scripts/ProxmoxVE/pull/13610))
## 2026-04-08
### 🆕 New Scripts
- IronClaw | Alpine-IronClaw ([#13591](https://github.com/community-scripts/ProxmoxVE/pull/13591))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- immich: disable upgrade-insecure-requests CSP directive [@MickLesk](https://github.com/MickLesk) ([#13600](https://github.com/community-scripts/ProxmoxVE/pull/13600))
- Immich: v2.7.2 [@vhsdream](https://github.com/vhsdream) ([#13579](https://github.com/community-scripts/ProxmoxVE/pull/13579))
- Update flaresolverr-install.sh [@maztheman](https://github.com/maztheman) ([#13584](https://github.com/community-scripts/ProxmoxVE/pull/13584))
- #### ✨ New Features
- bambuddy: add mkdir before data restore & add ffmpeg dependency [@MickLesk](https://github.com/MickLesk) ([#13601](https://github.com/community-scripts/ProxmoxVE/pull/13601))
- #### 🔧 Refactor
- feat: update UHF Server script to use setup_ffmpeg [@zackwithak13](https://github.com/zackwithak13) ([#13564](https://github.com/community-scripts/ProxmoxVE/pull/13564))
### 💾 Core
- #### ✨ New Features
- core: add script page badges to descriptions | change donate URL [@MickLesk](https://github.com/MickLesk) ([#13596](https://github.com/community-scripts/ProxmoxVE/pull/13596))
## 2026-04-07
### 🗑️ Deleted Scripts
- Remove low-install-count CT scripts and installers [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#13570](https://github.com/community-scripts/ProxmoxVE/pull/13570))
### 💾 Core
- #### ✨ New Features
- core: improve resilience for top Proxmox error codes (209, 215, 118, 206) [@MickLesk](https://github.com/MickLesk) ([#13575](https://github.com/community-scripts/ProxmoxVE/pull/13575))
## 2026-04-06
### 🆕 New Scripts
- OpenThread Border Router ([#13536](https://github.com/community-scripts/ProxmoxVE/pull/13536))
- Homelable ([#13539](https://github.com/community-scripts/ProxmoxVE/pull/13539))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Papra: check env before copy [@MickLesk](https://github.com/MickLesk) ([#13553](https://github.com/community-scripts/ProxmoxVE/pull/13553))
- changedetection: fix: typing_extensions error [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13548](https://github.com/community-scripts/ProxmoxVE/pull/13548))
- kasm: fix: fetch latest version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13547](https://github.com/community-scripts/ProxmoxVE/pull/13547))
## 2026-04-05
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grist: remove install:ee step (private repo, not needed for grist-core) [@MickLesk](https://github.com/MickLesk) ([#13526](https://github.com/community-scripts/ProxmoxVE/pull/13526))
- Nginx Proxy Manager: ensure /tmp/nginx/body exists via openresty service [@MickLesk](https://github.com/MickLesk) ([#13528](https://github.com/community-scripts/ProxmoxVE/pull/13528))
- MotionEye: run as root to enable SMB share support [@MickLesk](https://github.com/MickLesk) ([#13527](https://github.com/community-scripts/ProxmoxVE/pull/13527))
### 💾 Core
- #### 🔧 Refactor
- core: silent() function - use return instead of exit to allow || true error handling [@MickLesk](https://github.com/MickLesk) ([#13529](https://github.com/community-scripts/ProxmoxVE/pull/13529))
## 2026-04-04
### 🧰 Tools
- #### 🐞 Bug Fixes
- komodo: set `PERIPHERY_CORE_PUBLIC_KEYS` to default value if absent [@4ndv](https://github.com/4ndv) ([#13519](https://github.com/community-scripts/ProxmoxVE/pull/13519))
## 2026-04-03
### 🆕 New Scripts
- netboot.xyz ([#13480](https://github.com/community-scripts/ProxmoxVE/pull/13480))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- OpenWRT-VM: use poweroff instead of halt to properly stop VM [@MickLesk](https://github.com/MickLesk) ([#13504](https://github.com/community-scripts/ProxmoxVE/pull/13504))
- NginxProxyManager: fix openresty restart by setting user root before reload [@MickLesk](https://github.com/MickLesk) ([#13500](https://github.com/community-scripts/ProxmoxVE/pull/13500))
- #### ✨ New Features
- Crafty Controller: add Java 25 for Minecraft 1.26.1+ [@MickLesk](https://github.com/MickLesk) ([#13502](https://github.com/community-scripts/ProxmoxVE/pull/13502))
- Wealthfolio: update to v3.2.1 and Node.js 24 [@afadil](https://github.com/afadil) ([#13486](https://github.com/community-scripts/ProxmoxVE/pull/13486))
### 💾 Core
- #### 🐞 Bug Fixes
- core.func: prevent profile.d scripts from aborting on non-zero exit [@MickLesk](https://github.com/MickLesk) ([#13503](https://github.com/community-scripts/ProxmoxVE/pull/13503))
- #### ✨ New Features
- APT Proxy: Support full URLs (http/https with custom ports) [@MickLesk](https://github.com/MickLesk) ([#13474](https://github.com/community-scripts/ProxmoxVE/pull/13474))
### 🧰 Tools
- #### 🐞 Bug Fixes
- PVE LXC-Updater: pipe apt list through cat to prevent pager hang [@MickLesk](https://github.com/MickLesk) ([#13501](https://github.com/community-scripts/ProxmoxVE/pull/13501))
## 2026-04-02
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grist: Guard backup restore for empty docs/db files [@MickLesk](https://github.com/MickLesk) ([#13472](https://github.com/community-scripts/ProxmoxVE/pull/13472))
- fix(zigbee2mqtt): suppress grep error when pnpm-workspace.yaml is absent on update [@Copilot](https://github.com/Copilot) ([#13476](https://github.com/community-scripts/ProxmoxVE/pull/13476))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Cron LXC Updater: Add full PATH for cron environment [@MickLesk](https://github.com/MickLesk) ([#13473](https://github.com/community-scripts/ProxmoxVE/pull/13473))
## 2026-04-01
### 🆕 New Scripts
- DrawDB ([#13454](https://github.com/community-scripts/ProxmoxVE/pull/13454))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Filebrowser: make noauth setup use correct database [@MickLesk](https://github.com/MickLesk) ([#13457](https://github.com/community-scripts/ProxmoxVE/pull/13457))

2
.github/pull_request_template.md generated vendored
View File

@@ -22,6 +22,6 @@ Fixes #
- [ ]**New feature** Adds new, non-breaking functionality. - [ ]**New feature** Adds new, non-breaking functionality.
- [ ] 💥 **Breaking change** Alters existing functionality in a way that may require updates. - [ ] 💥 **Breaking change** Alters existing functionality in a way that may require updates.
- [ ] 🆕 **New script** A fully functional and tested script or script set. - [ ] 🆕 **New script** A fully functional and tested script or script set.
- [ ] 🌍 **Website update** Changes to script metadata (PocketBase/website data). - [ ] 🌍 **Website update** Changes to website-related JSON files or metadata.
- [ ] 🔧 **Refactoring / Code Cleanup** Improves readability or maintainability without changing functionality. - [ ] 🔧 **Refactoring / Code Cleanup** Improves readability or maintainability without changing functionality.
- [ ] 📝 **Documentation update** Changes to `README`, `AppName.md`, `CONTRIBUTING.md`, or other docs. - [ ] 📝 **Documentation update** Changes to `README`, `AppName.md`, `CONTRIBUTING.md`, or other docs.

View File

@@ -21,7 +21,7 @@ jobs:
const message = `Hello, it looks like you are referencing the **old tteck repo**. const message = `Hello, it looks like you are referencing the **old tteck repo**.
This repository is no longer used for active scripts. This repository is no longer used for active scripts.
**Please update your bookmarks** and use: [https://community-scripts.com](https://community-scripts.com) **Please update your bookmarks** and use: [https://helper-scripts.com](https://helper-scripts.com)
Also make sure your Bash command starts with: Also make sure your Bash command starts with:
\`\`\`bash \`\`\`bash

View File

@@ -1,4 +1,4 @@
name: Set state to is_deleted in pocketbase name: Delete PocketBase entry on script/JSON removal
on: on:
push: push:
@@ -52,15 +52,15 @@ jobs:
slugs=$(echo $slugs | xargs -n1 | sort -u | tr '\n' ' ') slugs=$(echo $slugs | xargs -n1 | sort -u | tr '\n' ' ')
if [[ -z "$slugs" ]]; then if [[ -z "$slugs" ]]; then
echo "No deleted JSON or script files to mark as deleted in PocketBase." echo "No deleted JSON or script files to remove from PocketBase."
echo "count=0" >> "$GITHUB_OUTPUT" echo "count=0" >> "$GITHUB_OUTPUT"
exit 0 exit 0
fi fi
echo "$slugs" > slugs_to_delete.txt echo "$slugs" > slugs_to_delete.txt
echo "count=$(echo $slugs | wc -w)" >> "$GITHUB_OUTPUT" echo "count=$(echo $slugs | wc -w)" >> "$GITHUB_OUTPUT"
echo "Slugs to mark as deleted: $slugs" echo "Slugs to delete: $slugs"
- name: Mark as deleted in PocketBase - name: Delete from PocketBase
if: steps.slugs.outputs.count != '0' if: steps.slugs.outputs.count != '0'
env: env:
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }} POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
@@ -75,8 +75,7 @@ jobs:
const http = require('http'); const http = require('http');
const url = require('url'); const url = require('url');
function request(fullUrl, opts, redirectCount) { function request(fullUrl, opts) {
redirectCount = redirectCount || 0;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl); const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:'; const isHttps = u.protocol === 'https:';
@@ -91,13 +90,6 @@ jobs:
if (body) options.headers['Content-Length'] = Buffer.byteLength(body); if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http; const lib = isHttps ? https : http;
const req = lib.request(options, function(res) { const req = lib.request(options, function(res) {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
const redirectUrl = url.resolve(fullUrl, res.headers.location);
res.resume();
resolve(request(redirectUrl, opts, redirectCount + 1));
return;
}
let data = ''; let data = '';
res.on('data', function(chunk) { data += chunk; }); res.on('data', function(chunk) { data += chunk; });
res.on('end', function() { res.on('end', function() {
@@ -131,8 +123,6 @@ jobs:
const token = JSON.parse(authRes.body).token; const token = JSON.parse(authRes.body).token;
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records'; const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
const patchBody = JSON.stringify({ is_deleted: true });
for (const slug of slugs) { for (const slug of slugs) {
const filter = "(slug='" + slug + "')"; const filter = "(slug='" + slug + "')";
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', { const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
@@ -144,15 +134,14 @@ jobs:
console.log('No PocketBase record for slug "' + slug + '", skipping.'); console.log('No PocketBase record for slug "' + slug + '", skipping.');
continue; continue;
} }
const patchRes = await request(recordsUrl + '/' + existingId, { const delRes = await request(recordsUrl + '/' + existingId, {
method: 'PATCH', method: 'DELETE',
headers: { 'Authorization': token, 'Content-Type': 'application/json' }, headers: { 'Authorization': token }
body: patchBody
}); });
if (patchRes.ok) { if (delRes.ok) {
console.log('Set is_deleted=true for slug "' + slug + '" (id=' + existingId + ').'); console.log('Deleted PocketBase record for slug "' + slug + '" (id=' + existingId + ').');
} else { } else {
console.warn('PATCH failed for slug "' + slug + '": ' + patchRes.statusCode + ' ' + patchRes.body); console.warn('DELETE failed for slug "' + slug + '": ' + delRes.statusCode + ' ' + delRes.body);
} }
} }
console.log('Done.'); console.log('Done.');

801
.github/workflows/pocketbase-bot.yml generated vendored
View File

@@ -1,801 +0,0 @@
name: PocketBase Bot
on:
issue_comment:
types: [created]
permissions:
issues: write
pull-requests: write
contents: read
jobs:
pocketbase-bot:
runs-on: self-hosted
# Only act on /pocketbase commands
if: startsWith(github.event.comment.body, '/pocketbase')
steps:
- name: Execute PocketBase bot command
env:
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_ID: ${{ github.event.comment.id }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
ACTOR: ${{ github.event.comment.user.login }}
ACTOR_ASSOCIATION: ${{ github.event.comment.author_association }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FRONTEND_URL: ${{ secrets.FRONTEND_URL }}
REVALIDATE_SECRET: ${{ secrets.REVALIDATE_SECRET }}
run: |
node << 'ENDSCRIPT'
(async function () {
const https = require('https');
const http = require('http');
const url = require('url');
// ── HTTP helper with redirect following ────────────────────────────
function request(fullUrl, opts, redirectCount) {
redirectCount = redirectCount || 0;
return new Promise(function (resolve, reject) {
const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:';
const body = opts.body;
const options = {
hostname: u.hostname,
port: u.port || (isHttps ? 443 : 80),
path: u.path,
method: opts.method || 'GET',
headers: opts.headers || {}
};
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http;
const req = lib.request(options, function (res) {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
const redirectUrl = url.resolve(fullUrl, res.headers.location);
res.resume();
resolve(request(redirectUrl, opts, redirectCount + 1));
return;
}
let data = '';
res.on('data', function (chunk) { data += chunk; });
res.on('end', function () {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
// ── GitHub API helpers ─────────────────────────────────────────────
const owner = process.env.REPO_OWNER;
const repo = process.env.REPO_NAME;
const issueNumber = parseInt(process.env.ISSUE_NUMBER, 10);
const commentId = parseInt(process.env.COMMENT_ID, 10);
const actor = process.env.ACTOR;
function ghRequest(path, method, body) {
const headers = {
'Authorization': 'Bearer ' + process.env.GITHUB_TOKEN,
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
'User-Agent': 'PocketBase-Bot'
};
const bodyStr = body ? JSON.stringify(body) : undefined;
if (bodyStr) headers['Content-Type'] = 'application/json';
return request('https://api.github.com' + path, { method: method || 'GET', headers, body: bodyStr });
}
async function addReaction(content) {
try {
await ghRequest(
'/repos/' + owner + '/' + repo + '/issues/comments/' + commentId + '/reactions',
'POST', { content }
);
} catch (e) {
console.warn('Could not add reaction:', e.message);
}
}
async function postComment(text) {
const res = await ghRequest(
'/repos/' + owner + '/' + repo + '/issues/' + issueNumber + '/comments',
'POST', { body: text }
);
if (!res.ok) console.warn('Could not post comment:', res.body);
}
// ── Permission check ───────────────────────────────────────────────
const association = process.env.ACTOR_ASSOCIATION;
if (association !== 'OWNER' && association !== 'MEMBER') {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: @' + actor + ' is not authorized to use this command.\n' +
'Only org members (Contributors team) can use `/pocketbase`.'
);
process.exit(0);
}
// ── Acknowledge ────────────────────────────────────────────────────
await addReaction('eyes');
// ── Parse command ──────────────────────────────────────────────────
const commentBody = process.env.COMMENT_BODY || '';
const lines = commentBody.trim().split('\n');
const firstLine = lines[0].trim();
const withoutCmd = firstLine.replace(/^\/pocketbase\s+/, '').trim();
function extractCodeBlock(body) {
const m = body.match(/```[^\n]*\n([\s\S]*?)```/);
return m ? m[1].trim() : null;
}
const codeBlockValue = extractCodeBlock(commentBody);
const HELP_TEXT =
'**Show current state:**\n' +
'```\n/pocketbase <slug> info\n```\n\n' +
'**Field update (simple):** `/pocketbase <slug> field=value [field=value ...]`\n\n' +
'**Field update (HTML/multiline) — value from code block:**\n' +
'````\n' +
'/pocketbase <slug> set description\n' +
'```html\n' +
'<p>Your <b>HTML</b> or multi-line content here</p>\n' +
'```\n' +
'````\n\n' +
'**Note management:**\n' +
'```\n' +
'/pocketbase <slug> note list\n' +
'/pocketbase <slug> note add <type> "<text>"\n' +
'/pocketbase <slug> note edit <type> "<old text>" "<new text>"\n' +
'/pocketbase <slug> note remove <type> "<text>"\n' +
'```\n\n' +
'**Install method management:**\n' +
'```\n' +
'/pocketbase <slug> method list\n' +
'/pocketbase <slug> method <type> cpu=4 ram=2048 hdd=20\n' +
'/pocketbase <slug> method <type> config_path="/opt/app/.env"\n' +
'/pocketbase <slug> method <type> os=debian version=13\n' +
'/pocketbase <slug> method add <type> cpu=2 ram=2048 hdd=8 os=debian version=13\n' +
'/pocketbase <slug> method remove <type>\n' +
'```\n' +
'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' +
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `github` ' +
'`config_path` `port` `default_user` `default_passwd` ' +
'`updateable` `privileged` `has_arm` `is_dev` ' +
'`is_disabled` `disable_message` `is_deleted` `deleted_message`';
if (!withoutCmd) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: No slug or command specified.\n\n' + HELP_TEXT);
process.exit(0);
}
const spaceIdx = withoutCmd.indexOf(' ');
const slug = (spaceIdx === -1 ? withoutCmd : withoutCmd.substring(0, spaceIdx)).trim();
const rest = spaceIdx === -1 ? '' : withoutCmd.substring(spaceIdx + 1).trim();
if (!rest) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: No command specified for slug `' + slug + '`.\n\n' + HELP_TEXT);
process.exit(0);
}
// ── PocketBase: authenticate ───────────────────────────────────────
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
const coll = process.env.POCKETBASE_COLLECTION;
const authRes = await request(apiBase + '/collections/users/auth-with-password', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
identity: process.env.POCKETBASE_ADMIN_EMAIL,
password: process.env.POCKETBASE_ADMIN_PASSWORD
})
});
if (!authRes.ok) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: PocketBase authentication failed. CC @' + owner + '/maintainers');
process.exit(1);
}
const token = JSON.parse(authRes.body).token;
// ── PocketBase: find record by slug ────────────────────────────────
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
headers: { 'Authorization': token }
});
const list = JSON.parse(listRes.body);
const record = list.items && list.items[0];
if (!record) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: No record found for slug `' + slug + '`.\n\n' +
'Make sure the script was already pushed to PocketBase (JSON must exist and have been synced).'
);
process.exit(0);
}
// ── Shared helpers ─────────────────────────────────────────────────
// Key=value parser: handles unquoted and "quoted" values
function parseKVPairs(str) {
const fields = {};
let pos = 0;
while (pos < str.length) {
while (pos < str.length && /\s/.test(str[pos])) pos++;
if (pos >= str.length) break;
let keyStart = pos;
while (pos < str.length && str[pos] !== '=' && !/\s/.test(str[pos])) pos++;
const key = str.substring(keyStart, pos).trim();
if (!key || pos >= str.length || str[pos] !== '=') { pos++; continue; }
pos++;
let value;
if (pos < str.length && str[pos] === '"') {
pos++;
let valStart = pos;
while (pos < str.length && str[pos] !== '"') {
if (str[pos] === '\\') pos++;
pos++;
}
value = str.substring(valStart, pos).replace(/\\"/g, '"');
if (pos < str.length) pos++;
} else {
let valStart = pos;
while (pos < str.length && !/\s/.test(str[pos])) pos++;
value = str.substring(valStart, pos);
}
fields[key] = value;
}
return fields;
}
// Token parser for note commands: unquoted-word OR "quoted string"
function parseTokens(str) {
const tokens = [];
let pos = 0;
while (pos < str.length) {
while (pos < str.length && /\s/.test(str[pos])) pos++;
if (pos >= str.length) break;
if (str[pos] === '"') {
pos++;
let start = pos;
while (pos < str.length && str[pos] !== '"') {
if (str[pos] === '\\') pos++;
pos++;
}
tokens.push(str.substring(start, pos).replace(/\\"/g, '"'));
if (pos < str.length) pos++;
} else {
let start = pos;
while (pos < str.length && !/\s/.test(str[pos])) pos++;
tokens.push(str.substring(start, pos));
}
}
return tokens;
}
// Read JSON blob from record (handles parsed objects and strings)
function readJsonBlob(val) {
if (Array.isArray(val)) return val;
try { return JSON.parse(val || '[]'); } catch (e) { return []; }
}
// Frontend cache revalidation (silent, best-effort)
async function revalidate(s) {
const frontendUrl = process.env.FRONTEND_URL;
const secret = process.env.REVALIDATE_SECRET;
if (!frontendUrl || !secret) return;
try {
await request(frontendUrl.replace(/\/$/, '') + '/api/revalidate', {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + secret, 'Content-Type': 'application/json' },
body: JSON.stringify({ tags: ['scripts', 'script-' + s] })
});
} catch (e) { console.warn('Revalidation skipped:', e.message); }
}
// Format notes list for display
function formatNotesList(arr) {
if (arr.length === 0) return '*None*';
return arr.map(function (n, i) {
return (i + 1) + '. **`' + (n.type || '?') + '`**: ' + (n.text || '');
}).join('\n');
}
// Format install methods list for display
function formatMethodsList(arr) {
if (arr.length === 0) return '*None*';
return arr.map(function (im, i) {
const r = im.resources || {};
const parts = [
(r.os || '?') + ' ' + (r.version || '?'),
(r.cpu != null ? r.cpu : '?') + 'C / ' + (r.ram != null ? r.ram : '?') + ' MB / ' + (r.hdd != null ? r.hdd : '?') + ' GB'
];
if (im.config_path) parts.push('config: `' + im.config_path + '`');
if (im.script) parts.push('script: `' + im.script + '`');
return (i + 1) + '. **`' + (im.type || '?') + '`** — ' + parts.join(', ');
}).join('\n');
}
// ── Route: dispatch to subcommand handler ──────────────────────────
const infoMatch = rest.match(/^info$/i);
const noteMatch = rest.match(/^note\s+(list|add|edit|remove)\b/i);
const methodMatch = rest.match(/^method\b/i);
const setMatch = rest.match(/^set\s+(\S+)/i);
if (infoMatch) {
// ── INFO SUBCOMMAND ──────────────────────────────────────────────
const notesArr = readJsonBlob(record.notes_json);
const methodsArr = readJsonBlob(record.install_methods_json);
const out = [];
out.push(' **PocketBase Bot**: Info for **`' + slug + '`**\n');
out.push('**Basic info:**');
out.push('- **Name:** ' + (record.name || '—'));
out.push('- **Slug:** `' + slug + '`');
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
out.push('- **ARM:** ' + (record.has_arm ? 'Yes' : 'No'));
if (record.is_dev) out.push('- **Dev:** Yes');
if (record.is_disabled) out.push('- **Disabled:** Yes' + (record.disable_message ? ' — ' + record.disable_message : ''));
if (record.is_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : ''));
out.push('');
out.push('**Links:**');
out.push('- **Website:** ' + (record.website || '—'));
out.push('- **Docs:** ' + (record.documentation || '—'));
out.push('- **Logo:** ' + (record.logo ? '[link](' + record.logo + ')' : '—'));
out.push('- **GitHub:** ' + (record.github || '—'));
if (record.config_path) out.push('- **Config:** `' + record.config_path + '`');
out.push('');
out.push('**Credentials:**');
out.push('- **User:** ' + (record.default_user || '—'));
out.push('- **Password:** ' + (record.default_passwd ? '*(set)*' : '—'));
out.push('');
out.push('**Install methods** (' + methodsArr.length + '):');
out.push(formatMethodsList(methodsArr));
out.push('');
out.push('**Notes** (' + notesArr.length + '):');
out.push(formatNotesList(notesArr));
await addReaction('+1');
await postComment(out.join('\n'));
} else if (noteMatch) {
// ── NOTE SUBCOMMAND ──────────────────────────────────────────────
const noteAction = noteMatch[1].toLowerCase();
const noteArgsStr = rest.substring(noteMatch[0].length).trim();
let notesArr = readJsonBlob(record.notes_json);
async function patchNotes(arr) {
const res = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify({ notes_json: JSON.stringify(arr) })
});
if (!res.ok) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Failed to update notes:\n```\n' + res.body + '\n```');
process.exit(1);
}
}
if (noteAction === 'list') {
await addReaction('+1');
await postComment(
' **PocketBase Bot**: Notes for **`' + slug + '`** (' + notesArr.length + ' total)\n\n' +
formatNotesList(notesArr)
);
} else if (noteAction === 'add') {
const tokens = parseTokens(noteArgsStr);
if (tokens.length < 2) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: `note add` requires `<type>` and `"<text>"`.\n\n' +
'**Usage:** `/pocketbase ' + slug + ' note add <type> "<text>"`'
);
process.exit(0);
}
const noteType = tokens[0].toLowerCase();
const noteText = tokens.slice(1).join(' ');
notesArr.push({ type: noteType, text: noteText });
await patchNotes(notesArr);
await revalidate(slug);
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Added note to **`' + slug + '`**\n\n' +
'- **Type:** `' + noteType + '`\n' +
'- **Text:** ' + noteText + '\n\n' +
'*Executed by @' + actor + '*'
);
} else if (noteAction === 'edit') {
const tokens = parseTokens(noteArgsStr);
if (tokens.length < 3) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: `note edit` requires `<type>`, `"<old text>"`, and `"<new text>"`.\n\n' +
'**Usage:** `/pocketbase ' + slug + ' note edit <type> "<old text>" "<new text>"`\n\n' +
'Use `/pocketbase ' + slug + ' note list` to see current notes.'
);
process.exit(0);
}
const noteType = tokens[0].toLowerCase();
const oldText = tokens[1];
const newText = tokens[2];
const idx = notesArr.findIndex(function (n) {
return n.type.toLowerCase() === noteType && n.text === oldText;
});
if (idx === -1) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: No `' + noteType + '` note found with that exact text.\n\n' +
'**Current notes for `' + slug + '`:**\n' + formatNotesList(notesArr)
);
process.exit(0);
}
notesArr[idx].text = newText;
await patchNotes(notesArr);
await revalidate(slug);
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Edited note in **`' + slug + '`**\n\n' +
'- **Type:** `' + noteType + '`\n' +
'- **Old:** ' + oldText + '\n' +
'- **New:** ' + newText + '\n\n' +
'*Executed by @' + actor + '*'
);
} else if (noteAction === 'remove') {
const tokens = parseTokens(noteArgsStr);
if (tokens.length < 2) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: `note remove` requires `<type>` and `"<text>"`.\n\n' +
'**Usage:** `/pocketbase ' + slug + ' note remove <type> "<text>"`\n\n' +
'Use `/pocketbase ' + slug + ' note list` to see current notes.'
);
process.exit(0);
}
const noteType = tokens[0].toLowerCase();
const noteText = tokens[1];
const before = notesArr.length;
notesArr = notesArr.filter(function (n) {
return !(n.type.toLowerCase() === noteType && n.text === noteText);
});
if (notesArr.length === before) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: No `' + noteType + '` note found with that exact text.\n\n' +
'**Current notes for `' + slug + '`:**\n' + formatNotesList(notesArr)
);
process.exit(0);
}
await patchNotes(notesArr);
await revalidate(slug);
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Removed note from **`' + slug + '`**\n\n' +
'- **Type:** `' + noteType + '`\n' +
'- **Text:** ' + noteText + '\n\n' +
'*Executed by @' + actor + '*'
);
}
} else if (methodMatch) {
// ── METHOD SUBCOMMAND ────────────────────────────────────────────
const methodArgs = rest.replace(/^method\s*/i, '').trim();
const methodListMode = !methodArgs || methodArgs.toLowerCase() === 'list';
let methodsArr = readJsonBlob(record.install_methods_json);
// Method field classification
const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' };
const METHOD_KEYS = { config_path: 'string', script: 'string' };
const ALL_METHOD_KEYS = Object.assign({}, RESOURCE_KEYS, METHOD_KEYS);
function applyMethodChanges(method, parsed) {
if (!method.resources) method.resources = {};
for (const [k, v] of Object.entries(parsed)) {
if (RESOURCE_KEYS[k]) {
method.resources[k] = RESOURCE_KEYS[k] === 'number' ? parseInt(v, 10) : v;
} else if (METHOD_KEYS[k]) {
method[k] = v === '' ? null : v;
}
}
}
async function patchMethods(arr) {
const res = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify({ install_methods_json: arr })
});
if (!res.ok) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Failed to update install methods:\n```\n' + res.body + '\n```');
process.exit(1);
}
}
if (methodListMode) {
await addReaction('+1');
await postComment(
' **PocketBase Bot**: Install methods for **`' + slug + '`** (' + methodsArr.length + ' total)\n\n' +
formatMethodsList(methodsArr)
);
} else {
// Check for add / remove sub-actions
const addMatch = methodArgs.match(/^add\s+(\S+)(?:\s+(.+))?$/i);
const removeMatch = methodArgs.match(/^remove\s+(\S+)$/i);
if (addMatch) {
// ── METHOD ADD ───────────────────────────────────────────────
const newType = addMatch[1];
if (methodsArr.some(function (im) { return (im.type || '').toLowerCase() === newType.toLowerCase(); })) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Install method `' + newType + '` already exists for `' + slug + '`.\n\nUse `/pocketbase ' + slug + ' method list` to see all methods.');
process.exit(0);
}
const newMethod = { type: newType, resources: { cpu: 1, ram: 512, hdd: 4, os: 'debian', version: '13' } };
if (addMatch[2]) {
const parsed = parseKVPairs(addMatch[2]);
const unknown = Object.keys(parsed).filter(function (k) { return !ALL_METHOD_KEYS[k]; });
if (unknown.length > 0) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Unknown method field(s): `' + unknown.join('`, `') + '`\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
process.exit(0);
}
applyMethodChanges(newMethod, parsed);
}
methodsArr.push(newMethod);
await patchMethods(methodsArr);
await revalidate(slug);
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Added install method **`' + newType + '`** to **`' + slug + '`**\n\n' +
formatMethodsList([newMethod]) + '\n\n' +
'*Executed by @' + actor + '*'
);
} else if (removeMatch) {
// ── METHOD REMOVE ────────────────────────────────────────────
const removeType = removeMatch[1].toLowerCase();
const removed = methodsArr.filter(function (im) { return (im.type || '').toLowerCase() === removeType; });
if (removed.length === 0) {
await addReaction('-1');
const available = methodsArr.map(function (im) { return im.type || '?'; });
await postComment('❌ **PocketBase Bot**: No install method `' + removeType + '` found.\n\n**Available:** `' + (available.length ? available.join('`, `') : '(none)') + '`');
process.exit(0);
}
methodsArr = methodsArr.filter(function (im) { return (im.type || '').toLowerCase() !== removeType; });
await patchMethods(methodsArr);
await revalidate(slug);
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Removed install method **`' + removed[0].type + '`** from **`' + slug + '`**\n\n' +
'*Executed by @' + actor + '*'
);
} else {
// ── METHOD EDIT ──────────────────────────────────────────────
const editParts = methodArgs.match(/^(\S+)\s+(.+)$/);
if (!editParts) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: Invalid `method` syntax.\n\n' +
'**Usage:**\n```\n/pocketbase ' + slug + ' method list\n' +
'/pocketbase ' + slug + ' method <type> cpu=4 ram=2048 hdd=20\n' +
'/pocketbase ' + slug + ' method <type> config_path="/opt/app/.env"\n' +
'/pocketbase ' + slug + ' method add <type> cpu=2 ram=2048 hdd=8\n' +
'/pocketbase ' + slug + ' method remove <type>\n```'
);
process.exit(0);
}
const targetType = editParts[1].toLowerCase();
const parsed = parseKVPairs(editParts[2]);
const unknown = Object.keys(parsed).filter(function (k) { return !ALL_METHOD_KEYS[k]; });
if (unknown.length > 0) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Unknown method field(s): `' + unknown.join('`, `') + '`\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
process.exit(0);
}
if (Object.keys(parsed).length === 0) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: No valid `key=value` pairs found.\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
process.exit(0);
}
const idx = methodsArr.findIndex(function (im) { return (im.type || '').toLowerCase() === targetType; });
if (idx === -1) {
await addReaction('-1');
const available = methodsArr.map(function (im) { return im.type || '?'; });
await postComment(
'❌ **PocketBase Bot**: No install method `' + targetType + '` found for `' + slug + '`.\n\n' +
'**Available:** `' + (available.length ? available.join('`, `') : '(none)') + '`\n\n' +
'Use `/pocketbase ' + slug + ' method list` to see all methods.'
);
process.exit(0);
}
applyMethodChanges(methodsArr[idx], parsed);
await patchMethods(methodsArr);
await revalidate(slug);
const changesLines = Object.entries(parsed)
.map(function ([k, v]) {
const unit = k === 'ram' ? ' MB' : k === 'hdd' ? ' GB' : '';
return '- `' + k + '` → `' + v + unit + '`';
}).join('\n');
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Updated install method **`' + methodsArr[idx].type + '`** for **`' + slug + '`**\n\n' +
'**Changes applied:**\n' + changesLines + '\n\n' +
'*Executed by @' + actor + '*'
);
}
}
} else if (setMatch) {
// ── SET SUBCOMMAND (value from code block) ───────────────────────
const fieldName = setMatch[1].toLowerCase();
const SET_ALLOWED = {
name: 'string', description: 'string', logo: 'string',
documentation: 'string', website: 'string', project_url: 'string', github: 'string',
config_path: 'string', disable_message: 'string', deleted_message: 'string'
};
if (!SET_ALLOWED[fieldName]) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: `set` only supports text fields.\n\n' +
'**Allowed:** `' + Object.keys(SET_ALLOWED).join('`, `') + '`\n\n' +
'For boolean/number fields use `field=value` syntax instead.'
);
process.exit(0);
}
if (!codeBlockValue) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: `set` requires a code block with the value.\n\n' +
'**Usage:**\n````\n/pocketbase ' + slug + ' set ' + fieldName + '\n```\nYour content here (HTML, multiline, special chars all fine)\n```\n````'
);
process.exit(0);
}
const setPayload = {};
setPayload[fieldName] = codeBlockValue;
const setPatchRes = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify(setPayload)
});
if (!setPatchRes.ok) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + setPatchRes.body + '\n```');
process.exit(1);
}
await revalidate(slug);
const preview = codeBlockValue.length > 300 ? codeBlockValue.substring(0, 300) + '…' : codeBlockValue;
await addReaction('+1');
await postComment(
'✅ **PocketBase Bot**: Set `' + fieldName + '` for **`' + slug + '`**\n\n' +
'**Value set:**\n```\n' + preview + '\n```\n\n' +
'*Executed by @' + actor + '*'
);
} else {
// ── FIELD=VALUE PATH ─────────────────────────────────────────────
const ALLOWED_FIELDS = {
name: 'string',
description: 'string',
logo: 'string',
documentation: 'string',
website: 'string',
project_url: 'string',
github: 'string',
config_path: 'string',
port: 'number',
default_user: 'nullable_string',
default_passwd: 'nullable_string',
updateable: 'boolean',
privileged: 'boolean',
has_arm: 'boolean',
is_dev: 'boolean',
is_disabled: 'boolean',
disable_message: 'string',
is_deleted: 'boolean',
deleted_message: 'string',
};
const parsedFields = parseKVPairs(rest);
const unknownFields = Object.keys(parsedFields).filter(function (f) { return !ALLOWED_FIELDS[f]; });
if (unknownFields.length > 0) {
await addReaction('-1');
await postComment(
'❌ **PocketBase Bot**: Unknown field(s): `' + unknownFields.join('`, `') + '`\n\n' +
'**Allowed fields:** `' + Object.keys(ALLOWED_FIELDS).join('`, `') + '`'
);
process.exit(0);
}
if (Object.keys(parsedFields).length === 0) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: Could not parse any valid `field=value` pairs.\n\n' + HELP_TEXT);
process.exit(0);
}
// Cast values to correct types
const payload = {};
for (const [key, rawVal] of Object.entries(parsedFields)) {
const type = ALLOWED_FIELDS[key];
if (type === 'boolean') {
if (rawVal === 'true') payload[key] = true;
else if (rawVal === 'false') payload[key] = false;
else {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: `' + key + '` must be `true` or `false`, got: `' + rawVal + '`');
process.exit(0);
}
} else if (type === 'number') {
const n = parseInt(rawVal, 10);
if (isNaN(n)) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: `' + key + '` must be a number, got: `' + rawVal + '`');
process.exit(0);
}
payload[key] = n;
} else if (type === 'nullable_string') {
payload[key] = rawVal === '' ? null : rawVal;
} else {
payload[key] = rawVal;
}
}
const patchRes = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!patchRes.ok) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + patchRes.body + '\n```');
process.exit(1);
}
await revalidate(slug);
await addReaction('+1');
const changesLines = Object.entries(payload)
.map(function ([k, v]) { return '- `' + k + '` → `' + JSON.stringify(v) + '`'; })
.join('\n');
await postComment(
'✅ **PocketBase Bot**: Updated **`' + slug + '`** successfully!\n\n' +
'**Changes applied:**\n' + changesLines + '\n\n' +
'*Executed by @' + actor + '*'
);
}
console.log('Done.');
})().catch(function (e) {
console.error('Fatal error:', e.message || e);
process.exit(1);
});
ENDSCRIPT
shell: bash

View File

@@ -48,8 +48,7 @@ jobs:
const https = require('https'); const https = require('https');
const http = require('http'); const http = require('http');
const url = require('url'); const url = require('url');
function request(fullUrl, opts, redirectCount) { function request(fullUrl, opts) {
redirectCount = redirectCount || 0;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl); const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:'; const isHttps = u.protocol === 'https:';
@@ -64,13 +63,6 @@ jobs:
if (body) options.headers['Content-Length'] = Buffer.byteLength(body); if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http; const lib = isHttps ? https : http;
const req = lib.request(options, function(res) { const req = lib.request(options, function(res) {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
const redirectUrl = url.resolve(fullUrl, res.headers.location);
res.resume();
resolve(request(redirectUrl, opts, redirectCount + 1));
return;
}
let data = ''; let data = '';
res.on('data', function(chunk) { data += chunk; }); res.on('data', function(chunk) { data += chunk; });
res.on('end', function() { res.on('end', function() {
@@ -133,15 +125,15 @@ jobs:
var osVersionToId = {}; var osVersionToId = {};
try { try {
const res = await request(apiBase + '/collections/z_ref_note_types/records?perPage=500', { headers: { 'Authorization': token } }); const res = await request(apiBase + '/collections/z_ref_note_types/records?perPage=500', { headers: { 'Authorization': token } });
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) { noteTypeToId[item.type] = item.id; noteTypeToId[item.type.toLowerCase()] = item.id; } }); if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) noteTypeToId[item.type] = item.id; });
} catch (e) { console.warn('z_ref_note_types:', e.message); } } catch (e) { console.warn('z_ref_note_types:', e.message); }
try { try {
const res = await request(apiBase + '/collections/z_ref_install_method_types/records?perPage=500', { headers: { 'Authorization': token } }); const res = await request(apiBase + '/collections/z_ref_install_method_types/records?perPage=500', { headers: { 'Authorization': token } });
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) { installMethodTypeToId[item.type] = item.id; installMethodTypeToId[item.type.toLowerCase()] = item.id; } }); if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.type != null) installMethodTypeToId[item.type] = item.id; });
} catch (e) { console.warn('z_ref_install_method_types:', e.message); } } catch (e) { console.warn('z_ref_install_method_types:', e.message); }
try { try {
const res = await request(apiBase + '/collections/z_ref_os/records?perPage=500', { headers: { 'Authorization': token } }); const res = await request(apiBase + '/collections/z_ref_os/records?perPage=500', { headers: { 'Authorization': token } });
if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.os != null) { osToId[item.os] = item.id; osToId[item.os.toLowerCase()] = item.id; } }); if (res.ok) JSON.parse(res.body).items?.forEach(function(item) { if (item.os != null) osToId[item.os] = item.id; });
} catch (e) { console.warn('z_ref_os:', e.message); } } catch (e) { console.warn('z_ref_os:', e.message); }
try { try {
const res = await request(apiBase + '/collections/z_ref_os_version/records?perPage=500&expand=os', { headers: { 'Authorization': token } }); const res = await request(apiBase + '/collections/z_ref_os_version/records?perPage=500&expand=os', { headers: { 'Authorization': token } });
@@ -162,7 +154,7 @@ jobs:
name: data.name, name: data.name,
slug: data.slug, slug: data.slug,
script_created: data.date_created || data.script_created, script_created: data.date_created || data.script_created,
script_updated: new Date().toISOString().split('T')[0], script_updated: data.date_created || data.script_updated,
updateable: data.updateable, updateable: data.updateable,
privileged: data.privileged, privileged: data.privileged,
port: data.interface_port != null ? data.interface_port : data.port, port: data.interface_port != null ? data.interface_port : data.port,
@@ -170,8 +162,9 @@ jobs:
website: data.website, website: data.website,
logo: data.logo, logo: data.logo,
description: data.description, description: data.description,
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user || null, config_path: data.config_path,
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd || null, default_user: (data.default_credentials && data.default_credentials.username) || data.default_user,
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd,
is_dev: false is_dev: false
}; };
var resolvedType = typeValueToId[data.type]; var resolvedType = typeValueToId[data.type];
@@ -197,7 +190,7 @@ jobs:
var postRes = await request(notesCollUrl, { var postRes = await request(notesCollUrl, {
method: 'POST', method: 'POST',
headers: { 'Authorization': token, 'Content-Type': 'application/json' }, headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify({ text: note.text || '', type: typeId, script: scriptId }) body: JSON.stringify({ text: note.text || '', type: typeId })
}); });
if (postRes.ok) noteIds.push(JSON.parse(postRes.body).id); if (postRes.ok) noteIds.push(JSON.parse(postRes.body).id);
} }

View File

@@ -83,8 +83,7 @@ jobs:
const http = require('http'); const http = require('http');
const url = require('url'); const url = require('url');
function request(fullUrl, opts, redirectCount) { function request(fullUrl, opts) {
redirectCount = redirectCount || 0;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl); const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:'; const isHttps = u.protocol === 'https:';
@@ -99,13 +98,6 @@ jobs:
if (body) options.headers['Content-Length'] = Buffer.byteLength(body); if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http; const lib = isHttps ? https : http;
const req = lib.request(options, function(res) { const req = lib.request(options, function(res) {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
if (redirectCount >= 5) return reject(new Error('Too many redirects from ' + fullUrl));
const redirectUrl = url.resolve(fullUrl, res.headers.location);
res.resume();
resolve(request(redirectUrl, opts, redirectCount + 1));
return;
}
let data = ''; let data = '';
res.on('data', function(chunk) { data += chunk; }); res.on('data', function(chunk) { data += chunk; });
res.on('end', function() { res.on('end', function() {
@@ -155,21 +147,13 @@ jobs:
console.log('Slug not in DB, skipping: ' + slug); console.log('Slug not in DB, skipping: ' + slug);
continue; continue;
} }
const today = new Date().toISOString().split('T')[0];
const patchBody = {
script_updated: today,
last_update_commit: process.env.PR_URL || process.env.COMMIT_URL || ''
};
// When a dev script is merged into main, promote it to production
if (record.is_dev === true) {
patchBody.is_dev = false;
patchBody.script_created = today;
console.log('Promoting dev script to production: ' + slug);
}
const patchRes = await request(recordsUrl + '/' + record.id, { const patchRes = await request(recordsUrl + '/' + record.id, {
method: 'PATCH', method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' }, headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify(patchBody) body: JSON.stringify({
name: record.name || record.slug,
last_update_commit: process.env.PR_URL || process.env.COMMIT_URL || ''
})
}); });
if (!patchRes.ok) { if (!patchRes.ok) {
console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body); console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body);

43
.gitignore vendored
View File

@@ -2,14 +2,32 @@
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# Editor & IDE files # Editor & IDE files (keeping .vscode settings but ignoring unnecessary metadata)
!.vscode/ !.vscode/
.vscode/*.workspace .vscode/*.workspace
.vscode/*.tmp .vscode/*.tmp
# Log files # Log and Cache files
logs/ logs/
*.log *.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Python-specific exclusions
__pycache__/
*.pyc
*.pyo
*.pyd
*.venv/
venv/
env/
*.env
# API and Backend specific exclusions
api/.env
api/__pycache__/
api/*.sqlite3
# Install scripts and temporary files # Install scripts and temporary files
install/tmp/ install/tmp/
@@ -23,7 +41,7 @@ vm/*.vmdk
vm/*.iso vm/*.iso
vm/*.bak vm/*.bak
# Miscellaneous temporary files # Miscellaneous temporary or unnecessary files
*.bak *.bak
*.swp *.swp
*.swo *.swo
@@ -31,7 +49,22 @@ vm/*.bak
*.tmp *.tmp
*.backup *.backup
# JSON temporary files # JSON configuration backups
json/
json/*.bak json/*.bak
json/*.tmp json/*.tmp
json/.vscode/
# Ignore compiled binaries or packaged artifacts
*.exe
*.dll
*.bin
*.deb
*.rpm
*.tar.gz
*.zip
*.tgz
# Ignore repository metadata or Git itself
.git/
.gitignore
.vscode/settings.json

16
.vscode/.editorconfig generated vendored Normal file
View File

@@ -0,0 +1,16 @@
; editorconfig.org
root = true
[*]
charset = utf-8
continuation_indent_size = 2
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 120
tab_width = 2
; trim_trailing_whitespace = true ; disabled until files are cleaned up
[*.md]
trim_trailing_whitespace = false

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +0,0 @@
# Contributing to Proxmox VE Helper-Scripts
Welcome! We're glad you want to contribute. This guide covers everything you need to add new scripts, improve existing ones, or help in other ways.
For detailed coding standards and full documentation, visit **[community-scripts.org/docs](https://community-scripts.org/docs)**.
---
## How Can I Help?
> [!IMPORTANT]
> **New scripts** must always be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) first — not to this repository.
> PRs with new scripts opened directly against ProxmoxVE **will be closed without review**.
> **Bug fixes, improvements, and features for existing scripts** go here (ProxmoxVE).
| I want to… | Where to go |
| :------------------------------------------ | :------------------------------------------------------------------------------------------- |
| **Add a brand-new script** | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — testing repo for new scripts |
| **Fix a bug or improve an existing script** | This repo (ProxmoxVE) — open a PR here |
| **Add a feature to an existing script** | This repo (ProxmoxVE) — open a PR here |
| Report a bug or broken script | [Open an Issue](https://github.com/community-scripts/ProxmoxVE/issues) |
| Request a new script or feature | [Start a Discussion](https://github.com/community-scripts/ProxmoxVE/discussions) |
| Report a security vulnerability | [Security Policy](SECURITY.md) |
| Chat with contributors | [Discord](https://discord.gg/3AnUqsXnmK) |
---
## Prerequisites
Before writing scripts, we recommend setting up:
- **Visual Studio Code** with these extensions:
- [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax)
- [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)
- [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format)
---
## Script Structure
Every script consists of two files:
| File | Purpose |
| :--------------------------- | :------------------------------------------------------ |
| `ct/AppName.sh` | Container creation, variable setup, and update handling |
| `install/AppName-install.sh` | Application installation logic |
Use existing scripts in [`ct/`](ct/) and [`install/`](install/) as reference. Full coding standards and annotated templates are at **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**.
---
## Contribution Process
### Adding a new script
New scripts are **not accepted directly in this repository**. The workflow is:
1. Fork [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) and clone it
2. Create a branch: `git switch -c feat/myapp`
3. Write your two script files:
- `ct/myapp.sh`
- `install/myapp-install.sh`
4. Test thoroughly in ProxmoxVED — run the script against a real Proxmox instance
5. Open a PR in **ProxmoxVED** for review and testing
6. Once accepted and verified there, the script will be promoted to ProxmoxVE by maintainers
Follow the coding standards at [community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution).
---
### Fixing a bug or improving an existing script
Changes to scripts that already exist in ProxmoxVE go directly here:
1. Fork **this repository** (ProxmoxVE) and clone it:
```bash
git clone https://github.com/YOUR_USERNAME/ProxmoxVE
cd ProxmoxVE
```
2. Create a branch:
```bash
git switch -c fix/myapp-description
```
3. Make your changes to the relevant files in `ct/` and/or `install/`
4. Open a PR from your fork to `community-scripts/ProxmoxVE/main`
Your PR should only contain the files you changed. Do not include unrelated modifications.
---
## Code Standards
Key rules at a glance:
- One script per service — keep them focused
- Naming convention: lowercase, hyphen-separated (`my-app.sh`)
- Shebang: `#!/usr/bin/env bash`
- Quote all variables: `"$VAR"` not `$VAR`
- Use lowercase variable names
- Do not hardcode credentials or sensitive values
Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**
---
## Developer Mode & Debugging
Set the `dev_mode` variable to enable debugging features when testing. Flags can be combined (comma-separated):
```bash
dev_mode="trace,keep" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
```
| Flag | Description |
| :----------- | :----------------------------------------------------------- |
| `trace` | Enables `set -x` for maximum verbosity during execution |
| `keep` | Prevents the container from being deleted if the build fails |
| `pause` | Pauses execution at key points before customization |
| `breakpoint` | Drops to a shell at hardcoded `breakpoint` calls in scripts |
| `logs` | Saves detailed build logs to `/var/log/community-scripts/` |
| `dryrun` | Bypasses actual container creation (limited support) |
| `motd` | Forces an update of the Message of the Day |
---
## Notes
- **Website metadata** (name, description, logo, tags) is managed via the website — use the "Report Issue" link on any script page to request changes. Do not submit metadata changes via repo files.
- **JSON files** in `json/` define script properties used by the website. See existing files for structure reference.
- Keep PRs small and focused. One fix or feature per PR is ideal.
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) instead.
- PRs that fail CI checks will not be merged.

400
README.md
View File

@@ -1,209 +1,283 @@
<div align="center"> <div align="center">
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="112px" alt="Proxmox VE Helper-Scripts Logo" /> <img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="120px" alt="Proxmox VE Helper-Scripts Logo" />
<h1>Proxmox VE Helper-Scripts</h1> <h1>Proxmox VE Helper-Scripts</h1>
<p><strong>One-command installations for services, containers, and VMs on Proxmox VE</strong><br/> <p><em>A Community Legacy in Memory of @tteck</em></p>
A community project — built on the foundation of <a href="https://github.com/tteck">@tteck</a>'s original work</p>
<p> <p>
<a href="https://community-scripts.org"><img src="https://img.shields.io/badge/Website-community--scripts.org-4c9b3f?style=flat-square" /></a> <a href="https://helper-scripts.com">
<a href="https://discord.gg/3AnUqsXnmK"><img src="https://img.shields.io/badge/Discord-Join_us-7289da?style=flat-square&logo=discord&logoColor=white" /></a> <img src="https://img.shields.io/badge/🌐_Website-Visit-4c9b3f?style=for-the-badge&labelColor=2d3748" alt="Website" />
<a href="https://github.com/community-scripts/ProxmoxVE/stargazers"><img src="https://img.shields.io/github/stars/community-scripts/ProxmoxVE?style=flat-square&label=Stars&color=f5a623" /></a> </a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/Changelog-view-6c5ce7?style=flat-square" /></a> <a href="https://discord.gg/3AnUqsXnmK">
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=flat-square" /></a> <img src="https://img.shields.io/badge/💬_Discord-Join-7289da?style=for-the-badge&labelColor=2d3748" alt="Discord" />
</a>
<a href="https://ko-fi.com/community_scripts">
<img src="https://img.shields.io/badge/❤_Support-Donate-FF5F5F?style=for-the-badge&labelColor=2d3748" alt="Donate" />
</a>
</p> </p>
<p>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/README.md">
<img src="https://img.shields.io/badge/🤝_Contribute-Guidelines-ff4785?style=for-the-badge&labelColor=2d3748" alt="Contribute" />
</a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/USER_SUBMITTED_GUIDES.md">
<img src="https://img.shields.io/badge/📚_Guides-Read-0077b5?style=for-the-badge&labelColor=2d3748" alt="Guides" />
</a>
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md">
<img src="https://img.shields.io/badge/📋_Changelog-View-6c5ce7?style=for-the-badge&labelColor=2d3748" alt="Changelog" />
</a>
</p>
<br />
**Simplify your Proxmox VE setup with community-driven automation scripts**
Originally created by tteck, now maintained and expanded by the community
</div>
<br />
<div align="center">
<sub>🙌 <strong>Shoutout to</strong></sub>
<br />
<br />
<a href="https://selfh.st/">
<img src="https://img.shields.io/badge/selfh.st-Icons_for_Self--Hosted-2563eb?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMkM2LjQ4IDIgMiA2LjQ4IDIgMTJzNC40OCAxMCAxMCAxMCAxMC00LjQ4IDEwLTEwUzE3LjUyIDIgMTIgMnptMCAxOGMtNC40MSAwLTgtMy41OS04LThzMy41OS04IDgtOCA4IDMuNTkgOCA4LTMuNTkgOC04IDh6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==&labelColor=1e3a8a" alt="selfh.st Icons" />
</a>
<br />
<sub><a href="https://github.com/selfhst/icons">View on GitHub</a> • Consistent, beautiful icons for 5000+ self-hosted apps</sub>
</div> </div>
--- ---
## What is this? ## 🎯 Key Features
**Simplify your Proxmox VE setup with community-driven automation scripts.** <div align="center">
Install and configure popular self-hosted services with a single command — no manual package hunting, no config file archaeology. Paste a command into your Proxmox shell, answer a few prompts, and your container or VM is up and running. <table>
The collection covers hundreds of services across categories like home automation, media servers, networking tools, databases, monitoring stacks, and more.
---
## Requirements
| Component | Details |
| -------------- | ------------------------------------------------ |
| **Proxmox VE** | Version 8.4, 9.0, or 9.1 |
| **Host OS** | Proxmox VE (Debian-based) |
| **Access** | Root shell access on the Proxmox host |
| **Network** | Internet connection required during installation |
---
## Getting Started
The fastest way to find and run scripts:
1. Go to **[community-scripts.org](https://community-scripts.org)**
2. Search for the service you want (e.g. "Home Assistant", "Nginx Proxy Manager", "Jellyfin")
3. Copy the one-line install command from the script page
4. Open your **Proxmox Shell** and paste it
5. Choose between **Default** or **Advanced** setup and follow the prompts
Each script page documents what the container includes, default resource allocation, and post-install notes.
---
## How Scripts Work
Every script follows the same pattern:
**Default mode** — Picks sensible resource defaults (CPU, RAM, storage) and asks only the minimum required questions. Most installs finish in under five minutes.
**Advanced mode** — Gives you full control over container settings, networking, storage backends, and application-level configuration before anything is installed.
After installation, each container ships with a **post-install helper** accessible from the Proxmox shell. It handles common tasks like:
- Applying updates to the installed service
- Changing application settings without manually editing config files
- Basic troubleshooting and log access
---
## What's Included
The repository covers a wide range of categories. A few examples:
| Category | Examples |
| --------------- | --------------------------------------------------- |
| Home Automation | Home Assistant, Zigbee2MQTT, ESPHome, Node-RED |
| Media | Jellyfin, Plex, Radarr, Sonarr, Immich |
| Networking | AdGuard Home, Nginx Proxy Manager, Pi-hole, Traefik |
| Monitoring | Grafana, Prometheus, Uptime Kuma, Netdata |
| Databases | PostgreSQL, MariaDB, Redis, InfluxDB |
| Security | Vaultwarden, CrowdSec, Authentik |
| Dev & Tools | Gitea, Portainer, VS Code Server, n8n |
> Browse the full list at **[community-scripts.org/categories](https://community-scripts.org/categories)** — new scripts are added regularly.
---
## Contributing
This project runs on community contributions. Whether you want to write new scripts, improve existing ones, or just report a bug — every bit helps.
### Where to start
| I want to… | Go here |
| ------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Add a **new** script | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — new scripts are tested here first |
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR in this repo |
| Report a bug or broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
| Request a new script or feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
| Report a security vulnerability | [Security Policy](SECURITY.md) |
| Get help or chat with other users | [Discord](https://discord.gg/3AnUqsXnmK) |
### Before you open a PR
- **New scripts go to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED), not here.** PRs with new scripts opened directly against this repo will be closed.
- Bug fixes and improvements to existing scripts belong in this repo — read the [Contributing Guidelines](CONTRIBUTING.md) first.
- Keep PRs focused. One fix or feature per PR.
- Document what your script installs and any non-obvious decisions in the corresponding JSON metadata file.
---
## Core Team
<table align="center">
<tr> <tr>
<td align="center"> <td align="center" width="25%">
<a href="https://github.com/MickLesk"> <h3>⚡ Quick Setup</h3>
<img src="https://github.com/MickLesk.png" width="80" height="80" style="border-radius:50%" alt="MickLesk" /><br/> <p>One-command installations for popular services and containers</p>
<sub><b>MickLesk</b></sub> </td>
<td align="center" width="25%">
<h3>⚙️ Flexible Config</h3>
<p>Simple mode for beginners, advanced options for power users</p>
</td>
<td align="center" width="25%">
<h3>🔄 Auto Updates</h3>
<p>Keep your installations current with built-in update mechanisms</p>
</td>
<td align="center" width="25%">
<h3>🛠️ Easy Management</h3>
<p>Post-install scripts for configuration and troubleshooting</p>
</td>
</tr>
<tr>
<td align="center" width="25%">
<h3>👥 Community Driven</h3>
<p>Actively maintained with contributions from users worldwide</p>
</td>
<td align="center" width="25%">
<h3>📖 Well Documented</h3>
<p>Comprehensive guides and community support</p>
</td>
<td align="center" width="25%">
<h3>🔒 Secure</h3>
<p>Regular security updates and best practices</p>
</td>
<td align="center" width="25%">
<h3>⚡ Performance</h3>
<p>Optimized configurations for best performance</p>
</td>
</tr>
</table>
</div>
---
## 📋 Requirements
<div align="center">
<table>
<tr>
<td align="center" width="33%">
<h3>🖥️ Proxmox VE</h3>
<p>Version: 8.4.x | 9.0.x | 9.1.x</p>
</td>
<td align="center" width="33%">
<h3>🐧 Operating System</h3>
<p>Debian-based with Proxmox Tools</p>
</td>
<td align="center" width="33%">
<h3>🌐 Network</h3>
<p>Internet connection required</p>
</td>
</tr>
</table>
</div>
---
## 📥 Getting Started
Choose your preferred installation method:
### Method 1: One-Click Web Installer
The fastest way to get started:
1. Visit **[helper-scripts.com](https://helper-scripts.com/)** 🌐
2. Search for your desired script (e.g., "Home Assistant", "Docker")
3. Copy the bash command displayed on the script page
4. Open your **Proxmox Shell** and paste the command
5. Press Enter and follow the interactive prompts
### Method 2: PVEScripts-Local
Install a convenient script manager directly in your Proxmox UI:
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pve-scripts-local.sh)"
```
This adds a menu to your Proxmox interface for easy script access without visiting the website.
📖 **Learn more:** [ProxmoxVE-Local Repository](https://github.com/community-scripts/ProxmoxVE-Local)
---
## 💬 Join the Community
<div align="center">
<table>
<tr>
<td align="center" width="33%">
<h3>💬 Discord</h3>
<p>Real-time chat, support, and discussions</p>
<a href="https://discord.gg/3AnUqsXnmK">
<img src="https://img.shields.io/badge/Join-7289da?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" />
</a> </a>
</td> </td>
<td align="center"> <td align="center" width="33%">
<a href="https://github.com/michelroegl-brunner"> <h3>💭 Discussions</h3>
<img src="https://github.com/michelroegl-brunner.png" width="80" height="80" style="border-radius:50%" alt="michelroegl-brunner" /><br/> <p>Feature requests, Q&A, and ideas</p>
<sub><b>michelroegl-brunner</b></sub> <a href="https://github.com/community-scripts/ProxmoxVE/discussions">
<img src="https://img.shields.io/badge/Discuss-238636?style=for-the-badge&logo=github&logoColor=white" alt="Discussions" />
</a> </a>
</td> </td>
<td align="center"> <td align="center" width="33%">
<a href="https://github.com/BramSuurdje"> <h3>🐛 Issues</h3>
<img src="https://github.com/BramSuurdje.png" width="80" height="80" style="border-radius:50%" alt="BramSuurdje" /><br/> <p>Bug reports and issue tracking</p>
<sub><b>BramSuurdje</b></sub> <a href="https://github.com/community-scripts/ProxmoxVE/issues">
</a> <img src="https://img.shields.io/badge/Report-d73a4a?style=for-the-badge&logo=github&logoColor=white" alt="Issues" />
</td>
<td align="center">
<a href="https://github.com/CrazyWolf13">
<img src="https://github.com/CrazyWolf13.png" width="80" height="80" style="border-radius:50%" alt="CrazyWolf13" /><br/>
<sub><b>CrazyWolf13</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tremor021">
<img src="https://github.com/tremor021.png" width="80" height="80" style="border-radius:50%" alt="tremor021" /><br/>
<sub><b>tremor021</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/vhsdream">
<img src="https://github.com/vhsdream.png" width="80" height="80" style="border-radius:50%" alt="vhsdream" /><br/>
<sub><b>vhsdream</b></sub>
</a> </a>
</td> </td>
</tr> </tr>
</table> </table>
</div>
--- ---
## Project Activity ## 🛠️ Contribute
<div align="center">
<table>
<tr>
<td align="center" width="25%">
<h3>💻 Code</h3>
<p>Add new scripts or improve existing ones</p>
</td>
<td align="center" width="25%">
<h3>📝 Documentation</h3>
<p>Write guides, improve READMEs, translate content</p>
</td>
<td align="center" width="25%">
<h3>🧪 Testing</h3>
<p>Test scripts and report compatibility issues</p>
</td>
<td align="center" width="25%">
<h3>💡 Ideas</h3>
<p>Suggest features or workflow improvements</p>
</td>
</tr>
</table>
</div>
<div align="center">
<br />
👉 Check our **[Contributing Guidelines](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/README.md)** to get started
</div>
---
## ❤️ Support the Project
This project is maintained by volunteers in memory of tteck. Your support helps us maintain infrastructure, improve documentation, and give back to important causes.
**🎗️ 30% of all donations go directly to cancer research and hospice care**
<div align="center">
<a href="https://ko-fi.com/community_scripts">
<img src="https://img.shields.io/badge/☕_Buy_us_a_coffee-Support_on_Ko--fi-FF5F5F?style=for-the-badge&labelColor=2d3748" alt="Support on Ko-fi" />
</a>
<br />
<sub>Every contribution helps keep this project alive and supports meaningful causes</sub>
</div>
---
## 📈 Project Statistics
<p align="center"> <p align="center">
<img <img
src="https://repobeats.axiom.co/api/embed/57edde03e00f88d739bdb5b844ff7d07dd079375.svg" src="https://repobeats.axiom.co/api/embed/57edde03e00f88d739bdb5b844ff7d07dd079375.svg"
alt="Repository activity" alt="Repobeats analytics"
width="700" width="650"
/> />
</p> </p>
<p align="center"> <p align="center">
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date"> <a href="https://star-history.com/#community-scripts/ProxmoxVE&Date">
<picture> <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" /> <source
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" /> media="(prefers-color-scheme: dark)"
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" width="700" /> srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
/>
<img
alt="Star History Chart"
src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
width="650"
/>
</picture> </picture>
</a> </a>
</p> </p>
--- ---
## Support the Project ## 📜 License
This project is maintained by volunteers. All infrastructure costs come out of pocket, and the work is done in people's spare time. This project is licensed under the **[MIT License](LICENSE)** - feel free to use, modify, and distribute.
**30% of all donations are forwarded directly to cancer research and hospice care** — a cause that was important to tteck.
<div align="center">
<a href="https://ko-fi.com/community_scripts">
<img src="https://img.shields.io/badge/Support_on_Ko--fi-FF5F5F?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Support on Ko-fi" />
</a>
&nbsp;
<a href="https://community-scripts.org/donate">
<img src="https://img.shields.io/badge/Donate-community--scripts.org%2Fdonate-4c9b3f?style=for-the-badge" alt="Donate via community-scripts.org" />
</a>
</div>
---
## License
This project is licensed under the [MIT License](LICENSE) — free to use, modify, and redistribute for personal and commercial purposes.
See the full license text in [LICENSE](LICENSE).
--- ---
<div align="center"> <div align="center">
<sub>Built on the foundation of <a href="https://github.com/tteck">tteck</a>'s original work · <a href="https://github.com/tteck/Proxmox">Original Repository</a></sub><br/> <sub>Made with ❤️ by the Proxmox community in memory of tteck</sub>
<sub>Maintained and expanded by the community · In memory of tteck</sub><br/> <br />
<sub><i>Proxmox® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a></i></sub> <sub><i>Proxmox® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a></i></sub>
</div> </div>

View File

@@ -56,7 +56,6 @@ function update_script() {
fi fi
$STD .venv/bin/python -m pip install --upgrade pip $STD .venv/bin/python -m pip install --upgrade pip
$STD .venv/bin/python -m pip install -r requirements.txt $STD .venv/bin/python -m pip install -r requirements.txt
$STD .venv/bin/python -m pip install 'djangorestframework<3.15'
$STD .venv/bin/python -m manage collectstatic --noinput $STD .venv/bin/python -m manage collectstatic --noinput
$STD .venv/bin/python -m manage migrate $STD .venv/bin/python -m manage migrate

View File

@@ -1,107 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Sander Koenders (sanderkoenders)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.borgbackup.org/
APP="Alpine-BorgBackup-Server"
var_tags="${var_tags:-alpine;backup}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-20}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -f /usr/bin/borg ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
CHOICE=$(msg_menu "BorgBackup Server Update Options" \
"1" "Update BorgBackup Server" \
"2" "Reset SSH Access" \
"3" "Enable password authentication for backup user (not recommended, use SSH key instead)" \
"4" "Disable password authentication for backup user (recommended for security, use SSH key)")
case $CHOICE in
1)
msg_info "Updating $APP LXC"
$STD apk -U upgrade
msg_ok "Updated $APP LXC successfully!"
;;
2)
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
msg_warn "Reset SSH Public key requires interactive mode, skipping."
exit
fi
msg_info "Setting up SSH Public Key for backup user"
msg_info "Please paste your SSH public key (e.g., ssh-rsa AAAAB3... user@host): \n"
read -p "Key: " SSH_PUBLIC_KEY
echo
if [[ -z "$SSH_PUBLIC_KEY" ]]; then
msg_error "No SSH public key provided!"
exit 1
fi
if [[ ! "$SSH_PUBLIC_KEY" =~ ^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-) ]]; then
msg_error "Invalid SSH public key format!"
exit 1
fi
msg_info "Setting up SSH access"
mkdir -p /home/backup/.ssh
echo "$SSH_PUBLIC_KEY" >/home/backup/.ssh/authorized_keys
chown -R backup:backup /home/backup/.ssh
chmod 700 /home/backup/.ssh
chmod 600 /home/backup/.ssh/authorized_keys
msg_ok "SSH access configured for backup user"
;;
3)
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
msg_warn "Enabling password authentication requires interactive mode, skipping."
exit
fi
msg_info "Enabling password authentication for backup user"
msg_warn "Password authentication is less secure than using SSH keys. Consider using SSH keys instead."
passwd backup
sed -i 's/^#*\s*PasswordAuthentication\s\+\(yes\|no\)/PasswordAuthentication yes/' /etc/ssh/sshd_config
rc-service sshd restart
msg_ok "Password authentication enabled for backup user"
;;
4)
msg_info "Disabling password authentication for backup user"
sed -i 's/^#*\s*PasswordAuthentication\s\+\(yes\|no\)/PasswordAuthentication no/' /etc/ssh/sshd_config
rc-service sshd restart
msg_ok "Password authentication disabled for backup user"
;;
esac
exit 0
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Connection information:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}ssh backup@${IP}${CL}"
echo -e "${TAB}${VERIFYPW}${YW}To set SSH key, run this script with the 'update' option and select option 2${CL}"

View File

@@ -1,71 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/nearai/ironclaw
APP="Alpine-IronClaw"
var_tags="${var_tags:-ai;agent;alpine}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-8}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/ironclaw ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
msg_info "Stopping Service"
rc-service ironclaw stop 2>/dev/null || true
msg_ok "Stopped Service"
msg_info "Backing up Configuration"
cp /root/.ironclaw/.env /root/ironclaw.env.bak
msg_ok "Backed up Configuration"
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
"ironclaw-$(uname -m)-unknown-linux-musl.tar.gz"
chmod +x /usr/local/bin/ironclaw
msg_info "Restoring Configuration"
cp /root/ironclaw.env.bak /root/.ironclaw/.env
rm -f /root/ironclaw.env.bak
msg_ok "Restored Configuration"
msg_info "Starting Service"
rc-service ironclaw start
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Complete setup by running:${CL}"
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
echo -e "${INFO}${YW} Then start the service:${CL}"
echo -e "${TAB}${BGN}rc-service ironclaw start${CL}"
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"

View File

@@ -35,8 +35,6 @@ function update_script() {
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Migration skipped. The old update will continue to work for now." msg_warn "Migration skipped. The old update will continue to work for now."
msg_warn "⚠️ Komodo v2 uses :2 image tags. The :latest tag is deprecated and will not receive v2 updates."
msg_warn "Please migrate to the addon script to receive Komodo v2."
msg_info "Updating ${APP} (legacy)" msg_info "Updating ${APP} (legacy)"
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1) COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
if [[ -z "$COMPOSE_FILE" ]]; then if [[ -z "$COMPOSE_FILE" ]]; then

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: cobalt (cobaltgit)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://ntfy.sh/
APP="Alpine-ntfy"
var_tags="${var_tags:-notification}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-256}"
var_disk="${var_disk:-2}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /etc/ntfy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ntfy LXC"
$STD apk -U upgrade
setcap 'cap_net_bind_service=+ep' /usr/bin/ntfy
msg_ok "Updated ntfy LXC"
msg_info "Restarting ntfy"
rc-service ntfy restart
msg_ok "Restarted ntfy"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@@ -1,71 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://wakapi.dev/ | https://github.com/muety/wakapi
APP="Alpine-Wakapi"
var_tags="${var_tags:-code;time-tracking}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}"
var_os="${var_os:-alpine}"
var_version="${var_version:-3.23}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
if [[ ! -d /opt/wakapi ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -s https://api.github.com/repos/muety/wakapi/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
if [ "${RELEASE}" != "$(cat ~/.wakapi 2>/dev/null)" ] || [ ! -f ~/.wakapi ]; then
msg_info "Stopping Wakapi Service"
$STD rc-service wakapi stop
msg_ok "Stopped Wakapi Service"
msg_info "Updating Wakapi LXC"
$STD apk -U upgrade
msg_ok "Updated Wakapi LXC"
msg_info "Creating backup"
mkdir -p /opt/wakapi-backup
cp /opt/wakapi/config.yml /opt/wakapi/wakapi_db.db /opt/wakapi-backup/
msg_ok "Created backup"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wakapi" "muety/wakapi" "prebuild" "latest" "/opt/wakapi" "wakapi_linux_amd64.zip"
msg_info "Configuring Wakapi"
cd /opt/wakapi
cp /opt/wakapi-backup/config.yml /opt/wakapi/
cp /opt/wakapi-backup/wakapi_db.db /opt/wakapi/
rm -rf /opt/wakapi-backup
msg_ok "Configured Wakapi"
msg_info "Starting Service"
$STD rc-service wakapi start
msg_ok "Started Service"
msg_ok "Updated successfully"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi
exit 0
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@@ -1,67 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://anytype.io
APP="Anytype-Server"
var_tags="${var_tags:-notes;productivity;sync}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-16}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/anytype/any-sync-bundle ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "anytype" "grishy/any-sync-bundle"; then
msg_info "Stopping Service"
systemctl stop anytype
msg_ok "Stopped Service"
msg_info "Backing up Data"
cp -r /opt/anytype/data /opt/anytype_data_backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "anytype" "grishy/any-sync-bundle" "prebuild" "latest" "/opt/anytype" "any-sync-bundle_*_linux_amd64.tar.gz"
chmod +x /opt/anytype/any-sync-bundle
msg_info "Restoring Data"
cp -r /opt/anytype_data_backup/. /opt/anytype/data
rm -rf /opt/anytype_data_backup
msg_ok "Restored Data"
msg_info "Starting Service"
systemctl start anytype
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:33010${CL}"
echo -e "${INFO}${YW} Client config file:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}/opt/anytype/data/client-config.yml${CL}"

View File

@@ -1,90 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Adrian-RDA
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/maziggy/bambuddy
APP="Bambuddy"
var_tags="${var_tags:-media;3d-printing}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/bambuddy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
ensure_dependencies ffmpeg
if check_for_gh_release "bambuddy" "maziggy/bambuddy"; then
msg_info "Stopping Service"
systemctl stop bambuddy
msg_ok "Stopped Service"
msg_info "Backing up Configuration and Data"
cp /opt/bambuddy/.env /opt/bambuddy.env.bak
cp -r /opt/bambuddy/data /opt/bambuddy_data_bak
[[ -f /opt/bambuddy/bambuddy.db ]] && cp /opt/bambuddy/bambuddy.db /opt/bambuddy.db.bak
[[ -f /opt/bambuddy/bambutrack.db ]] && cp /opt/bambuddy/bambutrack.db /opt/bambutrack.db.bak
[[ -d /opt/bambuddy/archive ]] && cp -r /opt/bambuddy/archive /opt/bambuddy_archive_bak
msg_ok "Backed up Configuration and Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bambuddy" "maziggy/bambuddy" "tarball" "latest" "/opt/bambuddy"
msg_info "Updating Python Dependencies"
cd /opt/bambuddy
$STD uv venv
$STD uv pip install -r requirements.txt
msg_ok "Updated Python Dependencies"
msg_info "Rebuilding Frontend"
cd /opt/bambuddy/frontend
$STD npm install
$STD npm run build
msg_ok "Rebuilt Frontend"
msg_info "Restoring Configuration and Data"
mkdir -p /opt/bambuddy/data
cp /opt/bambuddy.env.bak /opt/bambuddy/.env
cp -r /opt/bambuddy_data_bak/. /opt/bambuddy/data/
[[ -f /opt/bambuddy.db.bak ]] && cp /opt/bambuddy.db.bak /opt/bambuddy/bambuddy.db
[[ -f /opt/bambutrack.db.bak ]] && cp /opt/bambutrack.db.bak /opt/bambuddy/bambutrack.db
if [[ -d /opt/bambuddy_archive_bak ]]; then
mkdir -p /opt/bambuddy/archive
cp -r /opt/bambuddy_archive_bak/. /opt/bambuddy/archive/
fi
rm -f /opt/bambuddy.env.bak /opt/bambuddy.db.bak /opt/bambutrack.db.bak
rm -rf /opt/bambuddy_data_bak /opt/bambuddy_archive_bak
msg_ok "Restored Configuration and Data"
msg_info "Starting Service"
systemctl start bambuddy
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"

View File

@@ -42,6 +42,7 @@ function update_script() {
msg_info "Updating BentoPDF" msg_info "Updating BentoPDF"
cd /opt/bentopdf cd /opt/bentopdf
$STD npm ci --no-audit --no-fund $STD npm ci --no-audit --no-fund
$STD npm install http-server -g
if [[ -f /opt/production.env ]]; then if [[ -f /opt/production.env ]]; then
mv /opt/production.env ./.env.production mv /opt/production.env ./.env.production
else else
@@ -51,97 +52,15 @@ function update_script() {
export SIMPLE_MODE=true export SIMPLE_MODE=true
export VITE_USE_CDN=true export VITE_USE_CDN=true
$STD npm run build:all $STD npm run build:all
if [[ ! -f /opt/bentopdf/dist/config.json ]]; then
cat <<'EOF' >/opt/bentopdf/dist/config.json
{}
EOF
fi
msg_ok "Updated BentoPDF" msg_ok "Updated BentoPDF"
msg_info "Starting Service" msg_info "Starting Service"
ensure_dependencies nginx openssl if grep -q '8080' /etc/systemd/system/bentopdf.service; then
if [[ ! -f /etc/ssl/private/bentopdf-selfsigned.key || ! -f /etc/ssl/certs/bentopdf-selfsigned.crt ]]; then sed -i -e 's|/bentopdf|/bentopdf/dist|' \
CERT_CN="$(hostname -I | awk '{print $1}')" -e 's|npx.*|npx http-server -g -b -d false -r --no-dotfiles|' \
$STD openssl req -x509 -nodes -newkey rsa:2048 -days 3650 \ /etc/systemd/system/bentopdf.service
-keyout /etc/ssl/private/bentopdf-selfsigned.key \ systemctl daemon-reload
-out /etc/ssl/certs/bentopdf-selfsigned.crt \
-subj "/CN=${CERT_CN}"
fi fi
cat <<'EOF' >/etc/nginx/sites-available/bentopdf
server {
listen 8080;
server_name _;
return 301 https://$host:8443$request_uri;
}
server {
listen 8443 ssl;
server_name _;
ssl_certificate /etc/ssl/certs/bentopdf-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/bentopdf-selfsigned.key;
root /opt/bentopdf/dist;
index index.html;
# Required for LibreOffice WASM (Word/Excel/PowerPoint to PDF via SharedArrayBuffer)
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "cross-origin" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
gzip_static on;
location ~* /libreoffice-wasm/soffice\.wasm\.gz$ {
gzip off;
types {} default_type application/wasm;
add_header Content-Encoding gzip;
add_header Vary "Accept-Encoding";
add_header Cache-Control "public, immutable";
}
location ~* /libreoffice-wasm/soffice\.data\.gz$ {
gzip off;
types {} default_type application/octet-stream;
add_header Content-Encoding gzip;
add_header Vary "Accept-Encoding";
add_header Cache-Control "public, immutable";
}
location ~* \.wasm$ {
types {} default_type application/wasm;
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(wasm\.gz|data\.gz|data)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ $uri.html =404;
}
error_page 404 /404.html;
}
EOF
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/bentopdf
cat <<'EOF' >/etc/systemd/system/bentopdf.service
[Unit]
Description=BentoPDF Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/nginx -g "daemon off;"
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl start bentopdf systemctl start bentopdf
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
@@ -156,4 +75,4 @@ description
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"

View File

@@ -1,63 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/tphakala/birdnet-go
APP="BirdNET-Go"
var_tags="${var_tags:-monitoring;ai;nature}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-12}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-no}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/birdnet-go ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "birdnet" "tphakala/birdnet-go"; then
msg_info "Stopping Service"
systemctl stop birdnet
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-amd64.tar.gz"
msg_info "Deploying Binary"
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
chmod +x /usr/local/bin/birdnet-go
cp -r /opt/birdnet/libtensorflowlite_c.so /usr/local/lib/ || true
ldconfig
msg_ok "Deployed Binary"
msg_info "Starting Service"
systemctl start birdnet
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"

113
ct/booklore.sh Normal file
View File

@@ -0,0 +1,113 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/booklore-app/BookLore
APP="BookLore"
var_tags="${var_tags:-books;library}"
var_cpu="${var_cpu:-3}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-7}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/booklore ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "booklore" "booklore-app/BookLore"; then
JAVA_VERSION="25" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
ensure_dependencies ffmpeg
msg_info "Stopping Service"
systemctl stop booklore
msg_ok "Stopped Service"
if grep -qE "^BOOKLORE_(DATA_PATH|BOOKDROP_PATH|BOOKS_PATH|PORT)=" /opt/booklore_storage/.env 2>/dev/null; then
msg_info "Migrating old environment variables"
sed -i 's/^BOOKLORE_DATA_PATH=/APP_PATH_CONFIG=/g' /opt/booklore_storage/.env
sed -i 's/^BOOKLORE_BOOKDROP_PATH=/APP_BOOKDROP_FOLDER=/g' /opt/booklore_storage/.env
sed -i '/^BOOKLORE_BOOKS_PATH=/d' /opt/booklore_storage/.env
sed -i '/^BOOKLORE_PORT=/d' /opt/booklore_storage/.env
msg_ok "Migrated old environment variables"
fi
msg_info "Backing up old installation"
mv /opt/booklore /opt/booklore_bak
msg_ok "Backed up old installation"
fetch_and_deploy_gh_release "booklore" "booklore-app/BookLore" "tarball"
msg_info "Building Frontend"
cd /opt/booklore/booklore-ui
$STD npm install --force
$STD npm run build --configuration=production
msg_ok "Built Frontend"
msg_info "Embedding Frontend into Backend"
mkdir -p /opt/booklore/booklore-api/src/main/resources/static
cp -r /opt/booklore/booklore-ui/dist/booklore/browser/* /opt/booklore/booklore-api/src/main/resources/static/
msg_ok "Embedded Frontend into Backend"
msg_info "Building Backend"
cd /opt/booklore/booklore-api
APP_VERSION=$(get_latest_github_release "booklore-app/BookLore")
yq eval ".app.version = \"${APP_VERSION}\"" -i src/main/resources/application.yaml
$STD ./gradlew clean build -x test --no-daemon
mkdir -p /opt/booklore/dist
JAR_PATH=$(find /opt/booklore/booklore-api/build/libs -maxdepth 1 -type f -name "booklore-api-*.jar" ! -name "*plain*" | head -n1)
if [[ -z "$JAR_PATH" ]]; then
msg_error "Backend JAR not found"
exit
fi
cp "$JAR_PATH" /opt/booklore/dist/app.jar
msg_ok "Built Backend"
if systemctl is-active --quiet nginx 2>/dev/null; then
msg_info "Removing Nginx (no longer needed)"
systemctl disable --now nginx
$STD apt-get purge -y nginx nginx-common
msg_ok "Removed Nginx"
fi
if ! grep -q "^SERVER_PORT=" /opt/booklore_storage/.env 2>/dev/null; then
echo "SERVER_PORT=6060" >>/opt/booklore_storage/.env
fi
sed -i 's|ExecStart=.*|ExecStart=/usr/bin/java -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+UseCompactObjectHeaders -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError -jar /opt/booklore/dist/app.jar|' /etc/systemd/system/booklore.service
systemctl daemon-reload
msg_info "Starting Service"
systemctl start booklore
rm -rf /opt/booklore_bak
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6060${CL}"

View File

@@ -29,7 +29,6 @@ function update_script() {
exit exit
fi fi
setup_mariadb setup_mariadb
ensure_dependencies git
if check_for_gh_release "bookstack" "BookStackApp/BookStack"; then if check_for_gh_release "bookstack" "BookStackApp/BookStack"; then
msg_info "Stopping Apache2" msg_info "Stopping Apache2"
systemctl stop apache2 systemctl stop apache2

View File

@@ -29,41 +29,28 @@ function update_script() {
exit exit
fi fi
if check_for_gh_release "bytestash" "jordan-dalby/ByteStash"; then if check_for_gh_release "bytestash" "jordan-dalby/ByteStash"; then
msg_info "Stopping Services" read -rp "${TAB3}Did you make a backup via application WebUI? (y/n): " backuped
systemctl stop bytestash-backend bytestash-frontend if [[ "$backuped" =~ ^[Yy]$ ]]; then
msg_ok "Services Stopped" msg_info "Stopping Services"
systemctl stop bytestash-backend bytestash-frontend
msg_ok "Services Stopped"
msg_info "Backing up data" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash" "tarball"
tmp_dir="/opt/bytestash-data-backup"
mkdir -p "$tmp_dir" msg_info "Configuring ByteStash"
if [[ -d /opt/bytestash/data ]]; then cd /opt/bytestash/server
cp -r /opt/bytestash/data "$tmp_dir"/data $STD npm install
elif [[ -d /opt/data ]]; then cd /opt/bytestash/client
cp -r /opt/data "$tmp_dir"/data $STD npm install
msg_ok "Updated ByteStash"
msg_info "Starting Services"
systemctl start bytestash-backend bytestash-frontend
msg_ok "Started Services"
else
msg_error "PLEASE MAKE A BACKUP FIRST!"
exit
fi fi
msg_ok "Data backed up"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash" "tarball"
msg_info "Restoring data"
if [[ -d "$tmp_dir"/data ]]; then
mkdir -p /opt/bytestash/data
cp -r "$tmp_dir"/data/* /opt/bytestash/data/
rm -rf "$tmp_dir"
fi
msg_ok "Data restored"
msg_info "Configuring ByteStash"
cd /opt/bytestash/server
$STD npm install
cd /opt/bytestash/client
$STD npm install
msg_ok "Updated ByteStash"
msg_info "Starting Services"
systemctl start bytestash-backend bytestash-frontend
msg_ok "Started Services"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
exit exit

View File

@@ -34,11 +34,11 @@ function update_script() {
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
msg_info "Updating ${APP}" msg_info "Updating ${APP}"
$STD pip3 install changedetection.io --upgrade --break-system-packages --ignore-installed typing_extensions $STD pip3 install changedetection.io --upgrade
msg_ok "Updated ${APP}" msg_ok "Updated ${APP}"
msg_info "Updating Playwright" msg_info "Updating Playwright"
$STD pip3 install playwright --upgrade --break-system-packages $STD pip3 install playwright --upgrade
msg_ok "Updated Playwright" msg_ok "Updated Playwright"
if [[ -f /etc/systemd/system/browserless.service ]]; then if [[ -f /etc/systemd/system/browserless.service ]]; then

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}" var_disk="${var_disk:-6}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
@@ -29,11 +29,10 @@ function update_script() {
fi fi
RELEASE=$(curl -fsSL https://api.github.com/repos/checkmk/checkmk/tags | grep "name" | awk '{print substr($2, 3, length($2)-4) }' | tr ' ' '\n' | grep -Ev 'rc|b' | sort -V | tail -n 1) RELEASE=$(curl -fsSL https://api.github.com/repos/checkmk/checkmk/tags | grep "name" | awk '{print substr($2, 3, length($2)-4) }' | tr ' ' '\n' | grep -Ev 'rc|b' | sort -V | tail -n 1)
RELEASE="${RELEASE%%+*}"
msg_info "Updating ${APP} to v${RELEASE}" msg_info "Updating ${APP} to v${RELEASE}"
$STD omd stop monitoring $STD omd stop monitoring
$STD omd cp monitoring monitoringbackup $STD omd cp monitoring monitoringbackup
curl -fsSL "https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.$(get_os_info codename)_amd64.deb" -o "/opt/checkmk.deb" curl -fsSL "https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.bookworm_amd64.deb" -o "/opt/checkmk.deb"
$STD apt-get install -y /opt/checkmk.deb $STD apt-get install -y /opt/checkmk.deb
$STD omd --force -V ${RELEASE}.cre update --conflict=install monitoring $STD omd --force -V ${RELEASE}.cre update --conflict=install monitoring
$STD omd start monitoring $STD omd start monitoring

View File

@@ -24,7 +24,7 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
if [[ ! -d /opt/convertx ]]; then if [[ ! -d /var ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
@@ -33,8 +33,6 @@ function update_script() {
systemctl stop convertx systemctl stop convertx
msg_info "Stopped Service" msg_info "Stopped Service"
ensure_dependencies libreoffice-writer
msg_info "Move data-Folder" msg_info "Move data-Folder"
if [[ -d /opt/convertx/data ]]; then if [[ -d /opt/convertx/data ]]; then
mv /opt/convertx/data /opt/data mv /opt/convertx/data /opt/data

View File

@@ -1,16 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 tteck
# Copyright (c) 2021-2026 community-scripts ORG # Author: tteck (tteckster)
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://goteleport.com/ # Source: https://daemonsync.me/
APP="Teleport" APP="Daemon Sync"
var_tags="${var_tags:-zero-trust}" var_tags="${var_tags:-sync}"
var_cpu="${var_cpu:-1}" var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}" var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}" var_disk="${var_disk:-8}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
@@ -24,14 +23,14 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
if [[ ! -f /etc/teleport.yaml ]]; then if [[ ! -d /var ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
msg_info "Updating LXC"
msg_info "Updating Teleport"
$STD apt update $STD apt update
$STD apt upgrade -y $STD apt -y upgrade
msg_ok "Updated LXC"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit
} }
@@ -43,4 +42,4 @@ description
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:3080${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8084${CL}"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: DragoQC | Co-Author: nickheyer # Author: DragoQC
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://discopanel.app/ | Github: https://github.com/nickheyer/discopanel # Source: https://discopanel.app/ | Github: https://github.com/nickheyer/discopanel
@@ -38,15 +38,34 @@ function update_script() {
msg_info "Creating Backup" msg_info "Creating Backup"
mkdir -p /opt/discopanel_backup_temp mkdir -p /opt/discopanel_backup_temp
cp /opt/discopanel/data/discopanel.db /opt/discopanel_backup_temp/discopanel.db cp -r /opt/discopanel/data/discopanel.db \
/opt/discopanel/data/.recovery_key \
/opt/discopanel_backup_temp/
if [[ -d /opt/discopanel/data/servers ]]; then
cp -r /opt/discopanel/data/servers /opt/discopanel_backup_temp/
fi
msg_ok "Created Backup" msg_ok "Created Backup"
fetch_and_deploy_gh_release "discopanel" "nickheyer/discopanel" "prebuild" "latest" "/opt/discopanel" "discopanel-linux-amd64.tar.gz" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "discopanel" "nickheyer/discopanel" "tarball" "latest" "/opt/discopanel"
ln -sf /opt/discopanel/discopanel-linux-amd64 /opt/discopanel/discopanel
msg_info "Setting up DiscoPanel"
cd /opt/discopanel
$STD make gen
cd /opt/discopanel/web/discopanel
$STD npm install
$STD npm run build
msg_ok "Built Web Interface"
setup_go
msg_info "Building DiscoPanel"
cd /opt/discopanel
$STD go build -o discopanel cmd/discopanel/main.go
msg_ok "Built DiscoPanel"
msg_info "Restoring Data" msg_info "Restoring Data"
mkdir -p /opt/discopanel/data mkdir -p /opt/discopanel/data
mv /opt/discopanel_backup_temp/discopanel.db /opt/discopanel/data/discopanel.db cp -a /opt/discopanel_backup_temp/. /opt/discopanel/data/
rm -rf /opt/discopanel_backup_temp rm -rf /opt/discopanel_backup_temp
msg_ok "Restored Data" msg_ok "Restored Data"

View File

@@ -70,7 +70,7 @@ function update_script() {
source /opt/dispatcharr/.env source /opt/dispatcharr/.env
set +o allexport set +o allexport
if [[ -n "$POSTGRES_DB" ]] && [[ -n "$POSTGRES_USER" ]] && [[ -n "$POSTGRES_PASSWORD" ]]; then if [[ -n "$POSTGRES_DB" ]] && [[ -n "$POSTGRES_USER" ]] && [[ -n "$POSTGRES_PASSWORD" ]]; then
PGPASSWORD=$POSTGRES_PASSWORD pg_dump -U "$POSTGRES_USER" -h "${POSTGRES_HOST:-localhost}" -p "${POSTGRES_PORT:-5432}" "$POSTGRES_DB" >/tmp/dispatcharr_db_$(date +%F).sql PGPASSWORD=$POSTGRES_PASSWORD pg_dump -U $POSTGRES_USER -h ${POSTGRES_HOST:-localhost} $POSTGRES_DB >/tmp/dispatcharr_db_$(date +%F).sql
msg_info "Database backup created" msg_info "Database backup created"
fi fi
fi fi
@@ -110,9 +110,7 @@ function update_script() {
msg_info "Building Frontend" msg_info "Building Frontend"
cd /opt/dispatcharr/frontend cd /opt/dispatcharr/frontend
node -e "const p=require('./package.json');p.overrides=p.overrides||{};p.overrides['webworkify-webpack']='2.1.3';require('fs').writeFileSync('package.json',JSON.stringify(p,null,2));" $STD npm install --legacy-peer-deps
rm -f package-lock.json
$STD npm install --no-audit --progress=false
$STD npm run build $STD npm run build
msg_ok "Built Frontend" msg_ok "Built Frontend"

View File

@@ -34,7 +34,7 @@ function update_script() {
fi fi
if ! grep -Fq "www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" /etc/crontab; then if ! grep -Fq "www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" /etc/crontab; then
echo "0 0 * * * www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" >>/etc/crontab echo "0 0 * * * www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" >> /etc/crontab
fi fi
if check_for_gh_release "domain-monitor" "Hosteroid/domain-monitor"; then if check_for_gh_release "domain-monitor" "Hosteroid/domain-monitor"; then
@@ -52,7 +52,6 @@ function update_script() {
msg_info "Updating Domain Monitor" msg_info "Updating Domain Monitor"
cd /opt/domain-monitor cd /opt/domain-monitor
$STD composer install $STD composer install
chown -R www-data:www-data /opt/domain-monitor
msg_ok "Updated Domain Monitor" msg_ok "Updated Domain Monitor"
msg_info "Restoring backup" msg_info "Restoring backup"

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/drawdb-io/drawdb
APP="DrawDB"
var_tags="${var_tags:-database;dev-tools}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-6144}"
var_disk="${var_disk:-5}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/drawdb ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_tag "drawdb" "drawdb-io/drawdb"; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_tag "drawdb" "drawdb-io/drawdb" "latest" "/opt/drawdb"
msg_info "Rebuilding Frontend"
cd /opt/drawdb
$STD npm ci
NODE_OPTIONS="--max-old-space-size=4096" $STD npm run build
sed -i '/<head>/a <script>if(!crypto.randomUUID){crypto.randomUUID=function(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(c){return(c^(crypto.getRandomValues(new Uint8Array(1))[0]&(15>>c/4))).toString(16)})}};</script>' /opt/drawdb/dist/index.html
msg_ok "Rebuilt Frontend"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@@ -29,11 +29,11 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable) update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable)
if [[ "${update_available}" == "true" ]]; then if [[ "${update_available}" == "true" ]]; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop fileflows* systemctl stop fileflows
msg_info "Stopped Service" msg_info "Stopped Service"
msg_info "Creating Backup" msg_info "Creating Backup"
@@ -45,7 +45,7 @@ function update_script() {
fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows" fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start fileflows* systemctl start fileflows
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else else

View File

@@ -1,71 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/tess1o/geopulse
APP="GeoPulse"
var_tags="${var_tags:-location;tracking;gps}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/geopulse/backend/geopulse-backend ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "geopulse-backend" "tess1o/geopulse"; then
msg_info "Stopping Service"
systemctl stop geopulse-backend
msg_ok "Stopped Service"
if [[ "$(uname -m)" == "aarch64" ]]; then
if grep -qi "raspberry\|bcm" /proc/cpuinfo 2>/dev/null; then
BINARY_PATTERN="geopulse-backend-native-arm64-compat-*"
else
BINARY_PATTERN="geopulse-backend-native-arm64-[!c]*"
fi
else
if grep -q avx2 /proc/cpuinfo && grep -q bmi2 /proc/cpuinfo && grep -q fma /proc/cpuinfo; then
BINARY_PATTERN="geopulse-backend-native-amd64-[!c]*"
else
BINARY_PATTERN="geopulse-backend-native-amd64-compat-*"
fi
fi
fetch_and_deploy_gh_release "geopulse-backend" "tess1o/geopulse" "singlefile" "latest" "/opt/geopulse/backend" "${BINARY_PATTERN}"
fetch_and_deploy_gh_release "geopulse-frontend" "tess1o/geopulse" "prebuild" "latest" "/var/www/geopulse" "geopulse-frontend-*.tar.gz"
msg_info "Starting Service"
systemctl start geopulse-backend
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
echo -e "${INFO}${YW} To create an admin account, run:${CL}"
echo -e "${TAB}${BGN}/usr/local/bin/create-geopulse-admin${CL}"

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/qdm12/gluetun
APP="Gluetun"
var_tags="${var_tags:-vpn;wireguard;openvpn}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_tun="${var_tun:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/gluetun ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "gluetun" "qdm12/gluetun"; then
msg_info "Stopping Service"
systemctl stop gluetun
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gluetun" "qdm12/gluetun" "tarball"
msg_info "Building Gluetun"
cd /opt/gluetun
$STD go mod download
CGO_ENABLED=0 $STD go build -trimpath -ldflags="-s -w" -o /usr/local/bin/gluetun ./cmd/gluetun/
msg_ok "Built Gluetun"
msg_info "Starting Service"
systemctl start gluetun
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"

View File

@@ -32,16 +32,7 @@ function update_script() {
systemctl stop gokapi systemctl stop gokapi
msg_ok "Stopped Service" msg_ok "Stopped Service"
fetch_and_deploy_gh_release "gokapi" "Forceu/Gokapi" "prebuild" "latest" "/opt/gokapi" "*linux*amd64.zip" fetch_and_deploy_gh_release "gokapi" "Forceu/Gokapi" "prebuild" "latest" "/opt/gokapi" "gokapi-linux_amd64.zip"
# Migrate from pre-v2.2.4 binary name (gokapi-linux_amd64 -> gokapi)
if [[ -f /opt/gokapi/gokapi-linux_amd64 ]]; then
rm -f /opt/gokapi/gokapi-linux_amd64
fi
if grep -q "gokapi-linux_amd64" /etc/systemd/system/gokapi.service 2>/dev/null; then
sed -i 's|gokapi-linux_amd64|gokapi|g' /etc/systemd/system/gokapi.service
systemctl daemon-reload
fi
msg_info "Starting Service" msg_info "Starting Service"
systemctl start gokapi systemctl start gokapi

View File

@@ -64,12 +64,6 @@ function update_script() {
} }
start start
if [[ $(sysctl -n vm.max_map_count 2>/dev/null) -lt 262144 ]]; then
sysctl -w vm.max_map_count=262144 >/dev/null 2>&1
echo "vm.max_map_count=262144" >/etc/sysctl.d/graylog.conf
fi
build_container build_container
description description

View File

@@ -46,13 +46,12 @@ function update_script() {
msg_info "Updating Grist" msg_info "Updating Grist"
mkdir -p /opt/grist/docs mkdir -p /opt/grist/docs
cp -n /opt/grist_bak/.env /opt/grist/.env cp -n /opt/grist_bak/.env /opt/grist/.env
if ls /opt/grist_bak/docs/* &>/dev/null; then cp -r /opt/grist_bak/docs/* /opt/grist/docs/
cp -r /opt/grist_bak/docs/* /opt/grist/docs/ cp /opt/grist_bak/grist-sessions.db /opt/grist/grist-sessions.db
fi cp /opt/grist_bak/landing.db /opt/grist/landing.db
[[ -f /opt/grist_bak/grist-sessions.db ]] && cp /opt/grist_bak/grist-sessions.db /opt/grist/grist-sessions.db
[[ -f /opt/grist_bak/landing.db ]] && cp /opt/grist_bak/landing.db /opt/grist/landing.db
cd /opt/grist cd /opt/grist
$STD yarn install $STD yarn install
$STD yarn run install:ee
$STD yarn run build:prod $STD yarn run build:prod
$STD yarn run install:python $STD yarn run install:python
msg_ok "Updated Grist" msg_ok "Updated Grist"

View File

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

View File

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

View File

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

View File

@@ -1,6 +0,0 @@
___ __ _ _ __ __ _
/ | / /___ (_)___ ___ | | / /___ _/ /______ _____ (_)
/ /| | / / __ \/ / __ \/ _ \_____| | /| / / __ `/ //_/ __ `/ __ \/ /
/ ___ |/ / /_/ / / / / / __/_____/ |/ |/ / /_/ / ,< / /_/ / /_/ / /
/_/ |_/_/ .___/_/_/ /_/\___/ |__/|__/\__,_/_/|_|\__,_/ .___/_/
/_/ /_/

View File

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

View File

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

View File

@@ -1,6 +0,0 @@
____ _ ___ ______________ ______
/ __ )(_)________/ / | / / ____/_ __/ / ____/___
/ __ / / ___/ __ / |/ / __/ / /_____/ / __/ __ \
/ /_/ / / / / /_/ / /| / /___ / /_____/ /_/ / /_/ /
/_____/_/_/ \__,_/_/ |_/_____/ /_/ \____/\____/

6
ct/headers/booklore Normal file
View File

@@ -0,0 +1,6 @@
____ __ __
/ __ )____ ____ / /__/ / ____ ________
/ __ / __ \/ __ \/ //_/ / / __ \/ ___/ _ \
/ /_/ / /_/ / /_/ / ,< / /___/ /_/ / / / __/
/_____/\____/\____/_/|_/_____/\____/_/ \___/

6
ct/headers/daemonsync Normal file
View File

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

View File

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

View File

@@ -1,6 +0,0 @@
______ ____ __
/ ____/__ ____ / __ \__ __/ /_______
/ / __/ _ \/ __ \/ /_/ / / / / / ___/ _ \
/ /_/ / __/ /_/ / ____/ /_/ / (__ ) __/
\____/\___/\____/_/ \__,_/_/____/\___/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +0,0 @@
__ ______ __
____ ___ _ __/ /_/ ____/ ______ / /___ ________ _____
/ __ \/ _ \| |/_/ __/ __/ | |/_/ __ \/ / __ \/ ___/ _ \/ ___/
/ / / / __/> </ /_/ /____> </ /_/ / / /_/ / / / __/ /
/_/ /_/\___/_/|_|\__/_____/_/|_/ .___/_/\____/_/ \___/_/
/_/

View File

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

6
ct/headers/pf2etools Normal file
View File

@@ -0,0 +1,6 @@
____ _______ ______ __
/ __ \/ __/__ \ ___/_ __/___ ____ / /____
/ /_/ / /_ __/ // _ \/ / / __ \/ __ \/ / ___/
/ ____/ __// __// __/ / / /_/ / /_/ / (__ )
/_/ /_/ /____/\___/_/ \____/\____/_/____/

View File

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

View File

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

6
ct/headers/typesense Normal file
View File

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

6
ct/headers/verdaccio Normal file
View File

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

View File

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

View File

@@ -1,6 +0,0 @@
__ __ __ __
\ \/ /___ _____ ___ / /__________ ______/ /__
\ / __ `/ __ `__ \/ __/ ___/ __ `/ ___/ //_/
/ / /_/ / / / / / / /_/ / / /_/ / /__/ ,<
/_/\__,_/_/ /_/ /_/\__/_/ \__,_/\___/_/|_|

View File

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

View File

@@ -13,7 +13,6 @@ var_disk="${var_disk:-2}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
var_tun="${var_tun:-yes}"
header_info "$APP" header_info "$APP"
variables variables

View File

@@ -65,8 +65,6 @@ EOF
msg_info "Updating Homarr" msg_info "Updating Homarr"
cp /opt/homarr/redis.conf /etc/redis/redis.conf cp /opt/homarr/redis.conf /etc/redis/redis.conf
sed -i -e '$a\' /etc/redis/redis.conf
grep -q '^bind 127.0.0.1 -::1$' /etc/redis/redis.conf || echo "bind 127.0.0.1 -::1" >> /etc/redis/redis.conf
rm /etc/nginx/nginx.conf rm /etc/nginx/nginx.conf
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
msg_ok "Updated Homarr" msg_ok "Updated Homarr"

View File

@@ -73,7 +73,7 @@ function update_script() {
$STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin $STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-amd64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin
$STD filebrowser config init -a '0.0.0.0' $STD filebrowser config init -a '0.0.0.0'
$STD filebrowser config set -a '0.0.0.0' $STD filebrowser config set -a '0.0.0.0'
$STD filebrowser users add admin community-scripts.org --perm.admin $STD filebrowser users add admin helper-scripts.com --perm.admin
msg_ok "Installed FileBrowser" msg_ok "Installed FileBrowser"
msg_info "Creating Service" msg_info "Creating Service"
@@ -93,7 +93,7 @@ WantedBy=default.target" >$service_path
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "FileBrowser should be reachable by going to the following URL. echo -e "FileBrowser should be reachable by going to the following URL.
${BL}http://$LOCAL_IP:8080${CL} admin|community-scripts.org\n" ${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n"
exit exit
fi fi
} }

View File

@@ -1,78 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Pouzor/homelable
APP="Homelable"
var_tags="${var_tags:-monitoring;network;visualization}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/homelable ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "homelable" "Pouzor/homelable"; then
msg_info "Stopping Service"
systemctl stop homelable
msg_ok "Stopped Service"
msg_info "Backing up Configuration and Data"
cp /opt/homelable/backend/.env /opt/homelable.env.bak
cp -r /opt/homelable/data /opt/homelable_data_bak
msg_ok "Backed up Configuration and Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homelable" "Pouzor/homelable" "tarball" "latest" "/opt/homelable"
msg_info "Updating Python Dependencies"
cd /opt/homelable/backend
$STD uv venv /opt/homelable/backend/.venv
$STD uv pip install --python /opt/homelable/backend/.venv/bin/python -r requirements.txt
msg_ok "Updated Python Dependencies"
msg_info "Rebuilding Frontend"
cd /opt/homelable/frontend
$STD npm ci
$STD npm run build
msg_ok "Rebuilt Frontend"
msg_info "Restoring Configuration and Data"
cp /opt/homelable.env.bak /opt/homelable/backend/.env
cp -r /opt/homelable_data_bak/. /opt/homelable/data/
rm -f /opt/homelable.env.bak
rm -rf /opt/homelable_data_bak
msg_ok "Restored Configuration and Data"
msg_info "Starting Service"
systemctl start homelable
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@@ -76,16 +76,16 @@ EOF
SOURCE_DIR=${STAGING_DIR}/image-source SOURCE_DIR=${STAGING_DIR}/image-source
cd /tmp cd /tmp
if [[ -f ~/.intel_version ]]; then if [[ -f ~/.intel_version ]]; then
curl_with_retry "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile" "Dockerfile" curl -fsSLO https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile
readarray -t INTEL_URLS < <( readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}' sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}' sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
) )
INTEL_RELEASE="$(grep "intel-opencl-icd_" ./Dockerfile | awk -F '_' '{print $2}')" INTEL_RELEASE="$(grep "intel-opencl-icd_" ./Dockerfile | awk -F '_' '{print $2}')"
if [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then if [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
msg_info "Updating Intel OpenVINO dependencies" msg_info "Updating Intel iGPU dependencies"
for url in "${INTEL_URLS[@]}"; do for url in "${INTEL_URLS[@]}"; do
curl_with_retry "$url" "$(basename "$url")" curl -fsSLO "$url"
done done
$STD apt-mark unhold libigdgmm12 $STD apt-mark unhold libigdgmm12
$STD apt install -y --allow-downgrades ./libigdgmm12*.deb $STD apt install -y --allow-downgrades ./libigdgmm12*.deb
@@ -94,9 +94,9 @@ EOF
rm ./*.deb rm ./*.deb
$STD apt-mark hold libigdgmm12 $STD apt-mark hold libigdgmm12
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
rm -f ./Dockerfile msg_ok "Intel iGPU dependencies updated"
msg_ok "Updated Intel OpenVINO dependencies"
fi fi
rm ./Dockerfile
fi fi
if [[ -f ~/.immich_library_revisions ]]; then if [[ -f ~/.immich_library_revisions ]]; then
libraries=("libjxl" "libheif" "libraw" "imagemagick" "libvips") libraries=("libjxl" "libheif" "libraw" "imagemagick" "libvips")
@@ -109,8 +109,8 @@ EOF
msg_ok "Image-processing libraries up to date" msg_ok "Image-processing libraries up to date"
fi fi
RELEASE="v2.7.5" RELEASE="2.5.6"
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; 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"
cd /opt/immich/app/bin cd /opt/immich/app/bin
@@ -125,7 +125,7 @@ EOF
msg_ok "Stopped Services" msg_ok "Stopped Services"
VCHORD_RELEASE="0.5.3" VCHORD_RELEASE="0.5.3"
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord [[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}"; then
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-16-vchord_*_amd64.deb" fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-16-vchord_*_amd64.deb"
systemctl restart postgresql systemctl restart postgresql
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;" $STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
@@ -133,7 +133,7 @@ EOF
$STD sudo -u postgres psql -d immich -c "REINDEX INDEX face_index;" $STD sudo -u postgres psql -d immich -c "REINDEX INDEX face_index;"
$STD sudo -u postgres psql -d immich -c "REINDEX INDEX clip_index;" $STD sudo -u postgres psql -d immich -c "REINDEX INDEX clip_index;"
fi fi
ensure_dependencies ccache gcc-13 g++-13 ensure_dependencies ccache
INSTALL_DIR="/opt/${APP}" INSTALL_DIR="/opt/${APP}"
UPLOAD_DIR="$(sed -n '/^IMMICH_MEDIA_LOCATION/s/[^=]*=//p' /opt/immich/.env)" UPLOAD_DIR="$(sed -n '/^IMMICH_MEDIA_LOCATION/s/[^=]*=//p' /opt/immich/.env)"
@@ -165,8 +165,8 @@ EOF
) )
setup_uv setup_uv
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "${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] | split("+")[0]' ${SRC_DIR}/package.json)" PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
msg_info "Updating Immich web and microservices" msg_info "Updating Immich web and microservices"
@@ -181,12 +181,6 @@ EOF
unset SHARP_IGNORE_GLOBAL_LIBVIPS unset SHARP_IGNORE_GLOBAL_LIBVIPS
export SHARP_FORCE_GLOBAL_LIBVIPS=true export SHARP_FORCE_GLOBAL_LIBVIPS=true
$STD pnpm --filter immich --frozen-lockfile --prod --no-optional deploy "$APP_DIR" $STD pnpm --filter immich --frozen-lockfile --prod --no-optional deploy "$APP_DIR"
# Patch helmet.json: disable upgrade-insecure-requests for HTTP access
if [[ -f "$APP_DIR/helmet.json" ]]; then
jq '.contentSecurityPolicy.directives["upgrade-insecure-requests"] = null' "$APP_DIR/helmet.json" >"$APP_DIR/helmet.json.tmp" && mv "$APP_DIR/helmet.json.tmp" "$APP_DIR/helmet.json"
fi
cp "$APP_DIR"/package.json "$APP_DIR"/bin cp "$APP_DIR"/package.json "$APP_DIR"/bin
sed -i "s|^start|${APP_DIR}/bin/start|" "$APP_DIR"/bin/immich-admin sed -i "s|^start|${APP_DIR}/bin/start|" "$APP_DIR"/bin/immich-admin
@@ -220,41 +214,18 @@ EOF
cd "$SRC_DIR"/machine-learning cd "$SRC_DIR"/machine-learning
mkdir -p "$ML_DIR" mkdir -p "$ML_DIR"
# chown excluding upload dir contents (may be a mount with restricted permissions) chown -R immich:immich "$INSTALL_DIR"
chown immich:immich "$INSTALL_DIR"
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
chown immich:immich "${UPLOAD_DIR:-$INSTALL_DIR/upload}" 2>/dev/null || true
chown immich:immich ./uv.lock chown immich:immich ./uv.lock
export VIRTUAL_ENV="${ML_DIR}"/ml-venv export VIRTUAL_ENV="${ML_DIR}"/ml-venv
export UV_HTTP_TIMEOUT=300
if [[ -f ~/.openvino ]]; then if [[ -f ~/.openvino ]]; then
ML_PYTHON="python3.13" msg_info "Updating HW-accelerated machine-learning"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning" $STD uv add --no-sync --optional openvino onnxruntime-openvino==1.24.1 --active -n -p python3.13 --managed-python
for attempt in $(seq 1 3); do $STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p python3.13 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv python install "${ML_PYTHON}" && break
[[ $attempt -lt 3 ]] && msg_warn "Python download attempt $attempt failed, retrying..." && sleep 5
done
msg_ok "Pre-installed Python ${ML_PYTHON}"
msg_info "Updating Intel OpenVINO machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -nu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.13/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-313-x86_64-linux-gnu.so" patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.13/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-313-x86_64-linux-gnu.so"
msg_ok "Updated Intel OpenVINO machine-learning" msg_ok "Updated HW-accelerated machine-learning"
else else
ML_PYTHON="python3.11"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv python install "${ML_PYTHON}" && break
[[ $attempt -lt 3 ]] && msg_warn "Python download attempt $attempt failed, retrying..." && sleep 5
done
msg_ok "Pre-installed Python ${ML_PYTHON}"
msg_info "Updating machine-learning" msg_info "Updating machine-learning"
for attempt in $(seq 1 3); do $STD sudo --preserve-env=VIRTUAL_ENV -nu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p python3.11 --managed-python
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -nu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
msg_ok "Updated machine-learning" msg_ok "Updated machine-learning"
fi fi
cd "$SRC_DIR" cd "$SRC_DIR"
@@ -272,28 +243,11 @@ EOF
[[ ! -f /usr/bin/immich ]] && ln -sf "$APP_DIR"/cli/bin/immich /usr/bin/immich [[ ! -f /usr/bin/immich ]] && ln -sf "$APP_DIR"/cli/bin/immich /usr/bin/immich
[[ ! -f /usr/bin/immich-admin ]] && ln -sf "$APP_DIR"/bin/immich-admin /usr/bin/immich-admin [[ ! -f /usr/bin/immich-admin ]] && ln -sf "$APP_DIR"/bin/immich-admin /usr/bin/immich-admin
if ! grep -q '^DB_HOSTNAME=' "$INSTALL_DIR"/.env; then chown -R immich:immich "$INSTALL_DIR"
sed -i '/^DB_DATABASE_NAME/a DB_HOSTNAME=127.0.0.1' "$INSTALL_DIR"/.env
fi
if ! grep -q 'HELMET_FILE' "$INSTALL_DIR"/.env; then
sed -i -e '$a\' "$INSTALL_DIR"/.env
echo "IMMICH_HELMET_FILE=true" >>"$INSTALL_DIR"/.env
fi
if grep -q 'ExecStart=/usr/bin/node' /etc/systemd/system/immich-web.service; then
sed -i '/^EnvironmentFile=/d' /etc/systemd/system/immich-web.service
sed -i "s|^ExecStart=.*|ExecStart=${APP_DIR}/bin/start.sh|" /etc/systemd/system/immich-web.service
systemctl daemon-reload
fi
# chown excluding upload dir contents (may be a mount with restricted permissions)
chown immich:immich "$INSTALL_DIR"
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
chown immich:immich "${UPLOAD_DIR:-$INSTALL_DIR/upload}" 2>/dev/null || true
if [[ "${MAINT_MODE:-0}" == 1 ]]; then if [[ "${MAINT_MODE:-0}" == 1 ]]; then
msg_info "Disabling Maintenance Mode" msg_info "Disabling Maintenance Mode"
cd /opt/immich/app/bin cd /opt/immich/app/bin
$STD ./immich-admin disable-maintenance-mode || true $STD ./immich-admin disable-maintenance-mode
unset MAINT_MODE unset MAINT_MODE
$STD cd - $STD cd -
msg_ok "Disabled Maintenance Mode" msg_ok "Disabled Maintenance Mode"
@@ -309,8 +263,7 @@ function compile_libjxl() {
SOURCE=${SOURCE_DIR}/libjxl SOURCE=${SOURCE_DIR}/libjxl
JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62" JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0" JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
LIBJXL_REVISION="794a5dcf0d54f9f0b20d288a12e87afb91d20dfc" : "${LIBJXL_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)}"
# : "${LIBJXL_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)}"
if [[ "$LIBJXL_REVISION" != "$(grep 'libjxl' ~/.immich_library_revisions | awk '{print $2}')" ]]; then if [[ "$LIBJXL_REVISION" != "$(grep 'libjxl' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libjxl" msg_info "Recompiling libjxl"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE" [[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
@@ -354,8 +307,7 @@ function compile_libjxl() {
function compile_libheif() { function compile_libheif() {
SOURCE=${SOURCE_DIR}/libheif SOURCE=${SOURCE_DIR}/libheif
ensure_dependencies libaom-dev ensure_dependencies libaom-dev
LIBHEIF_REVISION="35dad50a9145332a7bfdf1ff6aef6801fb613d68" : "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
# : "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
if [[ "${update:-}" ]] || [[ "$LIBHEIF_REVISION" != "$(grep 'libheif' ~/.immich_library_revisions | awk '{print $2}')" ]]; then if [[ "${update:-}" ]] || [[ "$LIBHEIF_REVISION" != "$(grep 'libheif' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libheif" msg_info "Recompiling libheif"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE" [[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
@@ -386,8 +338,7 @@ function compile_libheif() {
function compile_libraw() { function compile_libraw() {
SOURCE=${SOURCE_DIR}/libraw SOURCE=${SOURCE_DIR}/libraw
LIBRAW_REVISION="0b56545a4f828743f28a4345cdfdd4c49f9f9a2a" : "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
# : "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libraw" msg_info "Recompiling libraw"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE" [[ -d "$SOURCE" ]] && rm -rf "$SOURCE"

View File

@@ -1,71 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/nearai/ironclaw
APP="IronClaw"
var_tags="${var_tags:-ai;agent;security}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/ironclaw ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
msg_info "Stopping Service"
systemctl stop ironclaw
msg_ok "Stopped Service"
msg_info "Backing up Configuration"
cp /root/.ironclaw/.env /root/ironclaw.env.bak
msg_ok "Backed up Configuration"
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
"ironclaw-$(uname -m)-unknown-linux-$([[ -f /etc/alpine-release ]] && echo "musl" || echo "gnu").tar.gz"
chmod +x /usr/local/bin/ironclaw
msg_info "Restoring Configuration"
cp /root/ironclaw.env.bak /root/.ironclaw/.env
rm -f /root/ironclaw.env.bak
msg_ok "Restored Configuration"
msg_info "Starting Service"
systemctl start ironclaw
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Complete setup by running:${CL}"
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
echo -e "${INFO}${YW} Then start the service:${CL}"
echo -e "${TAB}${BGN}systemctl start ironclaw${CL}"
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"

View File

@@ -30,14 +30,9 @@ function update_script() {
fi fi
setup_mariadb setup_mariadb
msg_info "Updating ITSM-NG" msg_info "Updating LXC"
$STD apt update $STD apt update
$STD apt -y upgrade $STD apt -y upgrade
chown -R www-data:www-data /var/lib/itsm-ng
mkdir -p /usr/share/itsm-ng/css/palettes
chown -R www-data:www-data /usr/share/itsm-ng/css
chown -R www-data:www-data /usr/share/itsm-ng/css_compiled
chown www-data:www-data /etc/itsm-ng/config_db.php
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit
} }

View File

@@ -39,23 +39,14 @@ function update_script() {
msg_ok "Updated Intel Dependencies" msg_ok "Updated Intel Dependencies"
fi fi
msg_info "Setting up Jellyfin Repository"
setup_deb822_repo \
"jellyfin" \
"https://repo.jellyfin.org/jellyfin_team.gpg.key" \
"https://repo.jellyfin.org/$(get_os_info id)" \
"$(get_os_info codename)"
msg_ok "Set up Jellyfin Repository"
msg_info "Updating Jellyfin" msg_info "Updating Jellyfin"
ensure_dependencies libjemalloc2 ensure_dependencies libjemalloc2
if [[ ! -f /usr/lib/libjemalloc.so ]]; then if [[ ! -f /usr/lib/libjemalloc.so ]]; then
ln -sf /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so ln -sf /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so
fi fi
$STD apt update
$STD apt -y upgrade $STD apt -y upgrade
$STD apt -y --with-new-pkgs upgrade jellyfin jellyfin-server jellyfin-ffmpeg7 $STD apt -y --with-new-pkgs upgrade jellyfin jellyfin-server
ln -sf /usr/lib/jellyfin-ffmpeg/ffmpeg /usr/bin/ffmpeg
ln -sf /usr/lib/jellyfin-ffmpeg/ffprobe /usr/bin/ffprobe
msg_ok "Updated Jellyfin" msg_ok "Updated Jellyfin"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit

View File

@@ -15,7 +15,6 @@ var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-0}" var_unprivileged="${var_unprivileged:-0}"
var_fuse="${var_fuse:-yes}" var_fuse="${var_fuse:-yes}"
var_tun="${var_tun:-yes}" var_tun="${var_tun:-yes}"
var_kasm_version="${var_kasm_version:-}"
header_info "$APP" header_info "$APP"
variables variables
@@ -33,21 +32,18 @@ function update_script() {
msg_info "Checking for new version" msg_info "Checking for new version"
CURRENT_VERSION=$(readlink -f /opt/kasm/current | awk -F'/' '{print $4}') CURRENT_VERSION=$(readlink -f /opt/kasm/current | awk -F'/' '{print $4}')
KASM_VERSION=$(curl -s https://kasm.com/downloads | grep -oP '<h1[^>]*>.*?</h1>' | sed -E 's/<\/?h1[^>]*>//g' | grep -oP '\d+\.\d+\.\d+') KASM_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_[0-9]+\.[0-9]+\.[0-9]+\.[a-z0-9]+\.tar\.gz' | head -n 1)
KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION:-var_kasm_version}.tar.gz" if [[ -z "$KASM_URL" ]]; then
SERVICE_IMAGE_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_service_images_amd64_[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' | head -n 1)
if [[ -n "$SERVICE_IMAGE_URL" ]]; then
KASM_VERSION=$(echo "$SERVICE_IMAGE_URL" | sed -E 's/.*kasm_release_service_images_amd64_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION}.tar.gz"
fi
else
KASM_VERSION=$(echo "$KASM_URL" | sed -E 's/.*kasm_release_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
fi
# KASM_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_[0-9]+\.[0-9]+\.[0-9]+\.[a-z0-9]+\.tar\.gz' | head -n 1) if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
# if [[ -z "$KASM_URL" ]]; then
# SERVICE_IMAGE_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_service_images_amd64_[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' | head -n 1)
# if [[ -n "$SERVICE_IMAGE_URL" ]]; then
# KASM_VERSION=$(echo "$SERVICE_IMAGE_URL" | sed -E 's/.*kasm_release_service_images_amd64_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
# KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION}.tar.gz"
# fi
# else
# KASM_VERSION=$(echo "$KASM_URL" | sed -E 's/.*kasm_release_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
# fi
if [[ -z "$KASM_VERSION" ]] || [[ -z "$KASM_URL" ]]; then
msg_error "Unable to detect latest Kasm release URL." msg_error "Unable to detect latest Kasm release URL."
exit 250 exit 250
fi fi

View File

@@ -48,9 +48,7 @@ function update_script() {
# Ensure APP_RUNTIME is in .env.local for CLI commands (upgrades from older versions) # Ensure APP_RUNTIME is in .env.local for CLI commands (upgrades from older versions)
if ! grep -q "APP_RUNTIME" /opt/koillection/.env.local 2>/dev/null; then if ! grep -q "APP_RUNTIME" /opt/koillection/.env.local 2>/dev/null; then
# Ensure file ends with newline before appending to avoid concatenation echo 'APP_RUNTIME="Symfony\Component\Runtime\SymfonyRuntime"' >> /opt/koillection/.env.local
[[ -s /opt/koillection/.env.local && -n "$(tail -c 1 /opt/koillection/.env.local)" ]] && echo "" >>/opt/koillection/.env.local
echo 'APP_RUNTIME="Symfony\Component\Runtime\SymfonyRuntime"' >>/opt/koillection/.env.local
fi fi
export COMPOSER_ALLOW_SUPERUSER=1 export COMPOSER_ALLOW_SUPERUSER=1

View File

@@ -61,5 +61,5 @@ description
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access Kometa Quickstart:${CL}" echo -e "${INFO}${YW} Access the LXC at following IP address:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7171${CL}" echo -e "${TAB}${GATEWAY}${BGN}${IP}${CL}"

View File

@@ -39,8 +39,6 @@ function update_script() {
read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM read -r -p "${TAB}Migrate update function now? [y/N]: " CONFIRM
if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then if [[ ! "${CONFIRM,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Migration skipped. The old update will continue to work for now." msg_warn "Migration skipped. The old update will continue to work for now."
msg_warn "⚠️ Komodo v2 uses :2 image tags. The :latest tag is deprecated and will not receive v2 updates."
msg_warn "Please migrate to the addon script to receive Komodo v2."
msg_info "Updating ${APP} (legacy)" msg_info "Updating ${APP} (legacy)"
COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1) COMPOSE_FILE=$(find /opt/komodo -maxdepth 1 -type f -name '*.compose.yaml' ! -name 'compose.env' | head -n1)
if [[ -z "$COMPOSE_FILE" ]]; then if [[ -z "$COMPOSE_FILE" ]]; then

View File

@@ -30,16 +30,16 @@ function update_script() {
exit exit
fi fi
DEB_URL=$(curl_with_retry 'https://lyrion.org/getting-started/' | grep -oP '<a\s[^>]*href="\K[^"]*amd64\.deb(?="[^>]*>)' | head -n 1) DEB_URL=$(curl -s 'https://lyrion.org/getting-started/' | grep -oP '<a\s[^>]*href="\K[^"]*amd64\.deb(?="[^>]*>)' | head -n 1)
RELEASE=$(echo "$DEB_URL" | grep -oP 'lyrionmusicserver_\K[0-9.]+(?=_amd64\.deb)') RELEASE=$(echo "$DEB_URL" | grep -oP 'lyrionmusicserver_\K[0-9.]+(?=_amd64\.deb)')
DEB_FILE="/tmp/lyrionmusicserver_${RELEASE}_amd64.deb" DEB_FILE="/tmp/lyrionmusicserver_${RELEASE}_amd64.deb"
if [[ ! -f /opt/lyrion_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/lyrion_version.txt)" ]]; then if [[ ! -f /opt/lyrion_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/lyrion_version.txt)" ]]; then
msg_info "Updating $APP to ${RELEASE}" msg_info "Updating $APP to ${RELEASE}"
curl_with_retry "$DEB_URL" "$DEB_FILE" curl -fsSL -o "$DEB_FILE" "$DEB_URL"
$STD apt install "$DEB_FILE" -y $STD apt install "$DEB_FILE" -y
systemctl restart lyrionmusicserver systemctl restart lyrion
rm -f "$DEB_FILE" $STD rm -f "$DEB_FILE"
echo "${RELEASE}" >/opt/lyrion_version.txt echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to ${RELEASE}" msg_ok "Updated $APP to ${RELEASE}"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else else

View File

@@ -1,60 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/matter-js/python-matter-server
APP="Matter-Server"
var_tags="${var_tags:-matter;iot;smart-home}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/matter-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "matter-server" "matter-js/python-matter-server"; then
msg_info "Stopping Service"
systemctl stop matter-server
msg_ok "Stopped Service"
msg_info "Updating Matter Server"
MATTER_VERSION=$(get_latest_github_release "matter-js/python-matter-server")
$STD uv pip install --python /opt/matter-server/.venv/bin/python --upgrade "python-matter-server[server]==${MATTER_VERSION}"
echo "${MATTER_VERSION}" >~/.matter-server
msg_ok "Updated Matter Server"
fetch_and_deploy_gh_release "chip-ota-provider-app" "home-assistant-libs/matter-linux-ota-provider" "singlefile" "latest" "/usr/local/bin" "chip-ota-provider-app-x86-64"
msg_info "Starting Service"
systemctl start matter-server
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Matter Server WebSocket API is running on port 5580.${CL}"
echo -e "${TAB}${GATEWAY}${BGN}ws://${IP}:5580/ws${CL}"

View File

@@ -40,7 +40,7 @@ function update_script() {
cp -f /opt/mealie/mealie.env /opt/mealie.env cp -f /opt/mealie/mealie.env /opt/mealie.env
msg_ok "Backup completed" msg_ok "Backup completed"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
msg_info "Installing Python Dependencies with uv" msg_info "Installing Python Dependencies with uv"
cd /opt/mealie cd /opt/mealie
@@ -49,10 +49,9 @@ function update_script() {
msg_info "Building Frontend" msg_info "Building Frontend"
MEALIE_VERSION=$(<$HOME/.mealie) MEALIE_VERSION=$(<$HOME/.mealie)
SITE_SETTINGS=$(find /opt/mealie/frontend -name "site-settings.vue" -path "*/admin/*" | head -1) $STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" /opt/mealie/frontend/pages/admin/site-settings.vue
$STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" "$SITE_SETTINGS" $STD sed -i "s|value: data.buildId,|value: \"v${MEALIE_VERSION}\",|g" /opt/mealie/frontend/pages/admin/site-settings.vue
$STD sed -i "s|value: data.buildId,|value: \"v${MEALIE_VERSION}\",|g" "$SITE_SETTINGS" $STD sed -i "s|value: data.production ? i18n.t(\"about.production\") : i18n.t(\"about.development\"),|value: \"bare-metal\",|g" /opt/mealie/frontend/pages/admin/site-settings.vue
$STD sed -i "s|value: data.production ? i18n.t(\"about.production\") : i18n.t(\"about.development\"),|value: \"bare-metal\",|g" "$SITE_SETTINGS"
export NUXT_TELEMETRY_DISABLED=1 export NUXT_TELEMETRY_DISABLED=1
cd /opt/mealie/frontend cd /opt/mealie/frontend
$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000 $STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000
@@ -98,3 +97,4 @@ msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9000${CL}" echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9000${CL}"

View File

@@ -62,7 +62,6 @@ function update_script() {
$STD corepack enable $STD corepack enable
$STD corepack prepare pnpm --activate || true $STD corepack prepare pnpm --activate || true
fi fi
echo 'onlyBuiltDependencies=*' >> .npmrc
$STD pnpm install --frozen-lockfile $STD pnpm install --frozen-lockfile
$STD pnpm run build $STD pnpm run build
msg_ok "Built Frontend" msg_ok "Built Frontend"

View File

@@ -1,89 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://netboot.xyz
APP="netboot.xyz"
var_tags="${var_tags:-network;pxe;boot}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
NSAPP="netboot-xyz"
var_install="${NSAPP}-install"
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f ~/.netboot-xyz ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "netboot-xyz" "netbootxyz/netboot.xyz"; then
msg_info "Backing up Configuration"
cp /var/www/html/boot.cfg /opt/netboot-xyz-boot.cfg.bak
msg_ok "Backed up Configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "netboot-xyz" "netbootxyz/netboot.xyz" "prebuild" "latest" "/var/www/html" "menus.tar.gz"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-efi" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-efi-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.efi.dsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snp.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snp-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snp.efi.dsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-snponly.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.efi.dsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snp.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snp-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snp.efi.dsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-snponly.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-kpxe" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.kpxe"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-undionly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-undionly.kpxe"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-kpxe" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal.kpxe"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-lkrn" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.lkrn"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-linux-bin" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-linux.bin"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-dsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.dsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-pdsk" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.pdsk"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64-snp.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64-snponly.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64-snp" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64-snp.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-metal-arm64-snponly" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-metal-arm64-snponly.efi"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.iso"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz.img"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.iso"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-arm64-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-arm64.img"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-multiarch-iso" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-multiarch.iso"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-multiarch-img" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-multiarch.img"
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "netboot-xyz-checksums" "netbootxyz/netboot.xyz" "singlefile" "latest" "/var/www/html" "netboot.xyz-sha256-checksums.txt"
msg_info "Restoring Configuration"
cp /opt/netboot-xyz-boot.cfg.bak /var/www/html/boot.cfg
rm -f /opt/netboot-xyz-boot.cfg.bak
msg_ok "Restored Configuration"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@@ -1,76 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/nxzai/nextExplorer
APP="nextExplorer"
var_tags="${var_tags:-files;documents}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/nextExplorer ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "nextExplorer" "nxzai/nextExplorer"; then
msg_info "Stopping nextExplorer"
$STD systemctl stop nextexplorer
msg_ok "Stopped nextExplorer"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nextExplorer" "nxzai/nextExplorer" "tarball" "latest" "/opt/nextExplorer"
msg_info "Updating nextExplorer"
APP_DIR="/opt/nextExplorer/app"
mkdir -p "$APP_DIR"
cd /opt/nextExplorer
export NODE_ENV=production
$STD npm ci --omit=dev --workspace backend
mv node_modules "$APP_DIR"
mv backend/{src,package.json} "$APP_DIR"
unset NODE_ENV
export NODE_ENV=development
$STD npm ci --workspace frontend
$STD npm run -w frontend build -- --sourcemap false
unset NODE_ENV
mv frontend/dist/ "$APP_DIR"/src/public
chown -R explorer:explorer "$APP_DIR" /etc/nextExplorer
sed -i "\|version|s|$(jq -cr '.version' ${APP_DIR}/package.json)|$(cat ~/.nextexplorer)|" "$APP_DIR"/package.json
sed -i 's/app.js/server.js/' /etc/systemd/system/nextexplorer.service && systemctl daemon-reload
msg_ok "Updated nextExplorer"
msg_info "Starting nextExplorer"
$STD systemctl start nextexplorer
msg_ok "Started nextExplorer"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster) | Co-Author: CrazyWolf13, MickLesk (CanbiZ) # Author: tteck (tteckster) | Co-Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nginxproxymanager.com/ | Github: https://github.com/NginxProxyManager/nginx-proxy-manager # Source: https://nginxproxymanager.com/ | Github: https://github.com/NginxProxyManager/nginx-proxy-manager
@@ -28,13 +28,18 @@ function update_script() {
exit exit
fi fi
if [[ $(grep -E '^VERSION_ID=' /etc/os-release) == *"12"* ]]; then
msg_error "Wrong Debian version detected!"
msg_error "Please create a snapshot first. You must upgrade your LXC to Debian Trixie before updating. Visit: https://github.com/community-scripts/ProxmoxVE/discussions/7489"
exit
fi
if command -v node &>/dev/null; then if command -v node &>/dev/null; then
CURRENT_NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) CURRENT_NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
if [[ "$CURRENT_NODE_VERSION" != "22" ]]; then if [[ "$CURRENT_NODE_VERSION" != "22" ]]; then
systemctl stop openresty systemctl stop openresty
$STD apt purge -y nodejs npm apt-get purge -y nodejs npm
$STD apt autoremove -y apt-get autoremove -y
rm -rf /usr/local/bin/node /usr/local/bin/npm rm -rf /usr/local/bin/node /usr/local/bin/npm
rm -rf /usr/local/lib/node_modules rm -rf /usr/local/lib/node_modules
rm -rf ~/.npm rm -rf ~/.npm
@@ -44,153 +49,92 @@ function update_script() {
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
if dpkg -s openresty &>/dev/null 2>&1; then RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
msg_info "Migrating from packaged OpenResty to source" grep "tag_name" |
rm -f /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg /etc/apt/trusted.gpg.d/openresty.gpg awk '{print substr($2, 3, length($2)-4) }')
rm -f /etc/apt/sources.list.d/openresty.list /etc/apt/sources.list.d/openresty.sources
$STD apt remove -y openresty CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "v${RELEASE}" "/opt/nginxproxymanager"
$STD apt autoremove -y
rm -f ~/.openresty msg_info "Stopping Services"
msg_ok "Migrated from packaged OpenResty to source" systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
msg_info "Cleaning old files"
$STD rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
/var/cache/nginx
msg_ok "Cleaned old files"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "s|\"version\": \"2.0.0\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/backend/package.json
sed -i "s|\"version\": \"2.0.0\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/frontend/package.json
sed -i 's+^daemon+#daemon+g' /opt/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find /opt/nginxproxymanager -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r /opt/nginxproxymanager/docker/rootfs/var/www/html/* /var/www/html/
cp -r /opt/nginxproxymanager/docker/rootfs/etc/nginx/* /etc/nginx/
cp /opt/nginxproxymanager/docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp /opt/nginxproxymanager/docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi fi
local pcre_pkg="libpcre3-dev" mkdir -p /app/frontend/images
if grep -qE 'VERSION_ID="1[3-9]"' /etc/os-release 2>/dev/null; then cp -r /opt/nginxproxymanager/backend/* /app
pcre_pkg="libpcre2-dev" msg_ok "Set up Environment"
fi
$STD apt install -y build-essential "$pcre_pkg" libssl-dev zlib1g-dev
if check_for_gh_release "openresty" "openresty/openresty"; then msg_info "Building Frontend"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "openresty" "openresty/openresty" "prebuild" "${CHECK_UPDATE_RELEASE}" "/opt/openresty" "openresty-*.tar.gz" export NODE_OPTIONS="--max_old_space_size=2048 --openssl-legacy-provider"
cd /opt/nginxproxymanager/frontend
# Replace node-sass with sass in package.json before installation
sed -E -i 's/"node-sass" *: *"([^"]*)"/"sass": "\1"/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn locale-compile
$STD yarn build
cp -r /opt/nginxproxymanager/frontend/dist/* /app/frontend
cp -r /opt/nginxproxymanager/frontend/public/images/* /app/frontend/images
msg_ok "Built Frontend"
msg_info "Building OpenResty" msg_info "Initializing Backend"
cd /opt/openresty rm -rf /app/config/default.json
$STD ./configure \ if [ ! -f /app/config/production.json ]; then
--with-http_v2_module \ cat <<'EOF' >/app/config/production.json
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_sub_module \
--with-http_auth_request_module \
--with-pcre-jit \
--with-stream \
--with-stream_ssl_module
$STD make -j"$(nproc)"
$STD make install
rm -rf /opt/openresty
cat <<'EOF' >/lib/systemd/system/openresty.service
[Unit]
Description=The OpenResty Application Platform
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=simple
ExecStartPre=-/bin/mkdir -p /tmp/nginx/body /run/nginx
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
ExecStart=/usr/local/openresty/nginx/sbin/nginx -g 'daemon off;'
[Install]
WantedBy=multi-user.target
EOF
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
systemctl daemon-reload
systemctl unmask openresty 2>/dev/null || true
systemctl restart openresty
msg_ok "Built OpenResty"
fi
cd /root
if [ -d /opt/certbot ]; then
msg_info "Updating Certbot"
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
msg_ok "Updated Certbot"
fi
if check_for_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager"; then
msg_info "Stopping Services"
systemctl stop openresty
systemctl stop npm
msg_ok "Stopped Services"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "${CHECK_UPDATE_RELEASE}" "/opt/nginxproxymanager"
msg_info "Cleaning old files"
$STD rm -rf /app \
/var/www/html \
/etc/nginx \
/var/log/nginx \
/var/lib/nginx \
/var/cache/nginx
msg_ok "Cleaned old files"
local RELEASE="${CHECK_UPDATE_RELEASE#v}"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/backend/package.json
sed -i "0,/\"version\": \"[^\"]*\"/s|\"version\": \"[^\"]*\"|\"version\": \"$RELEASE\"|" /opt/nginxproxymanager/frontend/package.json
sed -i 's+^daemon+#daemon+g' /opt/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find /opt/nginxproxymanager -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cp -r /opt/nginxproxymanager/docker/rootfs/var/www/html/* /var/www/html/
cp -r /opt/nginxproxymanager/docker/rootfs/etc/nginx/* /etc/nginx/
cp /opt/nginxproxymanager/docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp /opt/nginxproxymanager/docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
$STD openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem
fi
mkdir -p /app/frontend/images
cp -r /opt/nginxproxymanager/backend/* /app
msg_ok "Set up Environment"
msg_info "Building Frontend"
export NODE_OPTIONS="--max_old_space_size=2048 --openssl-legacy-provider"
cd /opt/nginxproxymanager/frontend
sed -E -i 's/"node-sass" *: *"([^"]*)"/"sass": "\1"/g' package.json
$STD yarn install --network-timeout 600000
$STD yarn locale-compile
$STD yarn build
cp -r /opt/nginxproxymanager/frontend/dist/* /app/frontend
cp -r /opt/nginxproxymanager/frontend/public/images/* /app/frontend/images
msg_ok "Built Frontend"
msg_info "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{ {
"database": { "database": {
"engine": "knex-native", "engine": "knex-native",
@@ -204,21 +148,40 @@ EOF
} }
} }
EOF EOF
fi
sed -i 's/"client": "sqlite3"/"client": "better-sqlite3"/' /app/config/production.json
cd /app
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
systemctl daemon-reload
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi fi
sed -i 's/"client": "sqlite3"/"client": "better-sqlite3"/' /app/config/production.json
cd /app
$STD yarn install --network-timeout 600000
msg_ok "Initialized Backend"
msg_info "Updating Certbot"
[ -f /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg ] && rm -f /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg
[ -f /etc/apt/sources.list.d/openresty.list ] && rm -f /etc/apt/sources.list.d/openresty.list
[ ! -f /etc/apt/trusted.gpg.d/openresty.gpg ] && curl -fsSL https://openresty.org/package/pubkey.gpg | gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/openresty.gpg
[ ! -f /etc/apt/sources.list.d/openresty.sources ] && cat <<'EOF' >/etc/apt/sources.list.d/openresty.sources
Types: deb
URIs: http://openresty.org/package/debian/
Suites: bookworm
Components: openresty
Signed-By: /etc/apt/trusted.gpg.d/openresty.gpg
EOF
$STD apt update
$STD apt -y install openresty
if [ -d /opt/certbot ]; then
$STD /opt/certbot/bin/pip install --upgrade pip setuptools wheel
$STD /opt/certbot/bin/pip install --upgrade certbot certbot-dns-cloudflare
fi
msg_ok "Updated Certbot"
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
systemctl enable -q --now openresty
systemctl enable -q --now npm
systemctl restart openresty
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit exit
} }

View File

@@ -23,18 +23,16 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
#RELEASE="0.301.1"
if [[ ! -f /etc/systemd/system/nocodb.service ]]; then if [[ ! -f /etc/systemd/system/nocodb.service ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
#if check_for_gh_release "nocodb" "nocodb/nocodb" "${RELEASE}"; then if check_for_gh_release "nocodb" "nocodb/nocodb" "0.301.1"; then
if check_for_gh_release "nocodb" "nocodb/nocodb"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop nocodb systemctl stop nocodb
msg_ok "Stopped Service" msg_ok "Stopped Service"
fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "latest" "/opt/nocodb/" "Noco-linux-x64" fetch_and_deploy_gh_release "nocodb" "nocodb/nocodb" "singlefile" "0.301.1" "/opt/nocodb/" "Noco-linux-x64"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start nocodb systemctl start nocodb

View File

@@ -29,8 +29,8 @@ function update_script() {
exit exit
fi fi
RELEASE="v6.0.0" RELEASE="v5.2.0"
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}"; then
msg_info "Stopping services" msg_info "Stopping services"
systemctl stop opencloud opencloud-wopi systemctl stop opencloud opencloud-wopi
msg_ok "Stopped services" msg_ok "Stopped services"

View File

@@ -1,87 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://openthread.io/guides/border-router
APP="OpenThread-BR"
var_tags="${var_tags:-thread;iot;border-router;matter}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-0}"
var_tun="${var_tun:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/ot-br-posix ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
cd /opt/ot-br-posix
LOCAL_COMMIT=$(git rev-parse HEAD)
$STD git fetch --depth 1 origin main
REMOTE_COMMIT=$(git rev-parse origin/main)
if [[ "${LOCAL_COMMIT}" == "${REMOTE_COMMIT}" ]]; then
msg_ok "Already up to date (${LOCAL_COMMIT:0:7})"
exit
fi
msg_info "Stopping Services"
systemctl stop otbr-web
systemctl stop otbr-agent
msg_ok "Stopped Services"
msg_info "Updating Source"
$STD git reset --hard origin/main
$STD git submodule update --depth 1 --init --recursive
msg_ok "Updated Source"
msg_info "Rebuilding OpenThread Border Router (Patience)"
cd /opt/ot-br-posix/build
$STD cmake -GNinja \
-DBUILD_TESTING=OFF \
-DCMAKE_INSTALL_PREFIX=/usr \
-DOTBR_DBUS=ON \
-DOTBR_MDNS=openthread \
-DOTBR_REST=ON \
-DOTBR_WEB=ON \
-DOTBR_BORDER_ROUTING=ON \
-DOTBR_BACKBONE_ROUTER=ON \
-DOT_FIREWALL=ON \
-DOT_POSIX_NAT64_CIDR="192.168.255.0/24" \
..
$STD ninja
$STD ninja install
msg_ok "Rebuilt OpenThread Border Router"
msg_info "Starting Services"
systemctl start otbr-agent
systemctl start otbr-web
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@@ -9,7 +9,7 @@ APP="Owncast"
var_tags="${var_tags:-broadcasting}" var_tags="${var_tags:-broadcasting}"
var_cpu="${var_cpu:-2}" var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}" var_disk="${var_disk:-2}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"

View File

@@ -8,7 +8,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
APP="Paperless-ngx" APP="Paperless-ngx"
var_tags="${var_tags:-document;management}" var_tags="${var_tags:-document;management}"
var_cpu="${var_cpu:-2}" var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-12}" var_disk="${var_disk:-12}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-13}"

View File

@@ -35,37 +35,14 @@ function update_script() {
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Backing up Configuration" msg_info "Backing up Configuration"
if [[ -f /opt/papra/apps/papra-server/.env ]]; then cp /opt/papra/apps/papra-server/.env /opt/papra_env.bak
cp /opt/papra/apps/papra-server/.env /opt/papra_env.bak
fi
msg_ok "Backed up Configuration" msg_ok "Backed up Configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "papra" "papra-hq/papra" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "papra" "papra-hq/papra" "tarball"
msg_info "Building Application" msg_info "Building Application"
cd /opt/papra cd /opt/papra
if [[ -f /opt/papra_env.bak ]]; then cp /opt/papra_env.bak /opt/papra/apps/papra-server/.env
cp /opt/papra_env.bak /opt/papra/apps/papra-server/.env
else
msg_warn ".env missing, regenerating from defaults"
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/papra/apps/papra-server/.env
NODE_ENV=production
SERVER_SERVE_PUBLIC_DIR=true
PORT=1221
DATABASE_URL=file:/opt/papra_data/db/db.sqlite
DOCUMENT_STORAGE_FILESYSTEM_ROOT=/opt/papra_data/documents
PAPRA_CONFIG_DIR=/opt/papra_data
AUTH_SECRET=$(cat /opt/papra_data/.secret)
BETTER_AUTH_SECRET=$(cat /opt/papra_data/.secret)
BETTER_AUTH_TELEMETRY=0
CLIENT_BASE_URL=http://${LOCAL_IP}:1221
SERVER_BASE_URL=http://${LOCAL_IP}:1221
EMAILS_DRY_RUN=true
INGESTION_FOLDER_IS_ENABLED=true
INGESTION_FOLDER_ROOT_PATH=/opt/papra_data/ingestion
EOF
fi
$STD pnpm install --frozen-lockfile $STD pnpm install --frozen-lockfile
$STD pnpm --filter "@papra/app-client..." run build $STD pnpm --filter "@papra/app-client..." run build
$STD pnpm --filter "@papra/app-server..." run build $STD pnpm --filter "@papra/app-server..." run build

View File

@@ -27,27 +27,36 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
RELEASE=$(get_latest_github_release "Part-DB/Part-DB-server")
if check_for_gh_release "partdb" "Part-DB/Part-DB-server"; then if check_for_gh_release "partdb" "Part-DB/Part-DB-server"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop apache2 systemctl stop apache2
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Updating $APP to v${RELEASE}"
cd /opt
mv /opt/partdb/ /opt/partdb-backup mv /opt/partdb/ /opt/partdb-backup
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "partdb" "Part-DB/Part-DB-server" "prebuild" "latest" "/opt/partdb" "partdb_with_assets.zip" curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip"
$STD unzip "v${RELEASE}.zip"
mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb
msg_info "Updating Part-DB"
cd /opt/partdb/ cd /opt/partdb/
cp -r /opt/partdb-backup/.env.local /opt/partdb/ cp -r "/opt/partdb-backup/.env.local" /opt/partdb/
cp -r /opt/partdb-backup/public/media /opt/partdb/public/ cp -r "/opt/partdb-backup/public/media" /opt/partdb/public/
cp -r /opt/partdb-backup/config/banner.md /opt/partdb/config/ cp -r "/opt/partdb-backup/config/banner.md" /opt/partdb/config/
export COMPOSER_ALLOW_SUPERUSER=1 export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev -o --no-interaction $STD composer install --no-dev -o --no-interaction
$STD yarn install
$STD yarn build
$STD php bin/console cache:clear $STD php bin/console cache:clear
$STD php bin/console doctrine:migrations:migrate -n $STD php bin/console doctrine:migrations:migrate -n
chown -R www-data:www-data /opt/partdb chown -R www-data:www-data /opt/partdb
rm -r "/opt/v${RELEASE}.zip"
rm -r /opt/partdb-backup rm -r /opt/partdb-backup
msg_ok "Updated Part-DB" echo "${RELEASE}" >~/.partdb
msg_ok "Updated $APP to v${RELEASE}"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start apache2 systemctl start apache2

View File

@@ -36,9 +36,8 @@ function update_script() {
read -r read -r
fi fi
RELEASE="v1.4.2"
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
if check_for_gh_release "PatchMon" "PatchMon/PatchMon" "${RELEASE}"; then if check_for_gh_release "PatchMon" "PatchMon/PatchMon" "v1.4.2"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop patchmon-server systemctl stop patchmon-server
msg_ok "Stopped Service" msg_ok "Stopped Service"
@@ -48,7 +47,7 @@ function update_script() {
cp /opt/patchmon/frontend/.env /opt/frontend.env cp /opt/patchmon/frontend/.env /opt/frontend.env
msg_ok "Backup Created" msg_ok "Backup Created"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "${RELEASE}" "/opt/patchmon" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "v1.4.2" "/opt/patchmon"
msg_info "Updating PatchMon" msg_info "Updating PatchMon"
VERSION=$(get_latest_github_release "PatchMon/PatchMon") VERSION=$(get_latest_github_release "PatchMon/PatchMon")

59
ct/pf2etools.sh Normal file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: TheRealVira
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://pf2etools.com/ | Github: https://github.com/Pf2eToolsOrg/Pf2eTools
APP="Pf2eTools"
var_tags="${var_tags:-wiki}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d "/opt/${APP}" ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "pf2etools" "Pf2eToolsOrg/Pf2eTools"; then
msg_info "Updating System"
$STD apt update
$STD apt -y upgrade
msg_ok "Updated System"
rm -rf /opt/Pf2eTools
fetch_and_deploy_gh_release "pf2etools" "Pf2eToolsOrg/Pf2eTools" "tarball" "latest" "/opt/Pf2eTools"
msg_info "Updating ${APP}"
cd /opt/Pf2eTools
$STD npm install
$STD npm run build
chown -R www-data: "/opt/${APP}"
chmod -R 755 "/opt/${APP}"
msg_ok "Updated ${APP}"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@@ -23,19 +23,18 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
RELEASE="0.10.0"
if [[ ! -d /opt/plant-it ]]; then if [[ ! -d /opt/plant-it ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
setup_mariadb setup_mariadb
if check_for_gh_release "plant-it" "MDeLuise/plant-it" "${RELEASE}" "last version that includes the web frontend"; then if check_for_gh_release "plant-it" "MDeLuise/plant-it"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop plant-it systemctl stop plant-it
msg_info "Stopped Service" msg_info "Stopped Service"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "${RELEASE}" "/opt/plant-it/backend" "server.jar" USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "0.10.0" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "${RELEASE}" "/opt/plant-it/frontend" "client.tar.gz" fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "0.10.0" "/opt/plant-it/frontend" "client.tar.gz"
msg_warn "Application is updated to latest Web version (v0.10.0). There will be no more updates available." msg_warn "Application is updated to latest Web version (v0.10.0). There will be no more updates available."
msg_warn "Please read: https://github.com/MDeLuise/plant-it/releases/tag/1.0.0" msg_warn "Please read: https://github.com/MDeLuise/plant-it/releases/tag/1.0.0"

View File

@@ -46,11 +46,11 @@ function update_script() {
"main" "main"
msg_ok "Migrated to new Plex repository" msg_ok "Migrated to new Plex repository"
fi fi
elif compgen -G "/etc/apt/sources.list.d/plex*.list" >/dev/null; then elif [[ -f /etc/apt/sources.list.d/plexmediaserver.list ]]; then
msg_info "Migrating to new Plex repository (deb822)" msg_info "Migrating to new Plex repository (deb822)"
rm -f /etc/apt/sources.list.d/plex*.list rm -f /etc/apt/sources.list.d/plexmediaserver.list
rm -f /etc/apt/sources.list.d/plex*
rm -f /usr/share/keyrings/PlexSign.asc rm -f /usr/share/keyrings/PlexSign.asc
rm -f /usr/share/keyrings/plexmediaserver.v2.gpg
setup_deb822_repo \ setup_deb822_repo \
"plexmediaserver" \ "plexmediaserver" \
"https://downloads.plex.tv/plex-keys/PlexSign.v2.key" \ "https://downloads.plex.tv/plex-keys/PlexSign.v2.key" \
@@ -58,15 +58,6 @@ function update_script() {
"public" \ "public" \
"main" "main"
msg_ok "Migrated to new Plex repository (deb822)" msg_ok "Migrated to new Plex repository (deb822)"
elif [[ ! -f /etc/apt/sources.list.d/plexmediaserver.sources ]]; then
msg_info "Setting up Plex repository"
setup_deb822_repo \
"plexmediaserver" \
"https://downloads.plex.tv/plex-keys/PlexSign.v2.key" \
"https://repo.plex.tv/deb/" \
"public" \
"main"
msg_ok "Set up Plex repository"
fi fi
if [[ -f /usr/local/bin/plexupdate ]] || [[ -d /opt/plexupdate ]]; then if [[ -f /usr/local/bin/plexupdate ]] || [[ -d /opt/plexupdate ]]; then
msg_info "Removing legacy plexupdate" msg_info "Removing legacy plexupdate"
@@ -79,11 +70,6 @@ function update_script() {
$STD apt update $STD apt update
$STD apt install -y plexmediaserver $STD apt install -y plexmediaserver
msg_ok "Updated Plex Media Server" msg_ok "Updated Plex Media Server"
msg_info "Restarting Plex Media Server"
systemctl restart plexmediaserver
msg_ok "Restarted Plex Media Server"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit
} }

Some files were not shown because too many files have changed in this diff Show More