Compare commits

...

125 Commits

Author SHA1 Message Date
community-scripts-pr-app[bot]
d4892d299f Update CHANGELOG.md (#10823)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-15 00:14:44 +00:00
community-scripts-pr-app[bot]
c6b01a62f0 Update versions.json (#10822)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-15 01:14:24 +01:00
community-scripts-pr-app[bot]
c41c78a0b2 Update CHANGELOG.md (#10819)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 17:04:48 +00:00
CanbiZ (MickLesk)
bdfd72e311 Switch Ollama install to .tar.zst and add zstd dependency (#10814) 2026-01-14 18:04:13 +01:00
community-scripts-pr-app[bot]
fa1f2784f9 Update .app files (#10817)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-14 18:01:11 +01:00
community-scripts-pr-app[bot]
b3b4d170b3 Update CHANGELOG.md (#10818)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 16:56:48 +00:00
community-scripts-pr-app[bot]
5e8c0d621b Update CHANGELOG.md (#10816)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 16:56:20 +00:00
community-scripts-pr-app[bot]
64bd501ed9 Update date in json (#10815)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-14 16:56:16 +00:00
push-app-to-main[bot]
95ad02c9ef Kutt (#10812)
* Add kutt (ct)

* Fix success message formatting in kutt.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-01-14 17:55:51 +01:00
community-scripts-pr-app[bot]
13decbf3a1 Update CHANGELOG.md (#10811)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 16:11:22 +00:00
Chris
c178058315 Install libde265-dev from Testing; refactor install check logic in update (#10810) 2026-01-14 17:10:58 +01:00
CanbiZ
1980e3c47f Usenoninteractive mode for NVIDIA setup
Replaces all apt commands with apt-get for consistency and adds noninteractive environment variables to prevent interactive dialogs during NVIDIA GPU driver installation. Also adds --force-confold to preserve existing config files and ensures smoother automated installs.
2026-01-14 15:51:00 +01:00
community-scripts-pr-app[bot]
b876001ffa Update CHANGELOG.md (#10809)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 13:40:21 +00:00
CanbiZ (MickLesk)
ce5ab97737 Improve NVIDIA GPU setup (5000x Series) (#10807) 2026-01-14 14:39:53 +01:00
community-scripts-pr-app[bot]
2aabd0c911 Update versions.json (#10808)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 13:07:20 +01:00
community-scripts-pr-app[bot]
5fb3ce7b33 Update CHANGELOG.md (#10803)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 09:09:05 +00:00
Bram
bf648203f0 Add search filtering to CommandDialog for improved script search functionality (#10800) 2026-01-14 10:08:44 +01:00
community-scripts-pr-app[bot]
277d1ed5a2 Update CHANGELOG.md (#10801)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 09:01:00 +00:00
durzo
97bd4833fd nginxproxymanager: allow updates now the build is fixed (#10796)
* nginxproxymanager: allow updates now the build is fixed

* fix func

* Change release version to 'latest' for deployment

* Update release version fetching for nginxproxymanager

* Update fetch_and_deploy_gh_release to use latest version

---------

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-01-14 10:00:32 +01:00
community-scripts-pr-app[bot]
2bc50833d6 Update CHANGELOG.md (#10799)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 08:45:43 +00:00
Benjamin Horvat
ff74fdff38 Fixed Apache Guacamole installer (#10798) 2026-01-14 09:45:21 +01:00
community-scripts-pr-app[bot]
dcfeaefad1 Update CHANGELOG.md (#10795)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 06:23:30 +00:00
Comk22
40933df6f7 Fix whiptail dialog hanging in Proxmox web console (#10794) 2026-01-14 07:22:21 +01:00
community-scripts-pr-app[bot]
556e6a71f2 Update CHANGELOG.md (#10792)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 00:16:11 +00:00
community-scripts-pr-app[bot]
7df7a9741a Update versions.json (#10791)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-14 01:15:45 +01:00
community-scripts-pr-app[bot]
749cde5bab Update CHANGELOG.md (#10790)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 20:17:58 +00:00
Chris
a990d39812 Fix intel version check; install legacy packages (#10787) 2026-01-13 21:17:26 +01:00
community-scripts-pr-app[bot]
8551ad33f3 Update CHANGELOG.md (#10789)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 20:17:00 +00:00
Michel Roegl-Brunner
fb1d508182 Remove default VLAN for LAN (#10782) 2026-01-13 21:16:36 +01:00
Michel Roegl-Brunner
648829f51e update_lxcs.sh: Add the option to skip stopped LXC (#10783)
* Add the option to skip stopped LXC

* Fix issue where a script aborts when /usr/lib/python3.*/EXTERNALLY-MANAGED is not there
2026-01-13 21:16:12 +01:00
community-scripts-pr-app[bot]
12a3b4ecd2 Update .app files (#10786)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-13 20:05:15 +01:00
MickLesk
6e420c311b fix typo 2026-01-13 20:03:49 +01:00
community-scripts-pr-app[bot]
7da60f5ec0 Update versions.json (#10780)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 13:06:23 +01:00
community-scripts-pr-app[bot]
92380e9155 Update .app files (#10778)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-13 10:56:30 +01:00
community-scripts-pr-app[bot]
9d0c4f8a16 Update CHANGELOG.md (#10779)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 09:47:05 +00:00
community-scripts-pr-app[bot]
a09121bc49 Update CHANGELOG.md (#10777)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 09:46:45 +00:00
community-scripts-pr-app[bot]
e549378eb1 Update date in json (#10776)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-13 09:46:42 +00:00
push-app-to-main[bot]
186c0f6d09 Investbrain (#10774)
* Add investbrain (ct)

* Fix success message capitalization

* Fix installation script message and import local IP

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-01-13 10:46:23 +01:00
community-scripts-pr-app[bot]
7794b49a43 Update CHANGELOG.md (#10775)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 09:44:06 +00:00
Slaviša Arežina
002c6624f7 Refactor: Joplin Server (#10769) 2026-01-13 10:43:44 +01:00
community-scripts-pr-app[bot]
5044024a19 Update .app files (#10772)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-13 08:55:50 +01:00
community-scripts-pr-app[bot]
d8fc9e5c85 Update CHANGELOG.md (#10773)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:54:25 +00:00
community-scripts-pr-app[bot]
033688ab7d Update CHANGELOG.md (#10771)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:54:03 +00:00
community-scripts-pr-app[bot]
faaebca358 Update date in json (#10770)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:53:59 +00:00
push-app-to-main[bot]
9984ab9d07 Fladder (#10768) 2026-01-13 08:53:37 +01:00
community-scripts-pr-app[bot]
8f1b2b9ad2 Update CHANGELOG.md (#10767)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:10:27 +00:00
Slaviša Arežina
42a2739db6 Backrest: Bump to Trixie (#10758)
* Bump to trixie

* Update
2026-01-13 08:10:06 +01:00
community-scripts-pr-app[bot]
62ed362fbf Update CHANGELOG.md (#10766)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:10:01 +00:00
Slaviša Arežina
7c3d9d231a Refactor (#10759) 2026-01-13 08:09:39 +01:00
community-scripts-pr-app[bot]
8d53604ae3 Update CHANGELOG.md (#10765)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 07:05:19 +00:00
Slaviša Arežina
225eae4b27 Refactor (#10760) 2026-01-13 08:04:59 +01:00
community-scripts-pr-app[bot]
462e75e8f3 Update CHANGELOG.md (#10764)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 06:54:06 +00:00
Copilot
10024723b6 Fix Zammad nginx configuration causing installation failure (#10757)
* Initial plan

* Fix nginx configuration setup in zammad-install.sh

Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>
2026-01-13 07:53:43 +01:00
community-scripts-pr-app[bot]
9256afda54 Update CHANGELOG.md (#10763)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 00:13:45 +00:00
community-scripts-pr-app[bot]
7d4b9316a2 Update versions.json (#10762)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-13 01:13:21 +01:00
community-scripts-pr-app[bot]
36743247f0 Update CHANGELOG.md (#10755)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 19:40:03 +00:00
community-scripts-pr-app[bot]
863876c3a2 Update CHANGELOG.md (#10754)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 19:39:42 +00:00
Christoph Niemann
50954ff560 Update influxdb-install.sh (#10753)
fix if/elif/else
2026-01-12 20:39:20 +01:00
community-scripts-pr-app[bot]
679c9cbb11 Update CHANGELOG.md (#10752)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 17:57:04 +00:00
Victor
b4c16ef05d Add setup for influxdb v3 (#10736) 2026-01-12 18:56:42 +01:00
CanbiZ
56e0783385 Show container ID warning only for user-specified IDs
The warning about a container ID being in use is now only shown if the user manually specified an ID, not when the ID is auto-assigned. This reduces unnecessary warnings during automated container creation.
2026-01-12 18:52:08 +01:00
CanbiZ
305a2ef449 Validate storage space only if container storage set
Storage space validation now occurs only when CONTAINER_STORAGE is defined, preventing premature validation before storage selection in certain modes. This avoids unnecessary errors and aligns validation with actual container creation logic.
2026-01-12 18:44:46 +01:00
CanbiZ
7f6ebeb119 Update build.func 2026-01-12 18:41:19 +01:00
community-scripts-pr-app[bot]
eb30288b1c Update CHANGELOG.md (#10750)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 17:13:42 +00:00
community-scripts-pr-app[bot]
5320b7dbad Update CHANGELOG.md (#10749)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 17:13:20 +00:00
CanbiZ (MickLesk)
27b55a5de4 Apache Guacamole: add schema upgrades and extension updates to Guacamole script (#10746) 2026-01-12 18:13:17 +01:00
CanbiZ (MickLesk)
ff76d83fa7 feat(storage): Add unified storage validation & fix GB/MB display (#10745) 2026-01-12 18:12:55 +01:00
community-scripts-pr-app[bot]
d0e22f73c6 Update CHANGELOG.md (#10748)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 17:12:01 +00:00
CanbiZ (MickLesk)
25594c30aa Apache Tomcat: update support and refactor install script (#10739) 2026-01-12 18:11:42 +01:00
CanbiZ (MickLesk)
c8f6786783 core: remove dupliocated pve_version in advanced installs (#10743) 2026-01-12 18:11:25 +01:00
CanbiZ (MickLesk)
a2a98cf26d remove locals 2026-01-12 18:02:41 +01:00
community-scripts-pr-app[bot]
a7a3514f92 Update CHANGELOG.md (#10744)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 15:50:57 +00:00
CanbiZ (MickLesk)
7e464cfdb0 refactor: Harmonize scripts and fix Booklore environment variables (#10742)
- apache-tomcat: Migrate to setup_java from tools.func
- apache-tomcat: Add update script with version detection from RELEASE-NOTES
- booklore: Fix environment variables (APP_PATH_CONFIG, APP_BOOKDROP_FOLDER)
- booklore: Remove unused variables (BOOKLORE_BOOKS_PATH, BOOKLORE_PORT)
- booklore: Refactor to use setup_mariadb_db and get_latest_github_release
- booklore: Add migration for old env vars in update script
- booklore: Add Node.js setup in update (was missing)
- booklore: Remove default nginx site to prevent conflicts
- jellystat: Replace custom get_ip() with import_local_ip
- jellystat: Remove unnecessary mkdir and simplify cd command
- jellystat: Use version variables for Node.js and PostgreSQL

Fixes #7499 (Booklore bookdrop issue)
2026-01-12 16:50:30 +01:00
community-scripts-pr-app[bot]
a1b381e920 Update .app files (#10735)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-12 14:21:54 +01:00
community-scripts-pr-app[bot]
9fca42fdea Update CHANGELOG.md (#10734)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:10:10 +00:00
CanbiZ (MickLesk)
57c87169a9 Apache Guacamole: Function Bump + update_script (#10728) 2026-01-12 14:09:46 +01:00
community-scripts-pr-app[bot]
0ec96f8287 Update CHANGELOG.md (#10733)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:05:27 +00:00
community-scripts-pr-app[bot]
c68f465fd1 Update date in json (#10732)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:05:24 +00:00
community-scripts-pr-app[bot]
235ed4f2ef Update CHANGELOG.md (#10731)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:05:17 +00:00
push-app-to-main[bot]
bf829988cc Jellystat (#10628)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2026-01-12 14:05:03 +01:00
community-scripts-pr-app[bot]
176b41a576 Update CHANGELOG.md (#10730)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:04:52 +00:00
CanbiZ (MickLesk)
1ccf90cb27 core: validate container ID before pct create to prevent failures (#10729)
* feat: validate container ID before pct create to prevent failures

Add validation to ensure container IDs are not already in use before attempting to create containers. This prevents pct create failures when an ID is already assigned to a VM/LXC or used in LVM volumes.

Changes:
- Add validate_container_id() and get_valid_container_id() functions to build.func
- Validate ID in base_settings() for default installation method
- Validate ID in advanced_settings() dialog with user prompt for next available ID
- Add validation to turnkey.sh with interactive dialog
- Add validation to all-templates.sh with automatic ID correction

Checks performed:
- Container config file existence (/etc/pve/lxc/*.conf)
- VM config file existence (/etc/pve/qemu-server/*.conf)
- LVM logical volume usage

Fixes issue where container creation would fail if the suggested/chosen ID was already in use.

* feat: validate container ID before pct create to prevent failures

Add validation to ensure container IDs are not already in use before attempting to create containers. This prevents pct create failures when an ID is already assigned to a VM/LXC or used in LVM volumes.

Changes:
- Add validate_container_id() and get_valid_container_id() functions to build.func
- Validate ID in base_settings() for default installation method
- Validate ID in advanced_settings() dialog with user prompt for next available ID
- Add validation to turnkey.sh with interactive dialog
- Add validation to all-templates.sh with automatic ID correction

Checks performed:
- Container config file existence (/etc/pve/lxc/*.conf)
- VM config file existence (/etc/pve/qemu-server/*.conf)
- LVM logical volume usage

Fixes issue where container creation would fail if the suggested/chosen ID was already in use.

* Update turnkey.sh

* Update build.func
2026-01-12 14:04:28 +01:00
community-scripts-pr-app[bot]
97c6c4558a Update .app files (#10727)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:26:18 +01:00
community-scripts-pr-app[bot]
cabf3a877e Update CHANGELOG.md (#10726)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 12:23:14 +00:00
community-scripts-pr-app[bot]
96bdd76beb Update CHANGELOG.md (#10725)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 12:22:57 +00:00
CanbiZ (MickLesk)
7234ecc406 Apache CouchDB: bump to debian 13 and add update support (#10721)
* Apache CouchDB: bump to debian 13 and add update support

Added update functionality to apache-couchdb.sh and marked CouchDB as updateable in the JSON metadata. Updated default OS version to 13 and improved credential file handling. Refactored the install script to use a helper for repository setup and standardized credential output.

* fix naming
2026-01-12 13:22:50 +01:00
community-scripts-pr-app[bot]
f0a291542d Update CHANGELOG.md (#10724)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 12:22:36 +00:00
CanbiZ (MickLesk)
18e1149cad Apache Cassandra: bump to debian 13 and add update support (#10720)
* Apache Cassandra: bump to debian 13 and add update support

Bump default Cassandra version from 12 to 13 in scripts and metadata. Refactor install script to use helper functions for Java and repository setup. Implement update functionality in the control script and mark Cassandra as updateable in the JSON metadata.

* Add success message for Cassandra update

Add success message after updating Apache Cassandra.
2026-01-12 13:22:34 +01:00
CanbiZ (MickLesk)
6d05319eb3 Bump Argus to Debian 13 (#10718) 2026-01-12 13:22:15 +01:00
community-scripts-pr-app[bot]
7fe3a47d24 Update CHANGELOG.md (#10723)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 12:22:07 +00:00
CanbiZ (MickLesk)
fac82643a8 Cockpit: Downgrade to Debian 12 Bookworm (45Drives Issue) (#10717)
* Change default var_version from 13 to 12

* Update OS version from 13 to 12 in cockpit.json
2026-01-12 13:22:01 +01:00
CanbiZ (MickLesk)
e33d4d76fe Refactor Docker/Dockge & Bump to Debian 13 (#10719)
* Refactor Docker/Dockge & Bump to Debian 13

* Add base system update to Dockge update script

The update_script function now updates and upgrades the base system before updating Dockge. This ensures the system is up to date prior to pulling new Docker images.

* some fixes

* Apply suggestion from @tremor021

* Apply suggestion from @tremor021

---------

Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2026-01-12 13:21:39 +01:00
community-scripts-pr-app[bot]
d505f3df08 Update versions.json (#10722)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 13:06:22 +01:00
community-scripts-pr-app[bot]
fe471daff9 Update CHANGELOG.md (#10715)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 07:48:57 +00:00
CanbiZ (MickLesk)
76e7755956 Enforce non-interactive apt mode in DB setup scripts (#10714) 2026-01-12 08:48:36 +01:00
community-scripts-pr-app[bot]
166350d2ba Update CHANGELOG.md (#10713)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 00:16:31 +00:00
community-scripts-pr-app[bot]
75d1f6bfe4 Update versions.json (#10712)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-12 01:16:10 +01:00
community-scripts-pr-app[bot]
b8d67c08ad Update CHANGELOG.md (#10710)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 21:42:39 +00:00
Copilot
1c1a3abefc Fix Invoice Ninja Error 500 by restoring file ownership after artisan commands (#10709)
* Initial plan

* Fix Invoice Ninja Error 500 by ensuring proper file ownership after artisan commands

Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MickLesk <47820557+MickLesk@users.noreply.github.com>
2026-01-11 22:42:19 +01:00
community-scripts-pr-app[bot]
5289dd256f Update CHANGELOG.md (#10707)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 17:07:12 +00:00
community-scripts-pr-app[bot]
674ed2c73f Update CHANGELOG.md (#10706)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 17:07:00 +00:00
Slaviša Arežina
e18a34ce63 Refactor: Infisical (#10693)
* Refactor

* Update

* Fix
2026-01-11 18:06:48 +01:00
community-scripts-pr-app[bot]
0090cb8b4b Update CHANGELOG.md (#10705)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 17:06:38 +00:00
Slaviša Arežina
b2602b83a0 Refactor (#10697) 2026-01-11 18:06:18 +01:00
community-scripts-pr-app[bot]
750b0a042e Update CHANGELOG.md (#10703)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 13:14:43 +00:00
Slaviša Arežina
932079a9f6 Refactor: Homer (#10698)
* Refactor

* Update
2026-01-11 14:14:19 +01:00
community-scripts-pr-app[bot]
d43899d5ad Update versions.json (#10702)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 13:05:58 +01:00
community-scripts-pr-app[bot]
b86a89e0fa Update CHANGELOG.md (#10696)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 00:17:34 +00:00
community-scripts-pr-app[bot]
bf9ceb9ce1 Update versions.json (#10695)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 01:17:06 +01:00
community-scripts-pr-app[bot]
328d2c2de1 Update CHANGELOG.md (#10692)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-10 16:26:06 +00:00
FutureCow
047dfb9c93 [Endurain] Increase default RAM from 2048 to 4096 (#10690)
* Increase default RAM from 2048 to 4096

For the new v0.16.5 2048 is not enough to build the app.

* Increase RAM allocation from 2048 to 4096
2026-01-10 17:25:46 +01:00
community-scripts-pr-app[bot]
d7fa87f349 Update versions.json (#10688)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-10 13:06:43 +01:00
community-scripts-pr-app[bot]
93827141fc Update CHANGELOG.md (#10686)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-10 10:42:11 +00:00
CanbiZ (MickLesk)
3e0d0f34cc fix(hwaccel): make beignet-opencl-icd optional for legacy Intel GPUs (#10677)
- Check if beignet-opencl-icd package is available before installation
- Package was removed in Debian 12+ and Ubuntu 22.04+
- VA-API hardware acceleration still works without OpenCL
- Prevents installation failure on systems with Intel HD 2000-5999 GPUs
2026-01-10 11:41:44 +01:00
community-scripts-pr-app[bot]
0a790bf544 Update CHANGELOG.md (#10679)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-10 00:15:38 +00:00
community-scripts-pr-app[bot]
570563539e Update versions.json (#10678)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-10 01:15:15 +01:00
community-scripts-pr-app[bot]
b5ad996bb2 Update CHANGELOG.md (#10675)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 20:20:13 +00:00
Tobias
d047d1aeb7 fix: setup_mariadb hangs on (#10672)
* fix: setup_mariadb hangs on

* readd: docs
2026-01-09 21:19:47 +01:00
community-scripts-pr-app[bot]
c3b5dc7c6f Update CHANGELOG.md (#10674)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 19:32:01 +00:00
Slaviša Arežina
2c1472bb58 Fixes (#10671) 2026-01-09 20:31:30 +01:00
community-scripts-pr-app[bot]
5b5bc11f1e Update CHANGELOG.md (#10666)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 14:19:28 +00:00
Slaviša Arežina
02bbfa5851 Fix (#10664) 2026-01-09 15:19:05 +01:00
community-scripts-pr-app[bot]
896e0c0257 Update versions.json (#10661)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 13:06:04 +01:00
community-scripts-pr-app[bot]
9cf17ef7df Update CHANGELOG.md (#10660)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-09 08:07:34 +00:00
Seth Gregory
f6f0a5553b Remove '--cpu' option from ExecStart command (#10659)
By default, the ExecStart in the system service includes the --cpu flag which forces ComfyUI to run entirely on CPU even if a GPU is present.  This commit removes that flag.
2026-01-09 09:07:11 +01:00
82 changed files with 2805 additions and 1066 deletions

View File

@@ -10,8 +10,154 @@
> [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2026-01-15
## 2026-01-14
### 🆕 New Scripts
- Kutt ([#10812](https://github.com/community-scripts/ProxmoxVE/pull/10812))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Switch Ollama install to .tar.zst and add zstd dependency [@MickLesk](https://github.com/MickLesk) ([#10814](https://github.com/community-scripts/ProxmoxVE/pull/10814))
- Immich: Install libde265-dev from Debian Testing [@vhsdream](https://github.com/vhsdream) ([#10810](https://github.com/community-scripts/ProxmoxVE/pull/10810))
- nginxproxymanager: allow updates now the build is fixed [@durzo](https://github.com/durzo) ([#10796](https://github.com/community-scripts/ProxmoxVE/pull/10796))
- Fixed Apache Guacamole installer [@horvatbenjamin](https://github.com/horvatbenjamin) ([#10798](https://github.com/community-scripts/ProxmoxVE/pull/10798))
### 💾 Core
- #### ✨ New Features
- core: Improve NVIDIA GPU setup (5000x Series) [@MickLesk](https://github.com/MickLesk) ([#10807](https://github.com/community-scripts/ProxmoxVE/pull/10807))
### 🧰 Tools
- Fix whiptail dialog hanging in Proxmox web console [@comk22](https://github.com/comk22) ([#10794](https://github.com/community-scripts/ProxmoxVE/pull/10794))
### 🌐 Website
- #### 🐞 Bug Fixes
- Add search filtering to CommandDialog for improved script search functionality [@BramSuurdje](https://github.com/BramSuurdje) ([#10800](https://github.com/community-scripts/ProxmoxVE/pull/10800))
## 2026-01-13
### 🆕 New Scripts
- Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774))
- Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: Fix Intel version check; install legacy Intel packages during new install [@vhsdream](https://github.com/vhsdream) ([#10787](https://github.com/community-scripts/ProxmoxVE/pull/10787))
- Openwrt: Remove default VLAN for LAN [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#10782](https://github.com/community-scripts/ProxmoxVE/pull/10782))
- Refactor: Joplin Server [@tremor021](https://github.com/tremor021) ([#10769](https://github.com/community-scripts/ProxmoxVE/pull/10769))
- Fix Zammad nginx configuration causing installation failure [@Copilot](https://github.com/Copilot) ([#10757](https://github.com/community-scripts/ProxmoxVE/pull/10757))
- #### 🔧 Refactor
- Backrest: Bump to Trixie [@tremor021](https://github.com/tremor021) ([#10758](https://github.com/community-scripts/ProxmoxVE/pull/10758))
- Refactor: Caddy [@tremor021](https://github.com/tremor021) ([#10759](https://github.com/community-scripts/ProxmoxVE/pull/10759))
- Refactor: Leantime [@tremor021](https://github.com/tremor021) ([#10760](https://github.com/community-scripts/ProxmoxVE/pull/10760))
### 🧰 Tools
- #### 🐞 Bug Fixes
- update_lxcs.sh: Add the option to skip stopped LXC [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#10783](https://github.com/community-scripts/ProxmoxVE/pull/10783))
## 2026-01-12
### 🆕 New Scripts
- Jellystat ([#10628](https://github.com/community-scripts/ProxmoxVE/pull/10628))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- InfluxSB: fix If / fi [@chrnie](https://github.com/chrnie) ([#10753](https://github.com/community-scripts/ProxmoxVE/pull/10753))
- Cockpit: Downgrade to Debian 12 Bookworm (45Drives Issue) [@MickLesk](https://github.com/MickLesk) ([#10717](https://github.com/community-scripts/ProxmoxVE/pull/10717))
- #### ✨ New Features
- InfluxDB: add setup for influxdb v3 [@victorlap](https://github.com/victorlap) ([#10736](https://github.com/community-scripts/ProxmoxVE/pull/10736))
- Apache Guacamole: add schema upgrades and extension updates [@MickLesk](https://github.com/MickLesk) ([#10746](https://github.com/community-scripts/ProxmoxVE/pull/10746))
- Apache Tomcat: update support and refactor install script + debian 13 [@MickLesk](https://github.com/MickLesk) ([#10739](https://github.com/community-scripts/ProxmoxVE/pull/10739))
- Apache Guacamole: Function Bump + update_script [@MickLesk](https://github.com/MickLesk) ([#10728](https://github.com/community-scripts/ProxmoxVE/pull/10728))
- Apache CouchDB: bump to debian 13 and add update support [@MickLesk](https://github.com/MickLesk) ([#10721](https://github.com/community-scripts/ProxmoxVE/pull/10721))
- Apache Cassandra: bump to debian 13 and add update support [@MickLesk](https://github.com/MickLesk) ([#10720](https://github.com/community-scripts/ProxmoxVE/pull/10720))
- #### 🔧 Refactor
- Refactor: Booklore [@MickLesk](https://github.com/MickLesk) ([#10742](https://github.com/community-scripts/ProxmoxVE/pull/10742))
- Bump Argus to Debian 13 [@MickLesk](https://github.com/MickLesk) ([#10718](https://github.com/community-scripts/ProxmoxVE/pull/10718))
- Refactor Docker/Dockge & Bump to Debian 13 [@MickLesk](https://github.com/MickLesk) ([#10719](https://github.com/community-scripts/ProxmoxVE/pull/10719))
### 💾 Core
- #### 🐞 Bug Fixes
- core: remove duplicated pve_version in advanced installs [@MickLesk](https://github.com/MickLesk) ([#10743](https://github.com/community-scripts/ProxmoxVE/pull/10743))
- #### ✨ New Features
- core: add storage validation & fix GB/MB display [@MickLesk](https://github.com/MickLesk) ([#10745](https://github.com/community-scripts/ProxmoxVE/pull/10745))
- core: validate container ID before pct create to prevent failures [@MickLesk](https://github.com/MickLesk) ([#10729](https://github.com/community-scripts/ProxmoxVE/pull/10729))
- #### 🔧 Refactor
- Enforce non-interactive apt mode in DB setup scripts [@MickLesk](https://github.com/MickLesk) ([#10714](https://github.com/community-scripts/ProxmoxVE/pull/10714))
## 2026-01-11
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Fix Invoice Ninja Error 500 by restoring file ownership after artisan commands [@Copilot](https://github.com/Copilot) ([#10709](https://github.com/community-scripts/ProxmoxVE/pull/10709))
- #### 🔧 Refactor
- Refactor: Infisical [@tremor021](https://github.com/tremor021) ([#10693](https://github.com/community-scripts/ProxmoxVE/pull/10693))
- Refactor: HortusFox [@tremor021](https://github.com/tremor021) ([#10697](https://github.com/community-scripts/ProxmoxVE/pull/10697))
- Refactor: Homer [@tremor021](https://github.com/tremor021) ([#10698](https://github.com/community-scripts/ProxmoxVE/pull/10698))
## 2026-01-10
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [Endurain] Increase default RAM from 2048 to 4096 [@FutureCow](https://github.com/FutureCow) ([#10690](https://github.com/community-scripts/ProxmoxVE/pull/10690))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: hwaccel - make beignet-opencl-icd optional for legacy Intel GPUs [@MickLesk](https://github.com/MickLesk) ([#10677](https://github.com/community-scripts/ProxmoxVE/pull/10677))
## 2026-01-09
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Jenkins: Fix application repository setup [@tremor021](https://github.com/tremor021) ([#10671](https://github.com/community-scripts/ProxmoxVE/pull/10671))
- deCONZ: Fix sources check in update script [@tremor021](https://github.com/tremor021) ([#10664](https://github.com/community-scripts/ProxmoxVE/pull/10664))
- Remove '--cpu' option from ExecStart command [@sethgregory](https://github.com/sethgregory) ([#10659](https://github.com/community-scripts/ProxmoxVE/pull/10659))
### 💾 Core
- #### 💥 Breaking Changes
- fix: setup_mariadb hangs on [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10672](https://github.com/community-scripts/ProxmoxVE/pull/10672))
## 2026-01-08
### 🆕 New Scripts

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -20,15 +20,19 @@ color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/cassandra.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/init.d/cassandra ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating Apache Cassandra"
$STD apt update
$STD apt install -y --only-upgrade cassandra cassandra-tools
msg_ok "Updated Apache Cassandra"
msg_ok "Updated successfully!"
exit
}
start

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -20,15 +20,19 @@ color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/couchdb.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/lib/systemd/system/couchdb.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating Apache CouchDB"
$STD apt-get update
$STD apt-get install -y --only-upgrade couchdb
msg_ok "Updated Apache CouchDB"
msg_ok "Updated successfully!"
exit
}
start

View File

@@ -27,8 +27,196 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
setup_mariadb
msg_error "Currently we don't provide an update function for this ${APP}."
# Fetch latest versions
LATEST_TOMCAT=$(curl -fsSL https://dlcdn.apache.org/tomcat/tomcat-9/ | grep -oP '(?<=href=")v[^"/]+(?=/")' | sed 's/^v//' | sort -V | tail -n1)
LATEST_SERVER=$(curl -fsSL https://api.github.com/repos/apache/guacamole-server/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
LATEST_CLIENT=$(curl -fsSL https://api.github.com/repos/apache/guacamole-client/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
LATEST_MYSQL_CONNECTOR=$(curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/maven-metadata.xml" | grep -oP '<latest>\K[^<]+')
# Read current versions from ~/.guacamole_*
CURRENT_TOMCAT=$(cat ~/.guacamole_tomcat 2>/dev/null || echo "unknown")
CURRENT_SERVER=$(cat ~/.guacamole_server 2>/dev/null || echo "unknown")
CURRENT_CLIENT=$(cat ~/.guacamole_client 2>/dev/null || echo "unknown")
CURRENT_MYSQL_CONNECTOR=$(cat ~/.guacamole_mysql_connector 2>/dev/null || echo "unknown")
UPDATE_NEEDED=false
[[ "$CURRENT_TOMCAT" != "$LATEST_TOMCAT" ]] && UPDATE_NEEDED=true
[[ "$CURRENT_SERVER" != "$LATEST_SERVER" ]] && UPDATE_NEEDED=true
[[ "$CURRENT_CLIENT" != "$LATEST_CLIENT" ]] && UPDATE_NEEDED=true
[[ "$CURRENT_MYSQL_CONNECTOR" != "$LATEST_MYSQL_CONNECTOR" ]] && UPDATE_NEEDED=true
if [[ "$UPDATE_NEEDED" == "false" ]]; then
msg_ok "All components are up to date"
exit
fi
JAVA_VERSION="11" setup_java
msg_info "Stopping Services"
systemctl stop guacd tomcat
msg_ok "Stopped Services"
# Update Tomcat
if [[ "$CURRENT_TOMCAT" != "$LATEST_TOMCAT" ]]; then
msg_info "Updating Tomcat (${CURRENT_TOMCAT}${LATEST_TOMCAT})"
cp -a /opt/apache-guacamole/tomcat9/conf /tmp/tomcat-conf-backup
curl -fsSL "https://dlcdn.apache.org/tomcat/tomcat-9/v${LATEST_TOMCAT}/bin/apache-tomcat-${LATEST_TOMCAT}.tar.gz" | tar -xz -C /opt/apache-guacamole/tomcat9 --strip-components=1 --exclude='conf/*'
cp -a /tmp/tomcat-conf-backup/* /opt/apache-guacamole/tomcat9/conf/
rm -rf /tmp/tomcat-conf-backup
chown -R tomcat: /opt/apache-guacamole/tomcat9
echo "${LATEST_TOMCAT}" >~/.guacamole_tomcat
msg_ok "Updated Tomcat"
else
msg_ok "Tomcat already up to date (${CURRENT_TOMCAT})"
fi
# Update Guacamole Server
if [[ "$CURRENT_SERVER" != "$LATEST_SERVER" ]]; then
msg_info "Updating Guacamole Server (${CURRENT_SERVER}${LATEST_SERVER})"
rm -rf /opt/apache-guacamole/server/*
curl -fsSL "https://api.github.com/repos/apache/guacamole-server/tarball/refs/tags/${LATEST_SERVER}" | tar -xz --strip-components=1 -C /opt/apache-guacamole/server
cd /opt/apache-guacamole/server
export CPPFLAGS="-Wno-error=deprecated-declarations"
$STD autoreconf -fi
$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots
$STD make
$STD make install
$STD ldconfig
echo "${LATEST_SERVER}" >~/.guacamole_server
msg_ok "Updated Guacamole Server"
# Auth JDBC follows server version
msg_info "Updating Guacamole Auth JDBC"
rm -f /etc/guacamole/extensions/guacamole-auth-jdbc-mysql-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-jdbc-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-jdbc.tar.gz"
$STD tar -xf /tmp/guacamole-auth-jdbc.tar.gz -C /tmp
mv /tmp/guacamole-auth-jdbc-"${LATEST_SERVER}"/mysql/guacamole-auth-jdbc-mysql-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
rm -rf /tmp/guacamole-auth-jdbc*
echo "${LATEST_SERVER}" >~/.guacamole_auth_jdbc
msg_ok "Updated Guacamole Auth JDBC"
else
msg_ok "Guacamole Server already up to date (${CURRENT_SERVER})"
fi
# Update Guacamole Client
if [[ "$CURRENT_CLIENT" != "$LATEST_CLIENT" ]]; then
msg_info "Updating Guacamole Client (${CURRENT_CLIENT}${LATEST_CLIENT})"
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_CLIENT}/binary/guacamole-${LATEST_CLIENT}.war" -o "/opt/apache-guacamole/tomcat9/webapps/guacamole.war"
echo "${LATEST_CLIENT}" >~/.guacamole_client
msg_ok "Updated Guacamole Client"
else
msg_ok "Guacamole Client already up to date (${CURRENT_CLIENT})"
fi
# Update MySQL Connector
if [[ "$CURRENT_MYSQL_CONNECTOR" != "$LATEST_MYSQL_CONNECTOR" ]]; then
msg_info "Updating MySQL Connector (${CURRENT_MYSQL_CONNECTOR}${LATEST_MYSQL_CONNECTOR})"
curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/${LATEST_MYSQL_CONNECTOR}/mysql-connector-j-${LATEST_MYSQL_CONNECTOR}.jar" -o "/etc/guacamole/lib/mysql-connector-j.jar"
echo "${LATEST_MYSQL_CONNECTOR}" >~/.guacamole_mysql_connector
msg_ok "Updated MySQL Connector"
else
msg_ok "MySQL Connector already up to date (${CURRENT_MYSQL_CONNECTOR})"
fi
# Apply SQL Schema Upgrades (CRITICAL!)
if [[ "$CURRENT_SERVER" != "$LATEST_SERVER" ]]; then
msg_info "Applying MySQL Schema Upgrades"
cd /tmp/guacamole-auth-jdbc-"${LATEST_SERVER}"/mysql/schema/upgrade/
UPGRADE_FILES=($(ls -1 upgrade-pre-*.sql 2>/dev/null | sort -V))
if [[ ${#UPGRADE_FILES[@]} -gt 0 ]]; then
for SQL_FILE in "${UPGRADE_FILES[@]}"; do
FILE_VERSION=$(echo ${SQL_FILE} | grep -oP 'upgrade-pre-\K[0-9\.]+(?=\.)')
# Apply upgrade if file version is newer than current but older/equal to target
if [[ $(echo -e "${FILE_VERSION}\n${CURRENT_SERVER}" | sort -V | head -n1) == "${CURRENT_SERVER}" && "${FILE_VERSION}" != "${CURRENT_SERVER}" ]]; then
msg_info "Applying schema patch: ${SQL_FILE}"
mysql -u root guacamole_db <"${SQL_FILE}" 2>/dev/null
if [[ $? -eq 0 ]]; then
msg_ok "Applied ${SQL_FILE}"
else
msg_warn "Failed to apply ${SQL_FILE} (may already be applied)"
fi
fi
done
fi
msg_ok "MySQL Schema updated"
fi
# Check and upgrade optional extensions
# TOTP Extension
if [[ -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar ]]; then
msg_info "Updating TOTP Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-totp-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-totp.tar.gz"
$STD tar -xf /tmp/guacamole-auth-totp.tar.gz -C /tmp
mv /tmp/guacamole-auth-totp-"${LATEST_SERVER}"/guacamole-auth-totp-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
chmod 664 /etc/guacamole/extensions/guacamole-auth-totp-"${LATEST_SERVER}".jar
rm -rf /tmp/guacamole-auth-totp*
msg_ok "Updated TOTP Extension"
fi
# DUO Extension
if [[ -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar ]]; then
msg_info "Updating DUO Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-duo-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-duo.tar.gz"
$STD tar -xf /tmp/guacamole-auth-duo.tar.gz -C /tmp
mv /tmp/guacamole-auth-duo-"${LATEST_SERVER}"/guacamole-auth-duo-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
chmod 664 /etc/guacamole/extensions/guacamole-auth-duo-"${LATEST_SERVER}".jar
rm -rf /tmp/guacamole-auth-duo*
msg_ok "Updated DUO Extension"
fi
# LDAP Extension
if [[ -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar ]]; then
msg_info "Updating LDAP Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-ldap-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-ldap.tar.gz"
$STD tar -xf /tmp/guacamole-auth-ldap.tar.gz -C /tmp
mv /tmp/guacamole-auth-ldap-"${LATEST_SERVER}"/guacamole-auth-ldap-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
chmod 664 /etc/guacamole/extensions/guacamole-auth-ldap-"${LATEST_SERVER}".jar
rm -rf /tmp/guacamole-auth-ldap*
msg_ok "Updated LDAP Extension"
fi
# Quick Connect Extension
if [[ -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar ]]; then
msg_info "Updating Quick Connect Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-quickconnect-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-auth-quickconnect.tar.gz"
$STD tar -xf /tmp/guacamole-auth-quickconnect.tar.gz -C /tmp
mv /tmp/guacamole-auth-quickconnect-"${LATEST_SERVER}"/guacamole-auth-quickconnect-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
chmod 664 /etc/guacamole/extensions/guacamole-auth-quickconnect-"${LATEST_SERVER}".jar
rm -rf /tmp/guacamole-auth-quickconnect*
msg_ok "Updated Quick Connect Extension"
fi
# History Recording Storage Extension
if [[ -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar ]]; then
msg_info "Updating History Recording Storage Extension"
rm -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar
curl -fsSL "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-history-recording-storage-${LATEST_SERVER}.tar.gz" -o "/tmp/guacamole-history-recording-storage.tar.gz"
$STD tar -xf /tmp/guacamole-history-recording-storage.tar.gz -C /tmp
mv /tmp/guacamole-history-recording-storage-"${LATEST_SERVER}"/guacamole-history-recording-storage-"${LATEST_SERVER}".jar /etc/guacamole/extensions/
chmod 664 /etc/guacamole/extensions/guacamole-history-recording-storage-"${LATEST_SERVER}".jar
rm -rf /tmp/guacamole-history-recording-storage*
msg_ok "Updated History Recording Storage Extension"
fi
# Reset permissions and prepare for service start
msg_info "Resetting permissions"
mkdir -p /var/guacamole
chown daemon:daemon /var/guacamole
mkdir -p /home/daemon/.config/freerdp
chown daemon:daemon /home/daemon/.config/freerdp
msg_ok "Permissions reset"
msg_info "Starting Services"
systemctl daemon-reload
systemctl start tomcat guacd
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}

View File

@@ -11,7 +11,7 @@ var_disk="${var_disk:-5}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -20,15 +20,79 @@ color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if ! ls -d /opt/tomcat-* >/dev/null 2>&1; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "Currently we don't provide an update function for this ${APP}."
header_info
check_container_storage
check_container_resources
TOMCAT_DIR=$(ls -d /opt/tomcat-* 2>/dev/null | head -n1)
if [[ -z "$TOMCAT_DIR" || ! -d "$TOMCAT_DIR" ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
# Detect major version and current version from install path (e.g., /opt/tomcat-11 -> 11)
TOMCAT_MAJOR=$(basename "$TOMCAT_DIR" | grep -oP 'tomcat-\K[0-9]+')
if [[ -z "$TOMCAT_MAJOR" ]]; then
msg_error "Cannot determine Tomcat major version from path: $TOMCAT_DIR"
exit
fi
CURRENT_VERSION=$(grep -oP 'Apache Tomcat Version \K[0-9.]+' "$TOMCAT_DIR/RELEASE-NOTES" 2>/dev/null || echo "unknown")
LATEST_VERSION=$(curl -fsSL "https://dlcdn.apache.org/tomcat/tomcat-${TOMCAT_MAJOR}/" | grep -oP 'v[0-9]+\.[0-9]+\.[0-9]+(-M[0-9]+)?/' | sort -V | tail -n1 | sed 's/\/$//; s/v//')
if [[ -z "$LATEST_VERSION" ]]; then
msg_error "Failed to fetch latest version for Tomcat ${TOMCAT_MAJOR}"
exit
fi
if [[ "$CURRENT_VERSION" == "$LATEST_VERSION" ]]; then
msg_ok "${APP} ${CURRENT_VERSION} is already up to date"
exit
fi
msg_info "Stopping Tomcat service"
systemctl stop tomcat
msg_ok "Stopped Tomcat service"
msg_info "Backing up configuration and applications"
BACKUP_DIR="/tmp/tomcat-backup-$$"
mkdir -p "$BACKUP_DIR"
cp -a "$TOMCAT_DIR/conf" "$BACKUP_DIR/conf"
cp -a "$TOMCAT_DIR/webapps" "$BACKUP_DIR/webapps"
[[ -d "$TOMCAT_DIR/lib" ]] && cp -a "$TOMCAT_DIR/lib" "$BACKUP_DIR/lib"
msg_ok "Backed up configuration and applications"
msg_info "Downloading Tomcat ${LATEST_VERSION}"
TOMCAT_URL="https://dlcdn.apache.org/tomcat/tomcat-${TOMCAT_MAJOR}/v${LATEST_VERSION}/bin/apache-tomcat-${LATEST_VERSION}.tar.gz"
curl -fsSL "$TOMCAT_URL" -o /tmp/tomcat-update.tar.gz
msg_ok "Downloaded Tomcat ${LATEST_VERSION}"
msg_info "Installing update"
rm -rf "${TOMCAT_DIR:?}"/*
tar --strip-components=1 -xzf /tmp/tomcat-update.tar.gz -C "$TOMCAT_DIR"
rm -f /tmp/tomcat-update.tar.gz
msg_ok "Installed update"
msg_info "Restoring configuration and applications"
cp -a "$BACKUP_DIR/conf"/* "$TOMCAT_DIR/conf/"
cp -a "$BACKUP_DIR/webapps"/* "$TOMCAT_DIR/webapps/" 2>/dev/null || true
if [[ -d "$BACKUP_DIR/lib" ]]; then
for jar in "$BACKUP_DIR/lib"/*.jar; do
[[ -f "$jar" ]] || continue
jar_name=$(basename "$jar")
if [[ ! -f "$TOMCAT_DIR/lib/$jar_name" ]]; then
cp "$jar" "$TOMCAT_DIR/lib/"
fi
done
fi
rm -rf "$BACKUP_DIR"
chown -R root:root "$TOMCAT_DIR"
msg_ok "Restored configuration and applications"
msg_info "Starting Tomcat service"
systemctl start tomcat
msg_ok "Started Tomcat service"
msg_ok "Updated successfully!"
exit
}
start

View File

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

View File

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

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-3}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-7}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -28,15 +28,29 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
setup_mariadb
if check_for_gh_release "booklore" "booklore-app/BookLore"; then
JAVA_VERSION="21" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
msg_info "Stopping Service"
systemctl stop booklore
msg_info "Stopped Service"
msg_ok "Stopped Service"
msg_info "backup old install"
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 "backup done"
msg_ok "Backed up old installation"
fetch_and_deploy_gh_release "booklore" "booklore-app/BookLore" "tarball"
@@ -46,12 +60,9 @@ function update_script() {
$STD npm run build --configuration=production
msg_ok "Built Frontend"
JAVA_VERSION="21" setup_java
setup_yq
msg_info "Building Backend"
cd /opt/booklore/booklore-api
APP_VERSION=$(curl -fsSL https://api.github.com/repos/booklore-app/BookLore/releases/latest | yq '.tag_name' | sed 's/^v//')
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 --no-daemon
mkdir -p /opt/booklore/dist

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -29,21 +29,19 @@ function update_script() {
fi
msg_info "Updating Caddy LXC"
$STD apt-get update
$STD apt-get -y upgrade
$STD apt update
$STD apt upgrade -y
msg_ok "Updated Caddy LXC"
if command -v xcaddy >/dev/null 2>&1; then
setup_go
msg_info "Updating xCaddy"
cd /opt
RELEASE=$(curl -fsSL https://api.github.com/repos/caddyserver/xcaddy/releases/latest | grep "tag_name" | awk -F '"' '{print $4}')
VERSION="${RELEASE#v}"
curl -fsSL "https://github.com/caddyserver/xcaddy/releases/download/${RELEASE}/xcaddy_${VERSION}_linux_amd64.deb" -o "xcaddy_${VERSION}_linux_amd64.deb"
$STD dpkg -i "xcaddy_${VERSION}_linux_amd64.deb"
rm -f "xcaddy_${VERSION}_linux_amd64.deb"
$STD xcaddy build
msg_ok "Updated xCaddy"
if check_for_gh_release "xcaddy" "caddyserver/xcaddy"; then
setup_go
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
msg_info "Updating xCaddy"
$STD xcaddy build
msg_ok "Updated xCaddy"
fi
fi
msg_ok "Updated successfully!"
exit

View File

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

View File

@@ -23,7 +23,7 @@ function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/apt/sources.list.d/deconz.list ]]; then
if [[ ! -f /etc/apt/sources.list.d/deconz.list && ! -f /etc/apt/sources.list.d/deconz.sources ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -24,33 +24,20 @@ function update_script() {
check_container_storage
check_container_resources
get_latest_release() {
curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
msg_info "Updating base system"
$STD apt-get update
$STD apt-get -y upgrade
$STD apt update
$STD apt upgrade -y
msg_ok "Base system updated"
msg_info "Updating Docker Engine"
$STD apt-get install --only-upgrade -y docker-ce docker-ce-cli containerd.io
$STD apt install --only-upgrade -y docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-buildx-plugin
msg_ok "Docker Engine updated"
if [[ -f /usr/local/lib/docker/cli-plugins/docker-compose ]]; then
COMPOSE_BIN="/usr/local/lib/docker/cli-plugins/docker-compose"
COMPOSE_NEW_VERSION=$(get_latest_release "docker/compose")
msg_info "Updating Docker Compose to $COMPOSE_NEW_VERSION"
curl -fsSL "https://github.com/docker/compose/releases/download/${COMPOSE_NEW_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o "$COMPOSE_BIN"
chmod +x "$COMPOSE_BIN"
msg_ok "Docker Compose updated"
fi
if docker ps -a --format '{{.Image}}' | grep -q '^portainer/portainer-ce:latest$'; then
msg_info "Updating Portainer"
$STD docker pull portainer/portainer-ce:latest
$STD docker stop portainer && docker rm portainer
$STD docker stop portainer
$STD docker rm portainer
$STD docker volume create portainer_data >/dev/null 2>&1
$STD docker run -d \
-p 8000:8000 \
@@ -66,7 +53,8 @@ function update_script() {
if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
msg_info "Updating Portainer Agent"
$STD docker pull portainer/agent:latest
$STD docker stop portainer_agent && docker rm portainer_agent
$STD docker stop portainer_agent
$STD docker rm portainer_agent
$STD docker run -d \
-p 9001:9001 \
--name=portainer_agent \

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-18}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -27,11 +27,17 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ${APP}"
msg_info "Updating base system"
$STD apt update
$STD apt upgrade -y
msg_ok "Base system updated"
msg_info "Updating Dockge"
cd /opt/dockge
$STD docker compose pull
$STD docker compose up -d
msg_ok "Updated ${APP}"
msg_ok "Updated Dockge"
msg_ok "Updated successfully!"
exit
}

View File

@@ -8,7 +8,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
APP="Endurain"
var_tags="${var_tags:-sport;social-media}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-5}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"

68
ct/fladder.sh Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: wendyliga
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/DonutWare/Fladder
APP="Fladder"
var_tags="${var_tags:-media}"
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/fladder ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "Fladder" "DonutWare/Fladder"; then
msg_info "Stopping Service"
systemctl stop nginx
msg_ok "Stopped Service"
if [[ -f /opt/fladder/assets/config/config.json ]]; then
msg_info "Backing up configuration"
cp /opt/fladder/assets/config/config.json /tmp/fladder_config.json.bak
msg_ok "Configuration backed up"
fi
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Fladder" "DonutWare/Fladder" "prebuild" "latest" "/opt/fladder" "Fladder-Web-*.zip"
if [[ -f /tmp/fladder_config.json.bak ]]; then
msg_info "Restoring configuration"
mkdir -p /opt/fladder/assets/config
cp /tmp/fladder_config.json.bak /opt/fladder/assets/config/config.json
rm -f /tmp/fladder_config.json.bak
msg_ok "Configuration restored"
fi
msg_info "Starting Service"
systemctl start nginx
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 IP:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

6
ct/headers/fladder Normal file
View File

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

6
ct/headers/investbrain Normal file
View File

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

6
ct/headers/kutt Normal file
View File

@@ -0,0 +1,6 @@
__ __ __ __
/ //_/_ __/ /_/ /_
/ ,< / / / / __/ __/
/ /| / /_/ / /_/ /_
/_/ |_\__,_/\__/\__/

View File

@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -27,36 +27,31 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Stopping Service"
systemctl stop homer
msg_ok "Stopped Service"
msg_info "Backing up assets directory"
cd ~
mkdir -p assets-backup
cp -R /opt/homer/assets/. assets-backup
msg_ok "Backed up assets directory"
if check_for_gh_release "homer" "bastienwirtz/homer"; then
msg_info "Stopping Service"
systemctl stop homer
msg_ok "Stopped Service"
msg_info "Updating ${APP}"
rm -rf /opt/homer/*
cd /opt/homer
curl -fsSL "https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip" -o $(basename "https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip")
$STD unzip homer.zip
msg_ok "Updated ${APP}"
msg_info "Backing up assets directory"
cd ~
mkdir -p assets-backup
cp -R /opt/homer/assets/. assets-backup
msg_ok "Backed up assets directory"
msg_info "Restoring assets directory"
cd ~
cp -Rf assets-backup/. /opt/homer/assets/
msg_ok "Restored assets directory"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homer" "bastienwirtz/homer" "prebuild" "latest" "/opt/homer" "homer.zip"
msg_info "Cleaning"
rm -rf assets-backup /opt/homer/homer.zip
msg_ok "Cleaned"
msg_info "Starting Service"
systemctl start homer
msg_ok "Started Service"
msg_ok "Updated successfully!"
msg_info "Restoring assets directory"
cd ~
cp -Rf assets-backup/. /opt/homer/assets/
rm -rf assets-backup
msg_ok "Restored assets directory"
msg_info "Starting Service"
systemctl start homer
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}

View File

@@ -57,9 +57,12 @@ EOF
fi
$STD apt update
msg_ok "Added Debian Testing repo"
msg_info "Installing libmimalloc3"
$STD apt install -t testing --no-install-recommends libmimalloc3
msg_ok "Installed libmimalloc3"
fi
if ! dpkg -l "libmimalloc3" | grep -q '3.1' || ! dpkg -l "libde265-dev" | grep -q '1.0.16'; then
msg_info "Installing/upgrading Testing repo packages"
$STD apt install -t testing libmimalloc3 libde265-dev -y
msg_ok "Installed/upgraded Testing repo packages"
fi
if [[ ! -f /etc/apt/sources.list.d/mise.list ]]; then
@@ -93,6 +96,7 @@ EOF
$STD apt install -y ./*.deb
rm ./*.deb
$STD apt-mark hold libigdgmm12
dpkg -l | grep -m1 "intel-opencl-icd" | awk '{print $3}' >~/.intel_version
msg_ok "Intel iGPU dependencies updated"
fi
rm ./Dockerfile

View File

@@ -33,6 +33,7 @@ function update_script() {
msg_ok "Service stopped"
msg_info "Creating backup"
[[ -f /opt/infisical_backup.sql ]] && rm -f /opt/infisical_backup.sql
DB_PASS=$(grep -Po '(?<=^Database Password:\s).*' ~/infisical.creds | head -n1)
PGPASSWORD=$DB_PASS pg_dump -U infisical -h localhost -d infisical_db > /opt/infisical_backup.sql
msg_ok "Created backup"

View File

@@ -43,4 +43,4 @@ 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} and Port 8888 for v1 or Port 8086 (v2)${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP} and Port 8888 for v1, Port 8086 for v2 or Port 8181 for v3${CL}"

90
ct/investbrain.sh Normal file
View File

@@ -0,0 +1,90 @@
#!/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: Benito Rodríguez (b3ni)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/investbrainapp/investbrain
APP="Investbrain"
var_tags="${var_tags:-finance;portfolio;investing}"
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/investbrain ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "Investbrain" "investbrainapp/investbrain"; then
PHP_VERSION="8.4"
msg_info "Stopping Services"
systemctl stop nginx php${PHP_VERSION}-fpm
$STD supervisorctl stop all
msg_ok "Services Stopped"
setup_composer
NODE_VERSION="22" setup_nodejs
PG_VERSION="17" setup_postgresql
msg_info "Creating Backup"
rm -f /opt/.env.backup
rm -rf /opt/investbrain_backup
cp /opt/investbrain/.env /opt/.env.backup
cp -r /opt/investbrain/storage /opt/investbrain_backup
msg_ok "Created Backup"
fetch_and_deploy_gh_release "Investbrain" "investbrainapp/investbrain" "tarball" "latest" "/opt/investbrain"
msg_info "Updating Investbrain"
cd /opt/investbrain
rm -rf /opt/investbrain/storage
cp /opt/.env.backup /opt/investbrain/.env
cp -r /opt/investbrain_backup/ /opt/investbrain/storage
export COMPOSER_ALLOW_SUPERUSER=1
$STD /usr/local/bin/composer install --no-interaction --no-dev --optimize-autoloader
$STD npm install
$STD npm run build
$STD php artisan storage:link
$STD php artisan migrate --force
$STD php artisan cache:clear
$STD php artisan view:clear
$STD php artisan route:clear
$STD php artisan event:clear
$STD php artisan route:cache
$STD php artisan event:cache
chown -R www-data:www-data /opt/investbrain
chmod -R 775 /opt/investbrain/storage /opt/investbrain/bootstrap/cache
rm -rf /opt/.env.backup /opt/investbrain_backup
msg_ok "Updated Investbrain"
msg_info "Starting Services"
systemctl start php${PHP_VERSION}-fpm nginx
$STD supervisorctl start all
msg_ok "Services Started"
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,7 +32,7 @@ function update_script() {
msg_info "Updating Jenkins"
$STD apt update
$STD apt -y upgrade
$STD apt upgrade -y
msg_ok "Updated Jenkins"
msg_ok "Updated successfully!"
exit

View File

@@ -35,10 +35,12 @@ function update_script() {
systemctl stop joplin-server
msg_ok "Stopped Services"
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
cp /opt/joplin-server/.env /opt
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball"
mv /opt/.env /opt/joplin-server
msg_info "Updating Joplin-Server"
cd /opt/joplin-server
cd /opt/joplin-server
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
export BUILD_SEQUENCIAL=1

74
ct/kutt.sh Normal file
View File

@@ -0,0 +1,74 @@
#!/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: tomfrenzel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/thedevs-network/kutt
APP="Kutt"
var_tags="${var_tags:-sharing}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-2}"
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/kutt ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "kutt" "thedevs-network/kutt"; then
msg_info "Stopping services"
systemctl stop kutt
msg_ok "Stopped services"
msg_info "Backing up data"
mkdir -p /opt/kutt-backup
[ -d /opt/kutt/custom ] && cp -r /opt/kutt/custom /opt/kutt-backup/
[ -d /opt/kutt/db ] && cp -r /opt/kutt/db /opt/kutt-backup/
cp /opt/kutt/.env /opt/kutt-backup/
msg_ok "Backed up data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "kutt" "thedevs-network/kutt" "tarball" "latest"
msg_info "Restoring data"
[ -d /opt/kutt-backup/custom ] && cp -r /opt/kutt-backup/custom /opt/kutt/
[ -d /opt/kutt-backup/db ] && cp -r /opt/kutt-backup/db /opt/kutt/
[ -f /opt/kutt-backup/.env ] && cp /opt/kutt-backup/.env /opt/kutt/
rm -rf /opt/kutt-backup
msg_ok "Restored data"
msg_info "Configuring Kutt"
cd /opt/kutt
$STD npm install
$STD npm run migrate
msg_ok "Configured Kutt"
msg_info "Starting services"
systemctl start kutt
msg_ok "Started services"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP} or https://<your-Kutt-domain>${CL}"

View File

@@ -49,11 +49,10 @@ function update_script() {
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
#RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
#grep "tag_name" |
#awk '{print substr($2, 3, length($2)-4) }')
RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
RELEASE="2.13.5"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "v${RELEASE}" "/opt/nginxproxymanager"
msg_info "Stopping Services"

View File

@@ -32,17 +32,22 @@ function update_script() {
if [[ ! -f /opt/Ollama_version.txt ]]; then
touch /opt/Ollama_version.txt
fi
if ! command -v zstd &>/dev/null; then
msg_info "Installing zstd"
$STD apt install -y zstd
msg_ok "Installed zstd"
fi
msg_info "Stopping Services"
systemctl stop ollama
msg_ok "Services Stopped"
TMP_TAR=$(mktemp --suffix=.tgz)
curl -fL# -C - -o "${TMP_TAR}" "https://github.com/ollama/ollama/releases/download/${RELEASE}/ollama-linux-amd64.tgz"
TMP_TAR=$(mktemp --suffix=.tar.zst)
curl -fL# -C - -o "${TMP_TAR}" "https://github.com/ollama/ollama/releases/download/${RELEASE}/ollama-linux-amd64.tar.zst"
msg_info "Updating Ollama to ${RELEASE}"
rm -rf /usr/local/lib/ollama
rm -rf /usr/local/bin/ollama
mkdir -p /usr/local/lib/ollama
tar -xzf "${TMP_TAR}" -C /usr/local/lib/ollama
tar --zstd -xf "${TMP_TAR}" -C /usr/local/lib/ollama
ln -sf /usr/local/lib/ollama/bin/ollama /usr/local/bin/ollama
rm -f "${TMP_TAR}"
echo "${RELEASE}" >/opt/Ollama_version.txt

View File

@@ -92,12 +92,17 @@ EOF
OLLAMA_VERSION=$(ollama -v | awk '{print $NF}')
RELEASE=$(curl -s https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
if [ "$OLLAMA_VERSION" != "$RELEASE" ]; then
if ! command -v zstd &>/dev/null; then
msg_info "Installing zstd"
$STD apt install -y zstd
msg_ok "Installed zstd"
fi
msg_info "Ollama update available: v$OLLAMA_VERSION -> v$RELEASE"
msg_info "Downloading Ollama v$RELEASE \n"
curl -fS#LO https://ollama.com/download/ollama-linux-amd64.tgz
curl -fS#LO https://github.com/ollama/ollama/releases/download/v${RELEASE}/ollama-linux-amd64.tar.zst
msg_ok "Download Complete"
if [ -f "ollama-linux-amd64.tgz" ]; then
if [ -f "ollama-linux-amd64.tar.zst" ]; then
msg_info "Stopping Ollama Service"
systemctl stop ollama
@@ -106,8 +111,8 @@ EOF
msg_info "Installing Ollama"
rm -rf /usr/lib/ollama
rm -rf /usr/bin/ollama
tar -C /usr -xzf ollama-linux-amd64.tgz
rm -rf ollama-linux-amd64.tgz
tar --zstd -C /usr -xf ollama-linux-amd64.tar.zst
rm -rf ollama-linux-amd64.tar.zst
msg_ok "Installed Ollama"
msg_info "Starting Ollama Service"

View File

@@ -6,7 +6,7 @@
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": false,
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://cassandra.apache.org/doc/latest/",
@@ -23,7 +23,7 @@
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "12"
"version": "13"
}
}
],

View File

@@ -1,19 +1,19 @@
{
"name": "Apache-CouchDB",
"name": "Apache CouchDB",
"slug": "apache-couchdb",
"categories": [
8
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": false,
"updateable": true,
"privileged": false,
"interface_port": 5984,
"documentation": "https://docs.couchdb.org/en/stable/",
"website": "https://couchdb.apache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/couchdb.webp",
"config_path": "etc/default.ini",
"description": "Apache-CouchDB Seamless multi-master sync, that scales from Big Data to Mobile, with an Intuitive HTTP/JSON API and designed for Reliability.",
"description": "Apache CouchDB Seamless multi-master sync, that scales from Big Data to Mobile, with an Intuitive HTTP/JSON API and designed for Reliability.",
"install_methods": [
{
"type": "default",
@@ -23,7 +23,7 @@
"ram": 4096,
"hdd": 10,
"os": "debian",
"version": "12"
"version": "13"
}
}
],
@@ -33,7 +33,7 @@
},
"notes": [
{
"text": "Show Login Credentials: `cat CouchDB.creds`",
"text": "Login Credentials: `cat ~/couchdb.creds`",
"type": "info"
}
]

View File

@@ -6,7 +6,7 @@
],
"date_created": "2024-12-19",
"type": "ct",
"updateable": false,
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://guacamole.apache.org/doc/gug/",

View File

@@ -6,7 +6,7 @@
],
"date_created": "2025-03-04",
"type": "ct",
"updateable": false,
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://cwiki.apache.org/confluence/display/TOMCAT",
@@ -23,7 +23,7 @@
"ram": 1024,
"hdd": 5,
"os": "debian",
"version": "12"
"version": "13"
}
}
],

View File

@@ -20,10 +20,10 @@
"script": "ct/argus.sh",
"resources": {
"cpu": 1,
"ram": 256,
"ram": 512,
"hdd": 3,
"os": "debian",
"version": "12"
"version": "13"
}
}
],

View File

@@ -12,7 +12,7 @@
"documentation": "https://garethgeorge.github.io/backrest/introduction/getting-started",
"website": "https://garethgeorge.github.io/backrest",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/backrest.webp",
"config_path": "/opt/backrest/config/config.json",
"config_path": "/opt/backrest/config/config.json | /opt/backrest/.env",
"description": "Backrest is a web-accessible backup solution built on top of restic and providing a WebUI which wraps the restic CLI and makes it easy to create repos, browse snapshots, and restore files. Additionally, Backrest can run in the background and take an opinionated approach to scheduling snapshots and orchestrating repo health operations.",
"install_methods": [
{
@@ -23,7 +23,7 @@
"ram": 512,
"hdd": 8,
"os": "debian",
"version": "12"
"version": "13"
}
}
],

View File

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

View File

@@ -23,7 +23,7 @@
"ram": 512,
"hdd": 6,
"os": "debian",
"version": "12"
"version": "13"
}
},
{

View File

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

View File

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

View File

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

View File

@@ -20,7 +20,7 @@
"script": "ct/endurain.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"ram": 4096,
"hdd": 5,
"os": "debian",
"version": "13"

View File

@@ -0,0 +1,35 @@
{
"name": "Fladder",
"slug": "fladder",
"categories": [
13
],
"date_created": "2026-01-13",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://github.com/DonutWare/Fladder/blob/develop/INSTALL.md#ubuntudebian",
"website": "https://github.com/DonutWare/Fladder",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/fladder.webp",
"config_path": "/opt/fladder/assets/config/config.json",
"description": "Fladder is a simple Jellyfin frontend built on top of Flutter. It provides a modern interface to stream and sync content locally, manage libraries, support multiple profiles, and offers direct, transcode and offline playback with media segments skipping.",
"install_methods": [
{
"type": "default",
"script": "ct/fladder.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -0,0 +1,40 @@
{
"name": "Investbrain",
"slug": "investbrain",
"categories": [
23
],
"date_created": "2026-01-13",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://github.com/investbrainapp/investbrain",
"website": "https://investbra.in",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/investbrain.webp",
"config_path": "/opt/investbrain/.env",
"description": "Investbrain is a smart open-source investment tracker that helps you manage, track, and make informed decisions about your investments.",
"install_methods": [
{
"type": "default",
"script": "ct/investbrain.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Database credentials: `cat ~/investbrain.creds`",
"type": "info"
}
]
}

View File

@@ -0,0 +1,48 @@
{
"name": "Jellystat",
"slug": "jellystat",
"categories": [
9
],
"date_created": "2026-01-12",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://github.com/CyferShepard/Jellystat",
"website": "https://github.com/CyferShepard/Jellystat",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/jellystat.webp",
"config_path": "/opt/jellystat/.env",
"description": "A free and open source statistics app for Jellyfin",
"install_methods": [
{
"type": "default",
"script": "tools/addon/jellystat.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Requires Node.js 20+ and PostgreSQL (auto-installed if missing)",
"type": "info"
},
{
"text": "Default PostgreSQL credentials: jellystat / jellystat",
"type": "info"
},
{
"text": "Update with: update_jellystat",
"type": "info"
}
]
}

View File

@@ -0,0 +1,40 @@
{
"name": "Kutt",
"slug": "kutt",
"categories": [
21
],
"date_created": "2026-01-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 443,
"documentation": "https://github.com/thedevs-network/kutt/",
"config_path": "/opt/kutt/.env",
"website": "https://kutt.it",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/kutt.webp",
"description": "Kutt is a modern URL shortener with support for custom domains. Create and edit links, view statistics, manage users, and more.",
"install_methods": [
{
"type": "default",
"script": "ct/kutt.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 2,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Kutt needs so be served with an SSL certificate for its login to work. During install, you will be prompted to choose if you want to have Caddy installed for SSL termination or if you want to use your own reverse proxy (in that case point your reverse porxy to port 3000).",
"type": "info"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -194,7 +194,20 @@ function CommandMenu() {
</TooltipProvider>
</div>
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandDialog
open={open}
onOpenChange={setOpen}
filter={(value: string, search: string) => {
const searchLower = search.toLowerCase().trim();
if (!searchLower)
return 1;
const valueLower = value.toLowerCase();
const searchWords = searchLower.split(/\s+/).filter(Boolean);
// All search words must appear somewhere in the value (name + description)
const allWordsMatch = searchWords.every((word: string) => valueLower.includes(word));
return allWordsMatch ? 1 : 0;
}}
>
<DialogTitle className="sr-only">Search scripts</DialogTitle>
<CommandInput placeholder="Search for a script..." />
<CommandList>
@@ -204,7 +217,7 @@ function CommandMenu() {
{scripts.map(script => (
<CommandItem
key={`script:${script.slug}`}
value={`${script.name}-${script.type}`}
value={`${script.name} ${script.type} ${script.description || ""}`}
onSelect={() => {
setOpen(false);
router.push(`/scripts?id=${script.slug}`);

View File

@@ -24,13 +24,18 @@ const Command = React.forwardRef<
));
Command.displayName = CommandPrimitive.displayName;
type CommandDialogProps = {} & DialogProps;
type CommandDialogProps = {
filter?: (value: string, search: string, keywords?: string[]) => number;
} & DialogProps;
function CommandDialog({ children, ...props }: CommandDialogProps) {
function CommandDialog({ children, filter, ...props }: CommandDialogProps) {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0 shadow-lg">
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
<Command
filter={filter}
className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5"
>
{children}
</Command>
</DialogContent>

View File

@@ -13,22 +13,16 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y apt-transport-https
msg_ok "Installed Dependencies"
msg_info "Installing Eclipse Temurin (Patience)"
curl -fsSL "https://packages.adoptium.net/artifactory/api/gpg/key/public" | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg
echo 'deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/adoptium.gpg] https://packages.adoptium.net/artifactory/deb bookworm main' >/etc/apt/sources.list.d/adoptium.list
$STD apt-get update
$STD apt-get install -y temurin-11-jdk
msg_ok "Installed Eclipse Temurin"
JAVA_VERSION="11" setup_java
msg_info "Installing Apache Cassandra"
curl -fsSL "https://downloads.apache.org/cassandra/KEYS" | gpg --dearmor >/etc/apt/trusted.gpg.d/cassandra.gpg
echo "deb https://debian.cassandra.apache.org 41x main" >/etc/apt/sources.list.d/cassandra.sources.list
$STD apt-get update
$STD apt-get install -y cassandra cassandra-tools
setup_deb822_repo \
"cassandra" \
"https://downloads.apache.org/cassandra/KEYS" \
"https://debian.cassandra.apache.org" \
"41x" \
"main"
$STD apt install -y cassandra cassandra-tools
sed -i -e 's/^rpc_address: localhost/#rpc_address: localhost/g' -e 's/^# rpc_interface: eth1/rpc_interface: eth0/g' /etc/cassandra/cassandra.yaml
msg_ok "Installed Apache Cassandra"

View File

@@ -13,10 +13,6 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y apt-transport-https
msg_ok "Installed Dependencies"
msg_info "Installing Apache CouchDB"
ERLANG_COOKIE=$(openssl rand -base64 32)
ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)"
@@ -25,14 +21,19 @@ debconf-set-selections <<<"couchdb couchdb/mode select standalone"
debconf-set-selections <<<"couchdb couchdb/bindaddress string 0.0.0.0"
debconf-set-selections <<<"couchdb couchdb/adminpass password $ADMIN_PASS"
debconf-set-selections <<<"couchdb couchdb/adminpass_again password $ADMIN_PASS"
curl -fsSL https://couchdb.apache.org/repo/keys.asc | gpg --dearmor -o /usr/share/keyrings/couchdb-archive-keyring.gpg
VERSION_CODENAME="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
echo "deb [signed-by=/usr/share/keyrings/couchdb-archive-keyring.gpg] https://apache.jfrog.io/artifactory/couchdb-deb/ ${VERSION_CODENAME} main" >/etc/apt/sources.list.d/couchdb.sources.list
$STD apt-get update
$STD apt-get install -y couchdb
echo -e "CouchDB Erlang Cookie: \e[32m$ERLANG_COOKIE\e[0m" >>~/CouchDB.creds
echo -e "CouchDB Admin Password: \e[32m$ADMIN_PASS\e[0m" >>~/CouchDB.creds
msg_ok "Installed Apache CouchDB."
setup_deb822_repo \
"couchdb" \
"https://couchdb.apache.org/repo/keys.asc" \
"https://apache.jfrog.io/artifactory/couchdb-deb" \
"$(get_os_info codename)" \
"main"
$STD apt install -y couchdb
{
echo "CouchDB Credentials"
echo "CouchDB Erlang Cookie: $ERLANG_COOKIE"
echo "CouchDB Admin Password: $ADMIN_PASS"
} >>~/couchdb.creds
msg_ok "Installed Apache CouchDB"
motd_ssh
customize

View File

@@ -15,12 +15,11 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
jq \
libcairo2-dev \
libturbojpeg0 \
libjpeg62-turbo-dev \
libpng-dev \
libtool-bin \
libossp-uuid-dev \
uuid-dev \
libvncserver-dev \
freerdp3-dev \
libssh2-1-dev \
@@ -34,71 +33,61 @@ $STD apt install -y \
libswscale-dev \
libavcodec-dev \
libavutil-dev \
libavformat-dev \
default-jdk
libavformat-dev
msg_ok "Installed Dependencies"
JAVA_VERSION="11" setup_java
setup_mariadb
MARIADB_DB_NAME="guacamole_db" MARIADB_DB_USER="guacamole_user" setup_mariadb_db
msg_info "Setup Apache Tomcat"
RELEASE=$(curl -fsSL https://dlcdn.apache.org/tomcat/tomcat-9/ | grep -oP '(?<=href=")v[^"/]+(?=/")' | sed 's/^v//' | sort -V | tail -n1)
mkdir -p /opt/apache-guacamole/tomcat9
mkdir -p /opt/apache-guacamole/server
curl -fsSL "https://dlcdn.apache.org/tomcat/tomcat-9/v${RELEASE}/bin/apache-tomcat-${RELEASE}.tar.gz" | tar -xz -C /opt/apache-guacamole/tomcat9 --strip-components=1
TOMCAT_VERSION=$(curl -fsSL https://dlcdn.apache.org/tomcat/tomcat-9/ | grep -oP '(?<=href=")v[^"/]+(?=/")' | sed 's/^v//' | sort -V | tail -n1)
mkdir -p /opt/apache-guacamole/{tomcat9,server}
curl -fsSL "https://dlcdn.apache.org/tomcat/tomcat-9/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz" | tar -xz -C /opt/apache-guacamole/tomcat9 --strip-components=1
useradd -r -d /opt/apache-guacamole/tomcat9 -s /bin/false tomcat
chown -R tomcat: /opt/apache-guacamole/tomcat9
chmod -R g+r /opt/apache-guacamole/tomcat9/conf
chmod g+x /opt/apache-guacamole/tomcat9/conf
msg_ok "Setup Apache Tomcat"
echo "${TOMCAT_VERSION}" >~/.guacamole_tomcat
msg_ok "Setup Apache Tomcat ${TOMCAT_VERSION}"
msg_info "Setup Apache Guacamole"
mkdir -p /etc/guacamole/{extensions,lib}
RELEASE_SERVER=$(curl -fsSL https://api.github.com/repos/apache/guacamole-server/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
curl -fsSL "https://api.github.com/repos/apache/guacamole-server/tarball/refs/tags/${RELEASE_SERVER}" | tar -xz --strip-components=1 -C /opt/apache-guacamole/server
GUAC_SERVER_VERSION=$(curl -fsSL https://api.github.com/repos/apache/guacamole-server/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
GUAC_CLIENT_VERSION=$(curl -fsSL https://api.github.com/repos/apache/guacamole-client/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
MYSQL_CONNECTOR_VERSION=$(curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/maven-metadata.xml" | grep -oP '<latest>\K[^<]+')
curl -fsSL "https://api.github.com/repos/apache/guacamole-server/tarball/refs/tags/${GUAC_SERVER_VERSION}" | tar -xz --strip-components=1 -C /opt/apache-guacamole/server
cd /opt/apache-guacamole/server
export CPPFLAGS="-Wno-error=deprecated-declarations"
$STD autoreconf -fi
$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots --disable-guaclog
$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots
$STD make
$STD make install
$STD ldconfig
RELEASE_CLIENT=$(curl -fsSL https://api.github.com/repos/apache/guacamole-client/tags | jq -r '.[].name' | grep -v -- '-RC' | head -n 1)
curl -fsSL "https://downloads.apache.org/guacamole/${RELEASE_CLIENT}/binary/guacamole-${RELEASE_CLIENT}.war" -o "/opt/apache-guacamole/tomcat9/webapps/guacamole.war"
echo "${GUAC_SERVER_VERSION}" >~/.guacamole_server
curl -fsSL "https://downloads.apache.org/guacamole/${GUAC_CLIENT_VERSION}/binary/guacamole-${GUAC_CLIENT_VERSION}.war" -o "/opt/apache-guacamole/tomcat9/webapps/guacamole.war"
echo "${GUAC_CLIENT_VERSION}" >~/.guacamole_client
curl -fsSL "https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/${MYSQL_CONNECTOR_VERSION}/mysql-connector-j-${MYSQL_CONNECTOR_VERSION}.jar" -o "/etc/guacamole/lib/mysql-connector-j.jar"
echo "${MYSQL_CONNECTOR_VERSION}" >~/.guacamole_mysql_connector
cd /root
curl -fsSL "https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-9.3.0.tar.gz" -o "/root/mysql-connector-j-9.3.0.tar.gz"
$STD tar -xf ~/mysql-connector-j-9.3.0.tar.gz
mv ~/mysql-connector-j-9.3.0/mysql-connector-j-9.3.0.jar /etc/guacamole/lib/
curl -fsSL "https://downloads.apache.org/guacamole/${RELEASE_SERVER}/binary/guacamole-auth-jdbc-${RELEASE_SERVER}.tar.gz" -o "/root/guacamole-auth-jdbc-${RELEASE_SERVER}.tar.gz"
$STD tar -xf ~/guacamole-auth-jdbc-"$RELEASE_SERVER".tar.gz
mv ~/guacamole-auth-jdbc-"$RELEASE_SERVER"/mysql/guacamole-auth-jdbc-mysql-"$RELEASE_SERVER".jar /etc/guacamole/extensions/
rm -rf ~/mysql-connector-j-9.3.0{,.tar.gz}
curl -fsSL "https://downloads.apache.org/guacamole/${GUAC_SERVER_VERSION}/binary/guacamole-auth-jdbc-${GUAC_SERVER_VERSION}.tar.gz" -o "/root/guacamole-auth-jdbc-${GUAC_SERVER_VERSION}.tar.gz"
$STD tar -xf ~/guacamole-auth-jdbc-"$GUAC_SERVER_VERSION".tar.gz
mv ~/guacamole-auth-jdbc-"$GUAC_SERVER_VERSION"/mysql/guacamole-auth-jdbc-mysql-"$GUAC_SERVER_VERSION".jar /etc/guacamole/extensions/
echo "${GUAC_SERVER_VERSION}" >~/.guacamole_auth_jdbc
msg_ok "Setup Apache Guacamole"
msg_info "Setup Database"
DB_NAME=guacamole_db
DB_USER=guacamole_user
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "Guacamole-Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/guacamole.creds
cd guacamole-auth-jdbc-"${RELEASE_SERVER}"/mysql/schema
cat *.sql | mariadb -u root ${DB_NAME}
msg_info "Importing Database Schema"
cd ~/guacamole-auth-jdbc-"${GUAC_SERVER_VERSION}"/mysql/schema
cat *.sql | mariadb -u root ${MARIADB_DB_NAME}
{
echo "mysql-hostname: 127.0.0.1"
echo "mysql-port: 3306"
echo "mysql-database: $DB_NAME"
echo "mysql-username: $DB_USER"
echo "mysql-password: $DB_PASS"
echo "mysql-database: $MARIADB_DB_NAME"
echo "mysql-username: $MARIADB_DB_USER"
echo "mysql-password: $MARIADB_DB_PASS"
} >>/etc/guacamole/guacamole.properties
rm -rf ~/guacamole-auth-jdbc-"$RELEASE_SERVER"{,.tar.gz}
msg_ok "Setup Database"
rm -rf ~/guacamole-auth-jdbc-"$GUAC_SERVER_VERSION"{,.tar.gz}
msg_ok "Imported Database Schema"
msg_info "Setup Service"
cat <<EOF >/etc/guacamole/guacd.conf
@@ -143,7 +132,7 @@ PIDFile=/var/run/guacd.pid
[Install]
WantedBy=multi-user.target
EOF
systemctl -q enable --now mysql tomcat guacd
systemctl enable -q --now mysql tomcat guacd
msg_ok "Setup Service"
motd_ssh

View File

@@ -13,19 +13,6 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
lsb-release \
apt-transport-https
msg_ok "Installed Dependencies"
msg_info "Setting up Adoptium Repository"
mkdir -p /etc/apt/keyrings
curl -fsSL "https://packages.adoptium.net/artifactory/api/gpg/key/public" | gpg --dearmor >/etc/apt/trusted.gpg.d/adoptium.gpg
echo "deb https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" >/etc/apt/sources.list.d/adoptium.list
$STD apt-get update
msg_ok "Set up Adoptium Repository"
read -r -p "${TAB3}Which Tomcat version would you like to install? (9, 10.1, 11): " version
case $version in
9)
@@ -33,25 +20,8 @@ case $version in
echo "Which LTS Java version would you like to use? (8, 11, 17, 21): "
read -r jdk_version
case $jdk_version in
8)
msg_info "Installing Temurin JDK 8 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-8-jdk
msg_ok "Setup Temurin JDK 8 (LTS)"
;;
11)
msg_info "Installing Temurin JDK 11 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-11-jdk
msg_ok "Setup Temurin JDK 11 (LTS)"
;;
17)
msg_info "Installing Temurin JDK 17 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -qqy temurin-17-jdk
msg_ok "Setup Temurin JDK 17 (LTS)"
;;
21)
msg_info "Installing Temurin JDK 21 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-21-jdk
msg_ok "Setup Temurin JDK 21 (LTS)"
8 | 11 | 17 | 21)
JAVA_VERSION="$jdk_version" setup_java
;;
*)
msg_error "Invalid JDK version selected. Please enter 8, 11, 17 or 21."
@@ -61,26 +31,14 @@ case $version in
;;
10 | 10.1)
TOMCAT_VERSION="10"
echo "Which LTS Java version would you like to use? (11, 17): "
echo "Which LTS Java version would you like to use? (11, 17, 21): "
read -r jdk_version
case $jdk_version in
11)
msg_info "Installing Temurin JDK 11 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-11-jdk
msg_ok "Setup Temurin JDK 11"
;;
17)
msg_info "Installing Temurin JDK 17 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-17-jdk
msg_ok "Setup Temurin JDK 17"
;;
21)
msg_info "Installing Temurin JDK 21 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-21-jdk
msg_ok "Setup Temurin JDK 21 (LTS)"
11 | 17 | 21)
JAVA_VERSION="$jdk_version" setup_java
;;
*)
msg_error "Invalid JDK version selected. Please enter 11 or 17."
msg_error "Invalid JDK version selected. Please enter 11, 17 or 21."
exit 1
;;
esac
@@ -90,15 +48,8 @@ case $version in
echo "Which LTS Java version would you like to use? (17, 21): "
read -r jdk_version
case $jdk_version in
17)
msg_info "Installing Temurin JDK 17 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -qqy temurin-17-jdk
msg_ok "Setup Temurin JDK 17"
;;
21)
msg_info "Installing Temurin JDK 21 (LTS) for Tomcat $TOMCAT_VERSION"
$STD apt-get install -y temurin-21-jdk
msg_ok "Setup Temurin JDK 21 (LTS)"
17 | 21)
JAVA_VERSION="$jdk_version" setup_java
;;
*)
msg_error "Invalid JDK version selected. Please enter 17 or 21."

View File

@@ -16,6 +16,13 @@ update_os
fetch_and_deploy_gh_release "backrest" "garethgeorge/backrest" "prebuild" "latest" "/opt/backrest/bin" "backrest_Linux_x86_64.tar.gz"
msg_info "Creating Service"
cat <<EOF >/opt/backrest/.env
BACKREST_PORT=9898
BACKREST_CONFIG=/opt/backrest/config/config.json
BACKREST_DATA=/opt/backrest/data
XDG_CACHE_HOME=/opt/backrest/cache
EOF
cat <<EOF >/etc/systemd/system/backrest.service
[Unit]
Description=Backrest
@@ -24,10 +31,7 @@ After=network.target
[Service]
Type=simple
ExecStart=/opt/backrest/bin/backrest
Environment="BACKREST_PORT=9898"
Environment="BACKREST_CONFIG=/opt/backrest/config/config.json"
Environment="BACKREST_DATA=/opt/backrest/data"
Environment="XDG_CACHE_HOME=/opt/backrest/cache"
EnvironmentFile=/opt/backrest/.env
[Install]
WantedBy=multi-user.target

View File

@@ -14,30 +14,15 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y nginx
$STD apt install -y nginx
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "booklore" "booklore-app/BookLore" "tarball"
JAVA_VERSION="21" setup_java
NODE_VERSION="22" setup_nodejs
setup_mariadb
setup_yq
msg_info "Setting up database"
DB_NAME=booklore_db
DB_USER=booklore_user
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';"
$STD mariadb -u root -e "GRANT SELECT ON \`mysql\`.\`time_zone_name\` TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "BookLore Database Credentials"
echo "Database: $DB_NAME"
echo "Username: $DB_USER"
echo "Password: $DB_PASS"
} >>~/booklore.creds
msg_ok "Set up database"
MARIADB_DB_NAME="booklore_db" MARIADB_DB_USER="booklore_user" MARIADB_DB_EXTRA_GRANTS="GRANT SELECT ON \`mysql\`.\`time_zone_name\`" setup_mariadb_db
fetch_and_deploy_gh_release "booklore" "booklore-app/BookLore" "tarball"
msg_info "Building Frontend"
cd /opt/booklore/booklore-ui
@@ -46,22 +31,22 @@ $STD npm run build --configuration=production
msg_ok "Built Frontend"
msg_info "Creating Environment"
mkdir -p /opt/booklore_storage{/data,/books,/bookdrop}
mkdir -p /opt/booklore_storage/{data,books,bookdrop}
cat <<EOF >/opt/booklore_storage/.env
DATABASE_URL=jdbc:mariadb://localhost:3306/$DB_NAME
DATABASE_USERNAME=$DB_USER
DATABASE_PASSWORD=$DB_PASS
BOOKLORE_PORT=6060
# Database Configuration
DATABASE_URL=jdbc:mariadb://localhost:3306/${MARIADB_DB_NAME}
DATABASE_USERNAME=${MARIADB_DB_USER}
DATABASE_PASSWORD=${MARIADB_DB_PASS}
BOOKLORE_DATA_PATH=/opt/booklore_storage/data
BOOKLORE_BOOKS_PATH=/opt/booklore_storage/books
BOOKLORE_BOOKDROP_PATH=/opt/booklore_storage/bookdrop
# App Configuration (Spring Boot mapping from app.* properties)
APP_PATH_CONFIG=/opt/booklore_storage/data
APP_BOOKDROP_FOLDER=/opt/booklore_storage/bookdrop
EOF
msg_ok "Created Environment"
msg_info "Building Backend"
cd /opt/booklore/booklore-api
APP_VERSION=$(curl -fsSL https://api.github.com/repos/booklore-app/BookLore/releases/latest | yq '.tag_name' | sed 's/^v//')
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 --no-daemon
mkdir -p /opt/booklore/dist
@@ -73,22 +58,24 @@ fi
cp "$JAR_PATH" /opt/booklore/dist/app.jar
msg_ok "Built Backend"
msg_info "Configure Nginx"
msg_info "Configuring Nginx"
rm -rf /usr/share/nginx/html
ln -s /opt/booklore/booklore-ui/dist/booklore/browser /usr/share/nginx/html
rm -f /etc/nginx/sites-enabled/default
cp /opt/booklore/nginx.conf /etc/nginx/nginx.conf
sed -i 's/listen \${BOOKLORE_PORT};/listen 6060;/' /etc/nginx/nginx.conf
sed -i 's/listen \[::\]:${BOOKLORE_PORT};/listen [::]:6060;/' /etc/nginx/nginx.conf
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating Systemd Service"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/booklore.service
[Unit]
Description=BookLore Java Service
After=network.target
After=network.target mariadb.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/booklore/dist
ExecStart=/usr/bin/java -jar /opt/booklore/dist/app.jar
@@ -102,7 +89,7 @@ RestartSec=5
WantedBy=multi-user.target
EOF
systemctl enable -q --now booklore
msg_ok "Created BookLore Service"
msg_ok "Created Service"
motd_ssh
customize

View File

@@ -14,29 +14,28 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
$STD apt install -y \
debian-keyring \
debian-archive-keyring \
apt-transport-https
msg_ok "Installed Dependencies"
msg_info "Installing Caddy"
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' >/etc/apt/sources.list.d/caddy-stable.list
$STD apt-get update
$STD apt-get install -y caddy
setup_deb822_repo \
"caddy" \
"https://dl.cloudsmith.io/public/caddy/stable/gpg.key" \
"https://dl.cloudsmith.io/public/caddy/stable/deb/debian" \
"any-version"
$STD apt install -y caddy
msg_ok "Installed Caddy"
read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
setup_go
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
msg_info "Setup xCaddy"
$STD apt-get install -y git
cd /opt
RELEASE=$(curl -fsSL https://api.github.com/repos/caddyserver/xcaddy/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
curl -fsSL "https://github.com/caddyserver/xcaddy/releases/download/${RELEASE}/xcaddy_${RELEASE:1}_linux_amd64.deb" -o "xcaddy_${RELEASE:1}_linux_amd64.deb"
$STD dpkg -i xcaddy_"${RELEASE:1}"_linux_amd64.deb
rm -rf /opt/xcaddy*
$STD apt install -y git
$STD xcaddy build
msg_ok "Setup xCaddy"
fi

View File

@@ -72,7 +72,7 @@ After=network.target
Type=simple
User=root
WorkingDirectory=/opt/ComfyUI
ExecStart=/opt/ComfyUI/venv/bin/python /opt/ComfyUI/main.py --listen --port 8188 --cpu
ExecStart=/opt/ComfyUI/venv/bin/python /opt/ComfyUI/main.py --listen --port 8188
Restart=on-failure
[Install]

View File

@@ -13,32 +13,17 @@ setting_up_container
network_check
update_os
get_latest_release() {
curl -fsSL https://api.github.com/repos/"$1"/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
DOCKER_LATEST_VERSION=$(get_latest_github_release "moby/moby")
PORTAINER_LATEST_VERSION=$(get_latest_github_release "portainer/portainer")
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_github_release "portainer/agent")
DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby")
PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer")
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose")
msg_info "Installing Docker $DOCKER_LATEST_VERSION"
msg_info "Installing Docker $DOCKER_LATEST_VERSION (with Compose, Buildx)"
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p $(dirname $DOCKER_CONFIG_PATH)
echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json
$STD sh <(curl -fsSL https://get.docker.com)
msg_ok "Installed Docker $DOCKER_LATEST_VERSION"
read -r -p "${TAB3}Install Docker Compose v2 plugin? <y/N> " prompt_compose
if [[ ${prompt_compose,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
mkdir -p /usr/local/lib/docker/cli-plugins
curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_LATEST_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/lib/docker/cli-plugins/docker-compose
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
fi
read -r -p "${TAB3}Would you like to add Portainer (UI)? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"

View File

@@ -13,27 +13,15 @@ setting_up_container
network_check
update_os
get_latest_release() {
curl -fsSL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
DOCKER_LATEST_VERSION=$(get_latest_github_release "moby/moby")
DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby")
DOCKER_COMPOSE_LATEST_VERSION=$(get_latest_release "docker/compose")
msg_info "Installing Docker $DOCKER_LATEST_VERSION"
msg_info "Installing Docker $DOCKER_LATEST_VERSION (with Compose, Buildx)"
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p $(dirname $DOCKER_CONFIG_PATH)
echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json
$STD sh <(curl -fsSL https://get.docker.com)
msg_ok "Installed Docker $DOCKER_LATEST_VERSION"
msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -fsSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION"
msg_info "Installing Dockge"
mkdir -p /opt/{dockge,stacks}
curl -fsSL "https://raw.githubusercontent.com/louislam/dockge/master/compose.yaml" -o "/opt/dockge/compose.yaml"

View File

@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: wendyliga
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/DonutWare/Fladder
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "Fladder" "DonutWare/Fladder" "prebuild" "latest" "/opt/fladder" "Fladder-Web-*.zip"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/conf.d/fladder.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /opt/fladder;
index index.html;
location / {
try_files \$uri \$uri/ /index.html;
}
}
EOF
rm -f /etc/nginx/sites-enabled/default
rm -f /etc/nginx/sites-available/default
systemctl enable -q --now nginx
systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc

View File

@@ -13,32 +13,25 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y pip
msg_ok "Installed Dependencies"
msg_info "Installing Homer"
mkdir -p /opt/homer
cd /opt/homer
curl -fsSL "https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip" -o "homer.zip"
$STD unzip homer.zip
rm -rf homer.zip
cp assets/config.yml.dist assets/config.yml
msg_ok "Installed Homer"
fetch_and_deploy_gh_release "homer" "bastienwirtz/homer" "prebuild" "latest" "/opt/homer" "homer.zip"
cp /opt/homer/assets/config.yml.dist /opt/homer/assets/config.yml
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/homer.service
[Unit]
Description=Homer Dashboard
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/homer
ExecStart=python3 -m http.server 8010
[Install]
WantedBy=multi-user.target
EOF
$STD systemctl enable --now homer
systemctl enable -q --now homer
msg_ok "Created Service"
motd_ssh

View File

@@ -13,37 +13,18 @@ setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y apache2
msg_ok "Installed Dependencies"
setup_mariadb
MARIADB_DB_NAME="hortusfox" MARIADB_DB_USER="hortusfox" setup_mariadb_db
PHP_MODULE="exif,mysql" PHP_APACHE="YES" PHP_FPM="NO" PHP_VERSION="8.3" setup_php
setup_composer
msg_info "Setting up database"
DB_NAME=hortusfox
DB_USER=hortusfox
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "HortusFox Database Credentials"
echo "Database: $DB_NAME"
echo "Username: $DB_USER"
echo "Password: $DB_PASS"
} >>~/hortusfox.creds
msg_ok "Set up database"
fetch_and_deploy_gh_release "hortusfox" "danielbrendel/hortusfox-web" "tarball"
msg_info "Configuring .env"
cp /opt/hortusfox/.env.example /opt/hortusfox/.env
sed -i "s|^DB_HOST=.*|DB_HOST=localhost|" /opt/hortusfox/.env
sed -i "s|^DB_USER=.*|DB_USER=$DB_USER|" /opt/hortusfox/.env
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" /opt/hortusfox/.env
sed -i "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" /opt/hortusfox/.env
sed -i "s|^DB_USER=.*|DB_USER=$MARIADB_DB_USER|" /opt/hortusfox/.env
sed -i "s|^DB_PASSWORD=.*|DB_PASSWORD=$MARIADB_DB_PASS|" /opt/hortusfox/.env
sed -i "s|^DB_DATABASE=.*|DB_DATABASE=$MARIADB_DB_NAME|" /opt/hortusfox/.env
sed -i "s|^DB_ENABLE=.*|DB_ENABLE=true|" /opt/hortusfox/.env
sed -i "s|^APP_TIMEZONE=.*|APP_TIMEZONE=Europe/Berlin|" /opt/hortusfox/.env
msg_ok ".env configured"
@@ -58,20 +39,20 @@ $STD php asatru migrate:fresh
msg_ok "Migration finished"
msg_info "Setting up HortusFox"
$STD mariadb -u root -D $DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());"
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());"
$STD php asatru plants:attributes
$STD php asatru calendar:classes
ADMIN_EMAIL="admin@example.com"
ADMIN_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)"
ADMIN_HASH=$(php -r "echo password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);")
$STD mariadb -u root -D $DB_NAME -e "INSERT IGNORE INTO UserModel (name, email, password, admin) VALUES ('Admin', '$ADMIN_EMAIL', '$ADMIN_HASH', 1);"
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO UserModel (name, email, password, admin) VALUES ('Admin', '$ADMIN_EMAIL', '$ADMIN_HASH', 1);"
{
echo ""
echo "HortusFox-Admin-Creds:"
echo "E-Mail: $ADMIN_EMAIL"
echo "Passwort: $ADMIN_PASS"
} >>~/hortusfox.creds
$STD mariadb -u root -D $DB_NAME -e "INSERT IGNORE INTO LocationsModel (name, active, created_at) VALUES ('Home', 1, NOW());"
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO LocationsModel (name, active, created_at) VALUES ('Home', 1, NOW());"
msg_ok "Set up HortusFox"
msg_info "Configuring Apache vHost"

View File

@@ -29,7 +29,6 @@ $STD apt install --no-install-recommends -y \
libltdl-dev \
libgdk-pixbuf-2.0-dev \
libbrotli-dev \
libde265-dev \
libexif-dev \
libexpat1-dev \
libglib2.0-dev \
@@ -99,20 +98,21 @@ if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
$STD apt install -y --no-install-recommends patchelf
tmp_dir=$(mktemp -d)
$STD pushd "$tmp_dir"
curl -fsSLZ -O "https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-core_1.0.17537.24_amd64.deb" \
-O "https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-opencl_1.0.17537.24_amd64.deb" \
-O "https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-opencl-icd-legacy1_24.35.30872.36_amd64.deb" \
-O "https://github.com/intel/intel-graphics-compiler/releases/download/v2.22.2/intel-igc-core-2_2.22.2+20121_amd64.deb" \
-O "https://github.com/intel/intel-graphics-compiler/releases/download/v2.22.2/intel-igc-opencl-2_2.22.2+20121_amd64.deb" \
-O "https://github.com/intel/compute-runtime/releases/download/25.44.36015.5/intel-opencl-icd_25.44.36015.5-0_amd64.deb" \
-O "https://github.com/intel/compute-runtime/releases/download/25.44.36015.5/libigdgmm12_22.8.2_amd64.deb"
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
)
for url in "${INTEL_URLS[@]}"; do
curl -fsSLO "$url"
done
$STD apt install -y ./libigdgmm12*.deb
rm ./libigdgmm12*.deb
$STD apt install -y ./*.deb
$STD apt-mark hold libigdgmm12
$STD popd
rm -rf "$tmp_dir"
dpkg -l | grep "intel-opencl-icd" | awk '{print $3}' >~/.intel_version
dpkg -l | grep -m1 "intel-opencl-icd" | awk '{print $3}' >~/.intel_version
msg_ok "Installed OpenVINO dependencies"
fi
@@ -129,9 +129,9 @@ Pin-Priority: 450
EOF
$STD apt update
msg_ok "Configured Debian Testing repo"
msg_info "Installing libmimalloc3"
$STD apt install -t testing --no-install-recommends -yqq libmimalloc3
msg_ok "Installed libmimalloc3"
msg_info "Installing packages from Debian Testing repo"
$STD apt install -t testing --no-install-recommends -yqq libmimalloc3 libde265-dev
msg_ok "Installed packages from Debian Testing repo"
PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/package.json" | jq -r '.packageManager | split("@")[1]')"
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs

View File

@@ -16,11 +16,12 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
apt-transport-https \
ca-certificates \
redis
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_DB_NAME="infisical_db" PG_DB_USER="infisical" setup_postgresql_db
import_local_ip
msg_info "Setting up Infisical Repository"
setup_deb822_repo \
@@ -30,34 +31,16 @@ setup_deb822_repo \
"stable"
msg_ok "Setup Infisical repository"
msg_info "Configuring PostgreSQL"
DB_NAME="infisical_db"
DB_USER="infisical"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
echo "Infiscal Credentials"
echo "Database Name: $DB_NAME"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
} >>~/infisical.creds
msg_ok "Configured PostgreSQL"
msg_info "Setting up Infisical"
AUTH_SECRET="$(openssl rand -base64 32 | tr -d '\n')"
ENC_KEY="$(openssl rand -hex 16 | tr -d '\n')"
IP_ADDR=$(hostname -I | awk '{print $1}')
$STD apt install -y infisical-core
mkdir -p /etc/infisical
cat <<EOF >/etc/infisical/infisical.rb
infisical_core['ENCRYPTION_KEY'] = '$ENC_KEY'
infisical_core['AUTH_SECRET'] = '$AUTH_SECRET'
infisical_core['HOST'] = '$IP_ADDR'
infisical_core['DB_CONNECTION_URI'] = 'postgres://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}'
infisical_core['HOST'] = '$LOCAL_IP'
infisical_core['DB_CONNECTION_URI'] = 'postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}'
infisical_core['REDIS_URL'] = 'redis://localhost:6379'
EOF
$STD infisical-ctl reconfigure

View File

@@ -21,23 +21,29 @@ setup_deb822_repo \
"stable"
msg_ok "Set up InfluxDB Repository"
read -r -p "${TAB3}Which version of InfluxDB to install? (1 or 2) " prompt
if [[ $prompt == "2" ]]; then
read -r -p "${TAB3}Which version of InfluxDB to install? (1, 2 or 3) " prompt
if [[ $prompt == "3" ]]; then
INFLUX="3"
elif [[ $prompt == "2" ]]; then
INFLUX="2"
else
INFLUX="1"
fi
msg_info "Installing InfluxDB"
if [[ $INFLUX == "2" ]]; then
msg_info "Installing InfluxDB v${INFLUX}"
if [[ $INFLUX == "3" ]]; then
$STD apt install -y influxdb3-core
systemctl enable -q --now influxdb3-core
elif [[ $INFLUX == "2" ]]; then
$STD apt install -y influxdb2
systemctl enable -q --now influxdb
else
$STD apt install -y influxdb
download_file "https://dl.influxdata.com/chronograf/releases/chronograf_1.10.8_amd64.deb" "${HOME}/chronograf_1.10.8_amd64.deb"
$STD dpkg -i "${HOME}/chronograf_1.10.8_amd64.deb"
rm -rf "${HOME}/chronograf_1.10.8_amd64.deb"
systemctl enable -q --now influxdb
fi
systemctl enable -q --now influxdb
msg_ok "Installed InfluxDB"
read -r -p "${TAB3}Would you like to add Telegraf? <y/N> " prompt

View File

@@ -0,0 +1,182 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Benito Rodríguez (b3ni)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/investbrainapp/investbrain
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
nginx \
supervisor \
redis-server \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
zlib1g-dev \
libzip-dev \
libicu-dev \
libpq-dev
msg_ok "Installed Dependencies"
export PHP_VERSION="8.4"
PHP_FPM=YES PHP_MODULE="gd,zip,intl,pdo,pgsql,pdo-pgsql,bcmath,opcache,mbstring,redis" setup_php
setup_composer
NODE_VERSION="22" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="investbrain" PG_DB_USER="investbrain" setup_postgresql_db
import_local_ip
fetch_and_deploy_gh_release "Investbrain" "investbrainapp/investbrain" "tarball" "latest" "/opt/investbrain"
msg_info "Installing Investbrain"
APP_KEY=$(openssl rand -base64 32)
cd /opt/investbrain
cat <<EOF >/opt/investbrain/.env
APP_KEY=base64:${APP_KEY}
APP_PORT=8000
APP_URL=http://${LOCAL_IP}:8000
ASSET_URL=http://${LOCAL_IP}:8000
LOG_CHANNEL=daily
LOG_LEVEL=warning
REGISTRATION_ENABLED=true
AI_CHAT_ENABLED=false
OPENAI_API_KEY=
OPENAI_ORGANIZATION=
MARKET_DATA_PROVIDER=yahoo
ALPHAVANTAGE_API_KEY=
FINNHUB_API_KEY=
ALPACA_API_KEY=
ALPACA_API_SECRET=
TWELVEDATA_API_SECRET=
MARKET_DATA_REFRESH=30
DAILY_CHANGE_TIME=
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=${PG_DB_NAME}
DB_USERNAME=${PG_DB_USER}
DB_PASSWORD=${PG_DB_PASS}
REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
CACHE_STORE=redis
CACHE_PREFIX=
SESSION_DRIVER=redis
SESSION_LIFETIME=120
QUEUE_CONNECTION=redis
MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_FROM_ADDRESS="investbrain@${LOCAL_IP}"
VITE_APP_NAME=Investbrain
EOF
export COMPOSER_ALLOW_SUPERUSER=1
$STD /usr/local/bin/composer install --no-interaction --no-dev --optimize-autoloader
$STD npm install
$STD npm run build
mkdir -p /opt/investbrain/storage/{framework/cache,framework/sessions,framework/views,app,logs}
$STD php artisan migrate --force
$STD php artisan storage:link
$STD php artisan cache:clear
$STD php artisan view:clear
$STD php artisan route:clear
$STD php artisan event:clear
$STD php artisan route:cache
$STD php artisan event:cache
chown -R www-data:www-data /opt/investbrain
chmod -R 775 /opt/investbrain/bootstrap/cache
msg_ok "Installed Investbrain"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/investbrain.conf
server {
listen 8000 default_server;
listen [::]:8000 default_server;
server_name _;
root /opt/investbrain/public;
index index.php;
client_max_body_size 50M;
charset utf-8;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location ~ \.php\$ {
fastcgi_pass unix:/var/run/php/php${PHP_VERSION}-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 300;
}
location ~ /\.(?!well-known).* {
deny all;
}
error_log /var/log/nginx/investbrain_error.log;
access_log /var/log/nginx/investbrain_access.log;
}
EOF
ln -sf /etc/nginx/sites-available/investbrain.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
$STD systemctl reload nginx
msg_ok "Configured Nginx"
msg_info "Setting up Supervisor"
cat <<EOF >/etc/supervisor/conf.d/investbrain.conf
[program:investbrain-queue]
process_name=%%(program_name)s_%%(process_num)02d
command=php /opt/investbrain/artisan queue:work --sleep=3 --tries=1 --memory=256 --timeout=3600
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/opt/investbrain/storage/logs/queue.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
numprocs=1
EOF
$STD supervisorctl reread
$STD supervisorctl update
$STD supervisorctl start all
msg_ok "Setup Supervisor"
msg_info "Setting up Cron for Scheduler"
cat <<EOF >/etc/cron.d/investbrain-scheduler
* * * * * www-data php /opt/investbrain/artisan schedule:run >> /dev/null 2>&1
EOF
chmod 644 /etc/cron.d/investbrain-scheduler
$STD systemctl restart cron
msg_ok "Setup Cron for Scheduler"
motd_ssh
customize
cleanup_lxc

View File

@@ -106,6 +106,7 @@ $STD php artisan migrate --force
$STD php artisan db:seed --force
$STD php artisan ninja:post-update
$STD php artisan optimize
chown -R www-data:www-data /opt/invoiceninja
msg_ok "Set up Database"
msg_info "Configuring Nginx"

View File

@@ -13,11 +13,14 @@ network_check
update_os
JAVA_VERSION="21" setup_java
setup_deb822_repo \
"jenkins" \
"https://pkg.jenkins.io/debian/jenkins.io-2026.key" \
"https://pkg.jenkins.io/debian" \
"binary/" \
" "
msg_info "Setup Jenkins"
curl -fsSL "https://pkg.jenkins.io/debian/jenkins.io-2023.key" -o "/usr/share/keyrings/jenkins-keyring.asc"
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" https://pkg.jenkins.io/debian binary/ >/etc/apt/sources.list.d/jenkins.list
$STD apt update
$STD apt install -y jenkins
msg_ok "Setup Jenkins"

View File

@@ -20,6 +20,7 @@ $STD apt install -y \
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_DB_NAME="joplin" PG_DB_USER="joplin" setup_postgresql_db
NODE_VERSION=24 NODE_MODULE="yarn,npm,pm2" setup_nodejs
mkdir -p /opt/pm2
export PM2_HOME=/opt/pm2
@@ -27,28 +28,10 @@ $STD pm2 install pm2-logrotate
$STD pm2 set pm2-logrotate:max_size 100MB
$STD pm2 set pm2-logrotate:retain 5
$STD pm2 set pm2-logrotate:compress tr
msg_info "Setting up PostgreSQL Database"
DB_NAME=joplin
DB_USER=joplin
DB_PASS="$(openssl rand -base64 18 | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC'"
{
echo "Joplin-Credentials"
echo "Joplin Database User: $DB_USER"
echo "Joplin Database Password: $DB_PASS"
echo "Joplin Database Name: $DB_NAME"
} >>~/joplin.creds
msg_ok "Set up PostgreSQL Database"
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball" "latest"
fetch_and_deploy_gh_release "joplin-server" "laurent22/joplin" "tarball"
import_local_ip
msg_info "Setting up Joplin Server (Patience)"
LOCAL_IP=$(hostname -I | awk '{print $1}')
cd /opt/joplin-server
sed -i "/onenote-converter/d" packages/lib/package.json
$STD yarn config set --home enableTelemetry 0
@@ -61,9 +44,9 @@ NODE_ENV=production
APP_BASE_URL=http://$LOCAL_IP:22300
APP_PORT=22300
DB_CLIENT=pg
POSTGRES_PASSWORD=$DB_PASS
POSTGRES_DATABASE=$DB_NAME
POSTGRES_USER=$DB_USER
POSTGRES_PASSWORD=$PG_DB_PASS
POSTGRES_DATABASE=$PG_DB_NAME
POSTGRES_USER=$PG_DB_USER
POSTGRES_PORT=5432
POSTGRES_HOST=localhost
EOF

75
install/kutt-install.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: tomfrenzel
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/thedevs-network/kutt
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
echo "${TAB3}How would you like to handle SSL termination?"
echo "${TAB3}[i]-Internal (self-signed SSL Certificate) [e]-External (use your own reverse proxy)"
read -rp "${TAB3}Enter your choice <i/e> (default: i): " ssl_choice
ssl_choice=${ssl_choice:-i}
case "${ssl_choice,,}" in
i)
import_local_ip
DEFAULT_HOST="$LOCAL_IP"
msg_info "Configuring Caddy"
$STD apt install -y caddy
cat <<EOF >/etc/caddy/Caddyfile
$LOCAL_IP {
reverse_proxy localhost:3000
}
EOF
systemctl restart caddy
msg_ok "Configured Caddy"
;;
e)
read -r -p "${TAB3}Enter the hostname you want to use for Kutt (eg. kutt.example.com): " custom_host
if [[ "$custom_host" ]]; then
DEFAULT_HOST="$custom_host"
fi
;;
esac
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "kutt" "thedevs-network/kutt" "tarball"
msg_info "Configuring Kutt"
cd /opt/kutt
cp .example.env ".env"
sed -i "s|JWT_SECRET=|JWT_SECRET=$(openssl rand -base64 32)|g" ".env"
sed -i "s|DEFAULT_DOMAIN=.*|DEFAULT_DOMAIN=$DEFAULT_HOST|g" ".env"
$STD npm install
$STD npm run migrate
msg_ok "Configured Kutt"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/kutt.service
[Unit]
Description=Kutt server
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/kutt
ExecStart=/usr/bin/npm start
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now kutt
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc

View File

@@ -15,22 +15,7 @@ update_os
PHP_VERSION="8.4" PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
setup_mariadb
msg_info "Setting up Database"
DB_NAME=leantime
DB_USER=leantime
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "Leantime Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/leantime.creds
msg_ok "Set up Database"
MARIADB_DB_NAME="leantime" MARIADB_DB_USER="leantime" setup_mariadb_db
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
msg_info "Setup Leantime"
@@ -58,9 +43,9 @@ cat <<EOF >/etc/apache2/sites-enabled/000-default.conf
</VirtualHost>
EOF
mv "/opt/leantime/config/sample.env" "/opt/leantime/config/.env"
sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
-e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \
-e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \
sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$MARIADB_DB_NAME'|" \
-e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$MARIADB_DB_USER'|" \
-e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$MARIADB_DB_PASS'|" \
-e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \
"/opt/leantime/config/.env"
$STD a2enmod -q proxy_fcgi setenvif rewrite

View File

@@ -54,12 +54,11 @@ msg_ok "Installed Openresty"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
# RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
# grep "tag_name" |
# awk '{print substr($2, 3, length($2)-4) }')
RELEASE="2.13.5"
RELEASE=$(curl -fsSL https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "v2.13.5"
fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "v${RELEASE}"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python

View File

@@ -16,7 +16,8 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
pkg-config
pkg-config \
zstd
msg_ok "Installed Dependencies"
msg_info "Setting up Intel® Repositories"
@@ -67,11 +68,11 @@ RELEASE=$(curl -fsSL https://api.github.com/repos/ollama/ollama/releases/latest
OLLAMA_INSTALL_DIR="/usr/local/lib/ollama"
BINDIR="/usr/local/bin"
mkdir -p $OLLAMA_INSTALL_DIR
OLLAMA_URL="https://github.com/ollama/ollama/releases/download/${RELEASE}/ollama-linux-amd64.tgz"
TMP_TAR="/tmp/ollama.tgz"
OLLAMA_URL="https://github.com/ollama/ollama/releases/download/${RELEASE}/ollama-linux-amd64.tar.zst"
TMP_TAR="/tmp/ollama.tar.zst"
echo -e "\n"
if curl -fL# -C - -o "$TMP_TAR" "$OLLAMA_URL"; then
if tar -xzf "$TMP_TAR" -C "$OLLAMA_INSTALL_DIR"; then
if tar --zstd -xf "$TMP_TAR" -C "$OLLAMA_INSTALL_DIR"; then
ln -sf "$OLLAMA_INSTALL_DIR/bin/ollama" "$BINDIR/ollama"
echo "${RELEASE}" >/opt/Ollama_version.txt
msg_ok "Installed Ollama ${RELEASE}"

View File

@@ -14,7 +14,9 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y ffmpeg
$STD apt install -y \
ffmpeg \
zstd
msg_ok "Installed Dependencies"
setup_hwaccel
@@ -69,9 +71,10 @@ EOF
msg_ok "Installed Intel® oneAPI Base Toolkit"
msg_info "Installing Ollama"
curl -fsSLO -C - https://ollama.com/download/ollama-linux-amd64.tgz
tar -C /usr -xzf ollama-linux-amd64.tgz
rm -rf ollama-linux-amd64.tgz
OLLAMA_RELEASE=$(curl -fsSL https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk -F '"' '{print $4}')
curl -fsSLO -C - https://github.com/ollama/ollama/releases/download/${OLLAMA_RELEASE}/ollama-linux-amd64.tar.zst
tar --zstd -C /usr -xf ollama-linux-amd64.tar.zst
rm -rf ollama-linux-amd64.tar.zst
cat <<EOF >/etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service

View File

@@ -52,7 +52,8 @@ msg_ok "Installed Zammad"
msg_info "Setup Services"
cp /opt/zammad/contrib/nginx/zammad.conf /etc/nginx/sites-available/zammad.conf
sed -i "s/server_name localhost;/server_name $LOCAL_IP;/g" /etc/nginx/sites-available/zammad.conf
unlink /etc/nginx/sites-available/default
ln -s /etc/nginx/sites-available/zammad.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
$STD systemctl reload nginx
msg_ok "Created Service"

View File

@@ -231,6 +231,100 @@ install_ssh_keys_into_ct() {
return 0
}
# ------------------------------------------------------------------------------
# validate_container_id()
#
# - Validates if a container ID is available for use
# - Checks if ID is already used by VM or LXC container
# - Checks if ID is used in LVM logical volumes
# - Returns 0 if ID is available, 1 if already in use
# ------------------------------------------------------------------------------
validate_container_id() {
local ctid="$1"
# Check if ID is numeric
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
return 1
fi
# Check if config file exists for VM or LXC
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# get_valid_container_id()
#
# - Returns a valid, unused container ID
# - If provided ID is valid, returns it
# - Otherwise increments from suggested ID until a free one is found
# - Calls validate_container_id() to check availability
# ------------------------------------------------------------------------------
get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
done
echo "$suggested_id"
}
# ------------------------------------------------------------------------------
# validate_container_id()
#
# - Validates if a container ID is available for use
# - Checks if ID is already used by VM or LXC container
# - Checks if ID is used in LVM logical volumes
# - Returns 0 if ID is available, 1 if already in use
# ------------------------------------------------------------------------------
validate_container_id() {
local ctid="$1"
# Check if ID is numeric
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
return 1
fi
# Check if config file exists for VM or LXC
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# get_valid_container_id()
#
# - Returns a valid, unused container ID
# - If provided ID is valid, returns it
# - Otherwise increments from suggested ID until a free one is found
# - Calls validate_container_id() to check availability
# ------------------------------------------------------------------------------
get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
done
echo "$suggested_id"
}
# ------------------------------------------------------------------------------
# find_host_ssh_keys()
#
@@ -417,6 +511,12 @@ choose_and_set_storage_for_file() {
if [[ "$count" -eq 1 ]]; then
STORAGE_RESULT=$(pvesm status -content "$content" | awk 'NR>1{print $1; exit}')
STORAGE_INFO=""
# Validate storage space for auto-picked container storage
if [[ "$class" == "container" && -n "${DISK_SIZE:-}" ]]; then
validate_storage_space "$STORAGE_RESULT" "$DISK_SIZE" "yes"
# Continue even if validation fails - user was warned
fi
else
# If the current value is preselectable, we could show it, but per your requirement we always offer selection
select_storage "$class" || return 1
@@ -483,7 +583,18 @@ base_settings() {
RAM_SIZE="${final_ram}"
VERBOSE=${var_verbose:-"${1:-no}"}
PW=${var_pw:-""}
CT_ID=${var_ctid:-$NEXTID}
# Validate and set Container ID
local requested_id="${var_ctid:-$NEXTID}"
if ! validate_container_id "$requested_id"; then
# Only show warning if user manually specified an ID (not auto-assigned)
if [[ -n "${var_ctid:-}" ]]; then
msg_warn "Container ID $requested_id is already in use. Using next available ID: $(get_valid_container_id "$requested_id")"
fi
requested_id=$(get_valid_container_id "$requested_id")
fi
CT_ID="$requested_id"
HN=${var_hostname:-$NSAPP}
BRG=${var_brg:-"vmbr0"}
NET=${var_net:-"dhcp"}
@@ -1098,6 +1209,13 @@ ensure_storage_selection_for_vars_file() {
if [[ -n "$tpl" && -n "$ct" ]]; then
TEMPLATE_STORAGE="$tpl"
CONTAINER_STORAGE="$ct"
# Validate storage space for loaded container storage
if [[ -n "${DISK_SIZE:-}" ]]; then
validate_storage_space "$ct" "$DISK_SIZE" "yes"
# Continue even if validation fails - user was warned
fi
return 0
fi
@@ -1308,7 +1426,25 @@ advanced_settings() {
--ok-button "Next" --cancel-button "Back" \
--inputbox "\nSet Container ID" 10 58 "$_ct_id" \
3>&1 1>&2 2>&3); then
_ct_id="${result:-$NEXTID}"
local input_id="${result:-$NEXTID}"
# Validate that ID is numeric
if ! [[ "$input_id" =~ ^[0-9]+$ ]]; then
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Invalid ID" --msgbox "Container ID must be numeric." 8 58
continue
fi
# Check if ID is already in use
if ! validate_container_id "$input_id"; then
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "ID Already In Use" \
--yesno "Container/VM ID $input_id is already in use.\n\nWould you like to use the next available ID ($(get_valid_container_id "$input_id"))?" 10 58; then
_ct_id=$(get_valid_container_id "$input_id")
else
continue
fi
else
_ct_id="$input_id"
fi
((STEP++))
else
((STEP--))
@@ -2292,7 +2428,6 @@ install_script() {
2 | advanced | ADVANCED)
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Install on node $PVEHOST_NAME${CL}"
echo -e "${INFO}${BOLD}${DGN}PVE Version ${PVEVERSION} (Kernel: ${KERNEL_VERSION})${CL}"
METHOD="advanced"
base_settings
advanced_settings
@@ -2853,6 +2988,21 @@ $PCT_OPTIONS_STRING"
export TEMPLATE_STORAGE="${var_template_storage:-}"
export CONTAINER_STORAGE="${var_container_storage:-}"
# Validate storage space only if CONTAINER_STORAGE is already set
# (Storage selection happens in create_lxc_container for some modes)
if [[ -n "$CONTAINER_STORAGE" ]]; then
msg_info "Validating storage space"
if ! validate_storage_space "$CONTAINER_STORAGE" "$DISK_SIZE" "no"; then
local free_space
free_space=$(pvesm status 2>/dev/null | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }')
local free_fmt
free_fmt=$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$free_space" 2>/dev/null || echo "${free_space}KB")
msg_error "Not enough space on '$CONTAINER_STORAGE'. Required: ${DISK_SIZE}GB, Available: ${free_fmt}"
exit 214
fi
msg_ok "Storage space validated"
fi
create_lxc_container || exit $?
LXC_CONFIG="/etc/pve/lxc/${CTID}.conf"
@@ -3384,9 +3534,9 @@ resolve_storage_preselect() {
free="$(awk '{print $6}' <<<"$line")"
local total_h used_h free_h
if command -v numfmt >/dev/null 2>&1; then
total_h="$(numfmt --to=iec --suffix=B --format %.1f "$total" 2>/dev/null || echo "$total")"
used_h="$(numfmt --to=iec --suffix=B --format %.1f "$used" 2>/dev/null || echo "$used")"
free_h="$(numfmt --to=iec --suffix=B --format %.1f "$free" 2>/dev/null || echo "$free")"
total_h="$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$total" 2>/dev/null || echo "$total")"
used_h="$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$used" 2>/dev/null || echo "$used")"
free_h="$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$free" 2>/dev/null || echo "$free")"
STORAGE_INFO="Free: ${free_h} Used: ${used_h}"
else
STORAGE_INFO="Free: ${free} Used: ${used}"
@@ -3502,8 +3652,8 @@ select_storage() {
while read -r TAG TYPE _ TOTAL USED FREE _; do
[[ -n "$TAG" && -n "$TYPE" ]] || continue
local DISPLAY="${TAG} (${TYPE})"
local USED_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$USED")
local FREE_FMT=$(numfmt --to=iec --from-unit=K --format %.1f <<<"$FREE")
local USED_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$USED")
local FREE_FMT=$(numfmt --to=iec --from-unit=1024 --format %.1f <<<"$FREE")
local INFO="Free: ${FREE_FMT}B Used: ${USED_FMT}B"
STORAGE_MAP["$DISPLAY"]="$TAG"
MENU+=("$DISPLAY" "$INFO" "OFF")
@@ -3541,10 +3691,87 @@ select_storage() {
break
fi
done
# Validate storage space for container storage
if [[ "$CLASS" == "container" && -n "${DISK_SIZE:-}" ]]; then
validate_storage_space "$STORAGE_RESULT" "$DISK_SIZE" "yes"
# Continue even if validation fails - user was warned
fi
return 0
done
}
# ------------------------------------------------------------------------------
# validate_storage_space()
#
# - Validates if storage has enough free space for container
# - Takes storage name and required size in GB
# - Returns 0 if enough space, 1 if not enough, 2 if storage unavailable
# - Can optionally show whiptail warning
# - Handles all storage types: dir, lvm, lvmthin, zfs, nfs, cifs, etc.
# ------------------------------------------------------------------------------
validate_storage_space() {
local storage="$1"
local required_gb="${2:-8}"
local show_dialog="${3:-no}"
# Get full storage line from pvesm status
local storage_line
storage_line=$(pvesm status 2>/dev/null | awk -v s="$storage" '$1 == s {print $0}')
# Check if storage exists and is active
if [[ -z "$storage_line" ]]; then
[[ "$show_dialog" == "yes" ]] && whiptail --msgbox "⚠️ Warning: Storage '$storage' not found!\n\nThe storage may be unavailable or disabled." 10 60
return 2
fi
# Check storage status (column 3)
local status
status=$(awk '{print $3}' <<<"$storage_line")
if [[ "$status" == "disabled" ]]; then
[[ "$show_dialog" == "yes" ]] && whiptail --msgbox "⚠️ Warning: Storage '$storage' is disabled!\n\nPlease enable the storage first." 10 60
return 2
fi
# Get storage type and free space (column 6)
local storage_type storage_free
storage_type=$(awk '{print $2}' <<<"$storage_line")
storage_free=$(awk '{print $6}' <<<"$storage_line")
# Some storage types (like PBS, iSCSI) don't report size info
# In these cases, skip space validation
if [[ -z "$storage_free" || "$storage_free" == "0" ]]; then
# Silent pass for storages without size info
return 0
fi
local required_kb=$((required_gb * 1024 * 1024))
local free_gb_fmt
free_gb_fmt=$(numfmt --to=iec --from-unit=1024 --suffix=B --format %.1f "$storage_free" 2>/dev/null || echo "${storage_free}KB")
if [[ "$storage_free" -lt "$required_kb" ]]; then
if [[ "$show_dialog" == "yes" ]]; then
whiptail --msgbox "⚠️ Warning: Storage '$storage' may not have enough space!\n\nStorage Type: ${storage_type}\nRequired: ${required_gb}GB\nAvailable: ${free_gb_fmt}\n\nYou can continue, but creation might fail." 14 70
fi
return 1
fi
return 0
}
# ==============================================================================
# SECTION 8: CONTAINER CREATION
# ==============================================================================
# ------------------------------------------------------------------------------
# create_lxc_container()
#
# - Main function for creating LXC containers
# - Handles all phases: validation, template discovery, container creation,
# network config, storage, etc.
# - Extensive error checking with detailed exit codes
# ------------------------------------------------------------------------------
create_lxc_container() {
# ------------------------------------------------------------------------------
# Optional verbose mode (debug tracing)
@@ -3716,14 +3943,6 @@ create_lxc_container() {
fi
msg_ok "Template storage '$TEMPLATE_STORAGE' validated"
# Free space check
STORAGE_FREE=$(pvesm status | awk -v s="$CONTAINER_STORAGE" '$1 == s { print $6 }')
REQUIRED_KB=$((${PCT_DISK_SIZE:-8} * 1024 * 1024))
[[ "$STORAGE_FREE" -ge "$REQUIRED_KB" ]] || {
msg_error "Not enough space on '$CONTAINER_STORAGE'. Needed: ${PCT_DISK_SIZE:-8}G."
exit 214
}
# Cluster quorum (if cluster)
if [[ -f /etc/pve/corosync.conf ]]; then
msg_info "Checking cluster quorum"

View File

@@ -184,7 +184,10 @@ install_packages_with_retry() {
local retry=0
while [[ $retry -le $max_retries ]]; do
if $STD apt install -y "${packages[@]}" 2>/dev/null; then
if DEBIAN_FRONTEND=noninteractive $STD apt install -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
"${packages[@]}" 2>/dev/null; then
return 0
fi
@@ -211,7 +214,10 @@ upgrade_packages_with_retry() {
local retry=0
while [[ $retry -le $max_retries ]]; do
if $STD apt install --only-upgrade -y "${packages[@]}" 2>/dev/null; then
if DEBIAN_FRONTEND=noninteractive $STD apt install --only-upgrade -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
"${packages[@]}" 2>/dev/null; then
return 0
fi
@@ -2920,8 +2926,15 @@ _setup_intel_legacy() {
vainfo \
intel-gpu-tools 2>/dev/null || msg_warn "Some Intel legacy packages failed"
# beignet provides OpenCL for older Intel GPUs (if available)
$STD apt -y install beignet-opencl-icd 2>/dev/null || true
# beignet provides OpenCL for older Intel GPUs (Sandy Bridge to Broadwell)
# Note: beignet-opencl-icd was removed in Debian 12+ and Ubuntu 22.04+
# Check if package is available before attempting installation
if apt-cache show beignet-opencl-icd &>/dev/null; then
$STD apt -y install beignet-opencl-icd 2>/dev/null || msg_warn "beignet-opencl-icd installation failed (optional)"
else
msg_warn "beignet-opencl-icd not available - OpenCL support for legacy Intel GPU limited"
msg_warn "Note: Hardware video encoding/decoding (VA-API) still works without OpenCL"
fi
msg_ok "Intel Legacy GPU configured"
}
@@ -2989,16 +3002,24 @@ _setup_nvidia_gpu() {
msg_info "Installing NVIDIA GPU drivers"
# Prevent interactive dialogs (e.g., "Mismatching nvidia kernel module" whiptail)
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
# Detect host driver version (passed through via /proc)
# Format varies by driver type:
# Proprietary: "NVRM version: NVIDIA UNIX x86_64 Kernel Module 550.54.14 Thu..."
# Open: "NVRM version: NVIDIA UNIX Open Kernel Module for x86_64 590.48.01 Release..."
# Use regex to extract version number (###.##.## pattern)
local nvidia_host_version=""
if [[ -f /proc/driver/nvidia/version ]]; then
nvidia_host_version=$(grep "NVRM version:" /proc/driver/nvidia/version 2>/dev/null | awk '{print $8}')
nvidia_host_version=$(grep -oP '\d{3,}\.\d+\.\d+' /proc/driver/nvidia/version 2>/dev/null | head -1)
fi
if [[ -z "$nvidia_host_version" ]]; then
msg_warn "NVIDIA host driver version not found in /proc/driver/nvidia/version"
msg_warn "Ensure NVIDIA drivers are installed on host and GPU passthrough is enabled"
$STD apt -y install va-driver-all vainfo 2>/dev/null || true
$STD apt-get -y install va-driver-all vainfo 2>/dev/null || true
return 0
fi
@@ -3011,53 +3032,74 @@ _setup_nvidia_gpu() {
sed -i -E 's/Components: (.*)$/Components: \1 contrib non-free non-free-firmware/g' /etc/apt/sources.list.d/debian.sources 2>/dev/null || true
fi
fi
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
# Determine CUDA repository
local cuda_repo="debian12"
case "$os_codename" in
bullseye) cuda_repo="debian11" ;;
bookworm) cuda_repo="debian12" ;;
trixie | sid) cuda_repo="debian12" ;; # Forward compatible
esac
# For Debian 13 Trixie/Sid: Use Debian's own nvidia packages first (better compatibility)
# NVIDIA's CUDA repo targets Debian 12 and may not have amd64 packages for Trixie
if [[ "$os_codename" == "trixie" || "$os_codename" == "sid" ]]; then
msg_info "Debian ${os_codename}: Using Debian's NVIDIA packages"
# Add NVIDIA CUDA repository
if [[ ! -f /usr/share/keyrings/cuda-archive-keyring.gpg ]]; then
msg_info "Adding NVIDIA CUDA repository (${cuda_repo})"
local cuda_keyring
cuda_keyring="$(mktemp)"
if curl -fsSL -o "$cuda_keyring" "https://developer.download.nvidia.com/compute/cuda/repos/${cuda_repo}/x86_64/cuda-keyring_1.1-1_all.deb" 2>/dev/null; then
$STD dpkg -i "$cuda_keyring" 2>/dev/null || true
# Try version-matched from Debian repos first
local nvidia_pkgs="libcuda1=${nvidia_host_version}* libnvcuvid1=${nvidia_host_version}* libnvidia-encode1=${nvidia_host_version}* libnvidia-ml1=${nvidia_host_version}*"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries from Debian"
else
msg_warn "Failed to download NVIDIA CUDA keyring"
# Fallback to unversioned (whatever Debian provides)
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null; then
msg_ok "Installed NVIDIA libraries from Debian (version may differ from host)"
else
msg_warn "NVIDIA library installation failed - GPU compute may not work"
fi
fi
rm -f "$cuda_keyring"
fi
$STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends nvidia-smi 2>/dev/null || true
# Pin NVIDIA repo for version matching
cat <<'NVIDIA_PIN' >/etc/apt/preferences.d/nvidia-cuda-pin
else
# Debian 11/12: Use NVIDIA CUDA repository for version matching
local cuda_repo="debian12"
case "$os_codename" in
bullseye) cuda_repo="debian11" ;;
bookworm) cuda_repo="debian12" ;;
esac
# Add NVIDIA CUDA repository
if [[ ! -f /usr/share/keyrings/cuda-archive-keyring.gpg ]]; then
msg_info "Adding NVIDIA CUDA repository (${cuda_repo})"
local cuda_keyring
cuda_keyring="$(mktemp)"
if curl -fsSL -o "$cuda_keyring" "https://developer.download.nvidia.com/compute/cuda/repos/${cuda_repo}/x86_64/cuda-keyring_1.1-1_all.deb" 2>/dev/null; then
$STD dpkg -i "$cuda_keyring" 2>/dev/null || true
else
msg_warn "Failed to download NVIDIA CUDA keyring"
fi
rm -f "$cuda_keyring"
fi
# Pin NVIDIA repo for version matching
cat <<'NVIDIA_PIN' >/etc/apt/preferences.d/nvidia-cuda-pin
Package: *
Pin: origin developer.download.nvidia.com
Pin-Priority: 1001
NVIDIA_PIN
$STD apt -y update
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
# Install version-matched NVIDIA libraries
local nvidia_pkgs="libcuda1=${nvidia_host_version}* libnvcuvid1=${nvidia_host_version}* libnvidia-encode1=${nvidia_host_version}* libnvidia-ml1=${nvidia_host_version}*"
# Install version-matched NVIDIA libraries
local nvidia_pkgs="libcuda1=${nvidia_host_version}* libnvcuvid1=${nvidia_host_version}* libnvidia-encode1=${nvidia_host_version}* libnvidia-ml1=${nvidia_host_version}*"
msg_info "Installing NVIDIA libraries (version ${nvidia_host_version})"
if $STD apt -y install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
msg_warn "Version-pinned install failed - trying unpinned"
if $STD apt -y install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null; then
msg_warn "Installed NVIDIA libraries (unpinned) - version mismatch may occur"
msg_info "Installing NVIDIA libraries (version ${nvidia_host_version})"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
msg_warn "NVIDIA library installation failed"
msg_warn "Version-pinned install failed - trying unpinned"
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends libcuda1 libnvcuvid1 libnvidia-encode1 libnvidia-ml1 2>/dev/null; then
msg_ok "Installed NVIDIA libraries (unpinned) - version mismatch may occur"
else
msg_warn "NVIDIA library installation failed"
fi
fi
fi
$STD apt -y install --no-install-recommends nvidia-smi 2>/dev/null || true
$STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends nvidia-smi 2>/dev/null || true
fi
elif [[ "$os_id" == "ubuntu" ]]; then
# Ubuntu versioning
@@ -3081,20 +3123,20 @@ NVIDIA_PIN
rm -f "$cuda_keyring"
fi
$STD apt -y update
$STD apt-get -y update 2>/dev/null || msg_warn "apt update failed - continuing anyway"
# Try version-matched install
local nvidia_pkgs="libcuda1=${nvidia_host_version}* libnvcuvid1=${nvidia_host_version}* libnvidia-encode1=${nvidia_host_version}* libnvidia-ml1=${nvidia_host_version}*"
if $STD apt -y install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
if $STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends $nvidia_pkgs 2>/dev/null; then
msg_ok "Installed version-matched NVIDIA libraries"
else
# Fallback to Ubuntu repo packages
$STD apt -y install --no-install-recommends libnvidia-decode libnvidia-encode nvidia-utils 2>/dev/null || msg_warn "NVIDIA installation failed"
$STD apt-get -y -o Dpkg::Options::="--force-confold" install --no-install-recommends libnvidia-decode libnvidia-encode nvidia-utils 2>/dev/null || msg_warn "NVIDIA installation failed"
fi
fi
# VA-API for hybrid setups (Intel + NVIDIA)
$STD apt -y install va-driver-all vainfo 2>/dev/null || true
$STD apt-get -y install va-driver-all vainfo 2>/dev/null || true
msg_ok "NVIDIA GPU configured"
}
@@ -3563,6 +3605,11 @@ EOF
setup_mariadb() {
local MARIADB_VERSION="${MARIADB_VERSION:-latest}"
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Resolve "latest" to actual version
if [[ "$MARIADB_VERSION" == "latest" ]]; then
if ! curl -fsI --max-time 10 http://mirror.mariadb.org/repo/ >/dev/null 2>&1; then
@@ -3601,6 +3648,20 @@ setup_mariadb() {
local CURRENT_VERSION=""
CURRENT_VERSION=$(is_tool_installed "mariadb" 2>/dev/null) || true
# Pre-configure debconf to prevent any interactive prompts during install/upgrade
local MARIADB_MAJOR_MINOR
MARIADB_MAJOR_MINOR=$(echo "$MARIADB_VERSION" | awk -F. '{print $1"."$2}')
if [[ -n "$MARIADB_MAJOR_MINOR" ]]; then
debconf-set-selections <<EOF
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/feedback boolean false
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/root_password password
mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/root_password_again password
mariadb-server mariadb-server/feedback boolean false
mariadb-server mariadb-server/root_password password
mariadb-server mariadb-server/root_password_again password
EOF
fi
# Scenario 1: Already installed at target version - just update packages
if [[ -n "$CURRENT_VERSION" && "$CURRENT_VERSION" == "$MARIADB_VERSION" ]]; then
msg_info "Update MariaDB $MARIADB_VERSION"
@@ -3667,15 +3728,7 @@ setup_mariadb() {
return 1
}
# Set debconf selections for all potential versions
local MARIADB_MAJOR_MINOR
MARIADB_MAJOR_MINOR=$(echo "$MARIADB_VERSION" | awk -F. '{print $1"."$2}')
if [[ -n "$MARIADB_MAJOR_MINOR" ]]; then
echo "mariadb-server-$MARIADB_MAJOR_MINOR mariadb-server/feedback boolean false" | debconf-set-selections
fi
# Install packages with retry logic
export DEBIAN_FRONTEND=noninteractive
if ! install_packages_with_retry "mariadb-server" "mariadb-client"; then
# Fallback: try without specific version
msg_warn "Failed to install MariaDB packages from upstream repo, trying distro fallback..."
@@ -3815,6 +3868,11 @@ function setup_mongodb() {
DISTRO_ID=$(get_os_info id)
DISTRO_CODENAME=$(get_os_info codename)
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Check AVX support
if ! grep -qm1 'avx[^ ]*' /proc/cpuinfo; then
local major="${MONGO_VERSION%%.*}"
@@ -3933,6 +3991,11 @@ function setup_mysql() {
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Get currently installed version
local CURRENT_VERSION=""
CURRENT_VERSION=$(is_tool_installed "mysql" 2>/dev/null) || true
@@ -4027,7 +4090,6 @@ EOF
ensure_apt_working || return 1
# Try multiple package names with retry logic
export DEBIAN_FRONTEND=noninteractive
local mysql_install_success=false
if apt-cache search "^mysql-server$" 2>/dev/null | grep -q . &&
@@ -4466,6 +4528,11 @@ function setup_postgresql() {
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Get currently installed version
local CURRENT_PG_VERSION=""
if command -v psql >/dev/null; then
@@ -4923,6 +4990,11 @@ function setup_clickhouse() {
DISTRO_ID=$(awk -F= '/^ID=/{print $2}' /etc/os-release | tr -d '"')
DISTRO_CODENAME=$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)
# Ensure non-interactive mode for all apt operations
export DEBIAN_FRONTEND=noninteractive
export NEEDRESTART_MODE=a
export NEEDRESTART_SUSPEND=1
# Resolve "latest" version
if [[ "$CLICKHOUSE_VERSION" == "latest" ]]; then
CLICKHOUSE_VERSION=$(curl -fsSL --max-time 15 https://packages.clickhouse.com/tgz/stable/ 2>/dev/null |
@@ -4985,7 +5057,6 @@ function setup_clickhouse() {
"main"
# Install packages with retry logic
export DEBIAN_FRONTEND=noninteractive
$STD apt update || {
msg_error "APT update failed for ClickHouse repository"
return 1

View File

@@ -42,6 +42,29 @@ function msg() {
local TEXT="$1"
echo -e "$TEXT"
}
function validate_container_id() {
local ctid="$1"
# Check if ID is numeric
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
return 1
fi
# Check if config file exists for VM or LXC
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
fi
return 0
}
function get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
done
echo "$suggested_id"
}
function cleanup_ctid() {
if pct status $CTID &>/dev/null; then
if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then
@@ -76,7 +99,15 @@ TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templat
# Setup script environment
NAME=$(echo "$TEMPLATE" | grep -oE '^[^-]+-[^-]+')
PASS="$(openssl rand -base64 8)"
# Get valid Container ID
CTID=$(pvesh get /cluster/nextid)
if ! validate_container_id "$CTID"; then
warn "Container ID $CTID is already in use."
CTID=$(get_valid_container_id "$CTID")
info "Using next available ID: $CTID"
fi
PCT_OPTIONS="
-features keyctl=1,nesting=1
-hostname $NAME

369
tools/addon/jellystat.sh Normal file
View File

@@ -0,0 +1,369 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/CyferShepard/Jellystat
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# ==============================================================================
# CONFIGURATION
# ==============================================================================
APP="Jellystat"
APP_TYPE="addon"
INSTALL_PATH="/opt/jellystat"
CONFIG_PATH="/opt/jellystat/.env"
DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
__ ____ __ __
/ /__ / / /_ _______/ /_____ _/ /_
__ / / _ \/ / / / / / ___/ __/ __ `/ __/
/ /_/ / __/ / / /_/ (__ ) /_/ /_/ / /_
\____/\___/_/_/\__, /____/\__/\__,_/\__/
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu."
exit 1
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/jellystat.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now jellystat.service &>/dev/null || true
rm -f "$SERVICE_PATH"
rm -rf "$INSTALL_PATH"
rm -f "/usr/local/bin/update_jellystat"
rm -f "$HOME/.jellystat"
msg_ok "${APP} has been uninstalled"
# Ask about PostgreSQL database removal
echo ""
echo -n "${TAB}Also remove PostgreSQL database 'jellystat'? (y/N): "
read -r db_prompt
if [[ "${db_prompt,,}" =~ ^(y|yes)$ ]]; then
if command -v psql &>/dev/null; then
msg_info "Removing PostgreSQL database and user"
$STD sudo -u postgres psql -c "DROP DATABASE IF EXISTS jellystat;" &>/dev/null || true
$STD sudo -u postgres psql -c "DROP USER IF EXISTS jellystat;" &>/dev/null || true
msg_ok "Removed PostgreSQL database 'jellystat' and user 'jellystat'"
else
msg_warn "PostgreSQL not found - database may have been removed already"
fi
else
msg_warn "PostgreSQL database was NOT removed. Remove manually if needed:"
echo -e "${TAB} sudo -u postgres psql -c \"DROP DATABASE jellystat;\""
echo -e "${TAB} sudo -u postgres psql -c \"DROP USER jellystat;\""
fi
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "jellystat" "CyferShepard/Jellystat"; then
msg_info "Stopping service"
systemctl stop jellystat.service &>/dev/null || true
msg_ok "Stopped service"
msg_info "Backing up configuration"
cp "$CONFIG_PATH" /tmp/jellystat.env.bak 2>/dev/null || true
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
msg_info "Restoring configuration"
cp /tmp/jellystat.env.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/jellystat.env.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies"
cd "$INSTALL_PATH"
$STD npm install
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
msg_info "Starting service"
systemctl start jellystat
msg_ok "Started service"
msg_ok "Updated successfully"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
# Setup Node.js (only installs if not present or different version)
if command -v node &>/dev/null; then
msg_ok "Node.js already installed ($(node -v))"
else
NODE_VERSION="22" setup_nodejs
fi
# Setup PostgreSQL (only installs if not present)
if command -v psql &>/dev/null; then
msg_ok "PostgreSQL already installed"
else
PG_VERSION="17" setup_postgresql
fi
# Create database and user (skip if already exists)
local DB_NAME="jellystat"
local DB_USER="jellystat"
local DB_PASS
msg_info "Setting up PostgreSQL database"
# Check if database already exists
if sudo -u postgres psql -lqt 2>/dev/null | cut -d \| -f 1 | grep -qw "$DB_NAME"; then
msg_warn "Database '${DB_NAME}' already exists - skipping creation"
echo -n "${TAB}Enter existing database password for '${DB_USER}': "
read -rs DB_PASS
echo ""
else
# Generate new password
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
# Check if user exists, create if not
if sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'" 2>/dev/null | grep -q 1; then
msg_info "User '${DB_USER}' exists, updating password"
$STD sudo -u postgres psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASS}';" || {
msg_error "Failed to update PostgreSQL user"
return 1
}
else
$STD sudo -u postgres psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}';" || {
msg_error "Failed to create PostgreSQL user"
return 1
}
fi
# Create database (use template0 for UTF8 encoding compatibility)
$STD sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} WITH OWNER ${DB_USER} ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0;" || {
msg_error "Failed to create PostgreSQL database"
return 1
}
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};" || {
msg_error "Failed to grant privileges"
return 1
}
# Grant schema permissions (required for PostgreSQL 15+)
$STD sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL ON SCHEMA public TO ${DB_USER};" || true
# Configure pg_hba.conf for password authentication on localhost
local PG_HBA
PG_HBA=$(sudo -u postgres psql -tAc "SHOW hba_file;" 2>/dev/null | tr -d ' ')
if [[ -n "$PG_HBA" && -f "$PG_HBA" ]]; then
# Check if md5/scram-sha-256 auth is already configured for local connections
if ! grep -qE "^host\s+${DB_NAME}\s+${DB_USER}\s+127.0.0.1" "$PG_HBA"; then
msg_info "Configuring PostgreSQL authentication"
# Add password auth for jellystat user on localhost (before the default rules)
sed -i "/^# IPv4 local connections:/a host ${DB_NAME} ${DB_USER} 127.0.0.1/32 scram-sha-256" "$PG_HBA"
sed -i "/^# IPv4 local connections:/a host ${DB_NAME} ${DB_USER} ::1/128 scram-sha-256" "$PG_HBA"
# Reload PostgreSQL to apply changes
systemctl reload postgresql
msg_ok "Configured PostgreSQL authentication"
fi
fi
msg_ok "Created PostgreSQL database '${DB_NAME}'"
fi
# Generate JWT Secret
local JWT_SECRET
JWT_SECRET=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c32)
# Force fresh download by removing version cache
rm -f "$HOME/.jellystat"
fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
msg_info "Installing dependencies"
cd "$INSTALL_PATH"
$STD npm install
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
msg_info "Creating configuration"
cat <<EOF >"$CONFIG_PATH"
# Jellystat Configuration
# Database
POSTGRES_USER=${DB_USER}
POSTGRES_PASSWORD=${DB_PASS}
POSTGRES_IP=localhost
POSTGRES_PORT=5432
POSTGRES_DB=${DB_NAME}
# Security
JWT_SECRET=${JWT_SECRET}
# Server
JS_LISTEN_IP=0.0.0.0
JS_BASE_URL=/
TZ=$(cat /etc/timezone 2>/dev/null || echo "UTC")
# Optional: GeoLite for IP Geolocation
# JS_GEOLITE_ACCOUNT_ID=
# JS_GEOLITE_LICENSE_KEY=
# Optional: Master Override (if you forget your password)
# JS_USER=admin
# JS_PASSWORD=admin
# Optional: Minimum playback duration to record (seconds)
# MINIMUM_SECONDS_TO_INCLUDE_PLAYBACK=1
# Optional: Self-signed certificates
REJECT_SELF_SIGNED_CERTIFICATES=true
EOF
chmod 600 "$CONFIG_PATH"
msg_ok "Created configuration"
msg_info "Creating service"
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=Jellystat - Statistics for Jellyfin
After=network.target postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_PATH}
EnvironmentFile=${CONFIG_PATH}
ExecStart=/usr/bin/node ${INSTALL_PATH}/backend/server.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now jellystat &>/dev/null
msg_ok "Created and started service"
# Create update script (simple wrapper that calls this addon with type=update)
msg_info "Creating update script"
cat <<'UPDATEEOF' >/usr/local/bin/update_jellystat
#!/usr/bin/env bash
# Jellystat Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/jellystat.sh)"
UPDATEEOF
chmod +x /usr/local/bin/update_jellystat
msg_ok "Created update script (/usr/local/bin/update_jellystat)"
# Save credentials
local CREDS_FILE="/root/jellystat.creds"
cat <<EOF >"$CREDS_FILE"
Jellystat Credentials
=====================
Database User: ${DB_USER}
Database Password: ${DB_PASS}
Database Name: ${DB_NAME}
JWT Secret: ${JWT_SECRET}
Web UI: http://${LOCAL_IP}:${DEFAULT_PORT}
EOF
chmod 600 "$CREDS_FILE"
echo ""
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
msg_ok "Credentials saved to: ${BL}${CREDS_FILE}${CL}"
echo ""
msg_warn "On first access, you'll need to configure your Jellyfin server connection."
}
# ==============================================================================
# MAIN
# ==============================================================================
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
header_info
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/package.json" ]]; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 1
fi
exit 0
fi
header_info
import_local_ip
# Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/package.json" ]]; then
msg_warn "${APP} is already installed."
echo ""
echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
# Fresh installation
msg_warn "${APP} is not installed."
echo ""
echo -e "${TAB}${INFO} This will install:"
echo -e "${TAB} - Node.js 22"
echo -e "${TAB} - PostgreSQL 17"
echo -e "${TAB} - Jellystat"
echo ""
echo -n "${TAB}Install ${APP}? (y/N): "
read -r install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
install
else
msg_warn "Installation cancelled. Exiting."
exit 0
fi

6
tools/headers/jellystat Normal file
View File

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

View File

@@ -27,6 +27,12 @@ CL=$(echo "\033[m")
header_info
echo "Loading..."
whiptail --backtitle "Proxmox VE Helper Scripts" --title "Proxmox VE LXC Updater" --yesno "This Will Update LXC Containers. Proceed?" 10 58
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Skip Not-Running Containers" --yesno "Do you want to skip containers that are not currently running?" 10 58; then
SKIP_STOPPED="yes"
else
SKIP_STOPPED="no"
fi
NODE=$(hostname)
EXCLUDE_MENU=()
MSG_MAX_LENGTH=0
@@ -67,7 +73,7 @@ function update_container() {
alpine) pct exec "$container" -- ash -c "apk -U upgrade" ;;
archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;;
fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;;
ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED" ;;
ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED || true" ;;
opensuse) pct exec "$container" -- bash -c "zypper ref && zypper --non-interactive dup" ;;
esac
}
@@ -81,6 +87,12 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do
sleep 1
else
status=$(pct status $container)
if [ "$SKIP_STOPPED" == "yes" ] && [ "$status" == "status: stopped" ]; then
header_info
echo -e "${BL}[Info]${GN} Skipping ${BL}$container${CL}${GN} (not running)${CL}"
sleep 1
continue
fi
template=$(pct config $container | grep -q "template:" && echo "true" || echo "false")
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n"

View File

@@ -42,6 +42,29 @@ function msg() {
local TEXT="$1"
echo -e "$TEXT"
}
function validate_container_id() {
local ctid="$1"
# Check if ID is numeric
if ! [[ "$ctid" =~ ^[0-9]+$ ]]; then
return 1
fi
# Check if config file exists for VM or LXC
if [[ -f "/etc/pve/qemu-server/${ctid}.conf" ]] || [[ -f "/etc/pve/lxc/${ctid}.conf" ]]; then
return 1
fi
# Check if ID is used in LVM logical volumes
if lvs --noheadings -o lv_name 2>/dev/null | grep -qE "(^|[-_])${ctid}($|[-_])"; then
return 1
fi
return 0
}
function get_valid_container_id() {
local suggested_id="${1:-$(pvesh get /cluster/nextid)}"
while ! validate_container_id "$suggested_id"; do
suggested_id=$((suggested_id + 1))
done
echo "$suggested_id"
}
function cleanup_ctid() {
if pct status $CTID &>/dev/null; then
if [ "$(pct status $CTID | awk '{print $2}')" == "running" ]; then
@@ -99,9 +122,26 @@ turnkey=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "TurnKey LXCs
# Setup script environment
PASS="$(openssl rand -base64 8)"
# Prompt user to confirm container ID
CTID=$(whiptail --backtitle "Container ID" --title "Choose the Container ID" --inputbox "Enter the conatiner ID..." 8 40 $(pvesh get /cluster/nextid) 3>&1 1>&2 2>&3)
while true; do
CTID=$(whiptail --backtitle "Container ID" --title "Choose the Container ID" --inputbox "Enter the container ID..." 8 40 $(pvesh get /cluster/nextid) 3>&1 1>&2 2>&3)
# Check if user cancelled
[ -z "$CTID" ] && die "No Container ID selected"
# Validate Container ID
if ! validate_container_id "$CTID"; then
SUGGESTED_ID=$(get_valid_container_id "$CTID")
if whiptail --backtitle "Container ID" --title "ID Already In Use" --yesno "Container/VM ID $CTID is already in use.\n\nWould you like to use the next available ID ($SUGGESTED_ID)?" 10 58; then
CTID="$SUGGESTED_ID"
break
fi
# User declined, loop back to input
else
break
fi
done
# Prompt user to confirm Hostname
HOST_NAME=$(whiptail --backtitle "Hostname" --title "Choose the Hostname" --inputbox "Enter the containers Hostname..." 8 40 "turnkey-${turnkey}" 3>&1 1>&2 2>&3)
HOST_NAME=$(whiptail --backtitle "Hostname" --title "Choose the Hostname" --inputbox "Enter the containers Hostname..." 8 40 "turnkey-${turnkey}" 3>&1 1>&2 2>&3)
PCT_OPTIONS="
-features keyctl=1,nesting=1
-hostname $HOST_NAME
@@ -206,8 +246,8 @@ echo "TurnKey ${turnkey} password: ${PASS}" >>~/turnkey-${turnkey}.creds # file
TUN_DEVICE_REQUIRED=("openvpn") # Setup this way in case future turnkeys also need tun access
if printf '%s\n' "${TUN_DEVICE_REQUIRED[@]}" | grep -qw "${turnkey}"; then
info "${turnkey} requires access to /dev/net/tun on the host. Modifying the container configuration to allow this."
echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >> /etc/pve/lxc/${CTID}.conf
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0" >> /etc/pve/lxc/${CTID}.conf
echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>/etc/pve/lxc/${CTID}.conf
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0" >>/etc/pve/lxc/${CTID}.conf
sleep 5
fi

View File

@@ -277,7 +277,7 @@ function default_settings() {
MAC=$GEN_MAC
LAN_MAC=$GEN_MAC_LAN
VLAN=""
LAN_VLAN=",tag=999"
LAN_VLAN=""
LAN_IP_ADDR="192.168.1.1"
LAN_NETMASK="255.255.255.0"
MTU=""
@@ -427,8 +427,8 @@ function advanced_settings() {
if VLAN2=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a LAN Vlan" 8 58 999 --title "LAN VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z $VLAN2 ]; then
VLAN2="999"
LAN_VLAN=",tag=$VLAN2"
VLAN2="Default"
LAN_VLAN=""
else
LAN_VLAN=",tag=$VLAN2"
fi