Compare commits

...

132 Commits

Author SHA1 Message Date
Michel Roegl-Brunner
0925e14c26 Fix PBS microcode naming 2026-03-12 16:03:37 +01:00
community-scripts-pr-app[bot]
fd8de10365 Update CHANGELOG.md (#12832)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 15:00:06 +00:00
Michel Roegl-Brunner
9066e318a6 Remove json files (#12830) 2026-03-12 15:59:35 +01:00
community-scripts-pr-app[bot]
56dca9e163 Update CHANGELOG.md (#12826)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 14:24:52 +00:00
Michel Roegl-Brunner
281ebe0e1e Delete Test (#12825)
* Delete ct/test.sh

* Delete install/test-install.sh
2026-03-12 15:24:16 +01:00
community-scripts-pr-app[bot]
36bedd85cc Update CHANGELOG.md (#12824)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 14:22:04 +00:00
push-app-to-main[bot]
ef7badb776 Add test (ct) (#12823)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-03-12 15:21:38 +01:00
community-scripts-pr-app[bot]
2ca6278caf Update CHANGELOG.md (#12820)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 13:30:43 +00:00
community-scripts-pr-app[bot]
0257dafe22 Update CHANGELOG.md (#12819)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 13:30:14 +00:00
Michel Roegl-Brunner
ef942a61c0 Cleanup workflows (#12818)
* Cleanup Workflows

* Cleanup unneded workflows
2026-03-12 14:29:48 +01:00
community-scripts-pr-app[bot]
57b59e8fbd Update CHANGELOG.md (#12817)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 13:20:22 +00:00
ANLO.PO
ee4111f2b0 Fix incorrect port in upstream requests by forwarding original host and port (#12812)
Replace `Host $host` with `Host $http_host` so the upstream application receives the original host including the port (e.g. `manyfold:8081`).
Add `X-Forwarded-Host` and `X-Forwarded-Port` headers to ensure the Rails app generates correct absolute URLs instead of defaulting to port 80 when running behind nginx on a non-standard port.
2026-03-12 14:19:54 +01:00
community-scripts-pr-app[bot]
106f9c5adf Update CHANGELOG.md (#12816)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 13:00:00 +00:00
community-scripts-pr-app[bot]
96920367f8 Update CHANGELOG.md (#12815)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 12:59:43 +00:00
community-scripts-pr-app[bot]
21af1cb143 Update CHANGELOG.md (#12814)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 12:59:33 +00:00
CanbiZ (MickLesk)
bfedeb0277 Cleanup: remove frontend, move JSONs to json/ top-level (#12813) 2026-03-12 13:59:18 +01:00
Chris
abccdef6cb Pin Patchmon to 1.4.2 (#12789) 2026-03-12 13:59:04 +01:00
community-scripts-pr-app[bot]
12bdbcce5c chore: update github-versions.json (#12811)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 12:11:11 +00:00
community-scripts-pr-app[bot]
51418f0d99 Update CHANGELOG.md (#12809)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 11:21:56 +00:00
CanbiZ (MickLesk)
3601388abe core: add mode=generated for unattended frontend installs (#12807) 2026-03-12 12:21:28 +01:00
community-scripts-pr-app[bot]
4189137f55 Update CHANGELOG.md (#12803)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:17:48 +00:00
community-scripts-pr-app[bot]
043401876b Update CHANGELOG.md (#12802)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:17:40 +00:00
community-scripts-pr-app[bot]
543b93ced0 Update CHANGELOG.md (#12801)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:17:22 +00:00
CanbiZ (MickLesk)
dd3b381813 core: validate storage availability when loading defaults (#12794) 2026-03-12 09:17:18 +01:00
CanbiZ (MickLesk)
667efeab5e SparkyFitness: install pnpm dependencies from workspace root (#12792) 2026-03-12 09:16:59 +01:00
community-scripts-pr-app[bot]
4103efd10b Update CHANGELOG.md (#12800)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:11:40 +00:00
CanbiZ (MickLesk)
00be37a151 n8n: add build-essential to update dependencies (#12795) 2026-03-12 09:11:14 +01:00
community-scripts-pr-app[bot]
c9f7453222 Update CHANGELOG.md (#12799)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:09:41 +00:00
semtex1987
7f95652e80 Frigate openvino labelmap patch (#12751)
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-03-12 09:09:12 +01:00
community-scripts-pr-app[bot]
15f6591d4c Update CHANGELOG.md (#12798)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:08:20 +00:00
community-scripts-pr-app[bot]
a530da5760 Update CHANGELOG.md (#12797)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 08:07:56 +00:00
CanbiZ (MickLesk)
cc95ef2987 tools.func: support older NVIDIA driver versions with 2 segments (xxx.xxx) (#12796) 2026-03-12 09:07:49 +01:00
CanbiZ (MickLesk)
38c9421493 tools.func: correct PATH escaping in ROCm profile script (#12793) 2026-03-12 09:07:33 +01:00
community-scripts-pr-app[bot]
5abd9170ba chore: update github-versions.json (#12791)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 06:19:42 +00:00
community-scripts-pr-app[bot]
375e526108 Update CHANGELOG.md (#12788)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 00:19:05 +00:00
community-scripts-pr-app[bot]
eb9013f1ce chore: update github-versions.json (#12787)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-12 00:18:39 +00:00
community-scripts-pr-app[bot]
de9168f6a7 Update CHANGELOG.md (#12785)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 22:19:00 +00:00
CanbiZ (MickLesk)
24a15d2c12 fix: Init telemetry in addon scripts (#12777)
* Init telemetry in addon scripts

Add a guarded call to init_tool_telemetry at the top of multiple tools/addon scripts (if the function is defined) and remove the previous placeholder init_tool_telemetry "" "addon" calls later in the files. This initializes telemetry earlier with the proper tool name and avoids invoking the initializer with an empty name. Affected files include: adguardhome-sync, arcane, coolify, copyparty, cronmaster, dockge, dokploy, immich-public-proxy, jellystat, komodo, nextcloud-exporter, pihole-exporter, prometheus-paperless-ngx-exporter, qbittorrent-exporter, and runtipi.

* Update umbrel-os-vm.sh
2026-03-11 23:18:35 +01:00
community-scripts-pr-app[bot]
a9ebaad37e chore: update github-versions.json (#12781)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 18:18:55 +00:00
Michel Roegl-Brunner
968e96e2c7 Delete removed scripts from pocketbase 2026-03-11 13:37:35 +01:00
community-scripts-pr-app[bot]
02b5c7f7a8 chore: update github-versions.json (#12772)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 12:12:49 +00:00
community-scripts-pr-app[bot]
f1f77e5283 Update CHANGELOG.md (#12769)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 11:03:53 +00:00
Michel Roegl-Brunner
1e726852df Tracearr: Increase default disk variable from 5 to 10 (#12762)
* Increase default disk variable from 5 to 10

* Increase HDD resource allocation from 5 to 10
2026-03-11 12:03:26 +01:00
community-scripts-pr-app[bot]
ba85fad318 Update CHANGELOG.md (#12768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 10:43:43 +00:00
Markus Zellner
6ae5eefdf5 Add -y flag to wgd.sh update command (#12767)
Otherwise script waits, which seems like hanging if called without verbose mode
2026-03-11 11:43:18 +01:00
Michel Roegl-Brunner
b6805bb845 HotFix variable assignment syntax in coder-code-server.sh 2026-03-11 09:29:22 +01:00
community-scripts-pr-app[bot]
3117145e6c Update CHANGELOG.md (#12759)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 07:44:05 +00:00
Michel Roegl-Brunner
c144915a74 Coder-Code-Server: Check if config file exists (#12758)
* Check if config file exists

* Apply suggestion from @tremor021

---------

Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2026-03-11 08:43:42 +01:00
Michel Roegl-Brunner
ad1e207ee1 Add GitHub Actions workflow for Pages redirect 2026-03-11 08:37:46 +01:00
community-scripts-pr-app[bot]
f9cb07ee4c chore: update github-versions.json (#12756)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 06:17:43 +00:00
community-scripts-pr-app[bot]
f5ec5b0e47 Update CHANGELOG.md (#12754)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 00:19:03 +00:00
community-scripts-pr-app[bot]
ba8b85972e chore: update github-versions.json (#12753)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-11 00:18:34 +00:00
community-scripts-pr-app[bot]
766f678321 chore: update github-versions.json (#12749)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 18:17:20 +00:00
CanbiZ (MickLesk)
c69c4afd25 update rybbit link 2026-03-10 16:56:47 +01:00
Michel Roegl-Brunner
516d8d7a0f toggle is_dev to false when a new script gets merged 2026-03-10 16:07:51 +01:00
Michel Roegl-Brunner
a0c93900e9 Remove unnecessary blank line in 2fauth.sh 2026-03-10 15:45:15 +01:00
Michel Roegl-Brunner
a11f282a43 Update workflow 2026-03-10 15:44:28 +01:00
Michel Roegl-Brunner
cac6b4ec59 Check workflow to update date in Pocketbase 2026-03-10 15:39:07 +01:00
Michel Roegl-Brunner
eba96a55d2 New workflow to update last updated field in Database when a script gets changed, also adds last_update_link to link to the latest changes 2026-03-10 15:33:15 +01:00
Michel Roegl-Brunner
37f4585110 New workflow to update last updated field in Database when a script gets changed, also adds last_update_link to link to the latest changes 2026-03-10 15:33:15 +01:00
community-scripts-pr-app[bot]
e6931434b0 Update CHANGELOG.md (#12745)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 14:23:26 +00:00
Chris
eec763bed0 [Fix] Immich: Pin libvips to 8.17.3 (#12744) 2026-03-10 15:22:48 +01:00
community-scripts-pr-app[bot]
fa62363628 chore: update github-versions.json (#12743)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 12:12:48 +00:00
community-scripts-pr-app[bot]
0bbb5a1c74 chore: update github-versions.json (#12741)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 06:15:50 +00:00
community-scripts-pr-app[bot]
064e440d00 Update CHANGELOG.md (#12737)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 00:19:06 +00:00
community-scripts-pr-app[bot]
129b85a8cf chore: update github-versions.json (#12736)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-10 00:18:44 +00:00
community-scripts-pr-app[bot]
586154d4e1 Update CHANGELOG.md (#12734)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 22:27:24 +00:00
Bram
b819231a01 feat: add CopycatWarningToast component for user warnings (#12733)
Introduced a new CopycatWarningToast component that displays a warning about copycat sites. The toast appears at the top-center of the screen and can be dismissed, with the dismissal state stored in local storage to prevent reappearing. Integrated the component into the RootLayout for global visibility.
2026-03-09 23:27:01 +01:00
community-scripts-pr-app[bot]
3ec9eba736 chore: update github-versions.json (#12732)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 18:17:57 +00:00
community-scripts-pr-app[bot]
75d4bc2b61 Update CHANGELOG.md (#12731)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 17:59:58 +00:00
Chris
a5ac56be7a [Hotfix] qBittorrent: Disable UPnP port forwarding by default (#12728) 2026-03-09 18:59:35 +01:00
community-scripts-pr-app[bot]
fe46d8c22d Update CHANGELOG.md (#12730)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 17:39:24 +00:00
Chris
93cbd51d5b [Quickfix] Opencloud: ensure correct case for binary (#12729) 2026-03-09 18:38:58 +01:00
CanbiZ (MickLesk)
0b99873194 Add dependency check for zstd before backup
Ensure zstd dependency is installed before backup.
2026-03-09 18:36:28 +01:00
community-scripts-pr-app[bot]
8113c7da22 Update CHANGELOG.md (#12726)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 16:06:44 +00:00
CanbiZ (MickLesk)
85023dab51 Omada: Bump libssl (#12724) 2026-03-09 17:06:07 +01:00
community-scripts-pr-app[bot]
f8ab3dc4b9 Update CHANGELOG.md (#12722)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 14:23:41 +00:00
Chris
fedabe4889 Pin Opencloud to 5.2.0 (#12721) 2026-03-09 15:23:07 +01:00
community-scripts-pr-app[bot]
eba19d8e42 Update CHANGELOG.md (#12718)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 12:52:21 +00:00
CanbiZ (MickLesk)
e180a3bc44 openwebui: Ensure required dependencies (#12717)
* openwebui: Ensure required dependencies

Added zstd and build-essential as dependencies for the script.

* Update dependencies in openwebui-install.sh

Added build-essential and libmariadb-dev to dependencies.
2026-03-09 13:51:59 +01:00
community-scripts-pr-app[bot]
a1a465708f Update CHANGELOG.md (#12716)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 12:24:37 +00:00
CanbiZ (MickLesk)
346d6c6a0a feat: improve zigbee2mqtt backup handler (#12714)
- Name backups by installed version (e.g. Zigbee2MQTT_backup_2.5.1.tar.zst)
- Use zstd compression instead of gzip
- Keep last 5 backups instead of deleting all previous ones
2026-03-09 13:24:09 +01:00
community-scripts-pr-app[bot]
c76813cbcb chore: update github-versions.json (#12715)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 12:12:25 +00:00
CanbiZ (MickLesk)
e7f551dab6 fix(hwaccel): install ROCm runtime only, reduce disk resize to +4GB
The full 'rocm' meta-package includes 15GB+ of dev tools (compilers,
debuggers, dev headers) which are unnecessary in LXC containers.
Install only runtime packages: rocm-opencl-runtime, rocm-hip-runtime,
rocm-smi-lib. Reduce disk resize from +8GB to +4GB accordingly.
2026-03-09 11:14:26 +01:00
CanbiZ (MickLesk)
d8b2a37228 fix(build): auto-resize disk +8GB when AMD GPU detected for ROCm 2026-03-09 10:18:23 +01:00
community-scripts-pr-app[bot]
af3950fafc Update CHANGELOG.md (#12710)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 09:03:30 +00:00
CanbiZ (MickLesk)
b20bf9c658 tools: add Alpine (apk) support to ensure_dependencies and is_package_installed (#12703) 2026-03-09 10:03:04 +01:00
CanbiZ (MickLesk)
8c5e340ad0 fix(hwaccel): use amdgpu/latest/ubuntu instead of versioned URL 2026-03-09 09:57:28 +01:00
community-scripts-pr-app[bot]
f3cd063816 Update CHANGELOG.md (#12709)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 08:48:16 +00:00
CanbiZ (MickLesk)
5adfa3cb45 Frigate: try an OpenVino model build fallback (#12704)
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-03-09 09:47:50 +01:00
community-scripts-pr-app[bot]
3398fe9361 Update CHANGELOG.md (#12708)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 08:37:47 +00:00
CanbiZ (MickLesk)
2afc25d51f tools.func: extend hwaccel with ROCm (#12707) 2026-03-09 09:37:26 +01:00
CanbiZ (MickLesk)
8c5d5c6679 Downgrade Node.js version from 24 to 22 2026-03-09 09:13:45 +01:00
community-scripts-pr-app[bot]
fca66c5b56 Update CHANGELOG.md (#12706)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 08:05:40 +00:00
CanbiZ (MickLesk)
d38ca1a7fc Reactive Resume: rewrite for v5 using original repo amruthpilla/reactive-resume (#12705)
* fix(reactive-resume): rewrite for v5 using original repo amruthpillai/reactive-resume

Replaces lazy-media fork with original upstream repo (amruthpillai/reactive-resume).
Rewrites install script for v5 architecture:
- TanStack Start / Drizzle ORM single-package build
- Headless Chromium for PDF generation (replaces Browserless)
- Local filesystem storage (removes MinIO dependency)
- Node 24 + pnpm
- Runtime: node .output/server/index.mjs

Fixes #12672, Fixes #11651

* add clean_install
2026-03-09 09:05:14 +01:00
community-scripts-pr-app[bot]
b3bedd720f Update CHANGELOG.md (#12702)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 07:06:16 +00:00
Nícolas Pastorello
b0858920d5 Change cronjob setup to use www-data user (#12695) 2026-03-09 08:05:50 +01:00
community-scripts-pr-app[bot]
e4e365b701 Update CHANGELOG.md (#12701)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 06:35:35 +00:00
Slaviša Arežina
c4315713b5 Fix check_for_gh_release function call (#12694) 2026-03-09 07:35:11 +01:00
community-scripts-pr-app[bot]
047ea2c66d chore: update github-versions.json (#12700)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 06:22:52 +00:00
community-scripts-pr-app[bot]
5e6eb400b5 Update CHANGELOG.md (#12697)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 00:21:57 +00:00
community-scripts-pr-app[bot]
db7880cab5 chore: update github-versions.json (#12696)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-09 00:21:34 +00:00
community-scripts-pr-app[bot]
3909095a2c Update CHANGELOG.md (#12693)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 23:05:51 +00:00
Chris
6685b88695 [Fix] Immich: chown install dir before machine-learning update (#12684) 2026-03-09 00:05:29 +01:00
community-scripts-pr-app[bot]
6076a7ecc7 Update CHANGELOG.md (#12692)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 23:00:50 +00:00
Chris
cc351a4817 [Fix] Scanopy: Build generate-fixtures (#12686) 2026-03-09 00:00:30 +01:00
community-scripts-pr-app[bot]
9217a0fb79 chore: update github-versions.json (#12688)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 18:07:32 +00:00
community-scripts-pr-app[bot]
5abaa2e7e3 Update CHANGELOG.md (#12685)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 15:13:19 +00:00
Slaviša Arežina
c3b8285584 Change slug from 'lxc-execute' to 'execute' (#12681) 2026-03-08 16:12:53 +01:00
community-scripts-pr-app[bot]
bf2667827b Update CHANGELOG.md (#12683)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 14:09:52 +00:00
Tobias
3b7283a13f fix: rustdeskserver: use correct repo string (#12682) 2026-03-08 15:09:28 +01:00
community-scripts-pr-app[bot]
5aaca69e91 Update CHANGELOG.md (#12680)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 12:25:47 +00:00
Slaviša Arežina
8be52ab1ad Fixes (#12675) 2026-03-08 13:25:24 +01:00
community-scripts-pr-app[bot]
447fe2c2e3 chore: update github-versions.json (#12678)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 12:08:17 +00:00
community-scripts-pr-app[bot]
0ecbbdf669 Update .app files (#12661)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-03-08 08:47:53 +01:00
community-scripts-pr-app[bot]
efce5888d7 chore: update github-versions.json (#12668)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 06:14:07 +00:00
community-scripts-pr-app[bot]
ab93083a9d chore: update github-versions.json (#12665)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 00:21:31 +00:00
community-scripts-pr-app[bot]
f757401d65 Update CHANGELOG.md (#12664)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 00:05:04 +00:00
community-scripts-pr-app[bot]
1e5d52098c Archive old changelog entries (#12663)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-08 00:04:39 +00:00
community-scripts-pr-app[bot]
152b703389 Update CHANGELOG.md (#12662)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 22:47:16 +00:00
community-scripts-pr-app[bot]
b0cf05fa5f Update CHANGELOG.md (#12660)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 22:47:00 +00:00
community-scripts-pr-app[bot]
e07f2ff160 Update date in json (#12659)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-03-07 22:46:53 +00:00
push-app-to-main[bot]
2bb60e2cec ImmichFrame (#12653)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: MickLesk <mickey.leskowitz@gmail.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-03-07 23:46:36 +01:00
community-scripts-pr-app[bot]
f0d070b857 Update CHANGELOG.md (#12658)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 21:15:02 +00:00
community-scripts-pr-app[bot]
732de1a5bc Update CHANGELOG.md (#12657)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 21:14:52 +00:00
community-scripts-pr-app[bot]
5d7701275b Update CHANGELOG.md (#12656)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 21:14:39 +00:00
CanbiZ (MickLesk)
8f557e460d fix(grocy): update PHP version from 8.3 to 8.5 (#12651)
Grocy now requires PHP 8.5. Update both the install script and the
update function to use PHP 8.5 instead of 8.3.

Closes #12647
2026-03-07 22:14:29 +01:00
CanbiZ (MickLesk)
148f0121df fix: add interactive GitHub PAT prompt on rate limit / auth failure (#12652)
When a GitHub API call fails with HTTP 401 (invalid token) or HTTP 403
(rate limit exceeded), the user is now prompted interactively to enter a
GitHub Personal Access Token (PAT). The token is validated (no empty
input, no whitespace) before being set and the API call is retried.

This applies to both github_api_call() and fetch_and_deploy_gh_release().

Closes #12615
2026-03-07 22:14:18 +01:00
community-scripts-pr-app[bot]
8eb2e58891 Update CHANGELOG.md (#12655)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 21:13:59 +00:00
community-scripts-pr-app[bot]
3ac7216e63 Update CHANGELOG.md (#12654)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-07 21:13:39 +00:00
CanbiZ (MickLesk)
80f58e1e07 fix(papra): update repository URL to papra-hq/papra (#12650)
The Papra repository moved from CorentinTh/papra to papra-hq/papra.
Update documentation and website URLs in the JSON config to avoid 404s.

Closes #12609
2026-03-07 22:13:34 +01:00
Markus Zellner
5446706286 Check for influxdb3 installation in update_script (#12648)
Fix current check only working for influxdb 1.x and 2.x
2026-03-07 22:13:18 +01:00
676 changed files with 1450 additions and 35862 deletions

183
.github/changelogs/2026/03.md generated vendored Normal file
View File

@@ -0,0 +1,183 @@
## 2026-03-07
### 🆕 New Scripts
- ImmichFrame ([#12653](https://github.com/community-scripts/ProxmoxVE/pull/12653))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grocy: bump PHP version from 8.3 to 8.5 [@MickLesk](https://github.com/MickLesk) ([#12651](https://github.com/community-scripts/ProxmoxVE/pull/12651))
- Check for influxdb3 installation in update_script [@odin568](https://github.com/odin568) ([#12648](https://github.com/community-scripts/ProxmoxVE/pull/12648))
- Update Rdtclient to dotnet 10.0 [@asylumexp](https://github.com/asylumexp) ([#12638](https://github.com/community-scripts/ProxmoxVE/pull/12638))
- fix(immich): fix update script failing to add Debian testing repo when preferences file already exists [@Copilot](https://github.com/Copilot) ([#12631](https://github.com/community-scripts/ProxmoxVE/pull/12631))
### 💾 Core
- #### ✨ New Features
- tools: add interactive GitHub PAT prompt on rate limit / auth failure [@MickLesk](https://github.com/MickLesk) ([#12652](https://github.com/community-scripts/ProxmoxVE/pull/12652))
### 🌐 Website
- #### 📝 Script Information
- Papra: update repository URL to papra-hq/papra [@MickLesk](https://github.com/MickLesk) ([#12650](https://github.com/community-scripts/ProxmoxVE/pull/12650))
## 2026-03-06
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- RustDesk Server: Fix update script [@tremor021](https://github.com/tremor021) ([#12625](https://github.com/community-scripts/ProxmoxVE/pull/12625))
- [Node-RED] Restart service after update [@Aurelien30000](https://github.com/Aurelien30000) ([#12621](https://github.com/community-scripts/ProxmoxVE/pull/12621))
- wealthfolio: update cors [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12617](https://github.com/community-scripts/ProxmoxVE/pull/12617))
- CryptPad: Better update handling [@tremor021](https://github.com/tremor021) ([#12611](https://github.com/community-scripts/ProxmoxVE/pull/12611))
- #### ✨ New Features
- RustDesk Server: Switch to updated repository [@tremor021](https://github.com/tremor021) ([#12083](https://github.com/community-scripts/ProxmoxVE/pull/12083))
- #### 💥 Breaking Changes
- Semaphore: Move from BoltDB to SQLite [@tremor021](https://github.com/tremor021) ([#12624](https://github.com/community-scripts/ProxmoxVE/pull/12624))
## 2026-03-05
### 🆕 New Scripts
- ddclient ([#12587](https://github.com/community-scripts/ProxmoxVE/pull/12587))
- Netbird ([#12585](https://github.com/community-scripts/ProxmoxVE/pull/12585))
- Papra ([#12577](https://github.com/community-scripts/ProxmoxVE/pull/12577))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fluid-calendar: add build-essential to install and update dependencies [@Copilot](https://github.com/Copilot) ([#12602](https://github.com/community-scripts/ProxmoxVE/pull/12602))
- Refactor: BentoPDF [@vhsdream](https://github.com/vhsdream) ([#12597](https://github.com/community-scripts/ProxmoxVE/pull/12597))
- Tianji: Fix the bug introduced by the refactor [@tremor021](https://github.com/tremor021) ([#12564](https://github.com/community-scripts/ProxmoxVE/pull/12564))
- PowerDNS: use 'launch=' instead of 'launch+=' for gsqlite3 backend [@MickLesk](https://github.com/MickLesk) ([#12579](https://github.com/community-scripts/ProxmoxVE/pull/12579))
### 🗑️ Deleted Scripts
- Suwayomi-Server: remove due to inactivity and very low usage [@MickLesk](https://github.com/MickLesk) ([#12596](https://github.com/community-scripts/ProxmoxVE/pull/12596))
### 💾 Core
- #### 🔧 Refactor
- core: add var_os / var_version to whitelist for app.vars [@MickLesk](https://github.com/MickLesk) ([#12576](https://github.com/community-scripts/ProxmoxVE/pull/12576))
## 2026-03-04
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: gitea-mirror [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12549](https://github.com/community-scripts/ProxmoxVE/pull/12549))
- fix(immich): correct LibRaw clone URL to official upstream [@DenislavDenev](https://github.com/DenislavDenev) ([#12526](https://github.com/community-scripts/ProxmoxVE/pull/12526))
- update: stirling-pdf: java 25 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12552](https://github.com/community-scripts/ProxmoxVE/pull/12552))
- Docmost: register NoopAuditService globally when EE submodule is missing [@MickLesk](https://github.com/MickLesk) ([#12551](https://github.com/community-scripts/ProxmoxVE/pull/12551))
- jellyseer/overseer migration corrupting /usr/bin/update [@MickLesk](https://github.com/MickLesk) ([#12539](https://github.com/community-scripts/ProxmoxVE/pull/12539))
- PowerDNS: use gsqlite3 backend instead of BIND [@MickLesk](https://github.com/MickLesk) ([#12538](https://github.com/community-scripts/ProxmoxVE/pull/12538))
- addon migrations: /usr/bin/update replacement to prevent syntax error [@MickLesk](https://github.com/MickLesk) ([#12540](https://github.com/community-scripts/ProxmoxVE/pull/12540))
- #### 🔧 Refactor
- Fluid-Calendar: NodeJS bump [@tremor021](https://github.com/tremor021) ([#12558](https://github.com/community-scripts/ProxmoxVE/pull/12558))
- Refactor: LiteLLM [@tremor021](https://github.com/tremor021) ([#12550](https://github.com/community-scripts/ProxmoxVE/pull/12550))
### 💾 Core
- #### 🐞 Bug Fixes
- tools: fall back to distro packages for psql [@MickLesk](https://github.com/MickLesk) ([#12542](https://github.com/community-scripts/ProxmoxVE/pull/12542))
- fix: whitelist var_searchdomain and fix the handling of var_ns and va… [@tommoyer](https://github.com/tommoyer) ([#12521](https://github.com/community-scripts/ProxmoxVE/pull/12521))
## 2026-03-03
### 🆕 New Scripts
- Tinyauth: v5 Support & add Debian Version [@MickLesk](https://github.com/MickLesk) ([#12501](https://github.com/community-scripts/ProxmoxVE/pull/12501))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- cross-seed: install build-essential to resolve missing `make` error [@Copilot](https://github.com/Copilot) ([#12522](https://github.com/community-scripts/ProxmoxVE/pull/12522))
- meshcentral: increased disk space to 4GB [@MickLesk](https://github.com/MickLesk) ([#12509](https://github.com/community-scripts/ProxmoxVE/pull/12509))
- #### 🔧 Refactor
- opnsense-vm: harden temp dir, bridge detection and network selection [@MickLesk](https://github.com/MickLesk) ([#12513](https://github.com/community-scripts/ProxmoxVE/pull/12513))
### 🗑️ Deleted Scripts
- Remove Unifi Network Server scripts (dead APT repo) [@Copilot](https://github.com/Copilot) ([#12500](https://github.com/community-scripts/ProxmoxVE/pull/12500))
### 💾 Core
- #### ✨ New Features
- core: recovery - add ENOSPC disk-full detection with auto-retry using * 2 hdd [@MickLesk](https://github.com/MickLesk) ([#12511](https://github.com/community-scripts/ProxmoxVE/pull/12511))
### 📚 Documentation
- Fix config_path casing in reactive-resume.json [@ScubyG](https://github.com/ScubyG) ([#12525](https://github.com/community-scripts/ProxmoxVE/pull/12525))
### 🌐 Website
- #### 🐞 Bug Fixes
- Revert #11534 PR that messed up search [@BramSuurdje](https://github.com/BramSuurdje) ([#12492](https://github.com/community-scripts/ProxmoxVE/pull/12492))
## 2026-03-02
### 🆕 New Scripts
- PowerDNS ([#12481](https://github.com/community-scripts/ProxmoxVE/pull/12481))
- Profilarr ([#12441](https://github.com/community-scripts/ProxmoxVE/pull/12441))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Tracearr: prepare for imminent v1.4.19 release [@durzo](https://github.com/durzo) ([#12413](https://github.com/community-scripts/ProxmoxVE/pull/12413))
- #### ✨ New Features
- Frigate: Bump to v0.17 [@MickLesk](https://github.com/MickLesk) ([#12474](https://github.com/community-scripts/ProxmoxVE/pull/12474))
- #### 💥 Breaking Changes
- Migrate: DokPloy, Komodo, Coolify, Dockge, Runtipi to Addons [@MickLesk](https://github.com/MickLesk) ([#12275](https://github.com/community-scripts/ProxmoxVE/pull/12275))
- #### 🔧 Refactor
- ref: replace generic exit 1 with specific exit codes in ct & install [@MickLesk](https://github.com/MickLesk) ([#12475](https://github.com/community-scripts/ProxmoxVE/pull/12475))
### 💾 Core
- #### ✨ New Features
- tools.func: Improve stability with retry logic, caching, and debug mode [@MickLesk](https://github.com/MickLesk) ([#10351](https://github.com/community-scripts/ProxmoxVE/pull/10351))
- #### 🔧 Refactor
- core: standardize exit codes and add mappings [@MickLesk](https://github.com/MickLesk) ([#12467](https://github.com/community-scripts/ProxmoxVE/pull/12467))
### 🌐 Website
- frontend: improve detail view badges, addon texts, and HTML title [@MickLesk](https://github.com/MickLesk) ([#12461](https://github.com/community-scripts/ProxmoxVE/pull/12461))
## 2026-03-01
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Sparkyfitness: use pnpm [@tomfrenzel](https://github.com/tomfrenzel) ([#12445](https://github.com/community-scripts/ProxmoxVE/pull/12445))
- OpenArchiver: Fix installation [@tremor021](https://github.com/tremor021) ([#12447](https://github.com/community-scripts/ProxmoxVE/pull/12447))

View File

@@ -1,68 +0,0 @@
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy as build
ARG TARGETOS
ARG TARGETARCH
ARG DOCKER_VERSION=27.5.1
ARG BUILDX_VERSION=0.20.1
ARG RUNNER_ARCH="x64"
RUN apt update -y && apt install sudo curl unzip -y
WORKDIR /actions-runner
RUN RUNNER_VERSION=$(curl -s https://api.github.com/repos/actions/runner/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
&& curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \
&& tar xzf ./runner.tar.gz \
&& rm runner.tar.gz
RUN RUNNER_CONTAINER_HOOKS_VERSION=$(curl -s https://api.github.com/repos/actions/runner-container-hooks/releases/latest | grep "tag_name" | head -n 1 | awk '{print substr($2, 3, length($2)-4)}') \
&& curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
&& unzip ./runner-container-hooks.zip -d ./k8s \
&& rm runner-container-hooks.zip
RUN export RUNNER_ARCH=${TARGETARCH} \
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
&& curl -fLo docker.tgz https://download.docker.com/${TARGETOS}/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
&& tar zxvf docker.tgz \
&& rm -rf docker.tgz \
&& mkdir -p /usr/local/lib/docker/cli-plugins \
&& curl -fLo /usr/local/lib/docker/cli-plugins/docker-buildx \
"https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-${TARGETARCH}" \
&& chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy
ENV DEBIAN_FRONTEND=noninteractive
ENV RUNNER_MANUALLY_TRAP_SIG=1
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
ENV ImageOS=ubuntu22
RUN apt update -y \
&& apt install -y --no-install-recommends sudo lsb-release gpg-agent software-properties-common curl jq unzip \
&& rm -rf /var/lib/apt/lists/*
RUN add-apt-repository ppa:git-core/ppa \
&& apt update -y \
&& apt install -y git \
&& rm -rf /var/lib/apt/lists/*
RUN adduser --disabled-password --gecos "" --uid 1001 runner \
&& groupadd docker --gid 123 \
&& usermod -aG sudo runner \
&& usermod -aG docker runner \
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \
&& echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers
# Install own dependencies in final image
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
&& apt-get install -y gh jq git
WORKDIR /home/runner
COPY --chown=runner:docker --from=build /actions-runner .
COPY --from=build /usr/local/lib/docker/cli-plugins/docker-buildx /usr/local/lib/docker/cli-plugins/docker-buildx
RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
USER runner

2
.github/workflows/autolabeler.yml generated vendored
View File

@@ -93,7 +93,7 @@ jobs:
const websiteRegex = new RegExp(`- \\[(x|X)\\]\\s*${escapedWebsite}`, "i");
if (websiteRegex.test(prBody)) {
const hasJson = prFiles.some((f) => f.filename.startsWith("frontend/public/json/"));
const hasJson = prFiles.some((f) => f.filename.startsWith("json/"));
const hasUpdateScript = labelsToAdd.has("update script");
const hasContentLabel = ["bugfix", "feature", "refactor"].some((l) => labelsToAdd.has(l));

View File

@@ -1,55 +0,0 @@
name: Auto-Close Wrong Template Issues
on:
issues:
types: [opened]
jobs:
close_tteck_issues:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Auto-close if wrong Template issue detected
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const content = `${issue.title}\n${issue.body}`;
const issueNumber = issue.number;
// Regex patterns (case-insensitive, flexible versioning)
const patterns = [
/Template\s+debian-13-standard_[\d.]+-[\d]+_amd64\.tar\.zst\s*\[(online|local)\]/i,
/Template\s+debian-13-standard_[\d.]+-[\d]+_amd64\.tar\.zst\s+is\s+missing\s+or\s+corrupted/i,
/Container\s+creation\s+failed\.?\s+Checking\s+if\s+template\s+is\s+corrupted\s+or\s+incomplete/i,
/Template\s+is\s+valid,\s+but\s+container\s+creation\s+still\s+failed/i,
/exit\s+code\s+0:\s+while\s+executing\s+command\s+bash\s+-c\s+"\$?\(curl\s+-fsSL\s+https:\/\/raw\.githubusercontent\.com\/[\w/-]+\/create_lxc\.sh\)"/i
];
const matched = patterns.some((regex) => regex.test(content));
if (matched) {
const message = "👋 Hello!\n\n" +
"It looks like you are referencing a **container creation issue with a Debian 13 template** (e.g. `debian-13-standard_13.x-x_amd64.tar.zst`).\n\n" +
"We receive many similar reports about this, and it's not related to the scripts themselves but to **a Proxmox base template bug**.\n\n" +
"Please refer to [discussion #8126](https://github.com/community-scripts/ProxmoxVE/discussions/8126) for details.\n" +
"If your issue persists after following the guidance there, feel free to reopen this issue.\n\n" +
"_This issue was automatically closed by a bot._";
await github.rest.issues.createComment({
...context.repo,
issue_number: issueNumber,
body: message
});
await github.rest.issues.addLabels({
...context.repo,
issue_number: issueNumber,
labels: ["not planned"]
});
await github.rest.issues.update({
...context.repo,
issue_number: issueNumber,
state: "closed"
});
}

View File

@@ -1,126 +0,0 @@
name: Crawl Versions from newreleases.io
on:
workflow_dispatch:
schedule:
# Runs at 12:00 AM and 12:00 PM UTC
- cron: "0 0,12 * * *"
permissions:
contents: write
pull-requests: write
jobs:
crawl-versions:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
repository: community-scripts/ProxmoxVE
ref: main
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Crawl from newreleases.io
env:
token: ${{ secrets.NEWRELEASES_TOKEN }}
run: |
page=1
projects_file="project_json"
output_file="frontend/public/json/versions.json"
echo "[]" > $output_file
while true; do
echo "Start loop on page: $page"
projects=$(curl -s -H "X-Key: $token" "https://api.newreleases.io/v1/projects?page=$page")
total_pages=$(echo "$projects" | jq -r '.total_pages')
if [ -z "$total_pages" ] || [ "$total_pages" -eq 0 ]; then
echo "No pages available. Exiting."
exit 1
fi
if [ $page == $total_pages ]; then
break
fi
if [ -z "$projects" ] || ! echo "$projects" | jq -e '.projects' > /dev/null; then
echo "No more projects or invalid response. Exiting."
break
fi
echo "$projects" > "$projects_file"
jq -r '.projects[] | "\(.id) \(.name)"' "$projects_file" | while read -r id name; do
version=$(curl -s -H "X-Key: $token" "https://api.newreleases.io/v1/projects/$id/latest-release")
version_data=$(echo "$version" | jq -r '.version // empty')
date=$(echo "$version" | jq -r '.date // empty')
if [ -n "$version_data" ]; then
jq --arg name "$name" --arg version "$version_data" --arg date "$date" \
'. += [{"name": $name, "version": $version, "date": $date}]' "$output_file" > "$output_file.tmp" && mv "$output_file.tmp" "$output_file"
fi
done
((page++))
done
- name: Commit JSON
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "GitHub Actions[bot]"
git checkout -b update_versions || git checkout update_versions
git add frontend/public/json/versions.json
if git diff --cached --quiet; then
echo "No changes detected."
echo "changed=false" >> "$GITHUB_ENV"
exit 0
else
echo "Changes detected:"
git diff --stat --cached
echo "changed=true" >> "$GITHUB_ENV"
fi
git commit -m "Update versions.json"
git push origin update_versions --force
gh pr create --title "[Github Action] Update versions.json" --body "Update versions.json, crawled from newreleases.io" --base main --head update_versions --label "automated pr"
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.PAT_AUTOMERGE }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
- name: Re-approve pull request after update
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "update_versions" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi

175
.github/workflows/bak/script-test.yml generated vendored
View File

@@ -1,175 +0,0 @@
name: Run Scripts on PVE Node for testing
permissions:
pull-requests: write
on:
pull_request_target:
branches:
- main
paths:
- "install/**.sh"
- "ct/**.sh"
jobs:
run-install-script:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: pvenode
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Add Git safe directory
run: |
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Get Changed Files
run: |
CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
echo "Changed files: $CHANGED_FILES"
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get scripts
id: check-install-script
run: |
ALL_FILES=()
ADDED_FILES=()
for FILE in ${{ env.SCRIPT }}; do
if [[ $FILE =~ ^install/.*-install\.sh$ ]] || [[ $FILE =~ ^ct/.*\.sh$ ]]; then
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
if [[ ! " ${ADDED_FILES[@]} " =~ " $STRIPPED_NAME " ]]; then
ALL_FILES+=("$FILE")
ADDED_FILES+=("$STRIPPED_NAME") # Mark this base file as added (without the path)
fi
fi
done
ALL_FILES=$(echo "${ALL_FILES[@]}" | xargs)
echo "$ALL_FILES"
echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV
- name: Run scripts
id: run-install
continue-on-error: true
run: |
set +e
#run for each files in /ct
for FILE in ${{ env.ALL_FILES }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
echo "Running Test for: $STRIPPED_NAME"
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "$FILE"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
if [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
CT_SCRIPT="ct/$STRIPPED_NAME.sh"
if [[ ! -f $CT_SCRIPT ]]; then
echo "No CT script found for $STRIPPED_NAME"
ERROR_MSG="No CT script found for $FILE"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
continue
fi
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "install/$STRIPPED_NAME-install.sh"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
echo "Found CT script for $STRIPPED_NAME"
chmod +x "$CT_SCRIPT"
RUNNING_FILE=$CT_SCRIPT
elif [[ $FILE =~ ^ct/.*\.sh$ ]]; then
INSTALL_SCRIPT="install/$STRIPPED_NAME-install.sh"
if [[ ! -f $INSTALL_SCRIPT ]]; then
echo "No install script found for $STRIPPED_NAME"
ERROR_MSG="No install script found for $FILE"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
continue
fi
echo "Found install script for $STRIPPED_NAME"
chmod +x "$INSTALL_SCRIPT"
RUNNING_FILE=$FILE
if grep -E -q 'read\s+-r\s+-p\s+".*"\s+\w+' "ct/$STRIPPED_NAME.sh"; then
echo "The script contains an interactive prompt. Skipping execution."
continue
fi
fi
git remote add community-scripts https://github.com/community-scripts/ProxmoxVE.git
git fetch community-scripts
rm -f .github/workflows/scripts/app-test/pr-build.func || true
rm -f .github/workflows/scripts/app-test/pr-install.func || true
rm -f .github/workflows/scripts/app-test/pr-alpine-install.func || true
rm -f .github/workflows/scripts/app-test/pr-create-lxc.sh || true
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-build.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-install.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-alpine-install.func
git checkout community-scripts/main -- .github/workflows/scripts/app-test/pr-create-lxc.sh
chmod +x $RUNNING_FILE
chmod +x .github/workflows/scripts/app-test/pr-create-lxc.sh
chmod +x .github/workflows/scripts/app-test/pr-install.func
chmod +x .github/workflows/scripts/app-test/pr-alpine-install.func
chmod +x .github/workflows/scripts/app-test/pr-build.func
sed -i 's|source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)|source .github/workflows/scripts/app-test/pr-build.func|g' "$RUNNING_FILE"
echo "Executing $RUNNING_FILE"
ERROR_MSG=$(./$RUNNING_FILE 2>&1 > /dev/null)
echo "Finished running $FILE"
if [ -n "$ERROR_MSG" ]; then
echo "ERROR in $STRIPPED_NAME: $ERROR_MSG"
echo "$ERROR_MSG" > result_$STRIPPED_NAME.log
fi
done
set -e # Restore exit-on-error
- name: Cleanup PVE Node
run: |
containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}' | awk '{print $1}')
for container_id in $containers; do
status=$(pct status $container_id | awk '{print $2}')
if [[ $status == "running" ]]; then
pct stop $container_id
pct destroy $container_id
fi
done
- name: Post error comments
run: |
ERROR="false"
SEARCH_LINE=".github/workflows/scripts/app-test/pr-build.func: line 255:"
# Get all existing comments on the PR
EXISTING_COMMENTS=$(gh pr view ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --json comments --jq '.comments[].body')
for FILE in ${{ env.ALL_FILES }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
if [[ ! -f result_$STRIPPED_NAME.log ]]; then
continue
fi
ERROR_MSG=$(cat result_$STRIPPED_NAME.log)
if [ -n "$ERROR_MSG" ]; then
CLEANED_ERROR_MSG=$(echo "$ERROR_MSG" | sed "s|$SEARCH_LINE.*||")
COMMENT_BODY=":warning: The script _**$FILE**_ failed with the following message: <br> <div><strong>${CLEANED_ERROR_MSG}</strong></div>"
# Check if the comment already exists
if echo "$EXISTING_COMMENTS" | grep -qF "$COMMENT_BODY"; then
echo "Skipping duplicate comment for $FILE"
else
echo "Posting error message for $FILE"
gh pr comment ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--body "$COMMENT_BODY"
ERROR="true"
fi
fi
done
echo "ERROR=$ERROR" >> $GITHUB_ENV

View File

@@ -1,243 +0,0 @@
name: Script Format Check
permissions:
pull-requests: write
on:
pull_request_target:
branches:
- main
paths:
- "install/*.sh"
- "ct/*.sh"
jobs:
run-install-script:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: pvenode
steps:
- name: Checkout PR branch (supports forks)
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
fetch-depth: 0
- name: Add Git safe directory
run: |
git config --global --add safe.directory /__w/ProxmoxVE/ProxmoxVE
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Get Changed Files
run: |
CHANGED_FILES=$(gh pr diff ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --name-only)
CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ')
echo "Changed files: $CHANGED_FILES"
echo "SCRIPT=$CHANGED_FILES" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check scripts
id: run-install
continue-on-error: true
run: |
for FILE in ${{ env.SCRIPT }}; do
STRIPPED_NAME=$(basename "$FILE" | sed 's/-install//' | sed 's/\.sh$//')
echo "Running Test for: $STRIPPED_NAME"
FILE_STRIPPED="${FILE##*/}"
LOG_FILE="result_$FILE_STRIPPED.log"
if [[ $FILE =~ ^ct/.*\.sh$ ]]; then
FIRST_LINE=$(sed -n '1p' "$FILE")
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
SECOND_LINE=$(sed -n '2p' "$FILE")
[[ "$SECOND_LINE" != "source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" ]] &&
echo "Line 2 was $SECOND_LINE | Should be: source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)" >> "$LOG_FILE"
THIRD_LINE=$(sed -n '3p' "$FILE")
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2026 community-scripts ORG" >> "$LOG_FILE"
fi
EXPECTED_AUTHOR="# Author:"
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
EXPECTED_SOURCE="# Source:"
EXPECTED_EMPTY=""
for i in {4..7}; do
LINE=$(sed -n "${i}p" "$FILE")
case $i in
4)
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
;;
5)
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
;;
6)
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
;;
7)
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
;;
esac
done
EXPECTED_PREFIXES=(
"APP="
"var_tags="
"var_cpu=" # Must be a number
"var_ram=" # Must be a number
"var_disk=" # Must be a number
"var_os=" # Must be debian, alpine, or ubuntu
"var_version="
"var_unprivileged=" # Must be 0 or 1
)
for i in {8..15}; do
LINE=$(sed -n "${i}p" "$FILE")
INDEX=$((i - 8))
case $INDEX in
2|3|4) # var_cpu, var_ram, var_disk (must be numbers)
if [[ "$LINE" =~ ^${EXPECTED_PREFIXES[$INDEX]}([0-9]+)$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: '${EXPECTED_PREFIXES[$INDEX]}<NUMBER>'" >> "$LOG_FILE"
fi
;;
5) # var_os (must be debian, alpine, or ubuntu)
if [[ "$LINE" =~ ^var_os=(debian|alpine|ubuntu)$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: 'var_os=[debian|alpine|ubuntu]'" >> "$LOG_FILE"
fi
;;
7) # var_unprivileged (must be 0 or 1)
if [[ "$LINE" =~ ^var_unprivileged=[01]$ ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should be: 'var_unprivileged=[0|1]'" >> "$LOG_FILE"
fi
;;
*) # Other lines (must start with expected prefix)
if [[ "$LINE" == ${EXPECTED_PREFIXES[$INDEX]}* ]]; then
continue # Valid
else
echo "Line $i was '$LINE' | Should start with '${EXPECTED_PREFIXES[$INDEX]}'" >> "$LOG_FILE"
fi
;;
esac
done
for i in {16..20}; do
LINE=$(sed -n "${i}p" "$FILE")
EXPECTED=(
"header_info \"$APP\""
"variables"
"color"
"catch_errors"
"function update_script() {"
)
[[ "$LINE" != "${EXPECTED[$((i-16))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-16))]}" >> "$LOG_FILE"
done
cat "$LOG_FILE"
elif [[ $FILE =~ ^install/.*-install\.sh$ ]]; then
FIRST_LINE=$(sed -n '1p' "$FILE")
[[ "$FIRST_LINE" != "#!/usr/bin/env bash" ]] && echo "Line 1 was $FIRST_LINE | Should be: #!/usr/bin/env bash" >> "$LOG_FILE"
SECOND_LINE=$(sed -n '2p' "$FILE")
[[ -n "$SECOND_LINE" ]] && echo "Line 2 should be empty" >> "$LOG_FILE"
THIRD_LINE=$(sed -n '3p' "$FILE")
if ! [[ "$THIRD_LINE" =~ ^#\ Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ community-scripts\ ORG$ || "$THIRD_LINE" =~ ^Copyright\ \(c\)\ [0-9]{4}-[0-9]{4}\ tteck$ ]]; then
echo "Line 3 was $THIRD_LINE | Should be: # Copyright (c) 2021-2026 community-scripts ORG" >> "$LOG_FILE"
fi
EXPECTED_AUTHOR="# Author:"
EXPECTED_LICENSE="# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE"
EXPECTED_SOURCE="# Source:"
EXPECTED_EMPTY=""
for i in {4..7}; do
LINE=$(sed -n "${i}p" "$FILE")
case $i in
4)
[[ $LINE == $EXPECTED_AUTHOR* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_AUTHOR" >> $LOG_FILE
;;
5)
[[ "$LINE" == "$EXPECTED_LICENSE" ]] || printf "Line %d was: '%s' | Should be: '%s'\n" "$i" "$LINE" "$EXPECTED_LICENSE" >> $LOG_FILE
;;
6)
[[ $LINE == $EXPECTED_SOURCE* ]] || printf "Line %d was: '%s' | Should start with: '%s'\n" "$i" "$LINE" "$EXPECTED_SOURCE" >> $LOG_FILE
;;
7)
[[ -z $LINE ]] || printf "Line %d was: '%s' | Should be empty\n" "$i" "$LINE" >> $LOG_FILE
;;
esac
done
[[ "$(sed -n '8p' "$FILE")" != 'source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' ]] && echo 'Line 8 should be: source /dev/stdin <<< "$FUNCTIONS_FILE_PATH"' >> "$LOG_FILE"
for i in {9..14}; do
LINE=$(sed -n "${i}p" "$FILE")
EXPECTED=(
"color"
"verb_ip6"
"catch_errors"
"setting_up_container"
"network_check"
"update_os"
)
[[ "$LINE" != "${EXPECTED[$((i-9))]}" ]] && echo "Line $i was $LINE | Should be: ${EXPECTED[$((i-9))]}" >> "$LOG_FILE"
done
[[ -n "$(sed -n '15p' "$FILE")" ]] && echo "Line 15 should be empty" >> "$LOG_FILE"
[[ "$(sed -n '16p' "$FILE")" != 'msg_info "Installing Dependencies"' ]] && echo 'Line 16 should be: msg_info "Installing Dependencies"' >> "$LOG_FILE"
LAST_3_LINES=$(tail -n 3 "$FILE")
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoremove"* ]] && echo 'Third to last line should be: $STD apt-get -y autoremove' >> "$LOG_FILE"
[[ "$LAST_3_LINES" != *"$STD apt-get -y autoclean"* ]] && echo 'Second to last line should be: $STD apt-get -y clean' >> "$LOG_FILE"
[[ "$LAST_3_LINES" != *'msg_ok "Cleaned"'* ]] && echo 'Last line should be: msg_ok "Cleaned"' >> "$LOG_FILE"
cat "$LOG_FILE"
fi
done
- name: Post error comments
run: |
ERROR="false"
for FILE in ${{ env.SCRIPT }}; do
FILE_STRIPPED="${FILE##*/}"
LOG_FILE="result_$FILE_STRIPPED.log"
echo $LOG_FILE
if [[ ! -f $LOG_FILE ]]; then
continue
fi
ERROR_MSG=$(cat $LOG_FILE)
if [ -n "$ERROR_MSG" ]; then
echo "Posting error message for $FILE"
echo ${ERROR_MSG}
gh pr comment ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--body ":warning: The script _**$FILE**_ has the following formatting errors: <br> <div><strong>${ERROR_MSG}</strong></div>"
ERROR="true"
fi
done
echo "ERROR=$ERROR" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail if error
if: ${{ env.ERROR == 'true' }}
run: exit 1

View File

@@ -1,158 +0,0 @@
name: Validate filenames
on:
pull_request_target:
paths:
- "ct/*.sh"
- "install/*.sh"
- "frontend/public/json/*.json"
jobs:
check-files:
if: github.repository == 'community-scripts/ProxmoxVE'
name: Check changed files
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Get pull request information
if: github.event_name == 'pull_request_target'
uses: actions/github-script@v7
id: pr
with:
script: |
const { data: pullRequest } = await github.rest.pulls.get({
...context.repo,
pull_number: context.payload.pull_request.number,
});
return pullRequest;
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Ensure the full history is fetched for accurate diffing
ref: ${{ github.event_name == 'pull_request_target' && fromJSON(steps.pr.outputs.result).merge_commit_sha || '' }}
- name: Get changed files
id: changed-files
run: |
if ${{ github.event_name == 'pull_request_target' }}; then
echo "files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ steps.pr.outputs.result && fromJSON(steps.pr.outputs.result).merge_commit_sha }} | xargs)" >> $GITHUB_OUTPUT
else
echo "files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT
fi
- name: "Validate filenames in ct and install directory"
if: always() && steps.changed-files.outputs.files != ''
id: check-scripts
run: |
CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^(ct|install)/.*\.sh$' || true; })
NON_COMPLIANT_FILES=""
for FILE in $CHANGED_FILES; do
BASENAME=$(echo "$(basename "${FILE%.*}")")
if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
fi
done
if [ -n "$NON_COMPLIANT_FILES" ]; then
echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
echo "Non-compliant filenames found, change to lowercase:"
for FILE in $NON_COMPLIANT_FILES; do
echo "$FILE"
done
exit 1
fi
- name: "Validate filenames in json directory."
if: always() && steps.changed-files.outputs.files != ''
id: check-json
run: |
CHANGED_FILES=$(printf "%s\n" ${{ steps.changed-files.outputs.files }} | { grep -E '^json/.*\.json$' || true; })
NON_COMPLIANT_FILES=""
for FILE in $CHANGED_FILES; do
BASENAME=$(echo "$(basename "${FILE%.*}")")
if [[ ! "$BASENAME" =~ ^[a-z0-9-]+$ ]]; then
NON_COMPLIANT_FILES="$NON_COMPLIANT_FILES $FILE"
fi
done
if [ -n "$NON_COMPLIANT_FILES" ]; then
echo "files=$NON_COMPLIANT_FILES" >> $GITHUB_OUTPUT
echo "Non-compliant filenames found, change to lowercase:"
for FILE in $NON_COMPLIANT_FILES; do
echo "$FILE"
done
exit 1
fi
- name: Post results and comment
if: always() && steps.check-scripts.outputs.files != '' && steps.check-json.outputs.files != '' && github.event_name == 'pull_request_target'
uses: actions/github-script@v7
with:
script: |
const result = "${{ job.status }}" === "success" ? "success" : "failure";
const nonCompliantFiles = {
script: "${{ steps.check-scripts.outputs.files }}",
JSON: "${{ steps.check-json.outputs.files }}",
};
const issueNumber = context.payload.pull_request
? context.payload.pull_request.number
: null;
const commentIdentifier = "validate-filenames";
let newCommentBody = `<!-- ${commentIdentifier}-start -->\n### Filename validation\n\n`;
if (result === "failure") {
newCommentBody += ":x: We found issues in the following changed files:\n\n";
for (const [check, files] of Object.entries(nonCompliantFiles)) {
if (files) {
newCommentBody += `**${check.charAt(0).toUpperCase() + check.slice(1)} filename invalid:**\n${files
.trim()
.split(" ")
.map((file) => `- ${file}`)
.join("\n")}\n\n`;
}
}
newCommentBody +=
"Please change the filenames to lowercase and use only alphanumeric characters and dashes.\n";
} else {
newCommentBody += `:rocket: All files passed filename validation!\n`;
}
newCommentBody += `\n\n<!-- ${commentIdentifier}-end -->`;
if (issueNumber) {
const { data: comments } = await github.rest.issues.listComments({
...context.repo,
issue_number: issueNumber,
});
const existingComment = comments.find(
(comment) => comment.user.login === "github-actions[bot]",
);
if (existingComment) {
if (existingComment.body.includes(commentIdentifier)) {
const re = new RegExp(String.raw`<!-- ${commentIdentifier}-start -->[\s\S]*?<!-- ${commentIdentifier}-end -->`, "");
newCommentBody = existingComment.body.replace(re, newCommentBody);
} else {
newCommentBody = existingComment.body + '\n\n---\n\n' + newCommentBody;
}
await github.rest.issues.updateComment({
...context.repo,
comment_id: existingComment.id,
body: newCommentBody,
});
} else {
await github.rest.issues.createComment({
...context.repo,
issue_number: issueNumber,
body: newCommentBody,
});
}
}

View File

@@ -1,164 +0,0 @@
name: Close Discussion on PR Merge
on:
push:
branches:
- main
permissions:
contents: read
discussions: write
jobs:
close-discussion:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set Up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Dependencies
run: npm install zx @octokit/graphql
- name: Close Discussion
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_SHA: ${{ github.sha }}
GITHUB_REPOSITORY: ${{ github.repository }}
run: |
npx zx << 'EOF'
import { graphql } from "@octokit/graphql";
(async function () {
try {
const token = process.env.GITHUB_TOKEN;
const commitSha = process.env.GITHUB_SHA;
const [owner, repo] = process.env.GITHUB_REPOSITORY.split("/");
if (!token || !commitSha || !owner || !repo) {
console.log("Missing required environment variables.");
process.exit(1);
}
const graphqlWithAuth = graphql.defaults({
headers: { authorization: `Bearer ${token}` },
});
// Find PR from commit SHA
const searchQuery = `
query($owner: String!, $repo: String!, $sha: GitObjectID!) {
repository(owner: $owner, name: $repo) {
object(oid: $sha) {
... on Commit {
associatedPullRequests(first: 1) {
nodes {
number
body
}
}
}
}
}
}
`;
const prResult = await graphqlWithAuth(searchQuery, {
owner,
repo,
sha: commitSha,
});
const pr = prResult.repository.object.associatedPullRequests.nodes[0];
if (!pr) {
console.log("No PR found for this commit.");
return;
}
const prNumber = pr.number;
const prBody = pr.body;
const match = prBody.match(/#(\d+)/);
if (!match) {
console.log("No discussion ID found in PR body.");
return;
}
const discussionNumber = match[1];
console.log(`Extracted Discussion Number: ${discussionNumber}`);
// Fetch GraphQL discussion ID
const discussionQuery = `
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
discussion(number: $number) {
id
}
}
}
`;
let discussionQLId;
try {
const discussionResponse = await graphqlWithAuth(discussionQuery, {
owner,
repo,
number: parseInt(discussionNumber, 10),
});
discussionQLId = discussionResponse.repository.discussion.id;
if (!discussionQLId) {
console.log("Failed to fetch discussion GraphQL ID.");
return;
}
} catch (error) {
console.error("Discussion not found or error occurred while fetching discussion:", error);
return;
}
// Post comment
const commentMutation = `
mutation($discussionId: ID!, $body: String!) {
addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
comment { id body }
}
}
`;
const commentResponse = await graphqlWithAuth(commentMutation, {
discussionId: discussionQLId,
body: `Merged with PR #${prNumber}`,
});
const commentId = commentResponse.addDiscussionComment.comment.id;
if (!commentId) {
console.log("Failed to post the comment.");
return;
}
console.log(`Comment Posted Successfully! Comment ID: ${commentId}`);
// Mark comment as answer
const markAnswerMutation = `
mutation($id: ID!) {
markDiscussionCommentAsAnswer(input: { id: $id }) {
discussion { id title }
}
}
`;
await graphqlWithAuth(markAnswerMutation, { id: commentId });
console.log("Comment marked as answer successfully!");
} catch (error) {
console.error("Error:", error);
process.exit(1);
}
})();
EOF

View File

@@ -6,14 +6,14 @@ on:
jobs:
close_issue:
if: github.event.pull_request.merged == true && github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
runs-on: self-hosted
steps:
- name: Checkout target repo (main)
- name: Checkout target repo (merge commit)
uses: actions/checkout@v4
with:
repository: community-scripts/ProxmoxVE
ref: main
ref: ${{ github.event.pull_request.merge_commit_sha }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract and Process PR Title
@@ -23,6 +23,39 @@ jobs:
echo "Processed Title: $title"
echo "title=$title" >> $GITHUB_ENV
- name: Get slugs from merged PR
id: get_slugs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pr_files=$(gh pr view ${{ github.event.pull_request.number }} --repo community-scripts/ProxmoxVE --json files -q '.files[].path' 2>/dev/null || true)
slugs=""
for path in $pr_files; do
[[ -f "$path" ]] || continue
if [[ "$path" == frontend/public/json/*.json ]]; then
s=$(jq -r '.slug // empty' "$path" 2>/dev/null)
[[ -n "$s" ]] && slugs="$slugs $s"
elif [[ "$path" == ct/*.sh ]] || [[ "$path" == install/*.sh ]] || [[ "$path" == tools/*.sh ]] || [[ "$path" == turnkey/*.sh ]] || [[ "$path" == vm/*.sh ]]; then
base=$(basename "$path" .sh)
if [[ "$path" == install/* && "$base" == *-install ]]; then
s="${base%-install}"
else
s="$base"
fi
[[ -n "$s" ]] && slugs="$slugs $s"
fi
done
slugs=$(echo $slugs | xargs -n1 | sort -u | tr '\n' ' ')
if [[ -z "$slugs" && -n "$title" ]]; then
slugs="$title"
fi
if [[ -z "$slugs" ]]; then
echo "count=0" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "$slugs" > pocketbase_slugs.txt
echo "count=$(echo $slugs | wc -w)" >> "$GITHUB_OUTPUT"
- name: Search for Issues with Similar Titles
id: find_issue
env:
@@ -63,3 +96,104 @@ jobs:
run: |
gh issue comment $issue_number --repo community-scripts/ProxmoxVED --body "Merged with #${{ github.event.pull_request.number }} in ProxmoxVE"
gh issue close $issue_number --repo community-scripts/ProxmoxVED
- name: Set is_dev to false in PocketBase
if: steps.get_slugs.outputs.count != '0'
env:
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
PR_URL: ${{ github.server_url }}/${{ github.repository }}/pull/${{ github.event.pull_request.number }}
run: |
node << 'ENDSCRIPT'
(async function() {
const fs = require('fs');
const https = require('https');
const http = require('http');
const url = require('url');
function request(fullUrl, opts) {
return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:';
const body = opts.body;
const options = {
hostname: u.hostname,
port: u.port || (isHttps ? 443 : 80),
path: u.path,
method: opts.method || 'GET',
headers: opts.headers || {}
};
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http;
const req = lib.request(options, function(res) {
let data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
const coll = process.env.POCKETBASE_COLLECTION;
const slugsText = fs.readFileSync('pocketbase_slugs.txt', 'utf8').trim();
const slugs = slugsText ? slugsText.split(/\s+/).filter(Boolean) : [];
if (slugs.length === 0) {
console.log('No slugs to update.');
return;
}
const authUrl = apiBase + '/collections/users/auth-with-password';
const authBody = JSON.stringify({
identity: process.env.POCKETBASE_ADMIN_EMAIL,
password: process.env.POCKETBASE_ADMIN_PASSWORD
});
const authRes = await request(authUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: authBody
});
if (!authRes.ok) {
throw new Error('Auth failed: ' + authRes.body);
}
const token = JSON.parse(authRes.body).token;
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
const prUrl = process.env.PR_URL || '';
for (const slug of slugs) {
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
headers: { 'Authorization': token }
});
const list = JSON.parse(listRes.body);
const record = list.items && list.items[0];
if (!record) {
console.log('Slug not in DB, skipping: ' + slug);
continue;
}
const patchRes = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify({
name: record.name || record.slug,
last_update_commit: prUrl,
is_dev: false
})
});
if (!patchRes.ok) {
console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body);
continue;
}
console.log('Set is_dev=false for slug: ' + slug);
}
console.log('Done.');
})().catch(e => { console.error(e); process.exit(1); });
ENDSCRIPT
shell: bash

View File

@@ -1,38 +0,0 @@
name: Build and Publish Docker Image
on:
push:
branches:
- main
paths:
- '.github/runner/docker/**'
schedule:
- cron: '0 0 * * *'
jobs:
build:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest #To ensure it always builds we use the github runner with all the right tooling
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Log in to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker image
run: |
repo_name=${{ github.repository }} # Get repository name
repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
docker build -t ghcr.io/$repo_name_lower/gh-runner-self:latest -f .github/runner/docker/gh-runner-self.dockerfile .
- name: Push Docker image to GHCR
run: |
repo_name=${{ github.repository }} # Get repository name
repo_name_lower=$(echo $repo_name | tr '[:upper:]' '[:lower:]') # Convert to lowercase
docker push ghcr.io/$repo_name_lower/gh-runner-self:latest

View File

@@ -1,29 +0,0 @@
name: Delete JSON date PR Branch
on:
pull_request:
types: [closed]
branches:
- main
jobs:
delete_branch:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v3
- name: Delete PR Update Branch
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'pr-update-json-')
run: |
PR_BRANCH="${{ github.event.pull_request.head.ref }}"
echo "Deleting branch $PR_BRANCH..."
# Avoid deleting the default branch (e.g., main)
if [[ "$PR_BRANCH" != "main" ]]; then
git push origin --delete "$PR_BRANCH"
else
echo "Skipping deletion of the main branch"
fi

View File

@@ -0,0 +1,150 @@
name: Delete PocketBase entry on script/JSON removal
on:
push:
branches:
- main
paths:
- "json/**"
- "vm/**"
- "tools/**"
- "turnkey/**"
- "ct/**"
- "install/**"
jobs:
delete-pocketbase-entry:
runs-on: self-hosted
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get slugs from deleted JSON and script files
id: slugs
run: |
BEFORE="${{ github.event.before }}"
AFTER="${{ github.event.after }}"
slugs=""
# Deleted JSON files: get slug from previous commit
deleted_json=$(git diff --name-only --diff-filter=D "$BEFORE" "$AFTER" -- json/ | grep '\.json$' || true)
for f in $deleted_json; do
[[ -z "$f" ]] && continue
s=$(git show "$BEFORE:$f" 2>/dev/null | jq -r '.slug // empty' 2>/dev/null || true)
[[ -n "$s" ]] && slugs="$slugs $s"
done
# Deleted script files: derive slug from path
deleted_sh=$(git diff --name-only --diff-filter=D "$BEFORE" "$AFTER" -- ct/ install/ tools/ turnkey/ vm/ | grep '\.sh$' || true)
for f in $deleted_sh; do
[[ -z "$f" ]] && continue
base="${f##*/}"
base="${base%.sh}"
if [[ "$f" == install/* && "$base" == *-install ]]; then
s="${base%-install}"
else
s="$base"
fi
[[ -n "$s" ]] && slugs="$slugs $s"
done
slugs=$(echo $slugs | xargs -n1 | sort -u | tr '\n' ' ')
if [[ -z "$slugs" ]]; then
echo "No deleted JSON or script files to remove from PocketBase."
echo "count=0" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "$slugs" > slugs_to_delete.txt
echo "count=$(echo $slugs | wc -w)" >> "$GITHUB_OUTPUT"
echo "Slugs to delete: $slugs"
- name: Delete from PocketBase
if: steps.slugs.outputs.count != '0'
env:
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
run: |
node << 'ENDSCRIPT'
(async function() {
const fs = require('fs');
const https = require('https');
const http = require('http');
const url = require('url');
function request(fullUrl, opts) {
return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:';
const body = opts.body;
const options = {
hostname: u.hostname,
port: u.port || (isHttps ? 443 : 80),
path: u.path,
method: opts.method || 'GET',
headers: opts.headers || {}
};
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http;
const req = lib.request(options, function(res) {
let data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
const coll = process.env.POCKETBASE_COLLECTION;
const slugs = fs.readFileSync('slugs_to_delete.txt', 'utf8').trim().split(/\s+/).filter(Boolean);
const authUrl = apiBase + '/collections/users/auth-with-password';
const authBody = JSON.stringify({
identity: process.env.POCKETBASE_ADMIN_EMAIL,
password: process.env.POCKETBASE_ADMIN_PASSWORD
});
const authRes = await request(authUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: authBody
});
if (!authRes.ok) {
throw new Error('Auth failed. Response: ' + authRes.body);
}
const token = JSON.parse(authRes.body).token;
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
for (const slug of slugs) {
const filter = "(slug='" + slug + "')";
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
headers: { 'Authorization': token }
});
const list = JSON.parse(listRes.body);
const existingId = list.items && list.items[0] && list.items[0].id;
if (!existingId) {
console.log('No PocketBase record for slug "' + slug + '", skipping.');
continue;
}
const delRes = await request(recordsUrl + '/' + existingId, {
method: 'DELETE',
headers: { 'Authorization': token }
});
if (delRes.ok) {
console.log('Deleted PocketBase record for slug "' + slug + '" (id=' + existingId + ').');
} else {
console.warn('DELETE failed for slug "' + slug + '": ' + delRes.statusCode + ' ' + delRes.body);
}
}
console.log('Done.');
})().catch(e => { console.error(e); process.exit(1); });
ENDSCRIPT
shell: bash

147
.github/workflows/frontend-cicd.yml generated vendored
View File

@@ -1,147 +0,0 @@
# Based on https://github.com/actions/starter-workflows/blob/main/pages/nextjs.yml
name: Frontend CI/CD
on:
push:
branches: ["main"]
paths:
- frontend/**
pull_request:
branches: ["main"]
types: [opened, synchronize, reopened, edited]
paths:
- frontend/**
workflow_dispatch:
permissions:
contents: read
concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: false
jobs:
test-json-files:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Test JSON files
run: |
python3 << 'EOF'
import json
import glob
import os
import sys
def test_json_files():
# Change to the correct directory
json_dir = "public/json"
if not os.path.exists(json_dir):
print(f"❌ Directory not found: {json_dir}")
return False
# Find all JSON files
pattern = os.path.join(json_dir, "*.json")
json_files = glob.glob(pattern)
if not json_files:
print(f"⚠️ No JSON files found in {json_dir}")
return True
print(f"Testing {len(json_files)} JSON files for valid syntax...")
invalid_files = []
for file_path in json_files:
try:
with open(file_path, 'r', encoding='utf-8') as f:
json.load(f)
print(f"✅ Valid JSON: {file_path}")
except json.JSONDecodeError as e:
print(f"❌ Invalid JSON syntax in: {file_path}")
print(f" Error: {e}")
invalid_files.append(file_path)
except Exception as e:
print(f"⚠️ Error reading: {file_path}")
print(f" Error: {e}")
invalid_files.append(file_path)
print("\n=== JSON Validation Summary ===")
print(f"Total files tested: {len(json_files)}")
print(f"Valid files: {len(json_files) - len(invalid_files)}")
print(f"Invalid files: {len(invalid_files)}")
if invalid_files:
print("\n❌ Found invalid JSON file(s):")
for file_path in invalid_files:
print(f" - {file_path}")
return False
else:
print("\n✅ All JSON files have valid syntax!")
return True
if __name__ == "__main__":
success = test_json_files()
sys.exit(0 if success else 1)
EOF
build:
if: github.repository == 'community-scripts/ProxmoxVE'
needs: test-json-files
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Configure Next.js for pages
uses: actions/configure-pages@v5
with:
static_site_generator: next
- name: Build with Next.js
run: bun run build
- name: Upload artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: frontend/out
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' && github.repository == 'community-scripts/ProxmoxVE'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- "frontend/public/json/**"
- "json/**"
jobs:
push-json:
@@ -19,7 +19,7 @@ jobs:
- name: Get changed JSON files with slug
id: changed
run: |
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- frontend/public/json/ | grep '\.json$' || true)
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- json/ | grep '\.json$' || true)
with_slug=""
for f in $changed; do
[[ -f "$f" ]] || continue
@@ -96,7 +96,7 @@ jobs:
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
let categoryIdToName = {};
try {
const metadata = JSON.parse(fs.readFileSync('frontend/public/json/metadata.json', 'utf8'));
const metadata = JSON.parse(fs.readFileSync('json/metadata.json', 'utf8'));
(metadata.categories || []).forEach(function(cat) { categoryIdToName[cat.id] = cat.name; });
} catch (e) { console.warn('Could not load metadata.json:', e.message); }
let typeValueToId = {};

48
.github/workflows/push-to-gitea.yaml generated vendored
View File

@@ -1,48 +0,0 @@
name: Sync to Gitea
on:
push:
branches:
- main
jobs:
sync:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Checkout source repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Change all links to git.community-scripts.org
run: |
echo "Searching for files containing raw.githubusercontent.com URLs..."
# Find all files containing GitHub raw URLs, excluding certain directories
files_with_github_urls=$(grep -r "https://raw.githubusercontent.com/community-scripts/ProxmoxVE" . --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=.github/workflows --files-with-matches || true)
if [ -n "$files_with_github_urls" ]; then
echo "$files_with_github_urls" | while read file; do
if [ -f "$file" ]; then
sed -i 's|https://raw\.githubusercontent\.com/community-scripts/ProxmoxVE/|https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/|g' "$file"
fi
done
else
echo "No files found containing GitHub raw URLs"
fi
- name: Push to Gitea
run: |
git config --global user.name "Push From Github"
git config --global user.email "actions@github.com"
git remote add gitea https://$GITEA_USER:$GITEA_TOKEN@git.community-scripts.org/community-scripts/ProxmoxVE.git
git add .
git commit -m "Sync to Gitea"
git push gitea --all --force
env:
GITEA_USER: ${{ secrets.GITEA_USERNAME }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

View File

@@ -1,85 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local line_number="$1"
local command="$2"
SCRIPT_NAME=$(basename "$0")
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
echo -e "\n$error_message"
exit 0
}
verb_ip6() {
STD=""
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
RETRY_NUM=10
RETRY_EVERY=3
i=$RETRY_NUM
setting_up_container() {
while [ $i -gt 0 ]; do
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" != "" ]; then
break
fi
echo 1>&2 -en "No Network! "
sleep $RETRY_EVERY
i=$((i - 1))
done
if [ "$(ip addr show | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | cut -d'/' -f1)" = "" ]; then
echo 1>&2 -e "\n No Network After $RETRY_NUM Tries"
echo -e "Check Network Settings"
exit 1
fi
msg_ok "Set up Container OS"
msg_ok "Network Connected: $(hostname -i)"
}
network_check() {
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
set -e
}
update_os() {
msg_info "Updating Container OS"
$STD apk -U upgrade
msg_ok "Updated Container OS"
}
motd_ssh() {
return
}
customize() {
return
}

View File

@@ -1,260 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
variables() {
NSAPP=$(echo ${APP,,} | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces.
var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP.
}
NEXTID=$(pvesh get /cluster/nextid)
timezone=$(cat /etc/timezone)
header_info() {
return
}
base_settings() {
# Default Settings
CT_TYPE="1"
DISK_SIZE="4"
CORE_COUNT="1"
RAM_SIZE="1024"
VERBOSE="no"
PW=""
CT_ID=$NEXTID
HN=$NSAPP
BRG="vmbr0"
NET="dhcp"
GATE=""
APT_CACHER=""
APT_CACHER_IP=""
DISABLEIP6="no"
MTU=""
SD=""
NS=""
MAC=""
VLAN=""
SSH="no"
SSH_AUTHORIZED_KEY=""
TAGS="community-script;"
# Override default settings with variables from ct script
CT_TYPE=${var_unprivileged:-$CT_TYPE}
DISK_SIZE=${var_disk:-$DISK_SIZE}
CORE_COUNT=${var_cpu:-$CORE_COUNT}
RAM_SIZE=${var_ram:-$RAM_SIZE}
VERB=${var_verbose:-$VERBOSE}
TAGS="${TAGS}${var_tags:-}"
# Since these 2 are only defined outside of default_settings function, we add a temporary fallback. TODO: To align everything, we should add these as constant variables (e.g. OSTYPE and OSVERSION), but that would currently require updating the default_settings function for all existing scripts
if [ -z "$var_os" ]; then
var_os="debian"
fi
if [ -z "$var_version" ]; then
var_version="12"
fi
}
color() {
# Colors
YW=$(echo "\033[33m")
YWB=$(echo "\033[93m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
# Formatting
CL=$(echo "\033[m")
UL=$(echo "\033[4m")
BOLD=$(echo "\033[1m")
BFR="\\r\\033[K"
HOLD=" "
TAB=" "
# Icons
CM="${TAB}✔️${TAB}${CL}"
CROSS="${TAB}✖️${TAB}${CL}"
INFO="${TAB}💡${TAB}${CL}"
OS="${TAB}🖥️${TAB}${CL}"
OSVERSION="${TAB}🌟${TAB}${CL}"
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
DISKSIZE="${TAB}💾${TAB}${CL}"
CPUCORE="${TAB}🧠${TAB}${CL}"
RAMSIZE="${TAB}🛠️${TAB}${CL}"
SEARCH="${TAB}🔍${TAB}${CL}"
VERIFYPW="${TAB}🔐${TAB}${CL}"
CONTAINERID="${TAB}🆔${TAB}${CL}"
HOSTNAME="${TAB}🏠${TAB}${CL}"
BRIDGE="${TAB}🌉${TAB}${CL}"
NETWORK="${TAB}📡${TAB}${CL}"
GATEWAY="${TAB}🌐${TAB}${CL}"
DISABLEIPV6="${TAB}🚫${TAB}${CL}"
DEFAULT="${TAB}⚙️${TAB}${CL}"
MACADDRESS="${TAB}🔗${TAB}${CL}"
VLANTAG="${TAB}🏷️${TAB}${CL}"
ROOTSSH="${TAB}🔑${TAB}${CL}"
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local line_number="$1"
local command="$2"
SCRIPT_NAME=$(basename "$0")
local error_message="$SCRIPT_NAME: Failure in line $line_number while executing command $command"
echo -e "\n$error_message"
exit 100
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
start() {
base_settings
return
}
build_container() {
# if [ "$VERB" == "yes" ]; then set -x; fi
if [ "$CT_TYPE" == "1" ]; then
FEATURES="keyctl=1,nesting=1"
else
FEATURES="nesting=1"
fi
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if [ "$var_os" == "alpine" ]; then
export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-alpine-install.func)"
else
export FUNCTIONS_FILE_PATH="$(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-install.func)"
fi
export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP"
export tz=""
export DISABLEIPV6="$DISABLEIP6"
export APPLICATION="$APP"
export app="$NSAPP"
export PASSWORD="$PW"
export VERBOSE="$VERB"
export SSH_ROOT="${SSH}"
export SSH_AUTHORIZED_KEY
export CTID="$CT_ID"
export CTTYPE="$CT_TYPE"
export PCT_OSTYPE="$var_os"
export PCT_OSVERSION="$var_version"
export PCT_DISK_SIZE="$DISK_SIZE"
export tz="$timezone"
export PCT_OPTIONS="
-features $FEATURES
-hostname $HN
-tags $TAGS
$SD
$NS
-net0 name=eth0,bridge=$BRG$MAC,ip=$NET$GATE$VLAN$MTU
-onboot 1
-cores $CORE_COUNT
-memory $RAM_SIZE
-unprivileged $CT_TYPE
$PW
"
echo "Container ID: $CTID"
# This executes create_lxc.sh and creates the container and .conf file
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/workflows/scripts/app-test/pr-create-lxc.sh)"
LXC_CONFIG=/etc/pve/lxc/${CTID}.conf
if [ "$CT_TYPE" == "0" ]; then
cat <<EOF >>$LXC_CONFIG
# USB passthrough
lxc.cgroup2.devices.allow: a
lxc.cap.drop:
lxc.cgroup2.devices.allow: c 188:* rwm
lxc.cgroup2.devices.allow: c 189:* rwm
lxc.mount.entry: /dev/serial/by-id dev/serial/by-id none bind,optional,create=dir
lxc.mount.entry: /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file
lxc.mount.entry: /dev/ttyUSB1 dev/ttyUSB1 none bind,optional,create=file
lxc.mount.entry: /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file
lxc.mount.entry: /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file
EOF
fi
if [ "$CT_TYPE" == "0" ]; then
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
lxc.cgroup2.devices.allow: c 29:0 rwm
lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
EOF
fi
else
if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "ErsatzTV" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" || "$APP" == "Ollama" ]]; then
if [[ -e "/dev/dri/renderD128" ]]; then
if [[ -e "/dev/dri/card0" ]]; then
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
dev0: /dev/dri/card0,gid=44
dev1: /dev/dri/renderD128,gid=104
EOF
else
cat <<EOF >>$LXC_CONFIG
# VAAPI hardware transcoding
dev0: /dev/dri/card1,gid=44
dev1: /dev/dri/renderD128,gid=104
EOF
fi
fi
fi
fi
# This starts the container and executes <app>-install.sh
msg_info "Starting LXC Container"
pct start "$CTID"
msg_ok "Started LXC Container"
if [[ ! -f "/root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh" ]]; then
msg_error "No install script found for $APP"
exit 1
fi
if [ "$var_os" == "alpine" ]; then
sleep 3
pct exec "$CTID" -- /bin/sh -c 'cat <<EOF >/etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/latest-stable/main
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
EOF'
pct exec "$CTID" -- ash -c "apk add bash >/dev/null"
fi
lxc-attach -n "$CTID" -- bash -c "$(cat /root/actions-runner/_work/ProxmoxVE/ProxmoxVE/install/$var_install.sh)"
}
description() {
IP=$(pct exec "$CTID" ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1)
}

View File

@@ -1,163 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Eeuo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
# This function handles errors
error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="Failure in line $line_number: exit code $exit_code: while executing command $command"
echo -e "\n$error_message"
exit 100
}
verb_ip6() {
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
VALIDCT=$(pvesm status -content rootdir | awk 'NR>1')
if [ -z "$VALIDCT" ]; then
msg_error "Unable to detect a valid Container Storage location."
exit 1
fi
VALIDTMP=$(pvesm status -content vztmpl | awk 'NR>1')
if [ -z "$VALIDTMP" ]; then
msg_error "Unable to detect a valid Template Storage location."
exit 1
fi
function select_storage() {
local CLASS=$1
local CONTENT
local CONTENT_LABEL
case $CLASS in
container)
CONTENT='rootdir'
CONTENT_LABEL='Container'
;;
template)
CONTENT='vztmpl'
CONTENT_LABEL='Container template'
;;
*) false || {
msg_error "Invalid storage class."
exit 201
} ;;
esac
# This Queries all storage locations
local -a MENU
while read -r line; do
local TAG=$(echo $line | awk '{print $1}')
local TYPE=$(echo $line | awk '{printf "%-10s", $2}')
local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
local ITEM="Type: $TYPE Free: $FREE "
local OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
local MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content $CONTENT | awk 'NR>1')
# Select storage location
if [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]}
else
msg_error "STORAGE ISSUES!"
exit 202
fi
}
[[ "${CTID:-}" ]] || {
msg_error "You need to set 'CTID' variable."
exit 203
}
[[ "${PCT_OSTYPE:-}" ]] || {
msg_error "You need to set 'PCT_OSTYPE' variable."
exit 204
}
# Test if ID is valid
[ "$CTID" -ge "100" ] || {
msg_error "ID cannot be less than 100."
exit 205
}
# Test if ID is in use
if pct status $CTID &>/dev/null; then
echo -e "ID '$CTID' is already in use."
unset CTID
msg_error "Cannot use ID that is already in use."
exit 206
fi
TEMPLATE_STORAGE=$(select_storage template) || exit
CONTAINER_STORAGE=$(select_storage container) || exit
pveam update >/dev/null
TEMPLATE_SEARCH=${PCT_OSTYPE}-${PCT_OSVERSION:-}
mapfile -t TEMPLATES < <(pveam available -section system | sed -n "s/.*\($TEMPLATE_SEARCH.*\)/\1/p" | sort -t - -k 2 -V)
[ ${#TEMPLATES[@]} -gt 0 ] || {
msg_error "Unable to find a template when searching for '$TEMPLATE_SEARCH'."
exit 207
}
TEMPLATE="${TEMPLATES[-1]}"
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
if ! pveam list "$TEMPLATE_STORAGE" | grep -q "$TEMPLATE"; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
{
msg_error "A problem occurred while downloading the LXC template."
exit 208
}
fi
grep -q "root:100000:65536" /etc/subuid || echo "root:100000:65536" >>/etc/subuid
grep -q "root:100000:65536" /etc/subgid || echo "root:100000:65536" >>/etc/subgid
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs "$CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}")
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
[[ -f "$TEMPLATE_PATH" ]] && rm -f "$TEMPLATE_PATH"
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE" >/dev/null ||
{
msg_error "A problem occurred while re-downloading the LXC template."
exit 208
}
if ! pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" "${PCT_OPTIONS[@]}" &>/dev/null; then
msg_error "A problem occurred while trying to create container after re-downloading template."
exit 200
fi
fi

View File

@@ -1,93 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Michel Roegl-Brunner (michelroegl-brunner)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
color() {
return
}
catch_errors() {
set -Euo pipefail
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
}
error_handler() {
local line_number="$1"
local command="$2"
local error_message="Failure in line $line_number while executing command '$command'"
echo -e "\n$error_message\n" >&2
exit 1
}
verb_ip6() {
STD="silent"
silent() {
"$@" >/dev/null 2>&1 || error_handler "${BASH_LINENO[0]}" "$*"
}
return
}
msg_info() {
local msg="$1"
echo -ne "${msg}\n"
}
msg_ok() {
local msg="$1"
echo -e "${msg}\n"
}
msg_error() {
local msg="$1"
echo -e "${msg}\n"
}
RETRY_NUM=10
RETRY_EVERY=3
setting_up_container() {
sed -i "/$LANG/ s/\(^# \)//" /etc/locale.gen
locale_line=$(grep -v '^#' /etc/locale.gen | grep -E '^[a-zA-Z]' | awk '{print $1}' | head -n 1)
echo "LANG=${locale_line}" >/etc/default/locale
locale-gen >/dev/null
export LANG=${locale_line}
echo $tz >/etc/timezone
ln -sf /usr/share/zoneinfo/$tz /etc/localtime
for ((i = RETRY_NUM; i > 0; i--)); do
if [ "$(hostname -I)" != "" ]; then
break
fi
sleep $RETRY_EVERY
done
if [ "$(hostname -I)" = "" ]; then
echo 1>&2 -e "\nNo Network After $RETRY_NUM Tries"
echo -e "Check Network Settings"
exit 101
fi
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
systemctl disable -q --now systemd-networkd-wait-online.service
}
network_check() {
RESOLVEDIP=$(getent hosts github.com | awk '{ print $1 }')
if [[ -z "$RESOLVEDIP" ]]; then msg_error "DNS Lookup Failure"; else msg_ok "DNS Resolved github.com to $RESOLVEDIP"; fi
set -e
}
update_os() {
export DEBIAN_FRONTEND=noninteractive
apt-get update >/dev/null 2>&1
apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade >/dev/null
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
}
motd_ssh() {
return
}
customize() {
return
}

View File

@@ -1,20 +0,0 @@
#!/bin/bash
FILE=$1
TODAY=$(date -u +"%Y-%m-%d")
if [[ -z "$FILE" ]]; then
echo "No file specified. Exiting."
exit 1
fi
if [[ ! -f "$FILE" ]]; then
echo "File $FILE not found. Exiting."
exit 1
fi
DATE_IN_JSON=$(jq -r '.date_created' "$FILE" 2>/dev/null || echo "")
if [[ "$DATE_IN_JSON" != "$TODAY" ]]; then
jq --arg date "$TODAY" '.date_created = $date' "$FILE" >tmp.json && mv tmp.json "$FILE"
fi

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
# Verzeichnis, das die JSON-Dateien enthält
json_dir="./json/*.json"
current_date=$(date +"%Y-%m-%d")
for json_file in $json_dir; do
if [[ -f "$json_file" ]]; then
current_json_date=$(jq -r '.date_created' "$json_file")
if [[ "$current_json_date" != "$current_date" ]]; then
echo "Updating $json_file with date $current_date"
jq --arg date "$current_date" '.date_created = $date' "$json_file" >temp.json && mv temp.json "$json_file"
git add "$json_file"
git commit -m "Update date_created to $current_date in $json_file"
else
echo "Date in $json_file is already up to date."
fi
fi
done
git push origin HEAD

41
.github/workflows/trigger_github_pages_redirect.yml generated vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Pages Redirect
on:
workflow_dispatch:
permissions:
pages: write
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create redirect page
run: |
mkdir site
cat <<EOF > site/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=https://community-scripts.org/">
<link rel="canonical" href="https://community-scripts.org/">
<title>Redirecting...</title>
</head>
<body>
Redirecting...
</body>
</html>
EOF
- uses: actions/upload-pages-artifact@v3
with:
path: site
- name: Deploy
uses: actions/deploy-pages@v4

View File

@@ -1,152 +0,0 @@
name: Update JSON Date
on:
push:
branches:
- main
paths:
- "frontend/public/json/**.json"
workflow_dispatch:
jobs:
update-app-files:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Generate dynamic branch name
id: timestamp
run: echo "BRANCH_NAME=pr-update-json-$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Set up GH_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "GH_TOKEN=${GH_TOKEN}" >> $GITHUB_ENV
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 2 # Ensure we have the last two commits
- name: Get Previous Commit
id: prev_commit
run: |
PREV_COMMIT=$(git rev-parse HEAD^)
echo "Previous commit: $PREV_COMMIT"
echo "prev_commit=$PREV_COMMIT" >> $GITHUB_ENV
- name: Get Newly Added JSON Files
id: new_json_files
run: |
git diff --name-only --diff-filter=A ${{ env.prev_commit }} HEAD | grep '^frontend/public/json/.*\.json$' > new_files.txt || true
echo "New files detected:"
cat new_files.txt || echo "No new files."
- name: Disable file mode changes
run: git config core.fileMode false
- name: Set up Git
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Change JSON Date
id: change-json-date
run: |
current_date=$(date +"%Y-%m-%d")
while IFS= read -r file; do
# Skip empty lines
[[ -z "$file" ]] && continue
if [[ -f "$file" ]]; then
echo "Processing $file..."
current_json_date=$(jq -r '.date_created // empty' "$file")
if [[ -z "$current_json_date" || "$current_json_date" != "$current_date" ]]; then
echo "Updating $file with date $current_date"
jq --arg date "$current_date" '.date_created = $date' "$file" > temp.json && mv temp.json "$file"
else
echo "Date in $file is already up to date."
fi
else
echo "Warning: File $file not found!"
fi
done < new_files.txt
rm new_files.txt
- name: Check if there are any changes
run: |
echo "Checking for changes..."
git add -A
git status
if git diff --cached --quiet; then
echo "No changes detected."
echo "changed=false" >> "$GITHUB_ENV"
else
echo "Changes detected:"
git diff --stat --cached
echo "changed=true" >> "$GITHUB_ENV"
fi
# Step 7: Commit and create PR if changes exist
- name: Commit and create PR if changes exist
if: env.changed == 'true'
run: |
git commit -m "Update date in json"
git checkout -b ${{ env.BRANCH_NAME }}
git push origin ${{ env.BRANCH_NAME }}
gh pr create --title "[core] update date in json" \
--body "This PR is auto-generated by a GitHub Action to update the date in json." \
--head ${{ env.BRANCH_NAME }} \
--base main \
--label "automated pr"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Approve pull request
if: env.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "${{ env.BRANCH_NAME }}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: env.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
run: |
git config --global user.name "github-actions-automege[bot]"
git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi
- name: No changes detected
if: env.changed == 'false'
run: echo "No changes to commit. Workflow completed successfully."

View File

@@ -0,0 +1,167 @@
name: Update script timestamp on .sh changes
on:
push:
branches:
- main
paths:
- "ct/**/*.sh"
- "install/**/*.sh"
- "tools/**/*.sh"
- "turnkey/**/*.sh"
- "vm/**/*.sh"
jobs:
update-script-timestamp:
runs-on: self-hosted
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed .sh files and derive slugs
id: slugs
run: |
changed=$(git diff --name-only "${{ github.event.before }}" "${{ github.event.after }}" -- ct/ install/ tools/ turnkey/ vm/ | grep '\.sh$' || true)
if [[ -z "$changed" ]]; then
echo "No .sh files changed in ct/, install/, tools/, turnkey/, or vm/."
echo "count=0" >> "$GITHUB_OUTPUT"
exit 0
fi
declare -A seen
slugs=""
for f in $changed; do
[[ -f "$f" ]] || continue
base="${f##*/}"
base="${base%.sh}"
if [[ "$f" == install/* && "$base" == *-install ]]; then
slug="${base%-install}"
else
slug="$base"
fi
if [[ -z "${seen[$slug]:-}" ]]; then
seen[$slug]=1
slugs="$slugs $slug"
fi
done
slugs=$(echo $slugs | xargs -n1 | sort -u)
if [[ -z "$slugs" ]]; then
echo "No slugs to update."
echo "count=0" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "$slugs" > changed_slugs.txt
echo "count=$(echo "$slugs" | wc -w)" >> "$GITHUB_OUTPUT"
- name: Parse PR number from merge commit
id: pr
run: |
re='#([0-9]+)'
if [[ "$COMMIT_MSG" =~ $re ]]; then
echo "number=${BASH_REMATCH[1]}" >> "$GITHUB_OUTPUT"
else
echo "number=" >> "$GITHUB_OUTPUT"
fi
env:
COMMIT_MSG: ${{ github.event.head_commit.message }}
- name: Update script timestamps in PocketBase
if: steps.slugs.outputs.count != '0'
env:
POCKETBASE_URL: ${{ secrets.POCKETBASE_URL }}
POCKETBASE_COLLECTION: ${{ secrets.POCKETBASE_COLLECTION }}
POCKETBASE_ADMIN_EMAIL: ${{ secrets.POCKETBASE_ADMIN_EMAIL }}
POCKETBASE_ADMIN_PASSWORD: ${{ secrets.POCKETBASE_ADMIN_PASSWORD }}
COMMIT_URL: ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}
PR_URL: ${{ steps.pr.outputs.number != '' && format('{0}/{1}/pull/{2}', github.server_url, github.repository, steps.pr.outputs.number) || '' }}
run: |
node << 'ENDSCRIPT'
(async function() {
const fs = require('fs');
const https = require('https');
const http = require('http');
const url = require('url');
function request(fullUrl, opts) {
return new Promise(function(resolve, reject) {
const u = url.parse(fullUrl);
const isHttps = u.protocol === 'https:';
const body = opts.body;
const options = {
hostname: u.hostname,
port: u.port || (isHttps ? 443 : 80),
path: u.path,
method: opts.method || 'GET',
headers: opts.headers || {}
};
if (body) options.headers['Content-Length'] = Buffer.byteLength(body);
const lib = isHttps ? https : http;
const req = lib.request(options, function(res) {
let data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, statusCode: res.statusCode, body: data });
});
});
req.on('error', reject);
if (body) req.write(body);
req.end();
});
}
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
const coll = process.env.POCKETBASE_COLLECTION;
const slugsText = fs.readFileSync('changed_slugs.txt', 'utf8').trim();
const slugs = slugsText ? slugsText.split(/\s+/).filter(Boolean) : [];
if (slugs.length === 0) {
console.log('No slugs to update.');
return;
}
const authUrl = apiBase + '/collections/users/auth-with-password';
const authBody = JSON.stringify({
identity: process.env.POCKETBASE_ADMIN_EMAIL,
password: process.env.POCKETBASE_ADMIN_PASSWORD
});
const authRes = await request(authUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: authBody
});
if (!authRes.ok) {
throw new Error('Auth failed: ' + authRes.body);
}
const token = JSON.parse(authRes.body).token;
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
for (const slug of slugs) {
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
headers: { 'Authorization': token }
});
const list = JSON.parse(listRes.body);
const record = list.items && list.items[0];
if (!record) {
console.log('Slug not in DB, skipping: ' + slug);
continue;
}
const patchRes = await request(recordsUrl + '/' + record.id, {
method: 'PATCH',
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
body: JSON.stringify({
name: record.name || record.slug,
last_update_commit: process.env.PR_URL || process.env.COMMIT_URL || ''
})
});
if (!patchRes.ok) {
console.warn('PATCH failed for slug ' + slug + ': ' + patchRes.body);
continue;
}
console.log('Updated timestamp for slug: ' + slug);
}
console.log('Done.');
})().catch(e => { console.error(e); process.exit(1); });
ENDSCRIPT
shell: bash

View File

@@ -1,236 +0,0 @@
name: Update GitHub Versions (New)
on:
workflow_dispatch:
schedule:
# Runs 4x daily: 00:00, 06:00, 12:00, 18:00 UTC
- cron: "0 0,6,12,18 * * *"
permissions:
contents: write
pull-requests: write
env:
VERSIONS_FILE: frontend/public/json/github-versions.json
BRANCH_NAME: automated/update-github-versions
AUTOMATED_PR_LABEL: "automated pr"
jobs:
update-github-versions:
if: github.repository == 'community-scripts/ProxmoxVE'
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: main
- name: Extract GitHub versions from install scripts
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
echo "========================================="
echo " Extracting GitHub versions from scripts"
echo "========================================="
# Initialize versions array
versions_json="[]"
# Function to add a version entry
add_version() {
local slug="$1"
local repo="$2"
local version="$3"
local pinned="$4"
local date="$5"
versions_json=$(echo "$versions_json" | jq \
--arg slug "$slug" \
--arg repo "$repo" \
--arg version "$version" \
--argjson pinned "$pinned" \
--arg date "$date" \
'. += [{"slug": $slug, "repo": $repo, "version": $version, "pinned": $pinned, "date": $date}]')
}
# Get list of slugs from JSON files
echo ""
echo "=== Scanning JSON files for slugs ==="
for json_file in frontend/public/json/*.json; do
[[ ! -f "$json_file" ]] && continue
# Skip non-app JSON files
basename_file=$(basename "$json_file")
case "$basename_file" in
metadata.json|versions.json|github-versions.json|dependency-check.json|update-apps.json)
continue
;;
esac
# Extract slug from JSON
slug=$(jq -r '.slug // empty' "$json_file" 2>/dev/null)
[[ -z "$slug" ]] && continue
# Find corresponding script (install script or addon script)
install_script=""
if [[ -f "install/${slug}-install.sh" ]]; then
install_script="install/${slug}-install.sh"
elif [[ -f "tools/addon/${slug}.sh" ]]; then
install_script="tools/addon/${slug}.sh"
else
continue
fi
# Look for fetch_and_deploy_gh_release calls
# Pattern: fetch_and_deploy_gh_release "app" "owner/repo" ["mode"] ["version"]
while IFS= read -r line; do
# Skip commented lines
[[ "$line" =~ ^[[:space:]]*# ]] && continue
# Extract repo and version from fetch_and_deploy_gh_release
if [[ "$line" =~ fetch_and_deploy_gh_release[[:space:]]+\"[^\"]*\"[[:space:]]+\"([^\"]+)\"([[:space:]]+\"([^\"]+)\")?([[:space:]]+\"([^\"]+)\")? ]]; then
repo="${BASH_REMATCH[1]}"
mode="${BASH_REMATCH[3]:-tarball}"
pinned_version="${BASH_REMATCH[5]:-latest}"
# Check if version is pinned (not "latest" and not empty)
is_pinned=false
target_version=""
if [[ -n "$pinned_version" && "$pinned_version" != "latest" ]]; then
is_pinned=true
target_version="$pinned_version"
fi
# Fetch version from GitHub
if [[ "$is_pinned" == "true" ]]; then
# For pinned versions, verify it exists and get date
response=$(gh api "repos/${repo}/releases/tags/${target_version}" 2>/dev/null || echo '{}')
if echo "$response" | jq -e '.tag_name' > /dev/null 2>&1; then
version=$(echo "$response" | jq -r '.tag_name')
date=$(echo "$response" | jq -r '.published_at // empty')
add_version "$slug" "$repo" "$version" "true" "$date"
echo "[$slug] ✓ $version (pinned)"
else
echo "[$slug] ⚠ pinned version $target_version not found"
fi
else
# Fetch latest release
response=$(gh api "repos/${repo}/releases/latest" 2>/dev/null || echo '{}')
if echo "$response" | jq -e '.tag_name' > /dev/null 2>&1; then
version=$(echo "$response" | jq -r '.tag_name')
date=$(echo "$response" | jq -r '.published_at // empty')
add_version "$slug" "$repo" "$version" "false" "$date"
echo "[$slug] ✓ $version"
else
# Try tags as fallback
version=$(gh api "repos/${repo}/tags" --jq '.[0].name // empty' 2>/dev/null || echo "")
if [[ -n "$version" ]]; then
add_version "$slug" "$repo" "$version" "false" ""
echo "[$slug] ✓ $version (from tags)"
else
echo "[$slug] ⚠ no version found"
fi
fi
fi
break # Only first match per script
fi
done < <(grep 'fetch_and_deploy_gh_release' "$install_script" 2>/dev/null || true)
done
# Save versions file
echo "$versions_json" | jq --arg date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{generated: $date, versions: (. | sort_by(.slug))}' > "$VERSIONS_FILE"
total=$(echo "$versions_json" | jq 'length')
echo ""
echo "========================================="
echo " Total versions extracted: $total"
echo "========================================="
- name: Check for changes
id: check-changes
run: |
# Check if file is new (untracked) or has changes
if [[ ! -f "$VERSIONS_FILE" ]]; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "Versions file was not created"
elif ! git ls-files --error-unmatch "$VERSIONS_FILE" &>/dev/null; then
# File exists but is not tracked - it's new
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "New file created: $VERSIONS_FILE"
elif git diff --quiet "$VERSIONS_FILE" 2>/dev/null; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "No changes detected"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "Changes detected:"
git diff --stat "$VERSIONS_FILE" 2>/dev/null || true
fi
- name: Commit and push changes
if: steps.check-changes.outputs.changed == 'true'
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git add "$VERSIONS_FILE"
git commit -m "chore: update github-versions.json"
git checkout -b $BRANCH_NAME || git checkout $BRANCH_NAME
git push origin $BRANCH_NAME --force
- name: Create pull request if not exists
if: steps.check-changes.outputs.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
PR_EXISTS=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -z "$PR_EXISTS" ]; then
gh pr create --title "[Github Action] Update github-versions.json" \
--body "This PR is auto-generated by a Github Action to update the github-versions.json file." \
--head $BRANCH_NAME \
--base main \
--label "$AUTOMATED_PR_LABEL"
fi
- name: Approve pull request
if: steps.check-changes.outputs.changed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
fi
- name: Approve pull request and merge
if: steps.check-changes.outputs.changed == 'true'
env:
GH_TOKEN: ${{ steps.generate-token-merge.outputs.token }}
run: |
git config --global user.name "github-actions-automege[bot]"
git config --global user.email "github-actions-automege[bot]@users.noreply.github.com"
PR_NUMBER=$(gh pr list --head "${BRANCH_NAME}" --json number --jq '.[].number')
if [ -n "$PR_NUMBER" ]; then
gh pr review $PR_NUMBER --approve
gh pr merge $PR_NUMBER --squash --admin
fi

7
.gitignore vendored
View File

@@ -24,13 +24,6 @@ venv/
env/
*.env
# Node.js dependencies (frontend folder was excluded, but keeping this rule for reference)
frontend/node_modules/
frontend/.svelte-kit/
frontend/.turbo/
frontend/.vite/
frontend/build/
# API and Backend specific exclusions
api/.env
api/__pycache__/

View File

@@ -24,6 +24,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
<details>
<summary><h2>📜 History</h2></summary>
@@ -32,6 +35,13 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
<summary><h3>2026</h3></summary>
<details>
<summary><h4>March (7 entries)</h4></summary>
[View March 2026 Changelog](.github/changelogs/2026/03.md)
</details>
<details>
<summary><h4>February (28 entries)</h4></summary>
@@ -410,15 +420,150 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-03-07
## 2026-03-12
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- manyfold: fix incorrect port in upstream requests by forwarding original host [@anlopo](https://github.com/anlopo) ([#12812](https://github.com/community-scripts/ProxmoxVE/pull/12812))
- SparkyFitness: install pnpm dependencies from workspace root [@MickLesk](https://github.com/MickLesk) ([#12792](https://github.com/community-scripts/ProxmoxVE/pull/12792))
- n8n: add build-essential to update dependencies [@MickLesk](https://github.com/MickLesk) ([#12795](https://github.com/community-scripts/ProxmoxVE/pull/12795))
- Frigate openvino labelmap patch [@semtex1987](https://github.com/semtex1987) ([#12751](https://github.com/community-scripts/ProxmoxVE/pull/12751))
- #### 🔧 Refactor
- Pin Patchmon to 1.4.2 [@vhsdream](https://github.com/vhsdream) ([#12789](https://github.com/community-scripts/ProxmoxVE/pull/12789))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: correct PATH escaping in ROCm profile script [@MickLesk](https://github.com/MickLesk) ([#12793](https://github.com/community-scripts/ProxmoxVE/pull/12793))
- #### ✨ New Features
- core: add mode=generated for unattended frontend installs [@MickLesk](https://github.com/MickLesk) ([#12807](https://github.com/community-scripts/ProxmoxVE/pull/12807))
- core: validate storage availability when loading defaults [@MickLesk](https://github.com/MickLesk) ([#12794](https://github.com/community-scripts/ProxmoxVE/pull/12794))
- #### 🔧 Refactor
- tools.func: support older NVIDIA driver versions with 2 segments (xxx.xxx) [@MickLesk](https://github.com/MickLesk) ([#12796](https://github.com/community-scripts/ProxmoxVE/pull/12796))
### 📂 Github
- Cleanup: remove old workflow files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12818](https://github.com/community-scripts/ProxmoxVE/pull/12818))
- Cleanup: remove frontend, move JSONs to json/ top-level [@MickLesk](https://github.com/MickLesk) ([#12813](https://github.com/community-scripts/ProxmoxVE/pull/12813))
### ❔ Uncategorized
- Remove json files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12830](https://github.com/community-scripts/ProxmoxVE/pull/12830))
## 2026-03-11
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: Init telemetry in addon scripts [@MickLesk](https://github.com/MickLesk) ([#12777](https://github.com/community-scripts/ProxmoxVE/pull/12777))
- Tracearr: Increase default disk variable from 5 to 10 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12762](https://github.com/community-scripts/ProxmoxVE/pull/12762))
- Fix Wireguard Dashboard update [@odin568](https://github.com/odin568) ([#12767](https://github.com/community-scripts/ProxmoxVE/pull/12767))
### 🧰 Tools
- #### ✨ New Features
- Coder-Code-Server: Check if config file exists [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12758](https://github.com/community-scripts/ProxmoxVE/pull/12758))
## 2026-03-10
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [Fix] Immich: Pin libvips to 8.17.3 [@vhsdream](https://github.com/vhsdream) ([#12744](https://github.com/community-scripts/ProxmoxVE/pull/12744))
## 2026-03-09
### 🚀 Updated Scripts
- Pin Opencloud to 5.2.0 [@vhsdream](https://github.com/vhsdream) ([#12721](https://github.com/community-scripts/ProxmoxVE/pull/12721))
- #### 🐞 Bug Fixes
- [Hotfix] qBittorrent: Disable UPnP port forwarding by default [@vhsdream](https://github.com/vhsdream) ([#12728](https://github.com/community-scripts/ProxmoxVE/pull/12728))
- [Quickfix] Opencloud: ensure correct case for binary [@vhsdream](https://github.com/vhsdream) ([#12729](https://github.com/community-scripts/ProxmoxVE/pull/12729))
- Omada: Bump libssl [@MickLesk](https://github.com/MickLesk) ([#12724](https://github.com/community-scripts/ProxmoxVE/pull/12724))
- openwebui: Ensure required dependencies [@MickLesk](https://github.com/MickLesk) ([#12717](https://github.com/community-scripts/ProxmoxVE/pull/12717))
- Frigate: try an OpenVino model build fallback [@MickLesk](https://github.com/MickLesk) ([#12704](https://github.com/community-scripts/ProxmoxVE/pull/12704))
- Change cronjob setup to use www-data user [@opastorello](https://github.com/opastorello) ([#12695](https://github.com/community-scripts/ProxmoxVE/pull/12695))
- RustDesk Server: Fix check_for_gh_release function call [@tremor021](https://github.com/tremor021) ([#12694](https://github.com/community-scripts/ProxmoxVE/pull/12694))
- #### ✨ New Features
- feat: improve zigbee2mqtt backup handler [@MickLesk](https://github.com/MickLesk) ([#12714](https://github.com/community-scripts/ProxmoxVE/pull/12714))
- #### 💥 Breaking Changes
- Reactive Resume: rewrite for v5 using original repo amruthpilla/reactive-resume [@MickLesk](https://github.com/MickLesk) ([#12705](https://github.com/community-scripts/ProxmoxVE/pull/12705))
### 💾 Core
- #### ✨ New Features
- tools: add Alpine (apk) support to ensure_dependencies and is_package_installed [@MickLesk](https://github.com/MickLesk) ([#12703](https://github.com/community-scripts/ProxmoxVE/pull/12703))
- tools.func: extend hwaccel with ROCm [@MickLesk](https://github.com/MickLesk) ([#12707](https://github.com/community-scripts/ProxmoxVE/pull/12707))
### 🌐 Website
- #### ✨ New Features
- feat: add CopycatWarningToast component for user warnings [@BramSuurdje](https://github.com/BramSuurdje) ([#12733](https://github.com/community-scripts/ProxmoxVE/pull/12733))
## 2026-03-08
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [Fix] Immich: chown install dir before machine-learning update [@vhsdream](https://github.com/vhsdream) ([#12684](https://github.com/community-scripts/ProxmoxVE/pull/12684))
- [Fix] Scanopy: Build generate-fixtures [@vhsdream](https://github.com/vhsdream) ([#12686](https://github.com/community-scripts/ProxmoxVE/pull/12686))
- fix: rustdeskserver: use correct repo string [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12682](https://github.com/community-scripts/ProxmoxVE/pull/12682))
- NZBGet: Fixes for RAR5 handling [@tremor021](https://github.com/tremor021) ([#12675](https://github.com/community-scripts/ProxmoxVE/pull/12675))
### 🌐 Website
- #### 🐞 Bug Fixes
- LXC-Execute: Fix slug [@tremor021](https://github.com/tremor021) ([#12681](https://github.com/community-scripts/ProxmoxVE/pull/12681))
## 2026-03-07
### 🆕 New Scripts
- ImmichFrame ([#12653](https://github.com/community-scripts/ProxmoxVE/pull/12653))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grocy: bump PHP version from 8.3 to 8.5 [@MickLesk](https://github.com/MickLesk) ([#12651](https://github.com/community-scripts/ProxmoxVE/pull/12651))
- Check for influxdb3 installation in update_script [@odin568](https://github.com/odin568) ([#12648](https://github.com/community-scripts/ProxmoxVE/pull/12648))
- Update Rdtclient to dotnet 10.0 [@asylumexp](https://github.com/asylumexp) ([#12638](https://github.com/community-scripts/ProxmoxVE/pull/12638))
- fix(immich): fix update script failing to add Debian testing repo when preferences file already exists [@Copilot](https://github.com/Copilot) ([#12631](https://github.com/community-scripts/ProxmoxVE/pull/12631))
### 💾 Core
- #### ✨ New Features
- tools: add interactive GitHub PAT prompt on rate limit / auth failure [@MickLesk](https://github.com/MickLesk) ([#12652](https://github.com/community-scripts/ProxmoxVE/pull/12652))
### 🌐 Website
- #### 📝 Script Information
- Papra: update repository URL to papra-hq/papra [@MickLesk](https://github.com/MickLesk) ([#12650](https://github.com/community-scripts/ProxmoxVE/pull/12650))
## 2026-03-06
### 🚀 Updated Scripts
@@ -1300,217 +1445,4 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
### ❔ Uncategorized
- Opencloud: fix JSON [@vhsdream](https://github.com/vhsdream) ([#11617](https://github.com/community-scripts/ProxmoxVE/pull/11617))
## 2026-02-05
### 🆕 New Scripts
- OpenCloud ([#11538](https://github.com/community-scripts/ProxmoxVE/pull/11538))
- Nginx-UI ([#11573](https://github.com/community-scripts/ProxmoxVE/pull/11573))
- New: SQL-Server 2025 | Refactor SQL-Server 2022 [@MickLesk](https://github.com/MickLesk) ([#11546](https://github.com/community-scripts/ProxmoxVE/pull/11546))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- OpenCloud: pin version to 5.0.2; Collabora CSP fix [@vhsdream](https://github.com/vhsdream) ([#11585](https://github.com/community-scripts/ProxmoxVE/pull/11585))
- Wanderer: Fix repo [@tremor021](https://github.com/tremor021) ([#11567](https://github.com/community-scripts/ProxmoxVE/pull/11567))
- #### ✨ New Features
- Refactor: Docker-VM (Multi-OS / Cloud-Init / Stabilization) [@MickLesk](https://github.com/MickLesk) ([#9047](https://github.com/community-scripts/ProxmoxVE/pull/9047))
### 💾 Core
- #### ✨ New Features
- cloud-init: add interactive SSH key discovery and selection [@MickLesk](https://github.com/MickLesk) ([#11547](https://github.com/community-scripts/ProxmoxVE/pull/11547))
### 📚 Documentation
- github: extend docs / contribution / templates [@MickLesk](https://github.com/MickLesk) ([#10921](https://github.com/community-scripts/ProxmoxVE/pull/10921))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): theme respective syntax highlighting [@ls-root](https://github.com/ls-root) ([#11565](https://github.com/community-scripts/ProxmoxVE/pull/11565))
## 2026-02-04
### 🆕 New Scripts
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
### 🚀 Updated Scripts
- Add log directory and permissions for koillection [@shineangelic](https://github.com/shineangelic) ([#11553](https://github.com/community-scripts/ProxmoxVE/pull/11553))
- #### 🐞 Bug Fixes
- [FIX] Scanopy: ensure Scanopy Daemon update [@vhsdream](https://github.com/vhsdream) ([#11541](https://github.com/community-scripts/ProxmoxVE/pull/11541))
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
### 💾 Core
- #### ✨ New Features
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
### 🧰 Tools
- #### ✨ New Features
- [ADDON] Immich Public Proxy addon [@vhsdream](https://github.com/vhsdream) ([#11518](https://github.com/community-scripts/ProxmoxVE/pull/11518))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
### ❔ Uncategorized
- [FIX] Immich Public Proxy docs link [@vhsdream](https://github.com/vhsdream) ([#11543](https://github.com/community-scripts/ProxmoxVE/pull/11543))
## 2026-02-03
### 🆕 New Scripts
- Wealthfolio ([#11511](https://github.com/community-scripts/ProxmoxVE/pull/11511))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- [FIX] Shelfmark: unpin Chromium version [@vhsdream](https://github.com/vhsdream) ([#11505](https://github.com/community-scripts/ProxmoxVE/pull/11505))
- #### ✨ New Features
- [FEAT] Scanopy: automatically update integrated daemon [@vhsdream](https://github.com/vhsdream) ([#11506](https://github.com/community-scripts/ProxmoxVE/pull/11506))
### 💾 Core
- #### 🐞 Bug Fixes
- [FIX] tools.func: trim spaces in app_lc when checking for gh release [@vhsdream](https://github.com/vhsdream) ([#11512](https://github.com/community-scripts/ProxmoxVE/pull/11512))
### 🌐 Website
- #### 🐞 Bug Fixes
- fix(frontend): decouple table pagination from summary fetching [@ls-root](https://github.com/ls-root) ([#11495](https://github.com/community-scripts/ProxmoxVE/pull/11495))
## 2026-02-02
### 🆕 New Scripts
- rustypaste | Alpine-rustypaste ([#11457](https://github.com/community-scripts/ProxmoxVE/pull/11457))
- KitchenOwl ([#11453](https://github.com/community-scripts/ProxmoxVE/pull/11453))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Grist: Update dependencies [@tremor021](https://github.com/tremor021) ([#11489](https://github.com/community-scripts/ProxmoxVE/pull/11489))
- Allow "downgrade" of libigdgmm12 [@vhsdream](https://github.com/vhsdream) ([#11478](https://github.com/community-scripts/ProxmoxVE/pull/11478))
- Disable NPM install and update due to OpenResty SHA-1 signature issues [@MickLesk](https://github.com/MickLesk) ([#11471](https://github.com/community-scripts/ProxmoxVE/pull/11471))
- #### ✨ New Features
- Refactor: Forgejo & readeck - migrate to codeberg functions [@MickLesk](https://github.com/MickLesk) ([#11460](https://github.com/community-scripts/ProxmoxVE/pull/11460))
- #### 💥 Breaking Changes
- [FIX] Scanopy: remove daemon build [@vhsdream](https://github.com/vhsdream) ([#11444](https://github.com/community-scripts/ProxmoxVE/pull/11444))
- #### 🔧 Refactor
- Refactor: Vaultwarden [@MickLesk](https://github.com/MickLesk) ([#11445](https://github.com/community-scripts/ProxmoxVE/pull/11445))
- various scripts: use ensure_dependencies instead of apt [@MickLesk](https://github.com/MickLesk) ([#11463](https://github.com/community-scripts/ProxmoxVE/pull/11463))
### 🌐 Website
- cleanup(frontend): remove unused /category-view route [@ls-root](https://github.com/ls-root) ([#11461](https://github.com/community-scripts/ProxmoxVE/pull/11461))
- #### ✨ New Features
- feat(frontend): preview tab [@ls-root](https://github.com/ls-root) ([#11475](https://github.com/community-scripts/ProxmoxVE/pull/11475))
## 2026-02-01
### 🚀 Updated Scripts
- fix headers [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11422](https://github.com/community-scripts/ProxmoxVE/pull/11422))
- #### 🐞 Bug Fixes
- 2fauth: export PHP_VERSION for nginx config [@MickLesk](https://github.com/MickLesk) ([#11441](https://github.com/community-scripts/ProxmoxVE/pull/11441))
- Prometheus Paperless NGX Exporter: Set correct binary path in systemd unit file [@andygrunwald](https://github.com/andygrunwald) ([#11438](https://github.com/community-scripts/ProxmoxVE/pull/11438))
- tracearr: install/update new prestart script from upstream [@durzo](https://github.com/durzo) ([#11433](https://github.com/community-scripts/ProxmoxVE/pull/11433))
- n8n: Fix dependencies [@tremor021](https://github.com/tremor021) ([#11429](https://github.com/community-scripts/ProxmoxVE/pull/11429))
- [Hotfix] Bunkerweb update [@vhsdream](https://github.com/vhsdream) ([#11402](https://github.com/community-scripts/ProxmoxVE/pull/11402))
- [Hotfix] Immich: revert healthcheck feature [@vhsdream](https://github.com/vhsdream) ([#11427](https://github.com/community-scripts/ProxmoxVE/pull/11427))
- #### ✨ New Features
- tools.func: add codeberg functions & autocaliweb: migrate from GitHub to Codeberg [@MickLesk](https://github.com/MickLesk) ([#11440](https://github.com/community-scripts/ProxmoxVE/pull/11440))
- Immich Refactor #2 [@vhsdream](https://github.com/vhsdream) ([#11375](https://github.com/community-scripts/ProxmoxVE/pull/11375))
- #### 🔧 Refactor
- WordPress: Refactor [@tremor021](https://github.com/tremor021) ([#11408](https://github.com/community-scripts/ProxmoxVE/pull/11408))
- Refactor: Whisparr [@tremor021](https://github.com/tremor021) ([#11411](https://github.com/community-scripts/ProxmoxVE/pull/11411))
### 💾 Core
- #### ✨ New Features
- [tools]: Update `fetch_and_deply_from_url()` [@tremor021](https://github.com/tremor021) ([#11410](https://github.com/community-scripts/ProxmoxVE/pull/11410))
### 🌐 Website
- feat(frontend): implement UX refinements and syntax highlighting [@ls-root](https://github.com/ls-root) ([#11423](https://github.com/community-scripts/ProxmoxVE/pull/11423))
- #### ✨ New Features
- feat(frontend): add contribution CTA to empty search state [@ls-root](https://github.com/ls-root) ([#11412](https://github.com/community-scripts/ProxmoxVE/pull/11412))
## 2026-01-31
### 🆕 New Scripts
- shelfmark ([#11371](https://github.com/community-scripts/ProxmoxVE/pull/11371))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: yubal: add git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11394](https://github.com/community-scripts/ProxmoxVE/pull/11394))
## 2026-01-30
### 🆕 New Scripts
- languagetool ([#11370](https://github.com/community-scripts/ProxmoxVE/pull/11370))
- Ampache ([#11369](https://github.com/community-scripts/ProxmoxVE/pull/11369))
### 🚀 Updated Scripts
- #### 🔧 Refactor
- Refactor: remove redundant PHP_MODULE entries in several scripts [@MickLesk](https://github.com/MickLesk) ([#11362](https://github.com/community-scripts/ProxmoxVE/pull/11362))
- Refactor: Koillection [@MickLesk](https://github.com/MickLesk) ([#11361](https://github.com/community-scripts/ProxmoxVE/pull/11361))
### 💾 Core
- #### 🐞 Bug Fixes
- core: meilisearch - add data migration for version upgrades [@MickLesk](https://github.com/MickLesk) ([#11356](https://github.com/community-scripts/ProxmoxVE/pull/11356))
- #### ✨ New Features
- [tools] Add `fetch_and_deploy_from_url()` [@tremor021](https://github.com/tremor021) ([#11376](https://github.com/community-scripts/ProxmoxVE/pull/11376))
- core: php - improve module handling and prevent installation failures [@MickLesk](https://github.com/MickLesk) ([#11358](https://github.com/community-scripts/ProxmoxVE/pull/11358))
- Opencloud: fix JSON [@vhsdream](https://github.com/vhsdream) ([#11617](https://github.com/community-scripts/ProxmoxVE/pull/11617))

View File

@@ -28,8 +28,8 @@ function update_script() {
exit
fi
php_ver=$(php -v | head -n 1 | awk '{print $2}')
if [[ ! $php_ver == "8.3"* ]]; then
PHP_VERSION="8.3" PHP_APACHE="YES" setup_php
if [[ ! $php_ver == "8.5"* ]]; then
PHP_VERSION="8.5" PHP_APACHE="YES" setup_php
fi
if check_for_gh_release "grocy" "grocy/grocy"; then
msg_info "Updating grocy"

6
ct/headers/immichframe Normal file
View File

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

View File

@@ -213,7 +213,8 @@ EOF
msg_ok "Updated Immich server, web, cli and plugins"
cd "$SRC_DIR"/machine-learning
mkdir -p "$ML_DIR" && chown -R immich:immich "$ML_DIR"
mkdir -p "$ML_DIR"
chown -R immich:immich "$INSTALL_DIR"
chown immich:immich ./uv.lock
export VIRTUAL_ENV="${ML_DIR}"/ml-venv
if [[ -f ~/.openvino ]]; then
@@ -379,7 +380,7 @@ function compile_imagemagick() {
function compile_libvips() {
SOURCE=$SOURCE_DIR/libvips
: "${LIBVIPS_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)}"
LIBVIPS_REVISION="0c9151a4f416d2f8ae20a755db218f6637050eec"
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libvips"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"

81
ct/immichframe.sh Normal file
View File

@@ -0,0 +1,81 @@
#!/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: Thiago Canozzo Lahr (tclahr)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/immichFrame/ImmichFrame
APP="ImmichFrame"
var_tags="${var_tags:-photos;slideshow}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/immichframe ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "immichframe" "immichFrame/ImmichFrame"; then
msg_info "Stopping Service"
systemctl stop immichframe
msg_ok "Stopped Service"
msg_info "Backing up Configuration"
cp -r /opt/immichframe/Config /tmp/immichframe_config.bak
msg_ok "Backed up Configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immichframe" "immichFrame/ImmichFrame" "tarball" "latest" "/tmp/immichframe"
msg_info "Setting up ImmichFrame"
cd /tmp/immichframe
$STD dotnet publish ImmichFrame.WebApi/ImmichFrame.WebApi.csproj \
--configuration Release \
--runtime linux-x64 \
--self-contained false \
--output /opt/immichframe
cd /tmp/immichframe/immichFrame.Web
$STD npm ci --silent
$STD npm run build
rm -rf /opt/immichframe/wwwroot/*
cp -r build/* /opt/immichframe/wwwroot
rm -rf /tmp/immichframe
msg_ok "Setup ImmichFrame"
msg_info "Restoring Configuration"
cp -r /tmp/immichframe_config.bak/* /opt/immichframe/Config/
rm -rf /tmp/immichframe_config.bak
chown -R immichframe:immichframe /opt/immichframe
msg_ok "Restored Configuration"
msg_info "Starting Service"
systemctl start immichframe
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"

View File

@@ -23,7 +23,7 @@ function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/bin/influxd ]]; then
if [[ ! -f /usr/bin/influxd && ! -f /usr/bin/influxdb3 ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

View File

@@ -28,7 +28,7 @@ function update_script() {
exit
fi
ensure_dependencies graphicsmagick
ensure_dependencies build-essential python3-setuptools graphicsmagick
NODE_VERSION="24" setup_nodejs
msg_info "Updating n8n"

View File

@@ -27,6 +27,16 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if ! command -v unrar &>/dev/null; then
setup_nonfree
$STD apt install -y unrar
if grep -q "UnrarCmd=unrar-free" /var/lib/nzbget/nzbget.conf; then
sed -i "s|UnrarCmd=unrar-free|UnrarCmd=unrar|g" /var/lib/nzbget/nzbget.conf
fi
fi
msg_info "Updating NZBGet"
$STD apt update
$STD apt upgrade -y

View File

@@ -29,7 +29,7 @@ function update_script() {
exit
fi
RELEASE="v5.1.0"
RELEASE="v5.2.0"
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}"; then
msg_info "Stopping services"
systemctl stop opencloud opencloud-wopi
@@ -41,7 +41,9 @@ function update_script() {
ensure_dependencies "inotify-tools"
msg_ok "Updated packages"
rm -f /usr/bin/{OpenCloud,opencloud}
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "${RELEASE}" "/usr/bin" "opencloud-*-linux-amd64"
mv /usr/bin/OpenCloud /usr/bin/opencloud
if ! grep -q 'POSIX_WATCH' /etc/opencloud/opencloud.env; then
sed -i '/^## External/i ## Uncomment below to enable PosixFS Collaborative Mode\

View File

@@ -25,6 +25,8 @@ function update_script() {
check_container_storage
check_container_resources
ensure_dependencies zstd build-essential libmariadb-dev
if [[ -d /opt/open-webui ]]; then
msg_warn "Legacy installation detected — migrating to uv based install..."
msg_info "Stopping Service"
@@ -92,7 +94,6 @@ 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
ensure_dependencies zstd
msg_info "Ollama update available: v$OLLAMA_VERSION -> v$RELEASE"
msg_info "Downloading Ollama v$RELEASE \n"
curl -fS#LO https://github.com/ollama/ollama/releases/download/v${RELEASE}/ollama-linux-amd64.tar.zst

View File

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

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: vhsdream
# Author: vhsdream | MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://rxresume.org | Github: https://github.com/lazy-media/Reactive-Resume
# Source: https://rxresume.org | Github: https://github.com/amruthpillai/reactive-resume
APP="Reactive-Resume"
var_tags="${var_tags:-documents}"
@@ -24,62 +24,29 @@ function update_script() {
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/Reactive-Resume.service ]]; then
if [[ ! -f /etc/systemd/system/reactive-resume.service ]]; then
msg_error "No $APP Installation Found!"
exit
fi
if check_for_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume"; then
if check_for_gh_release "reactive-resume" "amruthpillai/reactive-resume"; then
msg_info "Stopping services"
systemctl stop Reactive-Resume
systemctl stop reactive-resume
msg_ok "Stopped services"
cp /opt/Reactive-Resume/.env /opt/rxresume.env
fetch_and_deploy_gh_release "Reactive-Resume" "lazy-media/Reactive-Resume" "tarball" "latest" "/opt/Reactive-Resume"
cp /opt/reactive-resume/.env /opt/reactive-resume.env.bak
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "reactive-resume" "amruthpillai/reactive-resume" "tarball" "latest" "/opt/reactive-resume"
msg_info "Updating Reactive-Resume"
cd /opt/Reactive-Resume
export PUPPETEER_SKIP_DOWNLOAD="true"
export NEXT_TELEMETRY_DISABLED=1
msg_info "Updating Reactive Resume (Patience)"
cd /opt/reactive-resume
export CI="true"
export NODE_ENV="production"
$STD pnpm install --frozen-lockfile
$STD pnpm run build
$STD pnpm run prisma:generate
mv /opt/rxresume.env /opt/Reactive-Resume/.env
msg_ok "Updated Reactive-Resume"
msg_info "Updating Minio"
systemctl stop minio
cd /tmp
curl -fsSL https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb
$STD dpkg -i minio.deb
rm -f /tmp/minio.deb
msg_ok "Updated Minio"
msg_info "Updating Browserless (Patience)"
systemctl stop browserless
cp /opt/browserless/.env /opt/browserless.env
rm -rf /opt/browserless
brwsr_tmp=$(mktemp)
TAG=$(curl -fsSL https://api.github.com/repos/browserless/browserless/tags?per_page=1 | grep "name" | awk '{print substr($2, 3, length($2)-4) }')
curl -fsSL https://github.com/browserless/browserless/archive/refs/tags/v"$TAG".zip -o "$brwsr_tmp"
$STD unzip "$brwsr_tmp"
mv browserless-"$TAG"/ /opt/browserless
cd /opt/browserless
$STD npm install typescript
$STD npm install esbuild
$STD npm install
rm -rf src/routes/{chrome,edge,firefox,webkit}
$STD node_modules/playwright-core/cli.js install --with-deps chromium
$STD npm run build
$STD npm run build:function
$STD npm prune production
mv /opt/browserless.env /opt/browserless/.env
rm -f "$brwsr_tmp"
msg_ok "Updated Browserless"
mv /opt/reactive-resume.env.bak /opt/reactive-resume/.env
msg_ok "Updated Reactive Resume"
msg_info "Restarting services"
systemctl start minio Reactive-Resume browserless
systemctl start chromium-printer reactive-resume
msg_ok "Restarted services"
msg_ok "Updated successfully!"
fi

View File

@@ -29,7 +29,7 @@ function update_script() {
exit
fi
if check_for_gh_release "rustdesk-api"; then
if check_for_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server"; then
msg_info "Stopping Service"
systemctl stop rustdesk-hbbr
systemctl stop rustdesk-hbbs

View File

@@ -53,6 +53,13 @@ function update_script() {
fi
sed -i 's|_TARGET=.*$|_URL=http://127.0.0.1:60072|' /opt/scanopy/.env
msg_info "Building Scanopy Server (patience)"
cd /opt/scanopy/backend
$STD cargo build --release --bin server --bin generate-fixtures
$STD ./target/release/generate-fixtures --output-dir /opt/scanopy/ui/src/lib/data
mv ./target/release/server /usr/bin/scanopy-server
msg_ok "Built Scanopy Server"
msg_info "Creating frontend UI"
export PUBLIC_SERVER_HOSTNAME=default
export PUBLIC_SERVER_PORT=""
@@ -61,12 +68,6 @@ function update_script() {
$STD npm run build
msg_ok "Created frontend UI"
msg_info "Building Scanopy Server (patience)"
cd /opt/scanopy/backend
$STD cargo build --release --bin server
mv ./target/release/server /usr/bin/scanopy-server
msg_ok "Built Scanopy Server"
if [[ -f /etc/systemd/system/scanopy-daemon.service ]]; then
fetch_and_deploy_gh_release "Scanopy Daemon" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64"
mv "/usr/local/bin/Scanopy Daemon" /usr/local/bin/scanopy-daemon

View File

@@ -55,8 +55,9 @@ function update_script() {
msg_ok "Updated Sparky Fitness Backend"
msg_info "Updating Sparky Fitness Frontend (Patience)"
cd /opt/sparkyfitness/SparkyFitnessFrontend
cd /opt/sparkyfitness
$STD pnpm install
cd /opt/sparkyfitness/SparkyFitnessFrontend
$STD pnpm run build
cp -a /opt/sparkyfitness/SparkyFitnessFrontend/dist/. /var/www/sparkyfitness/
msg_ok "Updated Sparky Fitness Frontend"

View File

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

View File

@@ -37,7 +37,7 @@ function update_script() {
if [[ -d /etc/wgdashboard ]]; then
sleep 2
cd /etc/wgdashboard/src
$STD ./wgd.sh update
$STD ./wgd.sh update -y
$STD ./wgd.sh start
fi
msg_ok "Updated LXC"

View File

@@ -35,13 +35,16 @@ function update_script() {
msg_ok "Stopped Service"
msg_info "Creating Backup"
rm -rf /opt/${APP}_backup*.tar.gz
mkdir -p /opt/z2m_backup
$STD tar -czf /opt/z2m_backup/${APP}_backup_$(date +%Y%m%d%H%M%S).tar.gz -C /opt zigbee2mqtt
mv /opt/zigbee2mqtt/data /opt/z2m_backup
msg_ok "Backup Created"
ensure_dependencies zstd
mkdir -p /opt/{backups,z2m_backup}
BACKUP_VERSION="$(<"$HOME/.zigbee2mqtt")"
BACKUP_FILE="/opt/backups/${APP}_backup_${BACKUP_VERSION}.tar.zst"
$STD tar -cf - -C /opt zigbee2mqtt | zstd -q -o "$BACKUP_FILE"
ls -t /opt/backups/${APP}_backup_*.tar.zst 2>/dev/null | tail -n +6 | xargs -r rm -f
mv /opt/zigbee2mqtt/data /opt/z2m_backup/data
msg_ok "Backup Created (${BACKUP_VERSION})"
fetch_and_deploy_gh_release "Zigbee2MQTT" "Koenkk/zigbee2mqtt" "tarball" "latest" "/opt/zigbee2mqtt"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Zigbee2MQTT" "Koenkk/zigbee2mqtt" "tarball" "latest" "/opt/zigbee2mqtt"
msg_info "Updating Zigbee2MQTT"
rm -rf /opt/zigbee2mqtt/data

39
frontend/.gitignore vendored
View File

@@ -1,39 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# wrangler
.worker-next
.wrangler
# testing
/coverage
# next.js
/.next/
out
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# # local env files
# .env*.local
# .env
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

51
frontend/.vscode/settings.json generated vendored
View File

@@ -1,51 +0,0 @@
{
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"json5",
"jsonc",
"yaml",
"toml",
"xml",
"gql",
"graphql",
"astro",
"svelte",
"css",
"less",
"scss",
"pcss",
"postcss"
]
}

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024-Present Bram Suurd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,281 +0,0 @@
# Proxmox VE Helper-Scripts Frontend
> 🚀 **Modern frontend for the Community-Scripts Proxmox VE Helper-Scripts repository**
A comprehensive, user-friendly interface built with Next.js that provides access to 300+ automation scripts for Proxmox Virtual Environment management. This frontend serves as the official website for the Community-Scripts organization's Proxmox VE Helper-Scripts repository.
![Next.js](https://img.shields.io/badge/Next.js-15.2.4-black?style=flat-square&logo=next.js)
![React](https://img.shields.io/badge/React-19.0.0-blue?style=flat-square&logo=react)
![TypeScript](https://img.shields.io/badge/TypeScript-5.8.2-blue?style=flat-square&logo=typescript)
![Tailwind CSS](https://img.shields.io/badge/Tailwind-3.4.17-06B6D4?style=flat-square&logo=tailwindcss)
![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)
## 🌟 Features
### Core Functionality
- **📜 Script Management**: Browse, search, and filter 300+ Proxmox VE scripts
- **📱 Responsive Design**: Mobile-first approach with modern UI/UX
- **🔍 Advanced Search**: Fuzzy search with category filtering
- **📊 Analytics Integration**: Built-in analytics for usage tracking
- **🌙 Dark/Light Mode**: Theme switching with system preference detection
- **⚡ Performance Optimized**: Static site generation for lightning-fast loading
### Technical Features
- **🎨 Modern UI Components**: Built with Radix UI and shadcn/ui
- **📈 Data Visualization**: Charts and metrics using Chart.js
- **🔄 State Management**: React Query for efficient data fetching
- **📝 Type Safety**: Full TypeScript implementation
- **🚀 Static Export**: Optimized for GitHub Pages deployment
## 🛠️ Tech Stack
### Frontend Framework
- **[Next.js 15.2.4](https://nextjs.org/)** - React framework with App Router
- **[React 19.0.0](https://react.dev/)** - Latest React with concurrent features
- **[TypeScript 5.8.2](https://www.typescriptlang.org/)** - Type-safe JavaScript
### Styling & UI
- **[Tailwind CSS 3.4.17](https://tailwindcss.com/)** - Utility-first CSS framework
- **[Radix UI](https://www.radix-ui.com/)** - Unstyled, accessible UI components
- **[shadcn/ui](https://ui.shadcn.com/)** - Re-usable components built on Radix UI
- **[Framer Motion](https://www.framer.com/motion/)** - Animation library
- **[Lucide React](https://lucide.dev/)** - Icon library
### Data & State Management
- **[TanStack Query 5.71.1](https://tanstack.com/query)** - Powerful data synchronization
- **[Zod 3.24.2](https://zod.dev/)** - TypeScript-first schema validation
- **[nuqs 2.4.1](https://nuqs.47ng.com/)** - Type-safe search params state manager
### Development Tools
- **[Vitest 3.1.1](https://vitest.dev/)** - Fast unit testing framework
- **[React Testing Library](https://testing-library.com/react)** - Simple testing utilities
- **[ESLint](https://eslint.org/)** - Code linting and formatting
- **[Prettier](https://prettier.io/)** - Code formatting
### Additional Libraries
- **[Chart.js](https://www.chartjs.org/)** - Data visualization
- **[Fuse.js](https://fusejs.io/)** - Fuzzy search
- **[date-fns](https://date-fns.org/)** - Date utility library
- **[Next Themes](https://github.com/pacocoursey/next-themes)** - Theme management
## 🚀 Getting Started
### Prerequisites
- **Node.js 18+** (recommend using the latest LTS version)
- **npm**, **yarn**, **pnpm**, or **bun** package manager
- **Git** for version control
### Installation
1. **Clone the repository**
```bash
git clone https://github.com/community-scripts/ProxmoxVE.git
cd ProxmoxVE/frontend
```
2. **Install dependencies**
```bash
# Using npm
npm install
# Using yarn
yarn install
# Using pnpm
pnpm install
# Using bun
bun install
```
3. **Start the development server**
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
4. **Open your browser**
Navigate to [http://localhost:3000](http://localhost:3000) to see the application running.
### Environment Configuration
The application uses the following environment variables:
- `BASE_PATH`: Set to "ProxmoxVE" for GitHub Pages deployment
- Analytics configuration is handled in `src/config/siteConfig.tsx`
## 🧪 Development
### Available Scripts
```bash
# Development
npm run dev # Start development server with Turbopack
npm run build # Build for production
npm run start # Start production server (after build)
# Code Quality
npm run lint # Run ESLint
npm run typecheck # Run TypeScript type checking
npm run format:write # Format code with Prettier
npm run format:check # Check code formatting
# Deployment
npm run deploy # Build and deploy to GitHub Pages
```
### Development Workflow
1. **Feature Development**
- Create a new branch for your feature
- Follow the established TypeScript and React patterns
- Use the existing component library (shadcn/ui)
- Ensure responsive design principles
2. **Code Standards**
- Follow TypeScript strict mode
- Use functional components with hooks
- Implement proper error boundaries
- Write descriptive variable and function names
- Use early returns for better readability
3. **Styling Guidelines**
- Use Tailwind CSS utility classes
- Follow mobile-first responsive design
- Implement dark/light mode considerations
- Use CSS variables from the design system
4. **Testing**
- Write unit tests for utility functions
- Test React components with React Testing Library
- Ensure accessibility standards are met
- Run tests before committing
### Component Development
The project uses a component-driven development approach:
```typescript
// Example component structure
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
interface ComponentProps {
title: string;
className?: string;
}
export const Component = ({ title, className }: ComponentProps) => {
return (
<div className={cn("default-classes", className)}>
<Button>{title}</Button>
</div>
);
};
```
### Configuration for Static Export
The application is configured for static export in `next.config.mjs`:
```javascript
const nextConfig = {
output: "export",
basePath: `/ProxmoxVE`,
images: {
unoptimized: true // Required for static export
}
};
```
## 🤝 Contributing
We welcome contributions from the community! Here's how you can help:
### Getting Started
1. **Fork the repository** on GitHub
2. **Clone your fork** locally
3. **Create a new branch** for your feature or bugfix
4. **Make your changes** following our coding standards
5. **Submit a pull request** with a clear description
### Contribution Guidelines
#### Code Style
- Follow the existing TypeScript and React patterns
- Use descriptive variable and function names
- Implement proper error handling
- Write self-documenting code with appropriate comments
#### Component Guidelines
- Use functional components with hooks
- Implement proper TypeScript types
- Follow accessibility best practices
- Ensure responsive design
- Use the existing design system components
#### Pull Request Process
1. Update documentation if needed
2. Update the README if you've added new features
3. Request review from maintainers
### Areas for Contribution
- **🐛 Bug fixes**: Report and fix issues
- **✨ New features**: Enhance functionality
- **📚 Documentation**: Improve guides and examples
- **🎨 UI/UX**: Improve design and user experience
- **♿ Accessibility**: Enhance accessibility features
- **🚀 Performance**: Optimize loading and runtime performance
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🙏 Acknowledgments
- **[tteck](https://github.com/tteck)** - Original creator of the Proxmox VE Helper-Scripts
- **[Community-Scripts Organization](https://github.com/community-scripts)** - Maintaining and expanding the project
- **[Proxmox Community](https://forum.proxmox.com/)** - For continuous feedback and support
- **All Contributors** - Thank you for your valuable contributions!
## 📚 Additional Resources
- **[Proxmox VE Documentation](https://pve.proxmox.com/pve-docs/)**
- **[Community Scripts Repository](https://github.com/community-scripts/ProxmoxVE)**
- **[Discord Community](https://discord.gg/3AnUqsXnmK)**
- **[GitHub Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)**
## 🔗 Links
- **🌐 Live Website**: [https://community-scripts.github.io/ProxmoxVE/](https://community-scripts.github.io/ProxmoxVE/)
- **💬 Discord Server**: [https://discord.gg/3AnUqsXnmK](https://discord.gg/3AnUqsXnmK)
- **📝 Change Log**: [https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md](https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md)
---
**Made with ❤️ by the Community-Scripts team and contributors**

2031
frontend/bun.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "@/styles/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
},
"registries": {
"@animate-ui": "https://animate-ui.com/r/{name}.json"
}
}

View File

@@ -1,41 +0,0 @@
import antfu from "@antfu/eslint-config";
export default antfu(
{
type: "app",
typescript: true,
formatters: true,
next: true,
stylistic: {
indent: 2,
semi: true,
quotes: "double",
},
ignores: ["src/components/ui/**", "README.md", "public/json/**"],
},
{
rules: {
"ts/no-redeclare": "off",
"ts/consistent-type-definitions": ["error", "type"],
"no-console": ["warn"],
"antfu/no-top-level-await": ["off"],
"node/prefer-global/process": ["off"],
"node/no-process-env": ["error"],
"perfectionist/sort-imports": [
"error",
{
type: "line-length",
order: "desc",
},
],
"unicorn/filename-case": [
"error",
{
case: "kebabCase",
ignore: ["README.md"],
},
],
},
},
);

View File

@@ -1,29 +0,0 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.alias.canvas = false;
return config;
},
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**",
},
],
},
env: {
BASE_PATH: "ProxmoxVE",
},
eslint: {
ignoreDuringBuilds: true,
},
output: "export",
basePath: `/ProxmoxVE`,
};
export default nextConfig;

87
frontend/package.json generated
View File

@@ -1,87 +0,0 @@
{
"name": "proxmox-helper-scripts-website",
"type": "module",
"version": "1.0.0",
"private": true,
"author": {
"name": "Bram Suurd",
"url": "https://github.com/community-scripts"
},
"license": "MIT",
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "eslint . --fix",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.8",
"@radix-ui/react-navigation-menu": "^1.2.14",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.12",
"@types/react-syntax-highlighter": "^15.5.13",
"chart.js": "^4.5.1",
"chartjs-plugin-datalabels": "^2.2.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"framer-motion": "^12.23.26",
"fuse.js": "^7.1.0",
"lucide-react": "^0.561.0",
"mini-svg-data-uri": "^1.4.4",
"motion": "^12.23.26",
"next": "15.5.8",
"next-themes": "^0.4.6",
"nuqs": "^2.8.5",
"react": "19.2.3",
"react-chartjs-2": "^5.3.1",
"react-code-blocks": "^0.1.6",
"react-datepicker": "^9.0.0",
"react-day-picker": "^9.12.0",
"react-dom": "19.2.3",
"react-icons": "^5.5.0",
"react-syntax-highlighter": "^16.1.0",
"react-use-measure": "^2.1.7",
"recharts": "3.6.0",
"sharp": "^0.34.5",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"zod": "^4.2.1"
},
"devDependencies": {
"@antfu/eslint-config": "^6.7.1",
"@eslint-react/eslint-plugin": "^2.3.13",
"@next/eslint-plugin-next": "^15.5.8",
"@tanstack/eslint-plugin-query": "^5.91.2",
"@types/node": "^25.0.2",
"@types/react": "npm:types-react@19.0.0-rc.1",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
"@typescript-eslint/eslint-plugin": "^8.50.0",
"@typescript-eslint/parser": "^8.50.0",
"@vitejs/plugin-react": "^5.1.2",
"eslint": "^9.39.2",
"eslint-config-next": "15.5.8",
"eslint-plugin-format": "^1.1.0",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.25",
"jsdom": "^27.3.0",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-animated": "^1.1.2",
"typescript": "^5.9.3"
}
}

View File

@@ -1,8 +0,0 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

View File

@@ -1,44 +0,0 @@
{
"name": "2FAuth",
"slug": "2fauth",
"categories": [
6
],
"date_created": "2024-12-20",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.2fauth.app/",
"website": "https://2fauth.app/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/2fauth.webp",
"config_path": "cat /opt/2fauth/.env",
"description": "2FAuth is a web based self-hosted alternative to One Time Passcode (OTP) generators like Google Authenticator, designed for both mobile and desktop. It aims to ease you perform your 2FA authentication steps whatever the device you handle, with a clean and suitable interface.",
"install_methods": [
{
"type": "default",
"script": "ct/2fauth.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Database credentials: `cat ~/2FAuth.creds`",
"type": "info"
},
{
"text": "The very first account created is automatically set up as an administrator account.",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Actual Budget",
"slug": "actualbudget",
"categories": [
23
],
"date_created": "2025-05-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 5006,
"documentation": "https://github.com/community-scripts/ProxmoxVE/discussions/807",
"website": "https://actualbudget.org/",
"config_path": "/opt/actualbudget-data/config.json",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/actual-budget.webp",
"description": "Actual Budget is a super fast and privacy-focused app for managing your finances. At its heart is the well proven and much loved Envelope Budgeting methodology.",
"install_methods": [
{
"type": "default",
"script": "ct/actualbudget.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,52 +0,0 @@
{
"name": "PVE LXC Tag",
"slug": "add-iptag",
"categories": [
1
],
"date_created": "2025-06-16",
"type": "pve",
"updateable": false,
"privileged": false,
"interface_port": null,
"documentation": null,
"website": null,
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/proxmox.webp",
"config_path": "/opt/iptag/iptag.conf",
"description": "This script automatically adds IP address as tags to LXC containers or VM's using a systemd service. The service also updates the tags if a LXC/VM IP address is changed.",
"install_methods": [
{
"type": "default",
"script": "tools/pve/add-iptag.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Execute within the Proxmox shell",
"type": "info"
},
{
"text": "Configuration: `nano /opt/iptag/iptag.conf`. iptag Service must be restarted after change. See here for full documentation: `https://github.com/community-scripts/ProxmoxVE/discussions/5790`",
"type": "info"
},
{
"text": "The Proxmox Node must contain ipcalc and net-tools. `apt-get install -y ipcalc net-tools`",
"type": "warning"
},
{
"text": "You can execute the ip tool manually with `iptag-run`",
"type": "info"
}
]
}

View File

@@ -1,48 +0,0 @@
{
"name": "NetBird",
"slug": "add-netbird-lxc",
"categories": [
1
],
"date_created": "2024-05-19",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://docs.netbird.io/",
"website": "https://netbird.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/netbird.webp",
"config_path": "",
"description": "NetBird combines a configuration-free peer-to-peer private network and a centralized access control system in a single platform, making it easy to create secure private networks for your organization or home.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/add-netbird-lxc.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "After the script finishes, reboot the LXC then run `netbird up` in the LXC console",
"type": "info"
},
{
"text": "Execute within the Proxmox main shell",
"type": "info"
},
{
"text": "The script only works in Debian/Ubuntu, not in Alpine!",
"type": "warning"
}
]
}

View File

@@ -1,44 +0,0 @@
{
"name": "Tailscale",
"slug": "add-tailscale-lxc",
"categories": [
1
],
"date_created": "2024-05-02",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://tailscale.com/kb/1017/install",
"website": "https://tailscale.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/tailscale.webp",
"config_path": "",
"description": "Tailscale is a software-defined networking solution that enables secure communication between devices over the internet. It creates a virtual private network (VPN) that enables devices to communicate with each other as if they were on the same local network. Tailscale works even when the devices are separated by firewalls or subnets, and provides secure and encrypted communication between devices. With Tailscale, users can connect devices, servers, computers, and cloud instances to create a secure network, making it easier to manage and control access to resources. Tailscale is designed to be easy to set up and use, providing a streamlined solution for secure communication between devices over the internet.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/add-tailscale-lxc.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "After the script finishes, reboot the LXC then run `tailscale up` in the LXC console",
"type": "info"
},
{
"text": "Execute within the Proxmox host shell",
"type": "info"
}
]
}

View File

@@ -1,51 +0,0 @@
{
"name": "AdGuard Home",
"slug": "adguard",
"categories": [
5
],
"date_created": "2024-04-28",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started",
"website": "https://adguard.com/en/adguard-home/overview.html",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/adguard-home.webp",
"config_path": "/opt/AdGuardHome/AdGuardHome.yaml",
"description": "AdGuard Home is an open-source, self-hosted network-wide ad blocker. It blocks advertisements, trackers, phishing and malware websites, and provides protection against online threats. AdGuard Home is a DNS-based solution, which means it blocks ads and malicious content at the network level, before it even reaches your device. It runs on your home network and can be easily configured and managed through a web-based interface. It provides detailed statistics and logs, allowing you to see which websites are being blocked, and why. AdGuard Home is designed to be fast, lightweight, and easy to use, making it an ideal solution for home users who want to block ads, protect their privacy, and improve the speed and security of their online experience.",
"install_methods": [
{
"type": "default",
"script": "ct/adguard.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "debian",
"version": "13"
}
},
{
"type": "alpine",
"script": "ct/alpine-adguard.sh",
"resources": {
"cpu": 1,
"ram": 256,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "AdGuard Home can only be updated via the user interface.",
"type": "info"
}
]
}

View File

@@ -1,59 +0,0 @@
{
"name": "AdGuardHome-Sync",
"slug": "adguardhome-sync",
"categories": [
5
],
"date_created": "2025-12-13",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://github.com/bakito/adguardhome-sync",
"website": "https://github.com/bakito/adguardhome-sync",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/adguardhome-sync.webp",
"config_path": "/opt/adguardhome-sync/adguardhome-sync.yaml",
"description": "Synchronize AdGuardHome config to one or multiple replica instances. Syncs General Settings, Filters, Rewrites, Services, Clients, DNS Config, DHCP Config and Theme.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/adguardhome-sync.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
},
{
"type": "alpine",
"script": "tools/addon/adguardhome-sync.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Edit /opt/adguardhome-sync/adguardhome-sync.yaml to configure your AdGuardHome instances",
"type": "info"
},
{
"text": "Origin = Primary instance, Replicas = Instances to sync to",
"type": "info"
},
{
"text": "Update with: update_adguardhome-sync",
"type": "info"
}
]
}

View File

@@ -1,44 +0,0 @@
{
"name": "AdventureLog",
"slug": "adventurelog",
"categories": [
24
],
"date_created": "2024-10-26",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://adventurelog.app/docs/intro/adventurelog_overview.html",
"website": "https://adventurelog.app/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/adventurelog.webp",
"config_path": "/opt/adventurelog/backend/server/.env",
"description": "Adventure Log is an app designed to track outdoor activities and personal achievements, allowing users to log their adventures with photos, notes, and location data. It focuses on enhancing outdoor experiences by preserving memories and sharing them with others.",
"install_methods": [
{
"type": "default",
"script": "ct/adventurelog.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 7,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "AdventureLog uses an initial local IP, if you change your LXC-IP, you need to change the IP here: `/opt/adventurelog/backend/server/.env` and here: `/opt/adventurelog/frontend/.env`",
"type": "warning"
},
{
"text": "Use `cat ~/adventurelog.creds` to see login credentials.",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "AgentDVR",
"slug": "agentdvr",
"categories": [
15
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": true,
"interface_port": 8090,
"documentation": "https://www.ispyconnect.com/docs/agent/about",
"website": "https://www.ispyconnect.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/agent-dvr.webp",
"config_path": "/opt/agentdvr/agent/Media/XML/config.json",
"description": "AgentDVR a new video surveillance solution for the Internet Of Things.",
"install_methods": [
{
"type": "default",
"script": "ct/agentdvr.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "ubuntu",
"version": "24.04"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "All Templates",
"slug": "all-templates",
"categories": [
1
],
"date_created": "2024-05-02",
"type": "addon",
"updateable": false,
"privileged": false,
"interface_port": null,
"documentation": null,
"website": null,
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/proxmox.webp",
"config_path": "",
"description": "A script designed to allow for the creation of one of the many free LXC templates. Great for creating system LXCs.\r\nThe script creates a `*.creds` file in the Proxmox root directory with the password of the newly created LXC.\r\nPlease take note that if you plan to use this script for creating TurnKey LXCs, you'll need to modify the hostname after creation.",
"install_methods": [
{
"type": "default",
"script": "tools/addon/all-templates.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Resource and network settings are adjustable post LXC creation.",
"type": "info"
}
]
}

View File

@@ -1,46 +0,0 @@
{
"name": "Alpine-IT-Tools",
"slug": "alpine-it-tools",
"categories": [
20
],
"date_created": "2025-01-30",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": null,
"website": "https://sharevb-it-tools.vercel.app/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/it-tools.webp",
"config_path": "",
"description": "IT-Tools is a web-based suite of utilities designed to streamline and simplify various IT tasks, providing tools for developers and system administrators to manage their workflows efficiently.",
"install_methods": [
{
"type": "default",
"script": "ct/alpine-it-tools.sh",
"resources": {
"cpu": 1,
"ram": 256,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}
},
{
"type": "alpine",
"script": "ct/alpine-it-tools.sh",
"resources": {
"cpu": 1,
"ram": 256,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Alpine",
"slug": "alpine",
"categories": [
2
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": null,
"website": "https://www.alpinelinux.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/alpine-linux.webp",
"config_path": "",
"description": "A security-oriented, lightweight Linux distribution based on musl and BusyBox.\r\nBy default, the root password is set to alpine. If you choose to use advanced settings, you will need to define a password, autologin is currently unavailable.",
"install_methods": [
{
"type": "default",
"script": "ct/alpine.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 1,
"os": "alpine",
"version": "3.23"
}
}
],
"default_credentials": {
"username": null,
"password": "alpine"
},
"notes": [
{
"text": "To Update Alpine: `apk -U upgrade`",
"type": "info"
}
]
}

View File

@@ -1,48 +0,0 @@
{
"name": "Ampache",
"slug": "ampache",
"categories": [
13
],
"date_created": "2026-01-30",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://github.com/ampache/ampache/wiki",
"website": "https://ampache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ampache.webp",
"config_path": "/opt/ampache/config/ampache.cfg.php",
"description": "Ampache is a web-based audio streaming application and file manager that allows you to access your music & videos from anywhere. It features a powerful music catalog, multiple user support, transcoding, streaming, and more.",
"install_methods": [
{
"type": "default",
"script": "ct/ampache.sh",
"resources": {
"cpu": 4,
"ram": 2048,
"hdd": 5,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Complete the web-based setup at http://IP/install.php",
"type": "info"
},
{
"text": "Database credentials are stored in `~/ampache.creds` - use only the MySQL username and password from this file",
"type": "info"
},
{
"text": "During installation, only check 'Create Tables' - leave 'Create Database' and 'Create Database User' unchecked",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Apache-Cassandra",
"slug": "apache-cassandra",
"categories": [
8
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://cassandra.apache.org/doc/latest/",
"website": "https://cassandra.apache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/apache-cassandra.webp",
"config_path": "/etc/cassandra/cassandra.yaml",
"description": "Apache-Cassandra is an open source NoSQL distributed database trusted by thousands of companies for scalability and high availability without compromising performance.",
"install_methods": [
{
"type": "default",
"script": "ct/apache-cassandra.sh",
"resources": {
"cpu": 1,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Apache CouchDB",
"slug": "apache-couchdb",
"categories": [
8
],
"date_created": "2024-05-02",
"type": "ct",
"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.",
"install_methods": [
{
"type": "default",
"script": "ct/apache-couchdb.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 10,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Login Credentials: `cat ~/couchdb.creds`",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Apache Guacamole",
"slug": "apache-guacamole",
"categories": [
0
],
"date_created": "2024-12-19",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://guacamole.apache.org/doc/gug/",
"website": "https://guacamole.apache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/apache-guacamole.webp",
"config_path": "/etc/guacamole/guacd.conf",
"description": "Apache Guacamole is a clientless remote desktop gateway. It supports standard protocols like VNC, RDP, and SSH.",
"install_methods": [
{
"type": "default",
"script": "ct/apache-guacamole.sh",
"resources": {
"cpu": 1,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "guacadmin",
"password": "guacadmin"
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Apache Tika",
"slug": "apache-tika",
"categories": [
12
],
"date_created": "2025-02-05",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9998,
"documentation": "https://cwiki.apache.org/confluence/display/tika",
"website": "https://tika.apache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/apache-tika.webp",
"config_path": "/opt/apache-tika/tika-config.xml",
"description": "The Apache Tika™ toolkit detects and extracts metadata and text from over a thousand different file types (such as PPT, XLS, and PDF). All of these file types can be parsed through a single interface, making Tika useful for search engine indexing, content analysis, translation, and much more.",
"install_methods": [
{
"type": "default",
"script": "ct/apache-tika.sh",
"resources": {
"cpu": 1,
"ram": 2024,
"hdd": 10,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Configuration file is not created at install time. Example is at: `https://cwiki.apache.org/confluence/display/TIKA/TikaServer+in+Tika+2.x`",
"type": "info"
}
]
}

View File

@@ -1,40 +0,0 @@
{
"name": "Apache Tomcat",
"slug": "apache-tomcat",
"categories": [
10
],
"date_created": "2025-03-04",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://cwiki.apache.org/confluence/display/TOMCAT",
"website": "https://tomcat.apache.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/apache-tomcat.webp",
"config_path": "",
"description": "Apache Tomcat is an open-source application server that runs Java Servlets and JavaServer Pages (JSP). It allows developers to deploy and manage Java web applications by handling HTTP requests and serving dynamic content. Tomcat is widely used for lightweight web applications and supports various Java EE features like WebSockets and JNDI.",
"install_methods": [
{
"type": "default",
"script": "ct/apache-tomcat.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 5,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "User can select which Adoptium JDK should be used for the selected Tomcat version (9, 10.1 or 11). ",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Apt-Cacher-NG",
"slug": "apt-cacher-ng",
"categories": [
4
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3142,
"documentation": "https://www.unix-ag.uni-kl.de/~bloch/acng/html/index.html",
"website": "https://www.unix-ag.uni-kl.de/~bloch/acng/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/linux.webp",
"config_path": "/etc/apt-cacher-ng/acng.conf",
"description": "Apt-Cacher-NG is a caching proxy. Specialized for package files from Linux distributors, primarily for Debian (and Debian based) distributions.",
"install_methods": [
{
"type": "default",
"script": "ct/apt-cacher-ng.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 10,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Arcane",
"slug": "arcane",
"categories": [
3
],
"date_created": "2026-02-24",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 3552,
"documentation": "https://getarcane.app/docs",
"website": "https://getarcane.app/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/arcane.webp",
"config_path": "/opt/arcane/.env",
"description": "Arcane is designed to be an easy and modern Docker management platform, built with everybody in mind. The goal of Arcane is to be built for and by the community to make sure nobody feels left out or behind with their specific features or processes. ",
"install_methods": [
{
"type": "default",
"script": "tools/addon/arcane.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": "arcane",
"password": "arcane-admin"
},
"notes": [
{
"text": "This is an addon script intended to be used on top of an existing Docker container.",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "ArchiveBox",
"slug": "archivebox",
"categories": [
12
],
"date_created": "2024-10-19",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://github.com/ArchiveBox/ArchiveBox/wiki",
"website": "https://archivebox.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/archivebox.webp",
"config_path": "/opt/archivebox/data/ArchiveBox.conf",
"description": "ArchiveBox is an open source tool that lets organizations & individuals archive both public & private web content while retaining control over their data. It can be used to save copies of bookmarks, preserve evidence for legal cases, backup photos from FB/Insta/Flickr or media from YT/Soundcloud/etc., save research papers, and more...",
"install_methods": [
{
"type": "default",
"script": "ct/archivebox.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 8,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": "archivebox",
"password": "helper-scripts.com"
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Arch Linux",
"slug": "archlinux-vm",
"categories": [
2
],
"date_created": "2025-01-27",
"type": "vm",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://wiki.archlinux.org/title/Main_page",
"website": "https://archlinux.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/arch-linux.webp",
"config_path": "",
"description": "Arch Linux is a highly customizable, independent Linux distribution that gives users complete control over their system. Known for its rolling release model, Arch Linux is always up-to-date with the latest software. It's favored by experienced users who appreciate its minimalist approach, demanding a hands-on installation and configuration process. This level of control and flexibility makes it a popular choice for those who want to tailor their Linux system to their exact needs.",
"install_methods": [
{
"type": "default",
"script": "vm/archlinux-vm.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "doesnt work with lvm and lvmthin disks!",
"type": "warning"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Argus",
"slug": "argus",
"categories": [
11
],
"date_created": "2025-05-26",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://release-argus.io/docs/overview/",
"website": "https://release-argus.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/argus.webp",
"config_path": "/opt/argus/config.yml",
"description": "Argus will query websites at a user defined interval for new software releases and then trigger Gotify/Slack/Other notification(s) and/or WebHook(s) when one has been found. For example, you could set it to monitor the Argus repo (release-argus/argus). This will query the GitHub API and track the tag_name variable. When this variable changes from what it was on a previous query, a GitHub-style WebHook could be sent that triggers something (like AWX) to update Argus on your server.",
"install_methods": [
{
"type": "default",
"script": "ct/argus.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 3,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Aria2",
"slug": "aria2",
"categories": [
11
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 6880,
"documentation": "https://aria2.github.io/manual/en/html/index.html",
"website": "https://aria2.github.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/aria2.webp",
"config_path": "/root/aria2.daemon",
"description": "Aria2 is a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink.",
"install_methods": [
{
"type": "default",
"script": "ct/aria2.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Within the LXC console, run `cat rpc.secret` to display the rpc-secret. Copy this token and paste it into the Aria2 RPC Secret Token box within the AriaNG Settings. Then, click the reload AriaNG button.",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Asterisk",
"slug": "asterisk",
"categories": [
0
],
"date_created": "2025-05-14",
"type": "ct",
"updateable": false,
"privileged": false,
"interface_port": null,
"documentation": "https://docs.asterisk.org/",
"config_path": "/etc/asterisk",
"website": "https://asterisk.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/asterisk.webp",
"description": "Asterisk is an open-source framework for building communications applications, most commonly used as a phone system (PBX). Developed by Digium (now part of Sangoma), it turns a standard computer into a powerful telephony server.",
"install_methods": [
{
"type": "default",
"script": "ct/asterisk.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "Audiobookshelf",
"slug": "audiobookshelf",
"categories": [
13
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 13378,
"documentation": "https://www.audiobookshelf.org/guides/",
"website": "https://www.audiobookshelf.org/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/audiobookshelf.webp",
"config_path": "/usr/share/audiobookshelf/config",
"description": "Audiobookshelf is a Self-hosted audiobook and podcast server.",
"install_methods": [
{
"type": "default",
"script": "ct/audiobookshelf.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 5,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Authelia",
"slug": "authelia",
"categories": [
6
],
"date_created": "2025-02-24",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 443,
"documentation": "https://www.authelia.com/integration/deployment/bare-metal/",
"website": "https://www.authelia.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/authelia.webp",
"config_path": "/etc/authelia/configuration.yml",
"description": "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies.",
"install_methods": [
{
"type": "default",
"script": "ct/authelia.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "authelia",
"password": "authelia"
},
"notes": [
{
"text": "During installation, you will have to input your domain (ex. domain.com). Authelia will use auth.domain.com",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Autobrr",
"slug": "autobrr",
"categories": [
14
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 7474,
"documentation": "https://autobrr.com/configuration/autobrr",
"website": "https://autobrr.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/autobrr.webp",
"config_path": "/root/.config/autobrr/config.toml",
"description": "Autobrr is a torrent downloading tool that automates the process of downloading torrents. It is designed to be modern and user-friendly, providing users with a convenient and efficient way to download torrent files. With Autobrr, you can schedule and manage your torrent downloads, and have the ability to automatically download torrents based on certain conditions, such as time of day or availability of seeds. This can save you time and effort, allowing you to focus on other tasks while your torrents are being downloaded in the background.",
"install_methods": [
{
"type": "default",
"script": "ct/autobrr.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "Autocaliweb",
"slug": "autocaliweb",
"categories": [
13
],
"date_created": "2025-09-10",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8083,
"documentation": "https://codeberg.org/gelbphoenix/autocaliweb/wiki",
"config_path": "/etc/autocaliweb",
"website": "https://codeberg.org/gelbphoenix/autocaliweb",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/autocaliweb.webp",
"description": "A modern web management system for eBooks, eComics and PDFs",
"install_methods": [
{
"type": "default",
"script": "ct/autocaliweb.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 6,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin",
"password": "admin123"
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "Baby Buddy",
"slug": "babybuddy",
"categories": [
23
],
"date_created": "2025-05-21",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.baby-buddy.net/",
"website": "https://github.com/babybuddy/babybuddy",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/baby-buddy.webp",
"config_path": "/opt/babybuddy/babybuddy/settings/production.py",
"description": "Baby Buddy is an open-source web application designed to assist caregivers in tracking various aspects of a baby's daily routine, including sleep, feedings, diaper changes, tummy time, and more. By recording this data, caregivers can better understand and anticipate their baby's needs, reducing guesswork in daily care. The application offers a user-friendly dashboard for data entry and visualization, supports multiple users, and provides features like timers and reminders. Additionally, Baby Buddy can be integrated with platforms like Home Assistant and Grafana for enhanced functionality.",
"install_methods": [
{
"type": "default",
"script": "ct/babybuddy.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 5,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": "admin",
"password": "admin"
},
"notes": [
{
"text": "for private SSL setup visit: `https://github.com/babybuddy/babybuddy/blob/master/docs/setup/ssl.md`",
"type": "info"
}
]
}

View File

@@ -1,40 +0,0 @@
{
"name": "Backrest",
"slug": "backrest",
"categories": [
7
],
"date_created": "2025-05-27",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 9898,
"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 | /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": [
{
"type": "default",
"script": "ct/backrest.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 8,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"type": "info",
"text": "`cat ~/.ssh/id_ed25519.pub` to view ssh public key. This key is used to authenticate with sftp targets. You can add this key on the sftp server."
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Baïkal",
"slug": "baikal",
"categories": [
0
],
"date_created": "2025-01-31",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://sabre.io/dav/",
"website": "https://sabre.io/baikal/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/baikal.webp",
"config_path": "/opt/baikal/config/baikal.yaml",
"description": "Baïkal is a lightweight CalDAV+CardDAV server. It offers an extensive web interface with easy management of users, address books and calendars.",
"install_methods": [
{
"type": "default",
"script": "ct/baikal.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "Admin",
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "Bar-Assistant",
"slug": "bar-assistant",
"categories": [
24
],
"date_created": "2025-07-14",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.barassistant.app/",
"website": "https://barassistant.app/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bar-assistant.webp",
"config_path": "/opt/bar-assistant",
"description": "Bar Assistant is all-in-one solution for managing your home bar. Compared to other recipe management software that usually tries to be more for general use, Bar Assistant is made specifically for managing cocktail recipes. This means that there are a lot of cocktail-oriented features, like ingredient substitutes, first-class ingredients, ABV calculations, unit switching and more..",
"install_methods": [
{
"type": "default",
"script": "ct/bar-assistant.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "Bazarr",
"slug": "bazarr",
"categories": [
14
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 6767,
"documentation": "https://wiki.bazarr.media/",
"website": "https://www.bazarr.media/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bazarr.webp",
"config_path": "/opt/bazarr/data/config/config.yaml",
"description": "Bazarr is a companion application to Sonarr and Radarr that manages and downloads subtitles based on your requirements.",
"install_methods": [
{
"type": "default",
"script": "ct/bazarr.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "BentoPDF",
"slug": "bentopdf",
"categories": [
12
],
"date_created": "2025-10-30",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://github.com/alam00000/bentopdf",
"website": "https://www.bentopdf.com",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bentopdf.webp",
"config_path": "",
"description": "A privacy-first, 100% client-side PDF Toolkit. No signups/accounts, works in the browser, online or offline.",
"install_methods": [
{
"type": "default",
"script": "ct/bentopdf.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "Beszel",
"slug": "beszel",
"categories": [
9
],
"date_created": "2025-01-20",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8090,
"documentation": "https://beszel.dev/guide/what-is-beszel",
"website": "https://beszel.dev/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/beszel.webp",
"config_path": "",
"description": "A lightweight server monitoring platform that provides Docker statistics, historical data, and alert functions\n ",
"install_methods": [
{
"type": "default",
"script": "ct/beszel.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 5,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,44 +0,0 @@
{
"name": "Bichon",
"slug": "bichon",
"categories": [
7
],
"date_created": "2026-02-07",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 15630,
"documentation": "https://github.com/rustmailer/bichon/wiki",
"config_path": "/opt/bichon/bichon.env",
"website": "https://github.com/rustmailer/bichon",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bichon.webp",
"description": "Bichon is an open-source email archiving system that synchronizes emails from IMAP servers, indexes them for full-text search, and provides a REST API for programmatic access. Unlike email clients, Bichon is designed for archiving and searching rather than sending/receiving emails. It runs as a standalone server application that continuously synchronizes configured email accounts and maintains a searchable local archive.",
"install_methods": [
{
"type": "default",
"script": "ct/bichon.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin",
"password": "admin@bichon"
},
"notes": [
{
"text": "The Disk space initially allocated by the script is only a placeholder, as we can't know how much space you will ever need. You should increase it to match your workload.",
"type": "info"
},
{
"text": "Please copy your `BICHON_ENCRYPT_PASSWORD` from `/opt/bichon/bichon.env` to a safe place.",
"type": "warning"
}
]
}

View File

@@ -1,51 +0,0 @@
{
"name": "Bitmagnet",
"slug": "bitmagnet",
"categories": [
11
],
"date_created": "2025-05-15",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3333,
"documentation": "https://bitmagnet.io/setup.html",
"website": "https://bitmagnet.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bitmagnet.webp",
"config_path": "`/opt/bitmagnet/config.yml` or `/opt/bitmagnet/.env`",
"description": "A self-hosted BitTorrent indexer, DHT crawler, content classifier and torrent search engine with web UI, GraphQL API and Servarr stack integration.",
"install_methods": [
{
"type": "default",
"script": "ct/bitmagnet.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
},
{
"type": "alpine",
"script": "ct/alpine-bitmagnet.sh",
"resources": {
"cpu": 2,
"ram": 1024,
"hdd": 3,
"os": "alpine",
"version": "3.23"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "During installation you will be asked to enter your TMDB API key, if you wanna use it. Make sure you have it ready.",
"type": "info"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Blocky",
"slug": "blocky",
"categories": [
5
],
"date_created": "2024-05-02",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 4000,
"documentation": "https://0xerr0r.github.io/blocky/latest/configuration/",
"website": "https://0xerr0r.github.io/blocky/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/blocky.webp",
"config_path": "/opt/blocky/config.yml",
"description": "Blocky is a software tool designed for blocking unwanted ads and trackers on local networks. It functions as a DNS proxy and runs on the Go programming language. Blocky intercepts requests to advertisements and other unwanted content and blocks them before they reach the end user. This results in a cleaner, faster, and more secure online experience for users connected to the local network. Blocky is open-source, easy to configure and can be run on a variety of devices, making it a versatile solution for small to medium-sized local networks.",
"install_methods": [
{
"type": "default",
"script": "ct/blocky.sh",
"resources": {
"cpu": 1,
"ram": 512,
"hdd": 2,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,40 +0,0 @@
{
"name": "BookLore",
"slug": "booklore",
"categories": [
13
],
"date_created": "2025-06-27",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 6060,
"documentation": "https://booklore-app.github.io/booklore-docs/docs/getting-started",
"website": "https://github.com/booklore-app/booklore",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/booklore.webp",
"config_path": "/opt/booklore_storage/.env",
"description": "BookLore is a self-hosted digital library for managing and reading books, offering a beautiful interface and support for metadata management. Built with a modern tech stack, it provides support for importing, organizing, and reading EPUBs and PDFs, while also managing cover images and book metadata.",
"install_methods": [
{
"type": "default",
"script": "ct/booklore.sh",
"resources": {
"cpu": 3,
"ram": 3072,
"hdd": 7,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Starting Booklore (Web UI) may take up to 2 minutes after a restart or fresh installation.",
"type": "info"
}
]
}

View File

@@ -1,44 +0,0 @@
{
"name": "BookStack",
"slug": "bookstack",
"categories": [
12
],
"date_created": "2024-11-05",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://www.bookstackapp.com/docs/",
"website": "https://www.bookstackapp.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bookstack.webp",
"config_path": "/opt/bookstack/.env",
"description": "BookStack is a user-friendly documentation platform that offers a simple and intuitive experience. New users should be able to create content with basic word-processing skills. While the platform provides advanced features, they do not interfere with the core simplicity of the user experience.",
"install_methods": [
{
"type": "default",
"script": "ct/bookstack.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin@admin.com",
"password": "password"
},
"notes": [
{
"text": "Bookstack works only with static IP. If you change the IP of your LXC, you need to edit the .env file",
"type": "warning"
},
{
"text": "To see database credentials, type `cat ~/bookstack.creds` in LXC console",
"type": "info"
}
]
}

View File

@@ -1,40 +0,0 @@
{
"name": "BunkerWeb",
"slug": "bunkerweb",
"categories": [
6
],
"date_created": "2024-06-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://docs.bunkerweb.io/latest/",
"website": "https://www.bunkerweb.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bunkerweb.webp",
"config_path": "/etc/bunkerweb/variables.env",
"description": "BunkerWeb is a security-focused web server that enhances web application protection. It guards against common web vulnerabilities like SQL injection, XSS, and CSRF. It features simple setup and configuration using a YAML file, customizable security rules, and provides detailed logs for traffic monitoring and threat detection.",
"install_methods": [
{
"type": "default",
"script": "ct/bunkerweb.sh",
"resources": {
"cpu": 2,
"ram": 8192,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
"type": "warning"
}
]
}

View File

@@ -1,35 +0,0 @@
{
"name": "Byparr",
"slug": "byparr",
"categories": [
14
],
"date_created": "2026-01-21",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8191,
"documentation": "https://github.com/ThePhaseless/Byparr/blob/master/README.md",
"website": "https://github.com/ThePhaseless/Byparr",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/byparr.webp",
"config_path": "/etc/systemd/system/byparr.service",
"description": "Byparr is a proxy server to bypass Cloudflare and DDoS-GUARD protection.",
"install_methods": [
{
"type": "default",
"script": "ct/byparr.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -1,35 +0,0 @@
{
"name": "ByteStash",
"slug": "bytestash",
"categories": [
20
],
"date_created": "2025-02-27",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://github.com/jordan-dalby/ByteStash/wiki",
"website": "https://github.com/jordan-dalby/ByteStash",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/bytestash.webp",
"config_path": "",
"description": "ByteStash is a self-hosted web application designed to store, organise, and manage your code snippets efficiently. With support for creating, editing, and filtering snippets, ByteStash helps you keep track of your code in one secure place.",
"install_methods": [
{
"type": "default",
"script": "ct/bytestash.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

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