Compare commits

...

78 Commits

Author SHA1 Message Date
community-scripts-pr-app[bot]
8e25b70a25 Update CHANGELOG.md (#8062)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-03 00:12:10 +00:00
community-scripts-pr-app[bot]
1840cce15f Update versions.json (#8061)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-03 02:11:42 +02:00
community-scripts-pr-app[bot]
1d0ac4ca10 Update versions.json (#8055)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-02 14:05:34 +02:00
CanbiZ
deb85bd264 rm v in Version check 2025-10-02 13:18:59 +02:00
community-scripts-pr-app[bot]
348f8863a8 Update CHANGELOG.md (#8054)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-02 10:33:30 +00:00
CanbiZ
74b332b7ec EMQX: removal logic in emqx update (#8050)
Added conditional checks to remove either emqx or emqx-enterprise packages.
2025-10-02 12:33:08 +02:00
community-scripts-pr-app[bot]
2fe3ee667b Update CHANGELOG.md (#8053)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-02 10:32:45 +00:00
CanbiZ
48e3b66342 fix FlareSolverr version check to v3.3.25 (#8051) 2025-10-02 12:32:24 +02:00
community-scripts-pr-app[bot]
e93dccb0d5 Update CHANGELOG.md (#8045)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-02 00:13:27 +00:00
community-scripts-pr-app[bot]
168e7b7c2b Update versions.json (#8044)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-02 02:13:06 +02:00
community-scripts-pr-app[bot]
3f54d0d7f4 Update .app files (#8043)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-10-02 00:30:17 +02:00
community-scripts-pr-app[bot]
9477677385 Update CHANGELOG.md (#8042)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 22:29:30 +00:00
CanbiZ
e58d1dc3d2 Add conditional logic for EFI disk allocation (#8024) 2025-10-02 00:29:12 +02:00
Chris
2a765f58f0 Immich: bump version to 2.0.0 stable (#8041) 2025-10-02 00:28:51 +02:00
community-scripts-pr-app[bot]
8dfb632a4d Update CHANGELOG.md (#8036)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 15:07:56 +00:00
CanbiZ
42ae2a4cdc New Script: PhpMyAdmin (Addon) (#8030) 2025-10-01 17:07:28 +02:00
community-scripts-pr-app[bot]
36e41aca22 Update versions.json (#8031)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 14:07:20 +02:00
community-scripts-pr-app[bot]
6b1141f9de Update CHANGELOG.md (#8027)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 08:40:17 +00:00
community-scripts-pr-app[bot]
97f891d53b Update CHANGELOG.md (#8026)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 08:40:07 +00:00
Slaviša Arežina
0c63e64662 Pin version (#8023) 2025-10-01 10:39:55 +02:00
community-scripts-pr-app[bot]
d83a378af4 Update CHANGELOG.md (#8025)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 08:39:46 +00:00
Chris
6820bdcade Immich: bump version to 1.144.1 (#7994)
- small change during update to ensure the immich user can write to
uv.lock while building machine-learning
2025-10-01 10:39:20 +02:00
community-scripts-pr-app[bot]
8ff82d0c3c Update CHANGELOG.md (#8020)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 00:14:35 +00:00
community-scripts-pr-app[bot]
9e39c6cd2b Update versions.json (#8019)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-10-01 02:14:11 +02:00
community-scripts-pr-app[bot]
0bea24888e Update CHANGELOG.md (#8018)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 19:17:27 +00:00
CanbiZ
70d2be62e9 caddy: fix typo for setup_go (#8017) 2025-09-30 21:17:02 +02:00
community-scripts-pr-app[bot]
fe30e06a48 Update CHANGELOG.md (#8015)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 15:19:58 +00:00
community-scripts-pr-app[bot]
193a2ea2df Update CHANGELOG.md (#8014)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 15:19:46 +00:00
community-scripts-pr-app[bot]
ffbe0feee1 Update CHANGELOG.md (#8013)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 15:19:31 +00:00
Gerhard Burger
107865b06d Bump Guacamole to Debian 13 (#8010) 2025-09-30 17:19:22 +02:00
Hristo Stoyanov
0d33b38e29 Changedetection: Fix Browserless installation and update process (#8011)
* Fix the issue with changedetection.io install:
> @browserless.io/browserless@2.37.0 build:ts
> tsc

sh: 1: tsc: not found

[ERROR] in line 70: exit code 0: while executing command $STD npm run build --prefix /opt/browserless

* Just to verify the installation works

* Just to verify the installation works

* Try to fix typescript issues

* Try to fix TypeScript issues and update NodeJS

* Try to fix TypeScript issues

* Add more missing npm dependencies

* Cleanup test changes

* Revert testing changes and change the way dependencies are installed

* Revert testing changes and change the way dependencies are installed

* Revert manually added TypeScript and esbuild packages and tried to install them from the optional requirements

* Try the clean install

* Fix the update script and revert testing changes

* Added testing files again

* Revert testing repos again
2025-09-30 17:19:01 +02:00
CanbiZ
11ae7450c7 Add TypeScript and related packages installation 2025-09-30 16:07:34 +02:00
CanbiZ
598bfd291f Update npm install command to include dev dependencies 2025-09-30 14:26:13 +02:00
community-scripts-pr-app[bot]
1a38df4c12 Update CHANGELOG.md (#8007)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 12:17:18 +00:00
Slaviša Arežina
cfc85c1b79 Update n8n.sh (#8004) 2025-09-30 14:17:00 +02:00
community-scripts-pr-app[bot]
e7d41fecdc Update CHANGELOG.md (#8006)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 12:16:56 +00:00
CanbiZ
34ef80ac87 Changedetection: Bump nodejs to 24 (#8002) 2025-09-30 14:16:27 +02:00
community-scripts-pr-app[bot]
b18d45631f Update versions.json (#8005)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 14:06:34 +02:00
community-scripts-pr-app[bot]
efe1e1edb5 Update CHANGELOG.md (#7997)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 00:13:04 +00:00
community-scripts-pr-app[bot]
4567505c55 Update versions.json (#7996)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-30 02:12:43 +02:00
community-scripts-pr-app[bot]
42c87ba0d4 Update CHANGELOG.md (#7993)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 19:56:37 +00:00
Bram Suurd
b52c252553 fix sidebar loading issues and navbar on mobile (#7991)
* Refactor MobileSidebar to manage script and category selection based on current pathname. Introduced temporary state for non-scripts pages and updated logic for last viewed script handling. Improved accessibility by ensuring proper aria attributes and class management.

* Update API endpoint paths in data.ts to include ProxmoxVE prefix for category and version fetching functions.

* Refactor Navbar component layout for improved structure and responsiveness. Adjusted flex properties to ensure proper alignment of elements, enhancing the mobile and desktop user experience. Updated accessibility features and ensured consistent use of TailwindCSS classes.
2025-09-29 21:56:07 +02:00
community-scripts-pr-app[bot]
be5ac7153e Update CHANGELOG.md (#7989)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 16:17:00 +00:00
Bram Suurd
07f2849722 Improve mobile ui: added a hamburger navigation to the mobile view. (#7987)
* Update GitHubStarsButton component to be hidden on smaller screens

* feat: added a mobile navigation to the front-end.

* refactor: replace useQueryState with useSuspenseQueryState in ScriptContent and MobileSidebar components; add use-suspense-query-state hook

* Revert "refactor: replace useQueryState with useSuspenseQueryState in ScriptContent and MobileSidebar components; add use-suspense-query-state hook"

This reverts commit bfad01fc91.

* refactor: wrap MobileSidebar component in Suspense for improved loading handling

* Update mobile-sidebar.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-29 18:16:36 +02:00
community-scripts-pr-app[bot]
760299283a Update CHANGELOG.md (#7986)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 13:54:08 +00:00
community-scripts-pr-app[bot]
0bd2dd7a65 Update CHANGELOG.md (#7985)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 13:53:43 +00:00
community-scripts-pr-app[bot]
6591c30e66 Update date in json (#7984)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-29 13:53:39 +00:00
push-app-to-main[bot]
780e5c114c Ghostfolio (#7982)
* 'Add new script'

* Update frontend/public/json/ghostfolio.json

Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>

* Apply suggestion from @tremor021

---------

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>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2025-09-29 15:53:15 +02:00
community-scripts-pr-app[bot]
ba10ec721b Update .app files (#7981)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-29 14:29:49 +02:00
community-scripts-pr-app[bot]
f66dc834bd Update CHANGELOG.md (#7980)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 12:27:23 +00:00
community-scripts-pr-app[bot]
be36fc6a94 Update date in json (#7979)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-29 12:27:03 +00:00
push-app-to-main[bot]
65ada6e6f3 Warracker (#7977)
* 'Add new script'

* Correct application name casing in warracker.sh

---------

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>
2025-09-29 14:26:41 +02:00
community-scripts-pr-app[bot]
853eb40bba Update date in json (#7975)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-29 14:22:57 +02:00
community-scripts-pr-app[bot]
ace6265895 Update versions.json (#7978)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 14:05:52 +02:00
community-scripts-pr-app[bot]
639d4f2d53 Update CHANGELOG.md (#7976)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 11:49:12 +00:00
push-app-to-main[bot]
d7e77e232c 'Add new script' (#7974)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2025-09-29 13:48:51 +02:00
community-scripts-pr-app[bot]
b850d3f79e Update CHANGELOG.md (#7973)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 10:38:15 +00:00
CanbiZ
72e5ac5c80 Remove Frigate from Website (#7972) 2025-09-29 12:37:47 +02:00
community-scripts-pr-app[bot]
587579b3a1 Update CHANGELOG.md (#7970)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 07:15:31 +00:00
community-scripts-pr-app[bot]
9b4e996d93 Update CHANGELOG.md (#7969)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 07:15:08 +00:00
community-scripts-pr-app[bot]
e6f317ede9 Update date in json (#7968)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-29 07:15:02 +00:00
push-app-to-main[bot]
3e4420e357 'Add new script' (#7967)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2025-09-29 09:14:43 +02:00
community-scripts-pr-app[bot]
38f7e81d8b Update CHANGELOG.md (#7966)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 00:12:38 +00:00
community-scripts-pr-app[bot]
8f5d50a9fa Update versions.json (#7965)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-29 02:12:18 +02:00
community-scripts-pr-app[bot]
32048cff2d Update CHANGELOG.md (#7963)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-28 18:33:06 +00:00
Chris
5775f7cf33 Metube: remove uv flags (#7962) 2025-09-28 20:32:43 +02:00
community-scripts-pr-app[bot]
4d7c004810 Update CHANGELOG.md (#7960)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-28 14:22:51 +00:00
Tobias
d74131fe6f freshrss: fix for broken permissions after update (#7953)
Added permission check and fix for sensitive-log.sh.
2025-09-28 16:22:28 +02:00
community-scripts-pr-app[bot]
87b30f67fa Update versions.json (#7958)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-28 14:05:52 +02:00
community-scripts-pr-app[bot]
7ddc50bfe7 Update CHANGELOG.md (#7951)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-28 00:15:09 +00:00
community-scripts-pr-app[bot]
484a46beb1 Update versions.json (#7950)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-28 02:14:45 +02:00
community-scripts-pr-app[bot]
b85d1e5062 Update CHANGELOG.md (#7948)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-27 21:12:00 +00:00
Slaviša Arežina
05e41f67e1 Update goaway-install.sh (#7946) 2025-09-27 23:11:38 +02:00
community-scripts-pr-app[bot]
bfe6445c64 Update CHANGELOG.md (#7947)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-27 20:36:34 +00:00
Chris
ffde3a731c MeTube: Various fixes (#7936) 2025-09-27 22:36:14 +02:00
community-scripts-pr-app[bot]
d5b9da8f5f Update CHANGELOG.md (#7943)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-27 18:14:55 +00:00
Slaviša Arežina
1b8d790a14 Update odoo.sh (#7941) 2025-09-27 20:14:34 +02:00
community-scripts-pr-app[bot]
175b925ae4 Update versions.json (#7939)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-27 14:04:31 +02:00
48 changed files with 2033 additions and 582 deletions

View File

@@ -10,8 +10,95 @@
> [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2025-10-03
## 2025-10-02
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- EMQX: removal logic in emqx update [@MickLesk](https://github.com/MickLesk) ([#8050](https://github.com/community-scripts/ProxmoxVE/pull/8050))
- fix FlareSolverr version check to v3.3.25 [@MickLesk](https://github.com/MickLesk) ([#8051](https://github.com/community-scripts/ProxmoxVE/pull/8051))
## 2025-10-01
### 🆕 New Scripts
- New Script: PhpMyAdmin (Addon) [@MickLesk](https://github.com/MickLesk) ([#8030](https://github.com/community-scripts/ProxmoxVE/pull/8030))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- openwrt: Add conditional logic for EFI disk allocation [@MickLesk](https://github.com/MickLesk) ([#8024](https://github.com/community-scripts/ProxmoxVE/pull/8024))
- Plant-IT: Pin version to v0.10.0 [@tremor021](https://github.com/tremor021) ([#8023](https://github.com/community-scripts/ProxmoxVE/pull/8023))
- #### ✨ New Features
- Immich: bump version to 2.0.0 stable [@vhsdream](https://github.com/vhsdream) ([#8041](https://github.com/community-scripts/ProxmoxVE/pull/8041))
- #### 🔧 Refactor
- Immich: bump version to 1.144.1 [@vhsdream](https://github.com/vhsdream) ([#7994](https://github.com/community-scripts/ProxmoxVE/pull/7994))
## 2025-09-30
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- caddy: fix typo for setup_go [@MickLesk](https://github.com/MickLesk) ([#8017](https://github.com/community-scripts/ProxmoxVE/pull/8017))
- Changedetection: Fix Browserless installation and update process [@h-stoyanov](https://github.com/h-stoyanov) ([#8011](https://github.com/community-scripts/ProxmoxVE/pull/8011))
- n8n: Update procedure workaround [@tremor021](https://github.com/tremor021) ([#8004](https://github.com/community-scripts/ProxmoxVE/pull/8004))
- Changedetection: Bump nodejs to 24 [@MickLesk](https://github.com/MickLesk) ([#8002](https://github.com/community-scripts/ProxmoxVE/pull/8002))
- #### ✨ New Features
- Bump Guacamole to Debian 13 [@burgerga](https://github.com/burgerga) ([#8010](https://github.com/community-scripts/ProxmoxVE/pull/8010))
## 2025-09-29
### 🆕 New Scripts
- Ghostfolio ([#7982](https://github.com/community-scripts/ProxmoxVE/pull/7982))
- Warracker ([#7977](https://github.com/community-scripts/ProxmoxVE/pull/7977))
- MyIP ([#7974](https://github.com/community-scripts/ProxmoxVE/pull/7974))
- Verdaccio ([#7967](https://github.com/community-scripts/ProxmoxVE/pull/7967))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix sidebar loading issues and navbar on mobile [@BramSuurdje](https://github.com/BramSuurdje) ([#7991](https://github.com/community-scripts/ProxmoxVE/pull/7991))
- #### ✨ New Features
- Improve mobile ui: added a hamburger navigation to the mobile view. [@BramSuurdje](https://github.com/BramSuurdje) ([#7987](https://github.com/community-scripts/ProxmoxVE/pull/7987))
- #### 📝 Script Information
- Remove Frigate from Website [@MickLesk](https://github.com/MickLesk) ([#7972](https://github.com/community-scripts/ProxmoxVE/pull/7972))
## 2025-09-28
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Metube: remove uv flags [@vhsdream](https://github.com/vhsdream) ([#7962](https://github.com/community-scripts/ProxmoxVE/pull/7962))
- freshrss: fix for broken permissions after update [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7953](https://github.com/community-scripts/ProxmoxVE/pull/7953))
## 2025-09-27
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- GoAway: Make admin password aquisition more reliable [@tremor021](https://github.com/tremor021) ([#7946](https://github.com/community-scripts/ProxmoxVE/pull/7946))
- MeTube: Various fixes [@vhsdream](https://github.com/vhsdream) ([#7936](https://github.com/community-scripts/ProxmoxVE/pull/7936))
- Oddo: Fix typo in update procedure [@tremor021](https://github.com/tremor021) ([#7941](https://github.com/community-scripts/ProxmoxVE/pull/7941))
## 2025-09-26
### 🚀 Updated Scripts

View File

@@ -11,7 +11,7 @@ var_disk="${var_disk:-4}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-2048}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
@@ -38,4 +38,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}:8080/guacamole${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080/guacamole${CL}"

View File

@@ -33,7 +33,7 @@ function update_script() {
msg_ok "Updated $APP LXC"
if command -v xcaddy >/dev/null 2>&1; then
install_go
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}')

View File

@@ -36,6 +36,8 @@ function update_script() {
msg_ok "Updated Dependencies"
fi
NODE_VERSION="24" setup_nodejs
msg_info "Updating ${APP}"
$STD pip3 install changedetection.io --upgrade
msg_ok "Updated ${APP}"
@@ -49,6 +51,7 @@ function update_script() {
$STD git -C /opt/browserless/ fetch --all
$STD git -C /opt/browserless/ reset --hard origin/main
$STD npm update --prefix /opt/browserless
$STD npm ci --include=optional --include=dev --prefix /opt/browserless
$STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps
# Update Chrome separately, as it has to be done with the force option. Otherwise the installation of other browsers will not be done if Chrome is already installed.
$STD /opt/browserless/node_modules/playwright-core/cli.js install --force chrome

View File

@@ -31,7 +31,13 @@ function update_script() {
msg_ok "Stopped EMQX"
msg_info "Removing old EMQX"
$STD apt-get remove --purge -y emqx
if dpkg -l | grep -q "^ii\s\+emqx\s"; then
$STD apt-get remove --purge -y emqx
elif dpkg -l | grep -q "^ii\s\+emqx-enterprise\s"; then
$STD apt-get remove --purge -y emqx-enterprise
else
msg_ok "No old EMQX package found"
fi
msg_ok "Removed old EMQX"
msg_info "Downloading EMQX v${RELEASE}"

View File

@@ -28,7 +28,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "3.3.5"; then
if check_for_gh_release "flaresolverr" "FlareSolverr/FlareSolverr" "3.3.25"; then
msg_info "Stopping service"
systemctl stop flaresolverr
msg_ok "Stopped service"

View File

@@ -27,8 +27,16 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "FreshRSS should be updated via the user interface."
exit
if [ ! -x /opt/freshrss/cli/sensitive-log.sh ]; then
msg_info "Fixing wrong permissions"
chmod +x /opt/freshrss/cli/sensitive-log.sh
systemctl restart apache2
msg_ok "Fixed wrong permissions"
else
msg_error "FreshRSS should be updated via the user interface."
exit
fi
}
start
@@ -38,4 +46,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}${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

75
ct/ghostfolio.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/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: lucasfell
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ghostfol.io/
APP="Ghostfolio"
var_tags="${var_tags:-finance;investment}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/ghostfolio/dist/apps/api/main.js ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "ghostfolio" "ghostfolio/ghostfolio"; then
msg_info "Stopping Service"
systemctl stop ghostfolio
msg_ok "Stopped Service"
msg_info "Creating Backup"
tar -czf "/opt/ghostfolio_backup_$(date +%F).tar.gz" \
-C /opt \
--exclude="ghostfolio/node_modules" \
--exclude="ghostfolio/dist" \
ghostfolio
mv /opt/ghostfolio/.env /opt/env.backup
msg_ok "Backup Created"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"
msg_info "Updating Ghostfolio"
mv /opt/env.backup /opt/ghostfolio/.env
cd /opt/ghostfolio
$STD npm ci
$STD npm run build:production
$STD npx prisma migrate deploy
msg_ok "Updated Ghostfolio"
msg_info "Starting Service"
systemctl start ghostfolio
msg_ok "Started Service"
msg_info "Cleaning Up"
$STD npm cache clean --force
msg_ok "Cleanup Completed"
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}:3333${CL}"

6
ct/headers/ghostfolio Normal file
View File

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

6
ct/headers/myip Normal file
View File

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

6
ct/headers/verdaccio Normal file
View File

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

6
ct/headers/warracker Normal file
View File

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

View File

@@ -74,7 +74,7 @@ function update_script() {
done
msg_ok "Image-processing libraries up to date"
fi
RELEASE="1.143.1"
RELEASE="2.0.0"
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
msg_info "Stopping Services"
systemctl stop immich-web
@@ -158,6 +158,7 @@ EOF
cd "$SRC_DIR"/machine-learning
mkdir -p "$ML_DIR" && chown -R immich:immich "$ML_DIR"
chown immich:immich ./uv.lock
export VIRTUAL_ENV="${ML_DIR}"/ml-venv
if [[ -f ~/.openvino ]]; then
msg_info "Updating HW-accelerated machine-learning"
@@ -190,6 +191,7 @@ EOF
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt clean -y
msg_ok "Cleaned"
systemctl restart immich-ml immich-web
fi

View File

@@ -29,59 +29,53 @@ function update_script() {
exit
fi
msg_info "Stopping ${APP} Service"
systemctl stop metube
msg_ok "Stopped ${APP} Service"
msg_info "Backing up Old Installation"
if [[ -d /opt/metube_bak ]]; then
rm -rf /opt/metube_bak
if [[ $(echo ":$PATH:" != *":/usr/local/bin:"*) ]]; then
echo 'export PATH="/usr/local/bin:$PATH"' >>~/.bashrc
source ~/.bashrc
if ! command -v deno &>/dev/null; then
export DENO_INSTALL="/usr/local"
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
else
$STD deno upgrade
fi
fi
mv /opt/metube /opt/metube_bak
msg_ok "Backup created"
msg_info "Cloning Latest ${APP} Release"
$STD git clone https://github.com/alexta69/metube /opt/metube
msg_ok "Cloned ${APP}"
if check_for_gh_release "metube" "alexta69/metube"; then
msg_info "Stopping ${APP} Service"
systemctl stop metube
msg_ok "Stopped ${APP} Service"
msg_info "Building Frontend"
cd /opt/metube/ui
$STD npm install
$STD node_modules/.bin/ng build
msg_ok "Built Frontend"
msg_info "Backing up Old Installation"
if [[ -d /opt/metube_bak ]]; then
rm -rf /opt/metube_bak
fi
mv /opt/metube /opt/metube_bak
msg_ok "Backup created"
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "metube" "alexta69/metube" "tarball" "latest"
msg_info "Setting up Python Environment (uv)"
$STD uv venv /opt/metube/.venv
$STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
$STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
$STD /opt/metube/.venv/bin/python -m pip install pipenv
msg_ok "Python Environment Ready"
msg_info "Building Frontend"
cd /opt/metube/ui
$STD npm install
$STD node_modules/.bin/ng build
msg_ok "Built Frontend"
msg_info "Installing Backend Requirements"
cd /opt/metube
$STD /opt/metube/.venv/bin/pipenv install
msg_ok "Installed Backend"
msg_info "Restoring Environment File"
if [[ -f /opt/metube_bak/.env ]]; then
cp /opt/metube_bak/.env /opt/metube/.env
fi
msg_ok "Restored .env"
if [[ ! -d /opt/metube/.venv ]]; then
msg_info "Migrating to uv-based environment"
PYTHON_VERSION="3.13" setup_uv
$STD uv venv /opt/metube/.venv
$STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
$STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
$STD /opt/metube/.venv/bin/python -m pip install pipenv
$STD /opt/metube/.venv/bin/pipenv install
$STD /opt/metube/.venv/bin/pipenv update yt-dlp
msg_info "Patching systemd Service"
cat <<EOF >/etc/systemd/system/metube.service
msg_info "Installing Backend Requirements"
cd /opt/metube
$STD uv sync
msg_ok "Installed Backend"
msg_info "Restoring Environment File"
if [[ -f /opt/metube_bak/.env ]]; then
cp /opt/metube_bak/.env /opt/metube/.env
fi
msg_ok "Restored .env"
if grep -q 'pipenv' /etc/systemd/system/metube.service; then
msg_info "Patching systemd Service"
cat <<EOF >/etc/systemd/system/metube.service
[Unit]
Description=Metube - YouTube Downloader
After=network.target
@@ -90,30 +84,31 @@ After=network.target
Type=simple
WorkingDirectory=/opt/metube
EnvironmentFile=/opt/metube/.env
ExecStart=/opt/metube/.venv/bin/pipenv run python3 app/main.py
ExecStart=/opt/metube/.venv/bin/python3 app/main.py
Restart=always
User=root
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Patched systemd Service"
msg_ok "Patched systemd Service"
fi
$STD systemctl daemon-reload
msg_ok "Service Updated"
msg_info "Cleaning up"
rm -rf /opt/metube_bak
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned Up"
msg_info "Starting ${APP} Service"
systemctl start metube
sleep 1
msg_ok "Started ${APP} Service"
msg_ok "Updated Successfully!"
fi
$STD systemctl daemon-reload
msg_ok "Service Updated"
msg_info "Cleaning up"
rm -rf /opt/metube_bak
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned Up"
msg_info "Starting ${APP} Service"
systemctl enable -q --now metube
sleep 1
msg_ok "Started ${APP} Service"
msg_ok "Updated Successfully!"
}
start

55
ct/myip.sh Normal file
View File

@@ -0,0 +1,55 @@
#!/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: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ipcheck.ing/
APP="MyIP"
var_tags="${var_tags:-network}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
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/myip ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "myip" "jason5ng32/MyIP"; then
msg_info "Stopping Services"
systemctl stop myip
msg_ok "Stopped Services"
cp /opt/myip/.env /opt
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myip" "jason5ng32/MyIP" "tarball"
mv /opt/.env /opt/myip
msg_info "Starting Services"
systemctl start myip
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}http://${IP}:18966${CL}"

View File

@@ -41,7 +41,8 @@ EOF
NODE_VERSION="22" setup_nodejs
msg_info "Updating ${APP} LXC"
$STD npm update -g n8n
rm -rf /usr/lib/node_modules/.n8n-* /usr/lib/node_modules/n8n
$STD npm install -g n8n --force
systemctl restart n8n
msg_ok "Updated Successfully"
exit

View File

@@ -29,7 +29,7 @@ function update_script() {
exit 1
fi
if ! [[ $(dpkg -s python3-lxml-html-clean 2>/dev/null) ]]; then
$STD apt-get install python-lxml
$STD apt-get install python3-lxml
curl -fsSL "http://archive.ubuntu.com/ubuntu/pool/universe/l/lxml-html-clean/python3-lxml-html-clean_0.1.1-1_all.deb" -o /opt/python3-lxml-html-clean.deb
$STD dpkg -i /opt/python3-lxml-html-clean.deb
rm -f /opt/python3-lxml-html-clean.deb

View File

@@ -32,8 +32,10 @@ function update_script() {
systemctl stop plant-it
msg_ok "Stopped $APP"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "latest" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "latest" "/opt/plant-it/frontend" "client.tar.gz"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "0.10.0" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "0.10.0" "/opt/plant-it/frontend" "client.tar.gz"
msg_warn "Application is updated to latest Web version (v0.10.0). There will be no more updates available."
msg_warn "Please read: https://github.com/MDeLuise/plant-it/releases/tag/1.0.0"
msg_info "Starting $APP"
systemctl start plant-it

49
ct/verdaccio.sh Normal file
View File

@@ -0,0 +1,49 @@
#!/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: BrynnJKnight
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://verdaccio.org/
APP="Verdaccio"
var_tags="${var_tags:-dev-tools;npm;registry}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/verdaccio.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating LXC Container"
$STD apt update
$STD apt -y upgrade
msg_ok "Updated LXC Container"
NODE_VERSION="22" NODE_MODULE="verdaccio" setup_nodejs
systemctl restart verdaccio
msg_ok "Updated Successfully"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4873${CL}"

63
ct/warracker.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/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: BvdBerg01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/sassanix/Warracker/
APP="Warracker"
var_tags="${var_tags:-warranty}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
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/warracker ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "warracker" "sassanix/Warracker"; then
msg_info "Stopping Services"
systemctl stop warrackermigration
systemctl stop warracker
systemctl stop nginx
msg_ok "Stopped Services"
fetch_and_deploy_gh_release "warracker" "sassanix/Warracker" "tarball" "latest" "/opt/warracker"
msg_info "Updating Warracker"
cd /opt/warracker/backend
$STD uv venv .venv
$STD source .venv/bin/activate
$STD uv pip install -r requirements.txt
msg_ok "Updated Warracker"
msg_info "Starting Services"
systemctl start warracker
systemctl start nginx
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}http://${IP}${CL}"

View File

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

View File

@@ -0,0 +1,52 @@
{
"name": "Ghostfolio",
"slug": "ghostfolio",
"categories": [
23
],
"date_created": "2025-09-29",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3333,
"documentation": "https://github.com/ghostfolio/ghostfolio?tab=readme-ov-file#self-hosting",
"website": "https://ghostfol.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/ghostfolio.webp",
"config_path": "/opt/ghostfolio/.env",
"description": "Ghostfolio is an open source wealth management software built with web technology. The application empowers busy people to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions.",
"install_methods": [
{
"type": "default",
"script": "ct/ghostfolio.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Create your first user account by visiting the web interface and clicking 'Get Started'. The first user will automatically get admin privileges.",
"type": "info"
},
{
"text": "Database and Redis credentials: `cat ~/ghostfolio.creds`",
"type": "info"
},
{
"text": "Optional: CoinGecko API keys can be added during installation or later in the .env file for enhanced cryptocurrency data.",
"type": "info"
},
{
"text": "Build process requires 4GB RAM (runtime: ~2GB). A temporary swap file will be created automatically if insufficient memory is detected.",
"type": "warning"
}
]
}

View File

@@ -0,0 +1,35 @@
{
"name": "MyIP",
"slug": "myip",
"categories": [
4
],
"date_created": "2025-09-29",
"type": "ct",
"updateable": true,
"privileged": false,
"config_path": "/opt/myip/.env",
"interface_port": 18966,
"documentation": "https://github.com/jason5ng32/MyIP#-environment-variable",
"website": "https://ipcheck.ing/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/myip.webp",
"description": "The best IP Toolbox. Easy to check what's your IPs, IP geolocation, check for DNS leaks, examine WebRTC connections, speed test, ping test, MTR test, check website availability, whois search and more!",
"install_methods": [
{
"type": "default",
"script": "ct/myip.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -0,0 +1,44 @@
{
"name": "PhpMyAdmin",
"slug": "phpmyadmin",
"categories": [
8
],
"date_created": "2025-10-01",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://www.phpmyadmin.net/docs/",
"config_path": "Debian/Ubuntu: /var/www/html/phpMyAdmin | Alpine: /usr/share/phpmyadmin",
"website": "https://www.phpmyadmin.net/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/phpmyadmin.webp",
"description": "phpMyAdmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB. Frequently used operations (managing databases, tables, columns, relations, indexes, users, permissions, etc) can be performed via the user interface, while you still have the ability to directly execute any SQL statement.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/phpmyadmin.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Execute within an existing LXC Console",
"type": "warning"
},
{
"text": "To update or uninstall run bash call again",
"type": "info"
}
]
}

View File

@@ -0,0 +1,40 @@
{
"name": "Verdaccio",
"slug": "verdaccio",
"categories": [
20
],
"date_created": "2025-09-29",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 4873,
"documentation": "https://verdaccio.org/docs/what-is-verdaccio",
"website": "https://verdaccio.org/",
"logo": "https://verdaccio.org/img/logo/symbol/png/verdaccio-tiny.png",
"config_path": "/opt/verdaccio/config/config.yaml",
"description": "Verdaccio is a lightweight private npm proxy registry built with Node.js. It allows you to host your own npm registry with minimal configuration, providing a private npm repository for your projects. Verdaccio supports npm, yarn, and pnpm, and can cache packages from the public npm registry, allowing for faster installs and protection against npm registry outages. It includes a web interface for browsing packages, authentication and authorization features, and can be easily integrated into your development workflow.",
"install_methods": [
{
"type": "default",
"script": "ct/verdaccio.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "To create the first user, run: npm adduser --registry http://<container-ip>:4873",
"type": "info"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
{
"name": "Warracker",
"slug": "warracker",
"categories": [
12
],
"date_created": "2025-09-29",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": null,
"config_path": "/opt/.env",
"website": "https://warracker.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/warracker.webp",
"description": "Warracker is an open source, self-hostable warranty tracker to monitor expirations, store receipts, files. You own the data, your rules!",
"install_methods": [
{
"type": "default",
"script": "ct/warracker.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "The first user you register will be the admin user.",
"type": "info"
}
]
}

View File

@@ -103,18 +103,22 @@ export default function RootLayout({
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
<div className="flex w-full flex-col justify-center">
<Navbar />
<div className="flex min-h-screen flex-col justify-center">
<div className="flex w-full justify-center">
<div className="w-full max-w-[1440px] ">
<QueryProvider>
<NuqsAdapter>{children}</NuqsAdapter>
</QueryProvider>
<Toaster richColors />
<NuqsAdapter>
<QueryProvider>
<Navbar />
<div className="flex min-h-screen flex-col justify-center">
<div className="flex w-full justify-center">
<div className="w-full max-w-[1440px] ">
{children}
<Toaster richColors />
</div>
</div>
<Footer />
</div>
</div>
<Footer />
</div>
</QueryProvider>
</NuqsAdapter>
</div>
</ThemeProvider>
</body>

View File

@@ -27,12 +27,14 @@ export default function ScriptAccordion({
setSelectedScript,
selectedCategory,
setSelectedCategory,
onItemSelect,
}: {
items: Category[];
selectedScript: string | null;
setSelectedScript: (script: string | null) => void;
selectedCategory: string | null;
setSelectedCategory: (category: string | null) => void;
onItemSelect?: () => void;
}) {
const [expandedItem, setExpandedItem] = useState<string | undefined>(undefined);
const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
@@ -77,7 +79,7 @@ export default function ScriptAccordion({
value={expandedItem}
onValueChange={handleAccordionChange}
collapsible
className="overflow-y-scroll max-h-[calc(100vh-225px)] overflow-x-hidden p-2"
className="overflow-y-scroll sm:max-h-[calc(100vh-209px)] overflow-x-hidden p-1"
>
{items.map(category => (
<AccordionItem
@@ -125,6 +127,7 @@ export default function ScriptAccordion({
onClick={() => {
handleSelected(script.slug);
setSelectedCategory(category.name);
onItemSelect?.();
}}
ref={(el) => {
linkRefs.current[script.slug] = el;

View File

@@ -2,21 +2,29 @@
import type { Category, Script } from "@/lib/types";
import { cn } from "@/lib/utils";
import ScriptAccordion from "./script-accordion";
type SidebarProps = {
items: Category[];
selectedScript: string | null;
setSelectedScript: (script: string | null) => void;
selectedCategory: string | null;
setSelectedCategory: (category: string | null) => void;
onItemSelect?: () => void;
className?: string;
};
function Sidebar({
items,
selectedScript,
setSelectedScript,
selectedCategory,
setSelectedCategory,
}: {
items: Category[];
selectedScript: string | null;
setSelectedScript: (script: string | null) => void;
selectedCategory: string | null;
setSelectedCategory: (category: string | null) => void;
}) {
onItemSelect,
className,
}: SidebarProps) {
const uniqueScripts = items.reduce((acc, category) => {
for (const script of category.scripts) {
if (!acc.some(s => s.name === script.name)) {
@@ -27,7 +35,7 @@ function Sidebar({
}, [] as Script[]);
return (
<div className="flex min-w-[350px] flex-col sm:max-w-[350px]">
<div className={cn("flex w-full flex-col sm:min-w-[350px] sm:max-w-[350px]", className)}>
<div className="flex items-end justify-between pb-4">
<h1 className="text-xl font-bold">Categories</h1>
<p className="text-xs italic text-muted-foreground">
@@ -43,6 +51,7 @@ function Sidebar({
setSelectedScript={setSelectedScript}
selectedCategory={selectedCategory}
setSelectedCategory={setSelectedCategory}
onItemSelect={onItemSelect}
/>
</div>
</div>

View File

@@ -1,5 +1,5 @@
"use client";
import { useEffect, useState } from "react";
import { Suspense, useEffect, useState } from "react";
import Image from "next/image";
import Link from "next/link";
@@ -8,6 +8,7 @@ import { navbarLinks } from "@/config/site-config";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
import { GitHubStarsButton } from "./animate-ui/components/buttons/github-stars";
import { Button } from "./animate-ui/components/buttons/button";
import MobileSidebar from "./navigation/mobile-sidebar";
import { ThemeToggle } from "./ui/theme-toggle";
import CommandMenu from "./command-menu";
@@ -30,39 +31,45 @@ function Navbar() {
return (
<>
<div
className={`fixed left-0 top-0 z-50 flex w-screen justify-center px-4 xl:px-0 ${
isScrolled ? "glass border-b bg-background/50" : ""
className={`fixed left-0 top-0 z-50 flex w-screen justify-center px-4 xl:px-0 ${isScrolled ? "glass border-b bg-background/50" : ""
}`}
>
<div className="flex h-20 w-full max-w-[1440px] items-center justify-between sm:flex-row">
<Link
href="/"
className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row"
className="cursor-pointer w-full justify-center sm:justify-start flex-row-reverse hidden sm:flex items-center gap-2 font-semibold sm:flex-row"
>
<Image height={18} unoptimized width={18} alt="logo" src="/ProxmoxVE/logo.png" className="" />
<span className="hidden md:block">Proxmox VE Helper-Scripts</span>
<span className="">Proxmox VE Helper-Scripts</span>
</Link>
<div className="flex gap-2">
<CommandMenu />
<GitHubStarsButton username="community-scripts" repo="ProxmoxVE" />
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
<TooltipProvider key={event}>
<Tooltip delayDuration={100}>
<TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
<Button variant="ghost" size="icon" asChild>
<Link target="_blank" href={href} data-umami-event={event}>
{icon}
<span className="sr-only">{text}</span>
</Link>
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
{text}
</TooltipContent>
</Tooltip>
</TooltipProvider>
))}
<ThemeToggle />
<div className="flex items-center justify-between gap-2 w-full">
<div className="flex sm:hidden">
<Suspense>
<MobileSidebar />
</Suspense>
</div>
<div className="flex sm:gap-2">
<CommandMenu />
<GitHubStarsButton username="community-scripts" repo="ProxmoxVE" className="hidden md:flex" />
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
<TooltipProvider key={event}>
<Tooltip delayDuration={100}>
<TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
<Button variant="ghost" size="icon" asChild>
<Link target="_blank" href={href} data-umami-event={event}>
{icon}
<span className="sr-only">{text}</span>
</Link>
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
{text}
</TooltipContent>
</Tooltip>
</TooltipProvider>
))}
<ThemeToggle />
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,133 @@
"use client";
import { useCallback, useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { useQueryState } from "nuqs";
import { Menu } from "lucide-react";
import type { Category, Script } from "@/lib/types";
import { ScriptItem } from "@/app/scripts/_components/script-item";
import Sidebar from "@/app/scripts/_components/sidebar";
import { fetchCategories } from "@/lib/data";
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "../ui/sheet";
import { Button } from "../ui/button";
function MobileSidebar() {
const [isOpen, setIsOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [categories, setCategories] = useState<Category[]>([]);
const [lastViewedScript, setLastViewedScript] = useState<Script | undefined>(undefined);
const pathname = usePathname();
// Always call the hooks (React hooks can't be conditional)
const [selectedScript, setSelectedScript] = useQueryState("id");
const [selectedCategory, setSelectedCategory] = useQueryState("category");
// For non-scripts pages, we'll manage state locally
const [tempSelectedScript, setTempSelectedScript] = useState<string | null>(null);
const [tempSelectedCategory, setTempSelectedCategory] = useState<string | null>(null);
const isOnScriptsPage = pathname === "/scripts";
const currentSelectedScript = isOnScriptsPage ? selectedScript : tempSelectedScript;
const currentSelectedCategory = isOnScriptsPage ? selectedCategory : tempSelectedCategory;
const loadCategories = useCallback(async () => {
setIsLoading(true);
try {
const response = await fetchCategories();
setCategories(response);
}
catch (error) {
console.error(error);
}
finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
void loadCategories();
}, [loadCategories]);
useEffect(() => {
if (!currentSelectedScript || categories.length === 0) {
return;
}
const scriptMatch = categories
.flatMap(category => category.scripts)
.find(script => script.slug === currentSelectedScript);
setLastViewedScript(scriptMatch);
}, [currentSelectedScript, categories]);
const handleOpenChange = (openState: boolean) => {
setIsOpen(openState);
};
const handleItemSelect = () => {
setIsOpen(false);
};
const hasLinks = categories.length > 0;
return (
<Sheet open={isOpen} onOpenChange={handleOpenChange}>
<SheetTrigger asChild>
<Button
variant="ghost"
size="icon"
aria-label="Open navigation menu"
tabIndex={0}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
setIsOpen(true);
}
}}
>
<Menu className="size-5" aria-hidden="true" />
</Button>
</SheetTrigger>
<SheetHeader className="border-b border-border px-6 pb-4 pt-2 sr-only">
<SheetTitle className="sr-only">Categories</SheetTitle>
</SheetHeader>
<SheetContent side="left" className="flex w-full max-w-xs flex-col gap-4 overflow-hidden px-0 pb-6">
<div className="flex h-full flex-col gap-4 overflow-y-auto">
{isLoading && !hasLinks
? (
<div className="flex w-full flex-col items-center justify-center gap-2 px-6 py-4 text-sm text-muted-foreground">
Loading categories...
</div>
)
: (
<div className="flex flex-col gap-4 px-4">
<Sidebar
items={categories}
selectedScript={currentSelectedScript}
setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
selectedCategory={currentSelectedCategory}
setSelectedCategory={isOnScriptsPage ? setSelectedCategory : setTempSelectedCategory}
onItemSelect={handleItemSelect}
/>
</div>
)}
{currentSelectedScript && lastViewedScript
? (
<div className="flex flex-col gap-3 px-4">
<p className="text-sm font-medium">Last Viewed</p>
<ScriptItem
item={lastViewedScript}
setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
/>
</div>
)
: null}
</div>
</SheetContent>
</Sheet>
);
}
export default MobileSidebar;

View File

@@ -6,7 +6,7 @@ import { Command as CommandPrimitive } from "cmdk";
import { Search } from "lucide-react";
import * as React from "react";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { cn } from "@/lib/utils";
const Command = React.forwardRef<

View File

@@ -1,7 +1,7 @@
import type { Category } from "./types";
export async function fetchCategories() {
const response = await fetch("api/categories");
const response = await fetch(`/ProxmoxVE/api/categories`);
if (!response.ok) {
throw new Error(`Failed to fetch categories: ${response.statusText}`);
}
@@ -10,7 +10,7 @@ export async function fetchCategories() {
}
export async function fetchVersions() {
const response = await fetch(`api/versions`);
const response = await fetch(`/ProxmoxVE/api/versions`);
if (!response.ok) {
throw new Error(`Failed to fetch versions: ${response.statusText}`);
}

View File

@@ -13,7 +13,7 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
$STD apt install -y \
build-essential \
jq \
libcairo2-dev \
@@ -22,7 +22,7 @@ $STD apt-get install -y \
libtool-bin \
libossp-uuid-dev \
libvncserver-dev \
freerdp2-dev \
freerdp3-dev \
libssh2-1-dev \
libtelnet-dev \
libwebsockets-dev \
@@ -56,8 +56,9 @@ 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
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 ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots --disable-guaclog
$STD make
$STD make install
$STD ldconfig
@@ -149,6 +150,6 @@ customize
msg_info "Cleaning up"
rm -rf ~/mysql-connector-j-9.3.0{,.tar.gz}
rm -rf ~/guacamole-auth-jdbc-$RELEASE_SERVER{,.tar.gz}
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt -y autoremove
$STD apt -y autoclean
msg_ok "Cleaned"

View File

@@ -51,7 +51,7 @@ $STD apt-get install -y \
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Setup Python3"
NODE_VERSION="22" setup_nodejs
NODE_VERSION="24" setup_nodejs
msg_info "Installing Change Detection"
mkdir /opt/changedetection
@@ -62,7 +62,7 @@ msg_info "Installing Browserless & Playwright"
mkdir /opt/browserless
$STD python3 -m pip install playwright
$STD git clone https://github.com/browserless/chrome /opt/browserless
$STD npm install --prefix /opt/browserless
$STD npm ci --include=optional --include=dev --prefix /opt/browserless
$STD /opt/browserless/node_modules/playwright-core/cli.js install --with-deps &>/dev/null
$STD /opt/browserless/node_modules/playwright-core/cli.js install --force chrome &>/dev/null
$STD /opt/browserless/node_modules/playwright-core/cli.js install chromium firefox webkit &>/dev/null

View File

@@ -0,0 +1,131 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: lucasfell
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ghostfol.io/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
openssl \
ca-certificates \
redis-server
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
NODE_VERSION="24" setup_nodejs
msg_info "Setting up Database"
DB_NAME=ghostfolio
DB_USER=ghostfolio
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
REDIS_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
ACCESS_TOKEN_SALT=$(openssl rand -base64 32)
JWT_SECRET_KEY=$(openssl rand -base64 32)
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;"
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH ENCRYPTED PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
$STD sudo -u postgres psql -c "ALTER USER $DB_USER CREATEDB;"
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT ALL ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "GRANT CREATE ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_USER;"
$STD sudo -u postgres psql -d $DB_NAME -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_USER;"
{
echo "Ghostfolio Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
echo "Redis Password: $REDIS_PASS"
echo "Access Token Salt: $ACCESS_TOKEN_SALT"
echo "JWT Secret Key: $JWT_SECRET_KEY"
} >>~/ghostfolio.creds
msg_ok "Set up Database"
fetch_and_deploy_gh_release "ghostfolio" "ghostfolio/ghostfolio" "tarball" "latest" "/opt/ghostfolio"
msg_info "Setup Ghostfolio"
sed -i "s/# requirepass foobared/requirepass $REDIS_PASS/" /etc/redis/redis.conf
systemctl restart redis-server
cd /opt/ghostfolio
$STD npm ci
$STD npm run build:production
msg_ok "Built Ghostfolio"
msg_ok "Optional CoinGecko API Configuration"
echo
echo -e "${YW}CoinGecko API keys are optional but provide better cryptocurrency data.${CL}"
echo -e "${YW}You can skip this and add them later by editing /opt/ghostfolio/.env${CL}"
echo
read -rp "${TAB3}CoinGecko Demo API key (press Enter to skip): " COINGECKO_DEMO_KEY
read -rp "${TAB3}CoinGecko Pro API key (press Enter to skip): " COINGECKO_PRO_KEY
msg_info "Setting up Environment"
cat <<EOF >/opt/ghostfolio/.env
DATABASE_URL=postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME?connect_timeout=300&sslmode=prefer
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=$REDIS_PASS
ACCESS_TOKEN_SALT=$ACCESS_TOKEN_SALT
JWT_SECRET_KEY=$JWT_SECRET_KEY
NODE_ENV=production
PORT=3333
HOST=0.0.0.0
EOF
if [[ -n "${COINGECKO_DEMO_KEY:-}" ]]; then
echo "API_KEY_COINGECKO_DEMO=$COINGECKO_DEMO_KEY" >>/opt/ghostfolio/.env
fi
if [[ -n "${COINGECKO_PRO_KEY:-}" ]]; then
echo "API_KEY_COINGECKO_PRO=$COINGECKO_PRO_KEY" >>/opt/ghostfolio/.env
fi
msg_ok "Set up Environment"
msg_info "Running Database Migrations"
cd /opt/ghostfolio
$STD npx prisma migrate deploy
$STD npx prisma db seed
msg_ok "Database Migrations Complete"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/ghostfolio.service
[Unit]
Description=Ghostfolio Investment Tracker
After=network.target postgresql.service redis-server.service
Wants=postgresql.service redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ghostfolio/dist/apps/api
Environment=NODE_ENV=production
EnvironmentFile=/opt/ghostfolio/.env
ExecStart=/usr/bin/node main.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now ghostfolio
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD npm cache clean --force
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -40,7 +40,11 @@ WantedBy=multi-user.target
EOF
systemctl enable -q --now goaway
sleep 10
ADMIN_PASS=$(awk -F': ' '/Randomly generated admin password:/ {print $2}' /var/log/goaway.log | tail -n1)
for i in {1..30}; do
ADMIN_PASS=$(awk -F': ' "/Randomly generated admin password:/ {print \$2; exit}" /var/log/goaway.log)
[ -n "$ADMIN_PASS" ] && break
sleep 1
done
{
echo "GoAway Credentials"
echo "Admin User: admin"

View File

@@ -272,7 +272,7 @@ GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p "$INSTALL_DIR"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v1.143.1" "$SRC_DIR"
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.0.0" "$SRC_DIR"
msg_info "Installing ${APPLICATION} (patience)"
@@ -451,4 +451,5 @@ customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt clean -y
msg_ok "Cleaned"

View File

@@ -22,7 +22,6 @@ $STD apt-get install -y --no-install-recommends \
g++ \
musl-dev \
ffmpeg \
git \
make \
ca-certificates
msg_ok "Installed Dependencies"
@@ -30,25 +29,29 @@ msg_ok "Installed Dependencies"
PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" setup_nodejs
msg_info "Installing Deno"
export DENO_INSTALL="/usr/local"
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
[[ ":$PATH:" != *":/usr/local/bin:"* ]] &&
echo 'export PATH="/usr/local/bin:$PATH"' >>~/.bashrc &&
source ~/.bashrc
msg_ok "Installed Deno"
fetch_and_deploy_gh_release "metube" "alexta69/metube" "tarball" "latest"
msg_info "Installing MeTube"
$STD git clone https://github.com/alexta69/metube /opt/metube
cd /opt/metube/ui
$STD npm install
$STD node_modules/.bin/ng build
cd /opt/metube
$STD uv venv /opt/metube/.venv
$STD /opt/metube/.venv/bin/python -m ensurepip --upgrade
$STD /opt/metube/.venv/bin/python -m pip install --upgrade pip
$STD /opt/metube/.venv/bin/python -m pip install pipenv
$STD /opt/metube/.venv/bin/pipenv install
$STD /opt/metube/.venv/bin/pipenv update yt-dlp
$STD uv sync
mkdir -p /opt/metube_downloads /opt/metube_downloads/.metube /opt/metube_downloads/music /opt/metube_downloads/videos
cat <<EOF >/opt/metube/.env
DOWNLOAD_DIR=/opt/metube_downloads
STATE_DIR=/opt/metube_downloads/.metube
TEMP_DIR=/opt/metube_downloads
YTDL_OPTIONS={"trim_file_name":10}
YTDL_OPTIONS={"trim_file_name":10,"extractor_args":{"youtube":{"player_client":["default","-tv_simply"]}}}
EOF
msg_ok "Installed MeTube"
@@ -62,7 +65,7 @@ After=network.target
Type=simple
WorkingDirectory=/opt/metube
EnvironmentFile=/opt/metube/.env
ExecStart=/opt/metube/.venv/bin/pipenv run python3 app/main.py
ExecStart=/opt/metube/.venv/bin/python3 app/main.py
Restart=always
User=root

54
install/myip-install.sh Normal file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Slaviša Arežina (tremor021)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://ipcheck.ing/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "myip" "jason5ng32/MyIP" "tarball"
msg_info "Configuring MyIP"
cd /opt/myip
cp .env.example .env
$STD npm install
$STD npm run build
msg_ok "Configured MyIP"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/myip.service
[Unit]
Description=MyIP Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/myip
ExecStart=/usr/bin/npm start
EnvironmentFile=/opt/myip/.env
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now myip
msg_ok "Service created"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -15,8 +15,8 @@ update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
redis \
nginx
redis \
nginx
msg_ok "Installed Dependencies"
setup_mariadb
@@ -31,15 +31,15 @@ $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 "Plant-it Credentials"
echo "Plant-it Database User: $DB_USER"
echo "Plant-it Database Password: $DB_PASS"
echo "Plant-it Database Name: $DB_NAME"
echo "Plant-it Credentials"
echo "Plant-it Database User: $DB_USER"
echo "Plant-it Database Password: $DB_PASS"
echo "Plant-it Database Name: $DB_NAME"
} >>~/plant-it.creds
msg_ok "Set up MariaDB"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "latest" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "latest" "/opt/plant-it/frontend" "client.tar.gz"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "0.10.0" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "0.10.0" "/opt/plant-it/frontend" "client.tar.gz"
msg_info "Configured Plant-it"
mkdir -p /opt/plant-it-data

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: BrynnJKnight
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://verdaccio.org/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
ca-certificates \
build-essential
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="verdaccio" setup_nodejs
msg_info "Configuring Verdaccio"
mkdir -p /opt/verdaccio/config
mkdir -p /opt/verdaccio/storage
cat <<EOF >/opt/verdaccio/config/config.yaml
# Verdaccio configuration
storage: /opt/verdaccio/storage
auth:
htpasswd:
file: /opt/verdaccio/storage/htpasswd
max_users: 1000
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
'@*/*':
access: \$all
publish: \$authenticated
proxy: npmjs
'**':
access: \$all
publish: \$authenticated
proxy: npmjs
middlewares:
audit:
enabled: true
logs:
- {type: stdout, format: pretty, level: http}
listen:
- 0.0.0.0:4873
web:
enable: true
title: Verdaccio
gravatar: true
sort_packages: asc
login: true
EOF
chown -R root:root /opt/verdaccio
chmod -R 755 /opt/verdaccio
msg_ok "Configured Verdaccio"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/verdaccio.service
[Unit]
Description=Verdaccio lightweight private npm proxy registry
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/verdaccio --config /opt/verdaccio/config/config.yaml
Restart=on-failure
StandardOutput=journal
StandardError=journal
SyslogIdentifier=verdaccio
KillMode=control-group
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now verdaccio
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

View File

@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: bvdberg01
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/sassanix/Warracker/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
libpq-dev \
nginx
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
PG_VERSION="17" setup_postgresql
msg_info "Setup PostgreSQL"
DB_NAME="warranty_db"
DB_USER="warranty_user"
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
DB_ADMIN_USER="warracker_admin"
DB_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE USER $DB_ADMIN_USER WITH PASSWORD '$DB_ADMIN_PASS' SUPERUSER;"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_ADMIN_USER;"
$STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT USAGE ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d "$DB_NAME" -c "GRANT CREATE ON SCHEMA public TO $DB_USER;"
$STD sudo -u postgres psql -d "$DB_NAME" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO $DB_USER;"
{
echo "Application Credentials"
echo "DB_NAME: $DB_NAME"
echo "DB_USER: $DB_USER"
echo "DB_PASS: $DB_PASS"
echo "DB_ADMIN_USER: $DB_ADMIN_USER"
echo "DB_ADMIN_PASS: $DB_ADMIN_PASS"
} >>~/warracker.creds
msg_ok "Setup PostgreSQL"
fetch_and_deploy_gh_release "warracker" "sassanix/Warracker" "tarball" "latest" "/opt/warracker"
msg_info "Installing Warracker"
cd /opt/warracker/backend
$STD uv venv .venv
$STD source .venv/bin/activate
$STD uv pip install -r requirements.txt
mv /opt/warracker/env.example /opt/.env
sed -i \
-e "s/your_secure_database_password/$DB_PASS/" \
-e "s/your_secure_admin_password/$DB_ADMIN_PASS/" \
-e "s|^# DB_PORT=5432$|DB_HOST=127.0.0.1|" \
-e "s|your_very_secure_flask_secret_key_change_this_in_production|$(openssl rand -base64 32 | tr -d '\n')|" \
/opt/.env
mkdir -p /data/uploads
msg_ok "Installed Warracker"
msg_info "Configuring Nginx"
mv /opt/warracker/nginx.conf /etc/nginx/sites-available/warracker.conf
sed -i \
-e "s|alias /var/www/html/locales/;|alias /opt/warracker/locales/;|" \
-e "s|/var/www/html|/opt/warracker/frontend|g" \
-e "s/client_max_body_size __NGINX_MAX_BODY_SIZE_CONFIG_VALUE__/client_max_body_size 32M/" \
/etc/nginx/sites-available/warracker.conf
ln -s /etc/nginx/sites-available/warracker.conf /etc/nginx/sites-enabled/warracker.conf
rm /etc/nginx/sites-enabled/default
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating systemd services"
cat <<EOF >/etc/systemd/system/warrackermigration.service
[Unit]
Description=Warracker Migration Service
After=network.target
[Service]
Type=oneshot
WorkingDirectory=/opt/warracker/backend/migrations
EnvironmentFile=/opt/.env
ExecStart=/opt/warracker/backend/.venv/bin/python apply_migrations.py
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/warracker.service
[Unit]
Description=Warracker Service
After=network.target warrackermigration.service
Requires=warrackermigration.service
[Service]
WorkingDirectory=/opt/warracker
EnvironmentFile=/opt/.env
ExecStart=/opt/warracker/backend/.venv/bin/gunicorn --config /opt/warracker/backend/gunicorn_config.py backend:create_app() --bind 127.0.0.1:5000
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now warracker
msg_ok "Started Warracker Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt -y autoremove
$STD apt -y autoclean
$STD apt -y clean
msg_ok "Cleaned"

294
tools/addon/phpmyadmin.sh Normal file
View File

@@ -0,0 +1,294 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
function header_info {
clear
cat <<"EOF"
____ __ __ ___ ___ __ _
/ __ \/ /_ ____ / |/ /_ __/ | ____/ /___ ___ (_)___
/ /_/ / __ \/ __ \/ /|_/ / / / / /| |/ __ / __ `__ \/ / __ \
/ ____/ / / / /_/ / / / / /_/ / ___ / /_/ / / / / / / / / / /
/_/ /_/ /_/ .___/_/ /_/\__, /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
/_/ /____/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="phpMyAdmin"
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
[[ -z "$IP" ]] && IP="127.0.0.1"
# Detect OS
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
PKG_MANAGER_INSTALL="apk add --no-cache"
PKG_QUERY="apk info -e"
INSTALL_DIR="$INSTALL_DIR_ALPINE"
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
PKG_MANAGER_INSTALL="apt-get install -y"
PKG_QUERY="dpkg -l"
INSTALL_DIR="$INSTALL_DIR_DEBIAN"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
header_info
function msg_info() { echo -e "${INFO} ${YW}${1}...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}${1}${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}${1}${CL}"; }
function check_internet() {
msg_info "Checking Internet connectivity to GitHub"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://github.com)
if [[ "$HTTP_CODE" -ge 200 && "$HTTP_CODE" -lt 400 ]]; then
msg_ok "Internet connectivity OK"
else
msg_error "Internet connectivity or GitHub unreachable (Status $HTTP_CODE). Exiting."
exit 1
fi
}
function is_phpmyadmin_installed() {
if [[ "$OS" == "Debian" ]]; then
[[ -f "$INSTALL_DIR/config.inc.php" ]]
else
[[ -d "$INSTALL_DIR_ALPINE" ]] && rc-service lighttpd status &>/dev/null
fi
}
function install_php_and_modules() {
msg_info "Checking existing PHP installation"
if command -v php >/dev/null 2>&1; then
PHP_VERSION=$(php -r 'echo PHP_VERSION;')
msg_ok "Found PHP version $PHP_VERSION"
else
msg_info "PHP not found, will install PHP core"
fi
if [[ "$OS" == "Debian" ]]; then
PHP_MODULES=("php" "php-mysqli" "php-mbstring" "php-zip" "php-gd" "php-json" "php-curl")
MISSING_PACKAGES=()
for pkg in "${PHP_MODULES[@]}"; do
if ! dpkg -l | grep -qw "$pkg"; then
MISSING_PACKAGES+=("$pkg")
fi
done
if [[ ${#MISSING_PACKAGES[@]} -gt 0 ]]; then
msg_info "Installing missing PHP packages: ${MISSING_PACKAGES[*]}"
if ! apt-get update &>/dev/null || ! apt-get install -y "${MISSING_PACKAGES[@]}" &>/dev/null; then
msg_error "Failed to install required PHP modules. Exiting."
exit 1
fi
msg_ok "Installed missing PHP packages"
else
msg_ok "All required PHP modules are already installed"
fi
else
msg_info "Installing Lighttpd and PHP for Alpine"
$PKG_MANAGER_INSTALL lighttpd php php-fpm php-session php-json php-mysqli curl tar openssl &>/dev/null
msg_ok "Installed Lighttpd and PHP"
fi
}
function install_phpmyadmin() {
msg_info "Fetching latest phpMyAdmin release from GitHub"
LATEST_VERSION_RAW=$(curl -s https://api.github.com/repos/phpmyadmin/phpmyadmin/releases/latest | grep tag_name | cut -d '"' -f4)
LATEST_VERSION=$(echo "$LATEST_VERSION_RAW" | sed -e 's/^RELEASE_//' -e 's/_/./g')
if [[ -z "$LATEST_VERSION" ]]; then
msg_error "Could not determine latest phpMyAdmin version from GitHub falling back to 5.2.2"
LATEST_VERSION="RELEASE_5_2_2"
fi
msg_ok "Latest version: $LATEST_VERSION"
TARBALL_URL="https://files.phpmyadmin.net/phpMyAdmin/${LATEST_VERSION}/phpMyAdmin-${LATEST_VERSION}-all-languages.tar.gz"
msg_info "Downloading ${TARBALL_URL}"
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
msg_error "Download failed: $TARBALL_URL"
exit 1
fi
mkdir -p "$INSTALL_DIR"
tar xf /tmp/phpmyadmin.tar.gz --strip-components=1 -C "$INSTALL_DIR"
}
function configure_phpmyadmin() {
if [[ "$OS" == "Debian" ]]; then
cp "$INSTALL_DIR/config.sample.inc.php" "$INSTALL_DIR/config.inc.php"
SECRET=$(openssl rand -base64 24)
sed -i "s#\$cfg\['blowfish_secret'\] = '';#\$cfg['blowfish_secret'] = '${SECRET}';#" "$INSTALL_DIR/config.inc.php"
chmod 660 "$INSTALL_DIR/config.inc.php"
chown -R www-data:www-data "$INSTALL_DIR"
systemctl restart apache2
msg_ok "Configured phpMyAdmin with Apache"
else
msg_info "Configuring Lighttpd for phpMyAdmin (Alpine detected)"
mkdir -p /etc/lighttpd
cat <<EOF >/etc/lighttpd/lighttpd.conf
server.modules = (
"mod_access",
"mod_alias",
"mod_accesslog",
"mod_fastcgi"
)
server.document-root = "${INSTALL_DIR}"
server.port = 80
index-file.names = ( "index.php", "index.html" )
fastcgi.server = ( ".php" =>
((
"host" => "127.0.0.1",
"port" => 9000,
"check-local" => "disable"
))
)
alias.url = ( "/phpMyAdmin/" => "${INSTALL_DIR}/" )
accesslog.filename = "/var/log/lighttpd/access.log"
server.errorlog = "/var/log/lighttpd/error.log"
EOF
msg_info "Starting PHP-FPM and Lighttpd"
PHP_VERSION=$(php -r 'echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;')
PHP_FPM_SERVICE="php-fpm${PHP_VERSION}"
if $STD rc-service "$PHP_FPM_SERVICE" start && $STD rc-update add "$PHP_FPM_SERVICE" default; then
msg_ok "Started PHP-FPM service: $PHP_FPM_SERVICE"
else
msg_error "Failed to start PHP-FPM service: $PHP_FPM_SERVICE"
exit 1
fi
$STD rc-service lighttpd start
$STD rc-update add lighttpd default
msg_ok "Configured and started Lighttpd successfully"
fi
}
function uninstall_phpmyadmin() {
msg_info "Stopping Webserver"
if [[ "$OS" == "Debian" ]]; then
systemctl stop apache2
else
$STD rc-service lighttpd stop
$STD rc-service php-fpm stop
fi
msg_info "Removing phpMyAdmin directory"
rm -rf "$INSTALL_DIR"
if [[ "$OS" == "Alpine" ]]; then
msg_info "Removing Lighttpd config"
rm -f /etc/lighttpd/lighttpd.conf
$STD rc-service php-fpm restart
$STD rc-service lighttpd restart
else
$STD systemctl restart apache2
fi
msg_ok "Uninstalled phpMyAdmin"
}
function update_phpmyadmin() {
msg_info "Fetching latest phpMyAdmin release from GitHub"
LATEST_VERSION_RAW=$(curl -s https://api.github.com/repos/phpmyadmin/phpmyadmin/releases/latest | grep tag_name | cut -d '"' -f4)
LATEST_VERSION=$(echo "$LATEST_VERSION_RAW" | sed -e 's/^RELEASE_//' -e 's/_/./g')
if [[ -z "$LATEST_VERSION" ]]; then
msg_error "Could not determine latest phpMyAdmin version from GitHub falling back to 5.2.2"
LATEST_VERSION="5.2.2"
fi
msg_ok "Latest version: $LATEST_VERSION"
TARBALL_URL="https://files.phpmyadmin.net/phpMyAdmin/${LATEST_VERSION}/phpMyAdmin-${LATEST_VERSION}-all-languages.tar.gz"
msg_info "Downloading ${TARBALL_URL}"
if ! curl -fsSL "$TARBALL_URL" -o /tmp/phpmyadmin.tar.gz; then
msg_error "Download failed: $TARBALL_URL"
exit 1
fi
BACKUP_DIR="/tmp/phpmyadmin-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
BACKUP_ITEMS=("config.inc.php" "upload" "save" "tmp" "themes")
msg_info "Backing up existing phpMyAdmin data"
for item in "${BACKUP_ITEMS[@]}"; do
[[ -e "$INSTALL_DIR/$item" ]] && cp -a "$INSTALL_DIR/$item" "$BACKUP_DIR/" && echo " ↪︎ $item"
done
msg_ok "Backup completed: $BACKUP_DIR"
tar xf /tmp/phpmyadmin.tar.gz --strip-components=1 -C "$INSTALL_DIR"
msg_ok "Extracted phpMyAdmin $LATEST_VERSION"
msg_info "Restoring preserved files"
for item in "${BACKUP_ITEMS[@]}"; do
[[ -e "$BACKUP_DIR/$item" ]] && cp -a "$BACKUP_DIR/$item" "$INSTALL_DIR/" && echo " ↪︎ $item restored"
done
msg_ok "Restoration completed"
configure_phpmyadmin
}
if is_phpmyadmin_installed; then
echo -e "${YW}⚠️ ${APP} is already installed at ${INSTALL_DIR}.${CL}"
read -r -p "Would you like to Update (1), Uninstall (2) or Cancel (3)? [1/2/3]: " action
action="${action//[[:space:]]/}"
case "$action" in
1)
check_internet
update_phpmyadmin
;;
2)
uninstall_phpmyadmin
;;
3)
echo -e "${YW}⚠️ Action cancelled. Exiting.${CL}"
exit 0
;;
*)
echo -e "${YW}⚠️ Invalid input. Exiting.${CL}"
exit 1
;;
esac
else
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
install_prompt="${install_prompt//[[:space:]]/}"
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
check_internet
install_php_and_modules
install_phpmyadmin
configure_phpmyadmin
if [[ "$OS" == "Debian" ]]; then
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://${IP}/phpMyAdmin${CL}"
else
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://${IP}/${CL}"
fi
else
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
exit 0
fi
fi

6
tools/headers/phpmyadmin Normal file
View File

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

View File

@@ -530,7 +530,12 @@ msg_ok "Extracted OpenWrt Disk Image ${CL}${BL}$FILE${CL}"
msg_info "Creating OpenWrt VM"
qm create "$VMID" -cores "$CORE_COUNT" -memory "$RAM_SIZE" -name "$HN" \
-onboot 1 -ostype l26 -scsihw virtio-scsi-pci --tablet 0
pvesm alloc "$STORAGE" "$VMID" "vm-$VMID-disk-0" 4M >/dev/null
if [[ "$(pvesm status | awk -v s=$STORAGE '$1==s {print $2}')" == "dir" ]]; then
qm set "$VMID" -efidisk0 "${STORAGE}:0,efitype=4m,size=4M"
else
pvesm alloc "$STORAGE" "$VMID" "vm-$VMID-disk-0" 4M >/dev/null
qm set "$VMID" -efidisk0 "${STORAGE}:vm-$VMID-disk-0,efitype=4m,size=4M"
fi
IMPORT_OUT="$(qm importdisk "$VMID" "$FILE" "$STORAGE" --format raw 2>&1 || true)"
DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p")"