Compare commits
162 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bf0d43122 | |||
| 3e54356653 | |||
| 1f03150b77 | |||
| cfa250a795 | |||
| bb4c1f2fbf | |||
| 793fba1a53 | |||
| 06b788ee81 | |||
| 667da6a8fb | |||
| e40a258a27 | |||
| ff5aac3889 | |||
| e00d14a3ce | |||
| 5ee75b7460 | |||
| 069ab1b8df | |||
| 209eb2a003 | |||
| 594b1e82bb | |||
| bffc871aa9 | |||
| d77c65093b | |||
| f51d21ff9a | |||
| 27493df7a0 | |||
| 0973d1ccfb | |||
| 11acd8db75 | |||
| e39450ec48 | |||
| 2c4fbc01eb | |||
| dd7a659f22 | |||
| f9039c2ee7 | |||
| 44666826df | |||
| 64a89e3463 | |||
| 0d4e703d70 | |||
| 5fa9846d37 | |||
| e32161b18a | |||
| 92737744ce | |||
| 2fbb6e261c | |||
| 39b3ed29ad | |||
| 9bdc6ae13b | |||
| 9aff2f1090 | |||
| d6e4427ac9 | |||
| 770d89bb90 | |||
| 3aef3bb084 | |||
| e2b09a9fcd | |||
| 96710d22f2 | |||
| cfecd0ed05 | |||
| 480ba6d90f | |||
| 61dcda815a | |||
| 2340816c4e | |||
| 7700d7ce36 | |||
| d701955118 | |||
| 8dc0d17740 | |||
| 17ac5c491c | |||
| 111d9e189e | |||
| 4910c72f81 | |||
| 93fbb2de00 | |||
| 9bf0070762 | |||
| 35c43ad344 | |||
| d9abcadd01 | |||
| 9e879e8e0c | |||
| 413fbcf58a | |||
| bc9d4f19ae | |||
| 9c9bbb4995 | |||
| 5e5513522f | |||
| 1820e2f772 | |||
| 2fbdddefd0 | |||
| 9f20cf42a6 | |||
| 62be65b496 | |||
| 24ebf4d5ac | |||
| 047819b7f3 | |||
| 21b7a89a88 | |||
| 1c3f6a9f89 | |||
| e5535c2bfe | |||
| 236242ee86 | |||
| 7774a1a28d | |||
| e82cc0efc8 | |||
| a87c7556a9 | |||
| d3abb64d4d | |||
| f0cf766ec5 | |||
| b3df8b8b8f | |||
| 60722fe556 | |||
| 8ca359311c | |||
| 95c2dc0687 | |||
| 8c1618aac2 | |||
| 25b9f5f8c7 | |||
| 694f899575 | |||
| b9a2d39851 | |||
| bcb72dc9b8 | |||
| e65ff59c97 | |||
| f4388eacb3 | |||
| 33f8cd35cd | |||
| d19be124e4 | |||
| a03b9d6471 | |||
| 5598553755 | |||
| ff9dabb4f4 | |||
| fa4d0d1ede | |||
| 507d70ad57 | |||
| 5e78d293e6 | |||
| 35de3d31cd | |||
| 08f9c31c92 | |||
| 9d364c3d4e | |||
| 8a5daca0ed | |||
| f34cc91d62 | |||
| c566b53552 | |||
| 0e65b9469e | |||
| ef7f811a7a | |||
| b357b7843d | |||
| daf1a50364 | |||
| 1d190bdf25 | |||
| 2ace018034 | |||
| 9b65262e42 | |||
| 3faab0c7aa | |||
| cff71279aa | |||
| 9b56da1411 | |||
| cfd741c322 | |||
| 2372c4b4b0 | |||
| bc6ab71982 | |||
| 294e4efbc6 | |||
| 5f7cbfd26a | |||
| e8361e4867 | |||
| 4d43d24315 | |||
| 47481482e0 | |||
| e5241115f1 | |||
| 645c635650 | |||
| 8856ef02dd | |||
| 143a973f4f | |||
| 3cdee53cef | |||
| d2a6f1bcf7 | |||
| 526ff8ee04 | |||
| 08e2f99522 | |||
| 773d8e00fc | |||
| 502bd98c2d | |||
| d4fac83a8a | |||
| 4a74204837 | |||
| 3db9344e42 | |||
| 0f437e1b51 | |||
| 7ee5bf33bf | |||
| f18eac6a4f | |||
| 5d3a0ba3cb | |||
| 7d81e169b4 | |||
| c7dddcb1e0 | |||
| 26c68f20be | |||
| 01cf996980 | |||
| 3d1da31f8a | |||
| 9e15d0e45f | |||
| ddc217a7ab | |||
| de67f96032 | |||
| 85240b994e | |||
| f3ce8f7cb4 | |||
| c88fd3c77d | |||
| 4439ef2f3f | |||
| d864252eb8 | |||
| 472813b409 | |||
| 40663cb865 | |||
| 4b22056eb9 | |||
| 55dec1b1b8 | |||
| 8171d2c3dc | |||
| 1c9245c417 | |||
| 28fd647e6a | |||
| 8001edc4d4 | |||
| 83af1dccc3 | |||
| b1cf184616 | |||
| fd12b4c1db | |||
| c3ba64bf0c | |||
| 031debe496 | |||
| ee45ec67d8 | |||
| e6465645b9 |
@@ -58,9 +58,9 @@ body:
|
||||
|
||||
Before continuing, verify that the requested project meets the minimum requirements below.
|
||||
|
||||
**Projects with fewer than 1,000 stars are generally not eligible for a script request.**
|
||||
**Projects with fewer than 1,000 stars, or younger than 6 months, are generally not eligible for a script request.**
|
||||
|
||||
Exceptions are only considered where there is a clearly verifiable, significant public adoption signal.
|
||||
An automated check verifies the star count and project age for GitHub-hosted projects. If the project doesn't meet these requirements, fill in **Justification for an exception** below — without one, the request is closed automatically. With one, it's flagged for manual review instead. Exceptions are rare and require a clearly verifiable, significant public adoption signal.
|
||||
|
||||
- type: input
|
||||
id: repository-stars
|
||||
@@ -134,6 +134,22 @@ body:
|
||||
- label: I understand that requests outside the project scope may be closed without an extensive explanation.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: justification
|
||||
attributes:
|
||||
label: Justification for an exception
|
||||
description: >-
|
||||
Only needed if the project has fewer than 1,000 stars or is younger than 6 months (e.g. it has no GitHub
|
||||
presence, so stars don't apply). Explain the significant public adoption signal. Leave blank if the project
|
||||
meets the normal requirements — requests that don't meet the requirements and have no justification here are
|
||||
closed automatically.
|
||||
placeholder: |
|
||||
Example:
|
||||
No public GitHub repository, but the project has 50k+ active installs reported by its own telemetry
|
||||
dashboard and is covered by several established self-hosting publications.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 997 B After Width: | Height: | Size: 997 B |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
@@ -77,17 +77,6 @@
|
||||
"excludeGlobs": []
|
||||
}
|
||||
],
|
||||
"core": [
|
||||
{
|
||||
"fileStatus": null,
|
||||
"includeGlobs": [
|
||||
"misc/*.func"
|
||||
],
|
||||
"excludeGlobs": [
|
||||
"misc/api.func"
|
||||
]
|
||||
}
|
||||
],
|
||||
"documentation": [
|
||||
{
|
||||
"fileStatus": null,
|
||||
@@ -114,8 +103,7 @@
|
||||
{
|
||||
"fileStatus": null,
|
||||
"includeGlobs": [
|
||||
"api/**",
|
||||
"misc/api.func"
|
||||
"api/**"
|
||||
],
|
||||
"excludeGlobs": []
|
||||
}
|
||||
|
||||
@@ -1,3 +1,224 @@
|
||||
## 2026-10-31
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Docker VM: take the imported disk from vm_import_disk [@MickLesk](https://github.com/MickLesk) ([#18341](https://github.com/community-scripts/ProxmoxVE/pull/18341))
|
||||
- Twenty: move to Node.js 26 [@MickLesk](https://github.com/MickLesk) ([#18337](https://github.com/community-scripts/ProxmoxVE/pull/18337))
|
||||
- Norish: fetch Obscura from the repo Norish pins [@MickLesk](https://github.com/MickLesk) ([#18338](https://github.com/community-scripts/ProxmoxVE/pull/18338))
|
||||
- HAOS VM: take the imported disk from vm_import_disk [@MickLesk](https://github.com/MickLesk) ([#18342](https://github.com/community-scripts/ProxmoxVE/pull/18342))
|
||||
- Aurral: build the pnpm workspace and run backend/server.ts [@MickLesk](https://github.com/MickLesk) ([#18340](https://github.com/community-scripts/ProxmoxVE/pull/18340))
|
||||
- PS5-MQTT: build the yarn workspace and run the packaged server [@MickLesk](https://github.com/MickLesk) ([#18339](https://github.com/community-scripts/ProxmoxVE/pull/18339))
|
||||
- Jellyseerr, Overseerr, Paperless-ngx, Vikunja: skip migration prompts when unattended [@florianpunz](https://github.com/florianpunz) ([#18321](https://github.com/community-scripts/ProxmoxVE/pull/18321))
|
||||
- Discourse: track the Ruby version Discourse requires [@MickLesk](https://github.com/MickLesk) ([#18329](https://github.com/community-scripts/ProxmoxVE/pull/18329))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- MatterJS-Server: Add time sync [@tomfrenzel](https://github.com/tomfrenzel) ([#18330](https://github.com/community-scripts/ProxmoxVE/pull/18330))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Debian VM: keep a static IP without a snippets storage [@MickLesk](https://github.com/MickLesk) ([#18346](https://github.com/community-scripts/ProxmoxVE/pull/18346))
|
||||
- Ubuntu VM: check for a snippets storage before building a static-IP VM [@MickLesk](https://github.com/MickLesk) ([#18347](https://github.com/community-scripts/ProxmoxVE/pull/18347))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: add setup_java_memory: size Java services from the CT's RAM on Proxmox [@MickLesk](https://github.com/MickLesk) ([core#181](https://github.com/community-scripts/core/pull/181))
|
||||
- analytics: name the Proxmox tasks when a container stops mid-install [@MickLesk](https://github.com/MickLesk) ([core#184](https://github.com/community-scripts/core/pull/184))
|
||||
- PVE: do not abort when the spinner PID file cannot be written [@MickLesk](https://github.com/MickLesk) ([core#183](https://github.com/community-scripts/core/pull/183))
|
||||
|
||||
### 📂 Github
|
||||
|
||||
- Drop the legacy engine copies from misc/ [@MickLesk](https://github.com/MickLesk) ([#18294](https://github.com/community-scripts/ProxmoxVE/pull/18294))
|
||||
|
||||
## 2026-10-30
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Reconya ([#18325](https://github.com/community-scripts/ProxmoxVE/pull/18325))
|
||||
- Blinko ([#18324](https://github.com/community-scripts/ProxmoxVE/pull/18324))
|
||||
- ChartDB ([#18323](https://github.com/community-scripts/ProxmoxVE/pull/18323))
|
||||
|
||||
## 2026-10-29
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Karakeep: fix monolith release asset pattern [@MohamedBassem](https://github.com/MohamedBassem) ([#18317](https://github.com/community-scripts/ProxmoxVE/pull/18317))
|
||||
- Vikunja: fold the package's service block into the config's service section [@MickLesk](https://github.com/MickLesk) ([#18311](https://github.com/community-scripts/ProxmoxVE/pull/18311))
|
||||
- Stirling-PDF: size JVM heap from container memory, not host RAM [@aashishvanand](https://github.com/aashishvanand) ([#18292](https://github.com/community-scripts/ProxmoxVE/pull/18292))
|
||||
- fix(authentik): migrate systemd units when still on pre-2026.8 paths [@CervezaStallone](https://github.com/CervezaStallone) ([#18307](https://github.com/community-scripts/ProxmoxVE/pull/18307))
|
||||
- fix(dawarich): serve .mjs MapLibre modules as JavaScript [@ricbaral](https://github.com/ricbaral) ([#18304](https://github.com/community-scripts/ProxmoxVE/pull/18304))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- VictoriaLogs: enable syslog ingestion on TCP/UDP 514 [@opastorello](https://github.com/opastorello) ([#18300](https://github.com/community-scripts/ProxmoxVE/pull/18300))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: Performance - load host data in the background and stop reporting failed pre-checks [@MickLesk](https://github.com/MickLesk) ([core#179](https://github.com/community-scripts/core/pull/179))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- gh: let the bot set oidc_url and license [@MickLesk](https://github.com/MickLesk) ([#18313](https://github.com/community-scripts/ProxmoxVE/pull/18313))
|
||||
|
||||
## 2026-10-28
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- VictoriaLogs ([#18282](https://github.com/community-scripts/ProxmoxVE/pull/18282))
|
||||
- Deemix ([#18272](https://github.com/community-scripts/ProxmoxVE/pull/18272))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(vm/opnsense): increase startup wait from 90 to 180 seconds [@MTlyx](https://github.com/MTlyx) ([#18086](https://github.com/community-scripts/ProxmoxVE/pull/18086))
|
||||
- apache-tomcat: restore the update backup from its real store [@mazelado](https://github.com/mazelado) ([#18145](https://github.com/community-scripts/ProxmoxVE/pull/18145))
|
||||
- AdventureLog: clean-install on update and drop the DRF <3.15 pin [@angusmaul](https://github.com/angusmaul) ([#18281](https://github.com/community-scripts/ProxmoxVE/pull/18281))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Refactor: ownCloud VM [@MickLesk](https://github.com/MickLesk) ([#18295](https://github.com/community-scripts/ProxmoxVE/pull/18295))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Keep the console hint out of the default output [@MickLesk](https://github.com/MickLesk) ([core#176](https://github.com/community-scripts/core/pull/176))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Move a promoted script's telemetry history to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([#18271](https://github.com/community-scripts/ProxmoxVE/pull/18271))
|
||||
|
||||
### ❔ Uncategorized
|
||||
|
||||
- chore(ct): sync tdarr defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18289](https://github.com/community-scripts/ProxmoxVE/pull/18289))
|
||||
|
||||
## 2026-10-27
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Zabbix: leave out the NVIDIA agent2 plugin that breaks the all-plugins install [@MickLesk](https://github.com/MickLesk) ([#18262](https://github.com/community-scripts/ProxmoxVE/pull/18262))
|
||||
- Omada: detect latest version from product download page [@ChrisKappe](https://github.com/ChrisKappe) ([#18248](https://github.com/community-scripts/ProxmoxVE/pull/18248))
|
||||
- LanguageTool: count ngram prompt retries without tripping errexit [@MickLesk](https://github.com/MickLesk) ([#18258](https://github.com/community-scripts/ProxmoxVE/pull/18258))
|
||||
- Overseerr: point fresh installs to Seerr [@MickLesk](https://github.com/MickLesk) ([#18259](https://github.com/community-scripts/ProxmoxVE/pull/18259))
|
||||
- stalwart: pin to v0.16.27 until v1 migration is supported [@MickLesk](https://github.com/MickLesk) ([#18252](https://github.com/community-scripts/ProxmoxVE/pull/18252))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- TurnKey: offer only current appliances, stop on arm64 [@MickLesk](https://github.com/MickLesk) ([#18265](https://github.com/community-scripts/ProxmoxVE/pull/18265))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- NPMplus: let the ACME e-mail stay empty again, Let's Encrypt does not need one [@MickLesk](https://github.com/MickLesk) ([#18263](https://github.com/community-scripts/ProxmoxVE/pull/18263))
|
||||
|
||||
### 🗑️ Deleted Scripts
|
||||
|
||||
- Remove: Readarr [@MickLesk](https://github.com/MickLesk) ([#18264](https://github.com/community-scripts/ProxmoxVE/pull/18264))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Say the same thing on both hosts while a container is created [@MickLesk](https://github.com/MickLesk) ([core#173](https://github.com/community-scripts/core/pull/173))
|
||||
- Skip the IPv6 sysctl when the host kernel has no IPv6 [@MickLesk](https://github.com/MickLesk) ([core#171](https://github.com/community-scripts/core/pull/171))
|
||||
- Stop reporting a closed console as a user abort, and shield the host's own work [@MickLesk](https://github.com/MickLesk) ([core#172](https://github.com/community-scripts/core/pull/172))
|
||||
|
||||
## 2026-10-26
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Vane ([#18168](https://github.com/community-scripts/ProxmoxVE/pull/18168))
|
||||
- HomeTube ([#18172](https://github.com/community-scripts/ProxmoxVE/pull/18172))
|
||||
- Honcho ([#18169](https://github.com/community-scripts/ProxmoxVE/pull/18169))
|
||||
- YTPTube ([#18174](https://github.com/community-scripts/ProxmoxVE/pull/18174))
|
||||
- Stump ([#18173](https://github.com/community-scripts/ProxmoxVE/pull/18173))
|
||||
- Casdoor ([#18170](https://github.com/community-scripts/ProxmoxVE/pull/18170))
|
||||
- Streamystats ([#18171](https://github.com/community-scripts/ProxmoxVE/pull/18171))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Immich: lock only this platform when mise installs the plugin tools [@MickLesk](https://github.com/MickLesk) ([#18241](https://github.com/community-scripts/ProxmoxVE/pull/18241))
|
||||
- Fix service name case for Splunkd [@CerberusStyle](https://github.com/CerberusStyle) ([#18238](https://github.com/community-scripts/ProxmoxVE/pull/18238))
|
||||
- VMs: pass the machine type, CPU, disk cache and discard settings to qm [@MickLesk](https://github.com/MickLesk) ([#18232](https://github.com/community-scripts/ProxmoxVE/pull/18232))
|
||||
- excalidash: bump Node.js from 20 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18213](https://github.com/community-scripts/ProxmoxVE/pull/18213))
|
||||
- readmeabook: bump Node.js from 20 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18217](https://github.com/community-scripts/ProxmoxVE/pull/18217))
|
||||
- homepage: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18214](https://github.com/community-scripts/ProxmoxVE/pull/18214))
|
||||
- remove old -install.sh (verdaccio) [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18218](https://github.com/community-scripts/ProxmoxVE/pull/18218))
|
||||
- meshcentral: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18215](https://github.com/community-scripts/ProxmoxVE/pull/18215))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- MeshCentral: update the npm package, not just the OS [@MickLesk](https://github.com/MickLesk) ([#18243](https://github.com/community-scripts/ProxmoxVE/pull/18243))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: let an install survive a closed console / dont sighup installs [@MickLesk](https://github.com/MickLesk) ([core#167](https://github.com/community-scripts/core/pull/167))
|
||||
- feat: create containers from the linuxcontainers.org catalog when Proxmox has no template [@MickLesk](https://github.com/MickLesk) ([core#25](https://github.com/community-scripts/core/pull/25))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Ref: Docs / Readme [@MickLesk](https://github.com/MickLesk) ([#18233](https://github.com/community-scripts/ProxmoxVE/pull/18233))
|
||||
|
||||
## 2026-10-25
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Dreeve ([#18167](https://github.com/community-scripts/ProxmoxVE/pull/18167))
|
||||
- TaskView ([#18166](https://github.com/community-scripts/ProxmoxVE/pull/18166))
|
||||
- EmDash ([#18165](https://github.com/community-scripts/ProxmoxVE/pull/18165))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(mealie): install ffmpeg for video recipe import [@clartek](https://github.com/clartek) ([#18210](https://github.com/community-scripts/ProxmoxVE/pull/18210))
|
||||
- Termix: step through 2.9.2 when updating from 2.8 or older [@MickLesk](https://github.com/MickLesk) ([#18158](https://github.com/community-scripts/ProxmoxVE/pull/18158))
|
||||
- Element Synapse: remove the registration line by its text, not line 34 [@MickLesk](https://github.com/MickLesk) ([#18201](https://github.com/community-scripts/ProxmoxVE/pull/18201))
|
||||
- Element Synapse: drop the ::1 listener so a container without IPv6 starts [@MickLesk](https://github.com/MickLesk) ([#18180](https://github.com/community-scripts/ProxmoxVE/pull/18180))
|
||||
- Heimdall: generate the app key without the production prompt [@MickLesk](https://github.com/MickLesk) ([#18156](https://github.com/community-scripts/ProxmoxVE/pull/18156))
|
||||
- Frigate: fetch the Intel graphics key with retries before building the media driver [@MickLesk](https://github.com/MickLesk) ([#18192](https://github.com/community-scripts/ProxmoxVE/pull/18192))
|
||||
- Pterodactyl Panel: default the admin's first and last name when left empty [@MickLesk](https://github.com/MickLesk) ([#18177](https://github.com/community-scripts/ProxmoxVE/pull/18177))
|
||||
- Jellyseerr: point fresh installs to Seerr instead of a missing install script [@MickLesk](https://github.com/MickLesk) ([#18183](https://github.com/community-scripts/ProxmoxVE/pull/18183))
|
||||
- Pi-hole: download the installer before running it [@MickLesk](https://github.com/MickLesk) ([#18182](https://github.com/community-scripts/ProxmoxVE/pull/18182))
|
||||
- OmniTools: give the build a git commit to read [@MickLesk](https://github.com/MickLesk) ([#18181](https://github.com/community-scripts/ProxmoxVE/pull/18181))
|
||||
- iVentoy: stop early in an unprivileged container [@MickLesk](https://github.com/MickLesk) ([#18179](https://github.com/community-scripts/ProxmoxVE/pull/18179))
|
||||
- Immich: stop early on Debian 12 instead of failing at apt [@MickLesk](https://github.com/MickLesk) ([#18178](https://github.com/community-scripts/ProxmoxVE/pull/18178))
|
||||
- paperless-ngx: fix missing index folder [@Segelzwerg](https://github.com/Segelzwerg) ([#18142](https://github.com/community-scripts/ProxmoxVE/pull/18142))
|
||||
- Anytype Server: keep the .env across updates and recreate a lost one [@MickLesk](https://github.com/MickLesk) ([#18155](https://github.com/community-scripts/ProxmoxVE/pull/18155))
|
||||
- changedetection: build Browserless from its lockfile on update [@MickLesk](https://github.com/MickLesk) ([#18157](https://github.com/community-scripts/ProxmoxVE/pull/18157))
|
||||
- Zitadel: identify the machine by hostname when it has no private IPv4 [@MickLesk](https://github.com/MickLesk) ([#18139](https://github.com/community-scripts/ProxmoxVE/pull/18139))
|
||||
- fix(bar-assistant): publish starter media catalog so new bars provision [@och29](https://github.com/och29) ([#18130](https://github.com/community-scripts/ProxmoxVE/pull/18130))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Gramps-Web: run the Celery task queue with Redis [@MickLesk](https://github.com/MickLesk) ([#18141](https://github.com/community-scripts/ProxmoxVE/pull/18141))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Hermes Agent: install, update and run everything as the hermes user [@MickLesk](https://github.com/MickLesk) ([#18203](https://github.com/community-scripts/ProxmoxVE/pull/18203))
|
||||
- tubearchivist: fix: prepare tubearchivist for v0.6.0 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#17867](https://github.com/community-scripts/ProxmoxVE/pull/17867))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- TREK: build 5.0 with 4 GB RAM and without dependency install scripts [@MickLesk](https://github.com/MickLesk) ([#18194](https://github.com/community-scripts/ProxmoxVE/pull/18194))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- alpine: fix uv release url [@mfelipe](https://github.com/mfelipe) ([core#168](https://github.com/community-scripts/core/pull/168))
|
||||
- Set npm's script and git policy for root too, so --prefix keeps it [@MickLesk](https://github.com/MickLesk) ([core#170](https://github.com/community-scripts/core/pull/170))
|
||||
- Upgrade Node.js in place when an app package depends on it [@MickLesk](https://github.com/MickLesk) ([core#169](https://github.com/community-scripts/core/pull/169))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- post-pmg-install: hide the subscription nag in the PMG 9 mobile quarantine [@MickLesk](https://github.com/MickLesk) ([#18140](https://github.com/community-scripts/ProxmoxVE/pull/18140))
|
||||
- post-pve-install: hide the mobile subscription nag in every UI language [@MickLesk](https://github.com/MickLesk) ([#18143](https://github.com/community-scripts/ProxmoxVE/pull/18143))
|
||||
|
||||
## 2026-10-24
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
@@ -17,16 +17,6 @@ Fixes #
|
||||
**Tested on:** <!-- e.g. PVE 9.2 / Debian 13 / fresh install + update. Write "not tested" if you could not run it. -->
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🤖 AI Assistance (**X** in brackets)
|
||||
|
||||
> If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any scripts in this PR, you **must** confirm compliance below.
|
||||
> Select exactly one option.
|
||||
|
||||
- [ ] **No AI used** – Scripts were written without AI assistance.
|
||||
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/DevScripts/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/DevScripts/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Type of Change (**X** in brackets)
|
||||
@@ -70,3 +60,13 @@ Guidance:
|
||||
-->
|
||||
|
||||
<!-- The advisory block is only active once it is OUTSIDE this comment. -->
|
||||
|
||||
---
|
||||
|
||||
## 🤖 AI Assistance (**X** in brackets)
|
||||
|
||||
> If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any scripts in this PR, you **must** confirm compliance below.
|
||||
> Select exactly one option.
|
||||
|
||||
- [ ] **No AI used** – Scripts were written without AI assistance.
|
||||
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/DevScripts/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/DevScripts/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Close PRs Missing Template
|
||||
name: Flag PRs Missing Template
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
@@ -14,10 +14,12 @@ jobs:
|
||||
issues: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Close PR if it does not follow the PR template
|
||||
- name: Check PR against the template, comment and label instead of closing
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const MARKER = "<!-- pr-template-check -->";
|
||||
const LABELS = ["missing pr template", "stale"];
|
||||
const pr = context.payload.pull_request;
|
||||
const prNumber = pr.number;
|
||||
const author = pr.user.login;
|
||||
@@ -44,11 +46,11 @@ jobs:
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = pr.labels.map((label) => label.name);
|
||||
const prLabels = pr.labels.map((label) => label.name);
|
||||
const skipLabels = ["automated pr", "keep-open"];
|
||||
|
||||
if (skipLabels.some((label) => labels.includes(label))) {
|
||||
core.info(`PR #${prNumber} has a skip label (${labels.join(", ")}) — skipping template validation.`);
|
||||
if (skipLabels.some((label) => prLabels.includes(label))) {
|
||||
core.info(`PR #${prNumber} has a skip label (${prLabels.join(", ")}) — skipping template validation.`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -114,50 +116,52 @@ jobs:
|
||||
failures.push("At least one **Type of Change** checkbox must be checked.");
|
||||
}
|
||||
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner, repo, issue_number: prNumber, per_page: 100
|
||||
});
|
||||
const mine = comments.find(c => c.body && c.body.includes(MARKER));
|
||||
|
||||
if (failures.length === 0) {
|
||||
core.info(`PR #${prNumber} follows the PR template.`);
|
||||
if (mine && !mine.body.startsWith(MARKER + "\n✅")) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner, repo, comment_id: mine.id,
|
||||
body: MARKER + "\n✅ **Template check passed.** Thanks for fixing the description — the `stale` mark has been removed.",
|
||||
});
|
||||
}
|
||||
for (const name of LABELS) {
|
||||
if (prLabels.includes(name)) {
|
||||
await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name });
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
core.info(`Closing PR #${prNumber} — template validation failed.`);
|
||||
core.info(`PR #${prNumber} — template validation failed, flagging instead of closing.`);
|
||||
|
||||
const templateUrl =
|
||||
"https://github.com/community-scripts/ProxmoxVE/blob/main/.github/pull_request_template.md";
|
||||
const failureList = failures.map((item) => `- ${item}`).join("\n");
|
||||
|
||||
const comment = [
|
||||
`👋 Hi @${author},`,
|
||||
``,
|
||||
`This pull request was closed because it does not follow the [PR template](${templateUrl}).`,
|
||||
``,
|
||||
`Please fix the following and open a new PR (or reopen this one after updating the description):`,
|
||||
``,
|
||||
failureList,
|
||||
``,
|
||||
`> Use the template sections, fill in the description, check all prerequisite boxes, and select at least one type of change.`,
|
||||
``,
|
||||
`Maintainers can add the \`keep-open\` label to exempt a PR from this check.`,
|
||||
``,
|
||||
`Thank you for contributing! 🙏`,
|
||||
].join("\n");
|
||||
const text =
|
||||
MARKER + "\n" +
|
||||
`👋 Hi @${author},\n\n` +
|
||||
`This pull request does not follow the [PR template](${templateUrl}) yet:\n\n` +
|
||||
failureList + "\n\n" +
|
||||
`**Edit the PR description** to fix it — no new PR needed. This check runs again on every edit and clears itself once everything is in place.\n\n` +
|
||||
`Until then the PR is marked \`stale\` and will be closed in **7 days**.\n\n` +
|
||||
`Maintainers can add the \`keep-open\` label to exempt a PR from this check.\n\n` +
|
||||
`Thank you for contributing! 🙏`;
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: prNumber,
|
||||
body: comment,
|
||||
});
|
||||
if (mine) {
|
||||
if (mine.body !== text) {
|
||||
await github.rest.issues.updateComment({ owner, repo, comment_id: mine.id, body: text });
|
||||
}
|
||||
} else {
|
||||
await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body: text });
|
||||
}
|
||||
|
||||
await github.rest.pulls.update({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: prNumber,
|
||||
state: "closed",
|
||||
});
|
||||
|
||||
await github.rest.issues.addLabels({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: prNumber,
|
||||
labels: ["missing pr template"],
|
||||
});
|
||||
const toAdd = LABELS.filter(name => !prLabels.includes(name));
|
||||
if (toAdd.length > 0) {
|
||||
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: toAdd });
|
||||
}
|
||||
|
||||
@@ -258,3 +258,20 @@ jobs:
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
ENDSCRIPT
|
||||
shell: bash
|
||||
|
||||
- name: Move the scripts' telemetry to ProxmoxVE
|
||||
if: ${{ !cancelled() && steps.find_issue.outputs.issue_numbers != '' && steps.get_slugs.outputs.count != '0' }}
|
||||
shell: bash
|
||||
env:
|
||||
TELEMETRY_ADMIN_TOKEN: ${{ secrets.TELEMETRY_ADMIN_TOKEN }}
|
||||
run: |
|
||||
if [ -z "$TELEMETRY_ADMIN_TOKEN" ]; then
|
||||
echo "TELEMETRY_ADMIN_TOKEN is not set, skipping"
|
||||
exit 0
|
||||
fi
|
||||
body=$(jq -cn --arg s "$(cat pocketbase_slugs.txt)" \
|
||||
'{slugs: ($s | split(" ") | map(select(. != ""))), from: "DevScripts", to: "ProxmoxVE"}')
|
||||
curl -fsS -X POST "https://telemetry.community-scripts.org/api/admin/migrate-script" \
|
||||
-H "Authorization: Bearer ${TELEMETRY_ADMIN_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$body" || echo "::warning::Moving the telemetry history to ProxmoxVE failed"
|
||||
|
||||
@@ -267,15 +267,14 @@ jobs:
|
||||
const stubPath = path.join('ct', slug + '.sh');
|
||||
const content = [
|
||||
"#!/usr/bin/env bash",
|
||||
"source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)",
|
||||
"source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/core/main/core/core.func)",
|
||||
"# Copyright (c) 2021-2026 community-scripts ORG",
|
||||
"# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE",
|
||||
"",
|
||||
`APP="${appName.replace(/"/g, '\\"')}"`,
|
||||
"",
|
||||
'header_info "$APP"',
|
||||
'variables',
|
||||
'color',
|
||||
'header_info',
|
||||
"",
|
||||
'msg_error "This script is no longer available in community-scripts."',
|
||||
`msg_error "${deletedMessage.replace(/"/g, '\\"')}"`,
|
||||
|
||||
@@ -343,6 +343,7 @@ jobs:
|
||||
'`cpu` `ram` `hdd` `os` `version` also work without `method` — they go to the\n' +
|
||||
'default install method, e.g. `/pocketbase <slug> hdd=25`\n\n' +
|
||||
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `repository` ' +
|
||||
'`oidc_url` `license` ' +
|
||||
'`config_path` `port` `default_user` `default_passwd` ' +
|
||||
'`updateable` `privileged` `is_dev` `has_arm` ' +
|
||||
'`architectures` (amd64,arm64) `platforms` (pve,incus) ' +
|
||||
@@ -544,6 +545,7 @@ jobs:
|
||||
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
|
||||
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
|
||||
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
|
||||
out.push('- **License:** ' + (record.license || '—'));
|
||||
out.push('- **Architectures:** ' + ((record.architectures || []).join(', ') || 'amd64'));
|
||||
out.push('- **Platforms:** ' + ((record.platforms || []).join(', ') || 'pve'));
|
||||
if (record.is_dev) out.push('- **Dev:** Yes');
|
||||
@@ -554,6 +556,7 @@ jobs:
|
||||
out.push('**Links:**');
|
||||
out.push('- **Website:** ' + (record.website || '—'));
|
||||
out.push('- **Docs:** ' + (record.documentation || '—'));
|
||||
out.push('- **OIDC docs:** ' + (record.oidc_url || '—'));
|
||||
out.push('- **Logo:** ' + (record.logo ? '[link](' + record.logo + ')' : '—'));
|
||||
out.push('- **GitHub:** ' + (record.github || '—'));
|
||||
if (record.config_path) out.push('- **Config:** `' + record.config_path + '`');
|
||||
@@ -985,6 +988,8 @@ jobs:
|
||||
logo: 'string',
|
||||
documentation: 'string',
|
||||
website: 'string',
|
||||
oidc_url: 'string',
|
||||
license: 'string',
|
||||
project_url: 'string',
|
||||
repository: 'string',
|
||||
config_path: 'string',
|
||||
|
||||
@@ -184,8 +184,8 @@ jobs:
|
||||
);
|
||||
}
|
||||
lines.push(
|
||||
'Only the script itself comes from this branch. Whatever it loads, the engine',
|
||||
'or the `misc/` helpers, still comes from `main`.',
|
||||
'Only the script itself comes from this branch. The engine it loads still',
|
||||
'comes from community-scripts/core on `main`.',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
name: Request Script Eligibility Check
|
||||
|
||||
# category.slug is the same string GitHub uses in the "new discussion" URL
|
||||
# (?category=request-script, linked from every repo's issue chooser), so this
|
||||
# guard matches the live category without needing its numeric id.
|
||||
on:
|
||||
discussion:
|
||||
types: [created, edited, reopened]
|
||||
|
||||
jobs:
|
||||
check-eligibility:
|
||||
if: github.repository == 'community-scripts/ProxmoxVE' && github.event.discussion.category.slug == 'request-script'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
discussions: write
|
||||
issues: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Verify stars/age, flag or close
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const discussion = context.payload.discussion;
|
||||
|
||||
if (!discussion || discussion.state === "closed") {
|
||||
core.info("Discussion missing or already closed — skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const body = discussion.body || "";
|
||||
const lines = body.split("\n");
|
||||
const fields = {};
|
||||
let current = null;
|
||||
for (const line of lines) {
|
||||
const m = line.match(/^###\s+(.+?)\s*$/);
|
||||
if (m) {
|
||||
current = m[1].trim();
|
||||
fields[current] = [];
|
||||
} else if (current) {
|
||||
fields[current].push(line);
|
||||
}
|
||||
}
|
||||
function fieldText(label) {
|
||||
const raw = (fields[label] || []).join("\n").trim();
|
||||
return raw === "_No response_" ? "" : raw;
|
||||
}
|
||||
|
||||
const sourceRepo = fieldText("Source Repository");
|
||||
const justification = fieldText("Justification for an exception");
|
||||
|
||||
let eligible = false;
|
||||
let verified = false;
|
||||
const ghMatch = sourceRepo.match(/^https?:\/\/(?:www\.)?github\.com\/([^\/\s]+)\/([^\/\s#?]+?)(?:\.git)?\/?(?:[#?].*)?$/i);
|
||||
|
||||
if (ghMatch) {
|
||||
const [, repoOwner, repoName] = ghMatch;
|
||||
try {
|
||||
const { data: repoData } = await github.rest.repos.get({ owner: repoOwner, repo: repoName });
|
||||
const stars = repoData.stargazers_count;
|
||||
const createdAt = new Date(repoData.created_at);
|
||||
const now = new Date();
|
||||
const ageMonths =
|
||||
(now.getFullYear() - createdAt.getFullYear()) * 12 +
|
||||
(now.getMonth() - createdAt.getMonth()) -
|
||||
(now.getDate() < createdAt.getDate() ? 1 : 0);
|
||||
eligible = stars >= 1000 && ageMonths >= 6;
|
||||
verified = true;
|
||||
core.info(`Verified ${repoOwner}/${repoName}: ${stars} stars, ${ageMonths} months old, eligible=${eligible}`);
|
||||
} catch (err) {
|
||||
core.warning(`Could not verify ${repoOwner}/${repoName}: ${err.message} — treating as unverifiable.`);
|
||||
}
|
||||
} else {
|
||||
core.info("Source Repository is not a github.com URL — cannot auto-verify, treating as unverifiable.");
|
||||
}
|
||||
|
||||
if (eligible) {
|
||||
core.info(`Discussion #${discussion.number} meets the requirements — no action.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = (discussion.labels || []).map(l => l.name);
|
||||
const reasonLine = verified
|
||||
? "the source repository does not meet the 1,000-star / 6-month minimum adoption requirement"
|
||||
: "the source repository's star count and age could not be verified automatically";
|
||||
|
||||
if (justification) {
|
||||
if (labels.includes("investigation")) {
|
||||
core.info(`Discussion #${discussion.number} already flagged for investigation — skipping.`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await github.rest.issues.createLabel({
|
||||
owner, repo, name: "investigation",
|
||||
color: "fbca04",
|
||||
description: "Below the normal script-request threshold; a justification was given and needs maintainer review.",
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.status !== 422) throw err;
|
||||
}
|
||||
|
||||
const labelQuery = await github.graphql(
|
||||
`query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { label(name: "investigation") { id } } }`,
|
||||
{ owner, repo }
|
||||
);
|
||||
const labelNodeId = labelQuery.repository.label.id;
|
||||
|
||||
await github.graphql(
|
||||
`mutation($labelableId: ID!, $labelIds: [ID!]!) { addLabelsToLabelable(input: { labelableId: $labelableId, labelIds: $labelIds }) { clientMutationId } }`,
|
||||
{ labelableId: discussion.node_id, labelIds: [labelNodeId] }
|
||||
);
|
||||
|
||||
await github.graphql(
|
||||
`mutation($discussionId: ID!, $body: String!) { addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { comment { id } } }`,
|
||||
{
|
||||
discussionId: discussion.node_id,
|
||||
body:
|
||||
`Thanks for the justification — ${reasonLine}, so this has been flagged \`investigation\` for a maintainer ` +
|
||||
`to review manually rather than closed automatically.`,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
await github.graphql(
|
||||
`mutation($discussionId: ID!, $body: String!) { addDiscussionComment(input: { discussionId: $discussionId, body: $body }) { comment { id } } }`,
|
||||
{
|
||||
discussionId: discussion.node_id,
|
||||
body:
|
||||
`This request doesn't meet the minimum requirements (1,000 stars, project at least 6 months old) — ` +
|
||||
`${reasonLine}, and no justification was given. Closing automatically.\n\n` +
|
||||
`If you believe this project qualifies for an exception, edit this discussion to fill in ` +
|
||||
`**Justification for an exception** and reopen it — it will then be flagged for manual review instead of closed again.`,
|
||||
}
|
||||
);
|
||||
|
||||
await github.graphql(
|
||||
`mutation($discussionId: ID!) { closeDiscussion(input: { discussionId: $discussionId, reason: OUTDATED }) { discussion { id } } }`,
|
||||
{ discussionId: discussion.node_id }
|
||||
);
|
||||
}
|
||||
@@ -22,90 +22,112 @@ jobs:
|
||||
const now = new Date();
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
|
||||
// --- When stale label is added, comment immediately ---
|
||||
const TEMPLATE_LABEL = "missing pr template";
|
||||
const MAINTAINERS = ["OWNER", "MEMBER", "COLLABORATOR"];
|
||||
const days = d => (now - d) / (1000 * 60 * 60 * 24);
|
||||
const staleNotice = author =>
|
||||
`@${author} This PR has been marked as stale. It will be closed if no new commits are added in 7 days.`;
|
||||
|
||||
// Only fires for a maintainer's label: labels set with GITHUB_TOKEN raise no event.
|
||||
if (context.eventName === "pull_request_target" && context.payload.action === "labeled") {
|
||||
const label = context.payload.label?.name;
|
||||
if (label === "stale") {
|
||||
const author = context.payload.pull_request.user.login;
|
||||
const pr = context.payload.pull_request;
|
||||
const labels = (pr.labels || []).map(l => l.name);
|
||||
if (context.payload.label?.name === "stale" && !labels.includes(TEMPLATE_LABEL)) {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
body: `@${author} This PR has been marked as stale. It will be closed if no new commits are added in 7 days.`
|
||||
owner, repo, issue_number: pr.number, body: staleNotice(pr.user.login)
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Scheduled run: check all stale PRs ---
|
||||
const { data: prs } = await github.rest.pulls.list({
|
||||
owner,
|
||||
repo,
|
||||
state: "open",
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
|
||||
const prs = await github.paginate(github.rest.pulls.list, { owner, repo, state: "open", per_page: 100 });
|
||||
|
||||
for (const pr of prs) {
|
||||
const hasStale = pr.labels.some(l => l.name === "stale");
|
||||
if (!hasStale) continue;
|
||||
|
||||
// Get timeline events to find when stale label was added
|
||||
const { data: events } = await github.rest.issues.listEvents({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Find the most recent time the stale label was added
|
||||
const staleLabelEvents = events
|
||||
.filter(e => e.event === "labeled" && e.label?.name === "stale")
|
||||
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
|
||||
|
||||
if (staleLabelEvents.length === 0) continue;
|
||||
|
||||
const staleLabelDate = new Date(staleLabelEvents[0].created_at);
|
||||
const daysSinceStale = (now - staleLabelDate) / (1000 * 60 * 60 * 24);
|
||||
|
||||
// Check for new commits since stale label was added
|
||||
const { data: commits } = await github.rest.pulls.listCommits({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number
|
||||
});
|
||||
|
||||
const lastCommitDate = new Date(commits[commits.length - 1].commit.author.date);
|
||||
const labels = pr.labels.map(l => l.name);
|
||||
const author = pr.user.login;
|
||||
|
||||
// If there are new commits after the stale label, remove it
|
||||
if (lastCommitDate > staleLabelDate) {
|
||||
await github.rest.issues.removeLabel({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
name: "stale"
|
||||
const hasStale = labels.includes("stale");
|
||||
|
||||
if (labels.includes("keep-open")) {
|
||||
if (hasStale) {
|
||||
await github.rest.issues.removeLabel({ owner, repo, issue_number: pr.number, name: "stale" });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner, repo, issue_number: pr.number, per_page: 100
|
||||
});
|
||||
const commits = await github.paginate(github.rest.pulls.listCommits, {
|
||||
owner, repo, pull_number: pr.number, per_page: 100
|
||||
});
|
||||
const lastCommitDate = commits.length > 0
|
||||
? new Date(commits[commits.length - 1].commit.author.date)
|
||||
: new Date(pr.created_at);
|
||||
const humanComments = comments.filter(c => c.user?.type !== "Bot");
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Auto-label PRs with no activity in the last 14 days,
|
||||
// but ONLY if someone other than the author has engaged.
|
||||
// -------------------------------------------------------
|
||||
if (!hasStale) {
|
||||
const reviews = await github.paginate(github.rest.pulls.listReviews, {
|
||||
owner, repo, pull_number: pr.number, per_page: 100
|
||||
});
|
||||
const engaged =
|
||||
reviews.some(r => r.user?.type !== "Bot" && r.user?.login !== author) ||
|
||||
humanComments.some(c => c.user?.login !== author);
|
||||
if (!engaged) continue;
|
||||
|
||||
const lastCommentDate = humanComments.length > 0
|
||||
? new Date(humanComments[humanComments.length - 1].created_at)
|
||||
: null;
|
||||
const lastActivityDate = lastCommentDate && lastCommentDate > lastCommitDate
|
||||
? lastCommentDate
|
||||
: lastCommitDate;
|
||||
|
||||
if (days(lastActivityDate) > 14) {
|
||||
await github.rest.issues.addLabels({ owner, repo, issue_number: pr.number, labels: ["stale"] });
|
||||
await github.rest.issues.createComment({ owner, repo, issue_number: pr.number, body: staleNotice(author) });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Manage already-stale PRs
|
||||
// -------------------------------------------------------
|
||||
const events = await github.paginate(github.rest.issues.listEvents, {
|
||||
owner, repo, issue_number: pr.number, per_page: 100
|
||||
});
|
||||
const staleDates = events
|
||||
.filter(e => e.event === "labeled" && e.label?.name === "stale")
|
||||
.map(e => new Date(e.created_at));
|
||||
if (staleDates.length === 0) continue;
|
||||
const staleLabelDate = new Date(Math.max(...staleDates));
|
||||
const isTemplateIssue = labels.includes(TEMPLATE_LABEL);
|
||||
|
||||
// A push ends an inactivity mark; a template mark only ends via close-invalid-pr-template.yml's re-check.
|
||||
if (!isTemplateIssue && lastCommitDate > staleLabelDate) {
|
||||
await github.rest.issues.removeLabel({ owner, repo, issue_number: pr.number, name: "stale" });
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
owner, repo, issue_number: pr.number,
|
||||
body: `@${author} Recent activity detected. Removing stale label.`
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// If 7 days have passed since stale label, close the PR
|
||||
else if (daysSinceStale > 7) {
|
||||
await github.rest.pulls.update({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: pr.number,
|
||||
state: "closed"
|
||||
});
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: pr.number,
|
||||
body: `@${author} Closing stale PR due to inactivity (no commits for 7 days after stale label).`
|
||||
});
|
||||
}
|
||||
|
||||
// A maintainer comment after the mark restarts the 7 days.
|
||||
const maintainerDates = humanComments
|
||||
.filter(c => MAINTAINERS.includes(c.author_association) && c.user?.login !== author)
|
||||
.map(c => new Date(c.created_at))
|
||||
.filter(d => d > staleLabelDate);
|
||||
const clockStart = maintainerDates.length > 0 ? new Date(Math.max(...maintainerDates)) : staleLabelDate;
|
||||
if (days(clockStart) <= 7) continue;
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner, repo, issue_number: pr.number,
|
||||
body: isTemplateIssue
|
||||
? `@${author} Closing: the PR template requirements listed above were still missing 7 days later. Once they are in place, please open a new pull request.`
|
||||
: `@${author} Closing stale PR due to inactivity (no commits for 7 days after stale label).`
|
||||
});
|
||||
await github.rest.pulls.update({ owner, repo, pull_number: pr.number, state: "closed" });
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ name: Sync ct/install to Incus
|
||||
#
|
||||
# The actual mirroring + transformation lives in community-scripts/Incus
|
||||
# (.github/workflows/sync-scripts.yml): it rewrites each script's bootstrap line
|
||||
# to load the engine from community-scripts/core (ProxmoxVE's misc/build.func is
|
||||
# a monolith with no Incus backend), so a plain 1:1 copy would break every Incus
|
||||
# to load the engine from community-scripts/core (ct scripts here load its PVE
|
||||
# backend; Incus needs the Incus one), so a plain 1:1 copy would break every Incus
|
||||
# script. We therefore only fire a repository_dispatch and let that single
|
||||
# source of truth do the work (and auto-approve + merge its own PR).
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/.github/assets/logo.png" height="100px" />
|
||||
</a>
|
||||
</div>
|
||||
<h1 align="center">Changelog</h1>
|
||||
@@ -122,6 +122,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -135,7 +138,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
|
||||
<details>
|
||||
<summary><h4>October (24 entries)</h4></summary>
|
||||
<summary><h4>October (31 entries)</h4></summary>
|
||||
|
||||
[View October 2026 Changelog](.github/changelogs/2026/10.md)
|
||||
|
||||
@@ -568,6 +571,242 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-11-04
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Teleport: Poll readyz instead of fixed 10 second sleep. [@cthach](https://github.com/cthach) ([#18461](https://github.com/community-scripts/ProxmoxVE/pull/18461))
|
||||
- n8n: install past its unsatisfiable canvas dependencies [@MickLesk](https://github.com/MickLesk) ([#18439](https://github.com/community-scripts/ProxmoxVE/pull/18439))
|
||||
- Teable: add Redis cache [@MickLesk](https://github.com/MickLesk) ([#18450](https://github.com/community-scripts/ProxmoxVE/pull/18450))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: say why download_gpg_key failed [@MickLesk](https://github.com/MickLesk) ([core#208](https://github.com/community-scripts/core/pull/208))
|
||||
- feat: read the MOTD's OS version at login [@MickLesk](https://github.com/MickLesk) ([core#207](https://github.com/community-scripts/core/pull/207))
|
||||
- feat: skip screen clear when there is no terminal | pin only the scripts own app with var_appversion [@MickLesk](https://github.com/MickLesk) ([core#203](https://github.com/community-scripts/core/pull/203))
|
||||
|
||||
## 2026-11-03
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Fedora VM: let the engine install libguestfs-tools [@MickLesk](https://github.com/MickLesk) ([#18422](https://github.com/community-scripts/ProxmoxVE/pull/18422))
|
||||
- Cinephage: run the camoufox binary the package now ships [@MickLesk](https://github.com/MickLesk) ([#18426](https://github.com/community-scripts/ProxmoxVE/pull/18426))
|
||||
- AlmaLinux VM: report failures through the engine's error handler [@MickLesk](https://github.com/MickLesk) ([#18418](https://github.com/community-scripts/ProxmoxVE/pull/18418))
|
||||
- WireGuard: give the Debian container 1 GB for WGDashboard [@MickLesk](https://github.com/MickLesk) ([#18419](https://github.com/community-scripts/ProxmoxVE/pull/18419))
|
||||
- zabbix: use os specific apt packages [@MickLesk](https://github.com/MickLesk) ([#18417](https://github.com/community-scripts/ProxmoxVE/pull/18417))
|
||||
- Discourse: build libvips 8.18 for its image worker [@MickLesk](https://github.com/MickLesk) ([#18430](https://github.com/community-scripts/ProxmoxVE/pull/18430))
|
||||
- Wazuh: show the installer's own error when it fails [@MickLesk](https://github.com/MickLesk) ([#18428](https://github.com/community-scripts/ProxmoxVE/pull/18428))
|
||||
- Tracearr: move to Node.js 26 [@connorgallopo](https://github.com/connorgallopo) ([#18393](https://github.com/community-scripts/ProxmoxVE/pull/18393))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Wiki.js: install 3.x [@MickLesk](https://github.com/MickLesk) ([#18382](https://github.com/community-scripts/ProxmoxVE/pull/18382))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- OpenWrt VM: read the stable release from downloads.openwrt.org [@MickLesk](https://github.com/MickLesk) ([#18411](https://github.com/community-scripts/ProxmoxVE/pull/18411))
|
||||
- Immich: fetch VectorChord from its new repo, skip Java, get GeoNames first [@MickLesk](https://github.com/MickLesk) ([#18397](https://github.com/community-scripts/ProxmoxVE/pull/18397))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fix: put the reason for a VM failure into its trace [@MickLesk](https://github.com/MickLesk) ([core#200](https://github.com/community-scripts/core/pull/200))
|
||||
- fix: check the bridge before creating a container, and its state after start [@MickLesk](https://github.com/MickLesk) ([core#199](https://github.com/community-scripts/core/pull/199))
|
||||
- ref: offer to remove only the container this run created [@MickLesk](https://github.com/MickLesk) ([core#198](https://github.com/community-scripts/core/pull/198))
|
||||
- feat: report a cancelled tool dialog as an abort and name the failing command [@MickLesk](https://github.com/MickLesk) ([core#197](https://github.com/community-scripts/core/pull/197))
|
||||
- feat: check KVM and the host's threads before building a VM [@MickLesk](https://github.com/MickLesk) ([core#196](https://github.com/community-scripts/core/pull/196))
|
||||
- ref: give a host tool one log file for the whole run [@MickLesk](https://github.com/MickLesk) ([core#194](https://github.com/community-scripts/core/pull/194))
|
||||
- fix: keep a piped stdin when output moves to the log after a hangup [@MickLesk](https://github.com/MickLesk) ([core#193](https://github.com/community-scripts/core/pull/193))
|
||||
- fix: pve-LXC: say when the container went away during its setup [@MickLesk](https://github.com/MickLesk) ([core#192](https://github.com/community-scripts/core/pull/192))
|
||||
- fix: treat Esc in a VM wizard dialog as leaving the script [@MickLesk](https://github.com/MickLesk) ([core#190](https://github.com/community-scripts/core/pull/190))
|
||||
- ref: count a container stopped during a detached install as an abort [@MickLesk](https://github.com/MickLesk) ([core#187](https://github.com/community-scripts/core/pull/187))
|
||||
- feat: find the assets of a renamed GitHub repo without the API [@MickLesk](https://github.com/MickLesk) ([core#188](https://github.com/community-scripts/core/pull/188))
|
||||
- fix: restore npm when an interrupted update left it behind [@MickLesk](https://github.com/MickLesk) ([core#189](https://github.com/community-scripts/core/pull/189))
|
||||
- feat: add var_cmode to set the container console mode [@MickLesk](https://github.com/MickLesk) ([core#180](https://github.com/community-scripts/core/pull/180))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- all-templates: answering No or Cancel is not a failure [@MickLesk](https://github.com/MickLesk) ([#18423](https://github.com/community-scripts/ProxmoxVE/pull/18423))
|
||||
- homebrew: skip service accounts when picking the user, survive a failed apt update [@MickLesk](https://github.com/MickLesk) ([#18424](https://github.com/community-scripts/ProxmoxVE/pull/18424))
|
||||
- add-tailscale-lxc: start a stopped container and check its OS first [@MickLesk](https://github.com/MickLesk) ([#18421](https://github.com/community-scripts/ProxmoxVE/pull/18421))
|
||||
- netdata: survive a failed apt update, leave quietly on Cancel [@MickLesk](https://github.com/MickLesk) ([#18427](https://github.com/community-scripts/ProxmoxVE/pull/18427))
|
||||
- Privilege-Converter: offer only container-capable storages as the converter's restore target [@MickLesk](https://github.com/MickLesk) ([#18415](https://github.com/community-scripts/ProxmoxVE/pull/18415))
|
||||
- let post-pve-install go on when legacy sources are kept [@MickLesk](https://github.com/MickLesk) ([#18403](https://github.com/community-scripts/ProxmoxVE/pull/18403))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- update-apps: say why an backup or restore failed [@MickLesk](https://github.com/MickLesk) ([#18405](https://github.com/community-scripts/ProxmoxVE/pull/18405))
|
||||
- Keep host tools running when clear does not know the terminal [@MickLesk](https://github.com/MickLesk) ([#18412](https://github.com/community-scripts/ProxmoxVE/pull/18412))
|
||||
- Refuse to run the PBS 4 upgrade on a Proxmox VE host [@MickLesk](https://github.com/MickLesk) ([#18416](https://github.com/community-scripts/ProxmoxVE/pull/18416))
|
||||
- fstrim: keep trimming when pct fstrim fails on one container [@MickLesk](https://github.com/MickLesk) ([#18413](https://github.com/community-scripts/ProxmoxVE/pull/18413))
|
||||
- execute-lxc: do not abort on a container that is not Debian or Ubuntu [@MickLesk](https://github.com/MickLesk) ([#18414](https://github.com/community-scripts/ProxmoxVE/pull/18414))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- github: flag instead of closing on first PR template miss; add script-request eligibility check [@MickLesk](https://github.com/MickLesk) ([#18384](https://github.com/community-scripts/ProxmoxVE/pull/18384))
|
||||
|
||||
## 2026-11-02
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- FileFlows: replace the program folders on update [@MickLesk](https://github.com/MickLesk) ([#18380](https://github.com/community-scripts/ProxmoxVE/pull/18380))
|
||||
- anchor: bump Node.js from 24 to 26 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18373](https://github.com/community-scripts/ProxmoxVE/pull/18373))
|
||||
- guardian: bump Node.js from 24 to 26 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18375](https://github.com/community-scripts/ProxmoxVE/pull/18375))
|
||||
- nametag: bump Node.js from 20 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18376](https://github.com/community-scripts/ProxmoxVE/pull/18376))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- github: trim theater, add signal to the engine bug report; move AI block to end of PR template [@MickLesk](https://github.com/MickLesk) ([core#186](https://github.com/community-scripts/core/pull/186))
|
||||
- fix: do not wait forever for verbose output a daemon keeps open [@MickLesk](https://github.com/MickLesk) ([core#185](https://github.com/community-scripts/core/pull/185))
|
||||
|
||||
## 2026-11-01
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Amazon Linux ([#18369](https://github.com/community-scripts/ProxmoxVE/pull/18369))
|
||||
- CachyOS VM ([#18368](https://github.com/community-scripts/ProxmoxVE/pull/18368))
|
||||
- Razzia ([#18366](https://github.com/community-scripts/ProxmoxVE/pull/18366))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(zerobyte): build the bundled local agent [@nicotsx](https://github.com/nicotsx) ([#18363](https://github.com/community-scripts/ProxmoxVE/pull/18363))
|
||||
|
||||
## 2026-10-31
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Docker VM: take the imported disk from vm_import_disk [@MickLesk](https://github.com/MickLesk) ([#18341](https://github.com/community-scripts/ProxmoxVE/pull/18341))
|
||||
- Twenty: move to Node.js 26 [@MickLesk](https://github.com/MickLesk) ([#18337](https://github.com/community-scripts/ProxmoxVE/pull/18337))
|
||||
- Norish: fetch Obscura from the repo Norish pins [@MickLesk](https://github.com/MickLesk) ([#18338](https://github.com/community-scripts/ProxmoxVE/pull/18338))
|
||||
- HAOS VM: take the imported disk from vm_import_disk [@MickLesk](https://github.com/MickLesk) ([#18342](https://github.com/community-scripts/ProxmoxVE/pull/18342))
|
||||
- Aurral: build the pnpm workspace and run backend/server.ts [@MickLesk](https://github.com/MickLesk) ([#18340](https://github.com/community-scripts/ProxmoxVE/pull/18340))
|
||||
- PS5-MQTT: build the yarn workspace and run the packaged server [@MickLesk](https://github.com/MickLesk) ([#18339](https://github.com/community-scripts/ProxmoxVE/pull/18339))
|
||||
- Jellyseerr, Overseerr, Paperless-ngx, Vikunja: skip migration prompts when unattended [@florianpunz](https://github.com/florianpunz) ([#18321](https://github.com/community-scripts/ProxmoxVE/pull/18321))
|
||||
- Discourse: track the Ruby version Discourse requires [@MickLesk](https://github.com/MickLesk) ([#18329](https://github.com/community-scripts/ProxmoxVE/pull/18329))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- MatterJS-Server: Add time sync [@tomfrenzel](https://github.com/tomfrenzel) ([#18330](https://github.com/community-scripts/ProxmoxVE/pull/18330))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Debian VM: keep a static IP without a snippets storage [@MickLesk](https://github.com/MickLesk) ([#18346](https://github.com/community-scripts/ProxmoxVE/pull/18346))
|
||||
- Ubuntu VM: check for a snippets storage before building a static-IP VM [@MickLesk](https://github.com/MickLesk) ([#18347](https://github.com/community-scripts/ProxmoxVE/pull/18347))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: add setup_java_memory: size Java services from the CT's RAM on Proxmox [@MickLesk](https://github.com/MickLesk) ([core#181](https://github.com/community-scripts/core/pull/181))
|
||||
- analytics: name the Proxmox tasks when a container stops mid-install [@MickLesk](https://github.com/MickLesk) ([core#184](https://github.com/community-scripts/core/pull/184))
|
||||
- PVE: do not abort when the spinner PID file cannot be written [@MickLesk](https://github.com/MickLesk) ([core#183](https://github.com/community-scripts/core/pull/183))
|
||||
|
||||
### 📂 Github
|
||||
|
||||
- Drop the legacy engine copies from misc/ [@MickLesk](https://github.com/MickLesk) ([#18294](https://github.com/community-scripts/ProxmoxVE/pull/18294))
|
||||
|
||||
## 2026-10-30
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Reconya ([#18325](https://github.com/community-scripts/ProxmoxVE/pull/18325))
|
||||
- Blinko ([#18324](https://github.com/community-scripts/ProxmoxVE/pull/18324))
|
||||
- ChartDB ([#18323](https://github.com/community-scripts/ProxmoxVE/pull/18323))
|
||||
|
||||
## 2026-10-29
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Karakeep: fix monolith release asset pattern [@MohamedBassem](https://github.com/MohamedBassem) ([#18317](https://github.com/community-scripts/ProxmoxVE/pull/18317))
|
||||
- Vikunja: fold the package's service block into the config's service section [@MickLesk](https://github.com/MickLesk) ([#18311](https://github.com/community-scripts/ProxmoxVE/pull/18311))
|
||||
- Stirling-PDF: size JVM heap from container memory, not host RAM [@aashishvanand](https://github.com/aashishvanand) ([#18292](https://github.com/community-scripts/ProxmoxVE/pull/18292))
|
||||
- fix(authentik): migrate systemd units when still on pre-2026.8 paths [@CervezaStallone](https://github.com/CervezaStallone) ([#18307](https://github.com/community-scripts/ProxmoxVE/pull/18307))
|
||||
- fix(dawarich): serve .mjs MapLibre modules as JavaScript [@ricbaral](https://github.com/ricbaral) ([#18304](https://github.com/community-scripts/ProxmoxVE/pull/18304))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- VictoriaLogs: enable syslog ingestion on TCP/UDP 514 [@opastorello](https://github.com/opastorello) ([#18300](https://github.com/community-scripts/ProxmoxVE/pull/18300))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: Performance - load host data in the background and stop reporting failed pre-checks [@MickLesk](https://github.com/MickLesk) ([core#179](https://github.com/community-scripts/core/pull/179))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- gh: let the bot set oidc_url and license [@MickLesk](https://github.com/MickLesk) ([#18313](https://github.com/community-scripts/ProxmoxVE/pull/18313))
|
||||
|
||||
## 2026-10-28
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- VictoriaLogs ([#18282](https://github.com/community-scripts/ProxmoxVE/pull/18282))
|
||||
- Deemix ([#18272](https://github.com/community-scripts/ProxmoxVE/pull/18272))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(vm/opnsense): increase startup wait from 90 to 180 seconds [@MTlyx](https://github.com/MTlyx) ([#18086](https://github.com/community-scripts/ProxmoxVE/pull/18086))
|
||||
- apache-tomcat: restore the update backup from its real store [@mazelado](https://github.com/mazelado) ([#18145](https://github.com/community-scripts/ProxmoxVE/pull/18145))
|
||||
- AdventureLog: clean-install on update and drop the DRF <3.15 pin [@angusmaul](https://github.com/angusmaul) ([#18281](https://github.com/community-scripts/ProxmoxVE/pull/18281))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Refactor: ownCloud VM [@MickLesk](https://github.com/MickLesk) ([#18295](https://github.com/community-scripts/ProxmoxVE/pull/18295))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Keep the console hint out of the default output [@MickLesk](https://github.com/MickLesk) ([core#176](https://github.com/community-scripts/core/pull/176))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Move a promoted script's telemetry history to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([#18271](https://github.com/community-scripts/ProxmoxVE/pull/18271))
|
||||
|
||||
### ❔ Uncategorized
|
||||
|
||||
- chore(ct): sync tdarr defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#18289](https://github.com/community-scripts/ProxmoxVE/pull/18289))
|
||||
|
||||
## 2026-10-27
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Zabbix: leave out the NVIDIA agent2 plugin that breaks the all-plugins install [@MickLesk](https://github.com/MickLesk) ([#18262](https://github.com/community-scripts/ProxmoxVE/pull/18262))
|
||||
- Omada: detect latest version from product download page [@ChrisKappe](https://github.com/ChrisKappe) ([#18248](https://github.com/community-scripts/ProxmoxVE/pull/18248))
|
||||
- LanguageTool: count ngram prompt retries without tripping errexit [@MickLesk](https://github.com/MickLesk) ([#18258](https://github.com/community-scripts/ProxmoxVE/pull/18258))
|
||||
- Overseerr: point fresh installs to Seerr [@MickLesk](https://github.com/MickLesk) ([#18259](https://github.com/community-scripts/ProxmoxVE/pull/18259))
|
||||
- stalwart: pin to v0.16.27 until v1 migration is supported [@MickLesk](https://github.com/MickLesk) ([#18252](https://github.com/community-scripts/ProxmoxVE/pull/18252))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- TurnKey: offer only current appliances, stop on arm64 [@MickLesk](https://github.com/MickLesk) ([#18265](https://github.com/community-scripts/ProxmoxVE/pull/18265))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- NPMplus: let the ACME e-mail stay empty again, Let's Encrypt does not need one [@MickLesk](https://github.com/MickLesk) ([#18263](https://github.com/community-scripts/ProxmoxVE/pull/18263))
|
||||
|
||||
### 🗑️ Deleted Scripts
|
||||
|
||||
- Remove: Readarr [@MickLesk](https://github.com/MickLesk) ([#18264](https://github.com/community-scripts/ProxmoxVE/pull/18264))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Say the same thing on both hosts while a container is created [@MickLesk](https://github.com/MickLesk) ([core#173](https://github.com/community-scripts/core/pull/173))
|
||||
- Skip the IPv6 sysctl when the host kernel has no IPv6 [@MickLesk](https://github.com/MickLesk) ([core#171](https://github.com/community-scripts/core/pull/171))
|
||||
- Stop reporting a closed console as a user abort, and shield the host's own work [@MickLesk](https://github.com/MickLesk) ([core#172](https://github.com/community-scripts/core/pull/172))
|
||||
|
||||
## 2026-10-26
|
||||
|
||||
### 🆕 New Scripts
|
||||
@@ -1209,167 +1448,4 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- QoL: message blocks, clean-install keep list, password helper, network limits [@MickLesk](https://github.com/MickLesk) ([core#61](https://github.com/community-scripts/core/pull/61))
|
||||
|
||||
## 2026-10-01
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- romm: keep the asset links in sync with ROMM_BASE_PATH [@MickLesk](https://github.com/MickLesk) ([#17610](https://github.com/community-scripts/ProxmoxVE/pull/17610))
|
||||
- teslamate: build from the elixir directory since 4.3.0 [@MickLesk](https://github.com/MickLesk) ([#17612](https://github.com/community-scripts/ProxmoxVE/pull/17612))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- feat(glance): add alpine os [@skilletfun](https://github.com/skilletfun) ([#17605](https://github.com/community-scripts/ProxmoxVE/pull/17605))
|
||||
- feat(blocky): add alpine os [@skilletfun](https://github.com/skilletfun) ([#17637](https://github.com/community-scripts/ProxmoxVE/pull/17637))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- several scripts: apt instead of apt-get, cleanup_lxc, nginx_enable_site, drop needless daemon-reloads [@MickLesk](https://github.com/MickLesk) ([#17624](https://github.com/community-scripts/ProxmoxVE/pull/17624))
|
||||
- several scripts: use setup_postgresql_db / setup_mariadb_db instead of hand-written SQL [@MickLesk](https://github.com/MickLesk) ([#17622](https://github.com/community-scripts/ProxmoxVE/pull/17622))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Offer to raise the kernel key limits instead of only naming them [@MickLesk](https://github.com/MickLesk) ([core#81](https://github.com/community-scripts/core/pull/81))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- tools, turnkey: load core instead of the legacy misc functions [@MickLesk](https://github.com/MickLesk) ([#17621](https://github.com/community-scripts/ProxmoxVE/pull/17621))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- chore: drop the local header generation; headers come from core [@MickLesk](https://github.com/MickLesk) ([#17623](https://github.com/community-scripts/ProxmoxVE/pull/17623))
|
||||
|
||||
## 2026-09-30
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Shoko ([#17617](https://github.com/community-scripts/ProxmoxVE/pull/17617))
|
||||
- SIlo ([#17614](https://github.com/community-scripts/ProxmoxVE/pull/17614))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(blocky): restart on failure and wait for network-online [@haplo](https://github.com/haplo) ([#17601](https://github.com/community-scripts/ProxmoxVE/pull/17601))
|
||||
- SparkyFitness: update sed replacement [@tomfrenzel](https://github.com/tomfrenzel) ([#17604](https://github.com/community-scripts/ProxmoxVE/pull/17604))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- vm: autologin on the serial console for images without cloud-init [@MickLesk](https://github.com/MickLesk) ([core#80](https://github.com/community-scripts/core/pull/80))
|
||||
- download_gpg_key: make dearmored keyrings world-readable [@MickLesk](https://github.com/MickLesk) ([core#79](https://github.com/community-scripts/core/pull/79))
|
||||
|
||||
## 2026-09-29
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Anki Sync Server ([#17416](https://github.com/community-scripts/ProxmoxVE/pull/17416))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(kaneo): build with Vite+ instead of Turbo [@tinsever](https://github.com/tinsever) ([#17599](https://github.com/community-scripts/ProxmoxVE/pull/17599))
|
||||
- tianji: raise the Node heap for the static build on install [@MickLesk](https://github.com/MickLesk) ([#17582](https://github.com/community-scripts/ProxmoxVE/pull/17582))
|
||||
- fix(romm): snapshot Redis hourly like the upstream image [@DenislavDenev](https://github.com/DenislavDenev) ([#17562](https://github.com/community-scripts/ProxmoxVE/pull/17562))
|
||||
- checkmate: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17554](https://github.com/community-scripts/ProxmoxVE/pull/17554))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Drop the scripts base pin from every ct/ script [@MickLesk](https://github.com/MickLesk) ([#17585](https://github.com/community-scripts/ProxmoxVE/pull/17585))
|
||||
- odoo: move to Debian 13 and stay on the installed major on update [@MickLesk](https://github.com/MickLesk) ([#17581](https://github.com/community-scripts/ProxmoxVE/pull/17581))
|
||||
- manyfold: use upstream f3d for headless renders on amd64 [@MickLesk](https://github.com/MickLesk) ([#17583](https://github.com/community-scripts/ProxmoxVE/pull/17583))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Default the scripts base to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([core#76](https://github.com/community-scripts/core/pull/76))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- all-templates: handle the arch column of pveam available [@MickLesk](https://github.com/MickLesk) ([#17579](https://github.com/community-scripts/ProxmoxVE/pull/17579))
|
||||
|
||||
### 📂 Github
|
||||
|
||||
- Skip automated core pull requests in the changelog [@MickLesk](https://github.com/MickLesk) ([#17589](https://github.com/community-scripts/ProxmoxVE/pull/17589))
|
||||
- Post a test command for vm/, tools/ and turnkey/ changes too [@MickLesk](https://github.com/MickLesk) ([#17587](https://github.com/community-scripts/ProxmoxVE/pull/17587))
|
||||
- Remove the PocketBase AI bot [@MickLesk](https://github.com/MickLesk) ([#17591](https://github.com/community-scripts/ProxmoxVE/pull/17591))
|
||||
|
||||
## 2026-09-28
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- Immich: Pin version to 3.2.4 [@vhsdream](https://github.com/vhsdream) ([#17564](https://github.com/community-scripts/ProxmoxVE/pull/17564))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(autocaliweb): wire .env into all service units, not just autocali… [@bobartlett](https://github.com/bobartlett) ([#17561](https://github.com/community-scripts/ProxmoxVE/pull/17561))
|
||||
- Zipline: Change cp command [@Mraedis](https://github.com/Mraedis) ([#17559](https://github.com/community-scripts/ProxmoxVE/pull/17559))
|
||||
- Borg-UI: start through upstream's start.sh so migrations run [@MickLesk](https://github.com/MickLesk) ([#17563](https://github.com/community-scripts/ProxmoxVE/pull/17563))
|
||||
- linkding: serve favicons and preview images [@MickLesk](https://github.com/MickLesk) ([#17557](https://github.com/community-scripts/ProxmoxVE/pull/17557))
|
||||
- SparkyFitness: Fill in the nginx resolver 1.7.3 added [@MickLesk](https://github.com/MickLesk) ([#17556](https://github.com/community-scripts/ProxmoxVE/pull/17556))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Plane: Replace MinIO installation with Silo [@MickLesk](https://github.com/MickLesk) ([#17347](https://github.com/community-scripts/ProxmoxVE/pull/17347))
|
||||
|
||||
## 2026-09-27
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix(aurral): bump to Node 26 and bypass strict engine pin [@JodyVanden](https://github.com/JodyVanden) ([#17543](https://github.com/community-scripts/ProxmoxVE/pull/17543))
|
||||
- Tracearr: fetch map tiles on install/update [@durzo](https://github.com/durzo) ([#17544](https://github.com/community-scripts/ProxmoxVE/pull/17544))
|
||||
- fix(autocaliweb): define INSTALL_DIR before first use [@bobartlett](https://github.com/bobartlett) ([#17545](https://github.com/community-scripts/ProxmoxVE/pull/17545))
|
||||
|
||||
## 2026-09-26
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Manyfold: make /opt/manyfold_data writable for the manyfold user [@sergstepanenko](https://github.com/sergstepanenko) ([#17534](https://github.com/community-scripts/ProxmoxVE/pull/17534))
|
||||
- steamcmd: update itself before installing Satisfactory [@MickLesk](https://github.com/MickLesk) ([#17526](https://github.com/community-scripts/ProxmoxVE/pull/17526))
|
||||
- AudioMuse-AI: build noavx2 environment on Python 3.11 [@MickLesk](https://github.com/MickLesk) ([#17528](https://github.com/community-scripts/ProxmoxVE/pull/17528))
|
||||
- LobeHub: pin lobehub/ui at 5.49 while LobeHub's stable release needs it [@MickLesk](https://github.com/MickLesk) ([#17531](https://github.com/community-scripts/ProxmoxVE/pull/17531))
|
||||
- Keep Trilium updates on the server releases [@MickLesk](https://github.com/MickLesk) ([#17525](https://github.com/community-scripts/ProxmoxVE/pull/17525))
|
||||
- NginxProxyManager: generate admin config and repair certbot's venv on update [@MickLesk](https://github.com/MickLesk) ([#17523](https://github.com/community-scripts/ProxmoxVE/pull/17523))
|
||||
- Komodo: add KOMODO_HOST | fix broken spinner [@MickLesk](https://github.com/MickLesk) ([#17481](https://github.com/community-scripts/ProxmoxVE/pull/17481))
|
||||
- romm: run rq cron and a scans worker for RomM 5.3 [@davidbb](https://github.com/davidbb) ([#17502](https://github.com/community-scripts/ProxmoxVE/pull/17502))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Semaphore: fix BoltDB migration by pinning 2.18.30 [@MickLesk](https://github.com/MickLesk) ([#17439](https://github.com/community-scripts/ProxmoxVE/pull/17439))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Keep a dash-led bridge comment out of whiptail's options [@MickLesk](https://github.com/MickLesk) ([core#74](https://github.com/community-scripts/core/pull/74))
|
||||
|
||||
## 2026-09-25
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- RustFS ([#17499](https://github.com/community-scripts/ProxmoxVE/pull/17499))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Ignis: take the Obsidian version from release tag [@MickLesk](https://github.com/MickLesk) ([#17503](https://github.com/community-scripts/ProxmoxVE/pull/17503))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Refactor: Umbrel OS VM [@MickLesk](https://github.com/MickLesk) ([#17505](https://github.com/community-scripts/ProxmoxVE/pull/17505))
|
||||
- Docker-LXC: remove Portainer installation from install [@MickLesk](https://github.com/MickLesk) ([#17493](https://github.com/community-scripts/ProxmoxVE/pull/17493))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- Incus: make prompts visible for end-user [@MickLesk](https://github.com/MickLesk) ([core#73](https://github.com/community-scripts/core/pull/73))
|
||||
- incus: do not let an install script block on an invisible prompt [@MickLesk](https://github.com/MickLesk) ([core#71](https://github.com/community-scripts/core/pull/71))
|
||||
- tel: report progress from installs only, not updates [@MickLesk](https://github.com/MickLesk) ([core#72](https://github.com/community-scripts/core/pull/72))
|
||||
- QoL: message blocks, clean-install keep list, password helper, network limits [@MickLesk](https://github.com/MickLesk) ([core#61](https://github.com/community-scripts/core/pull/61))
|
||||
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<a href="misc/images/community-scripts.svg"><img src="misc/images/community-scripts.png" width="112" height="112" alt="Community Scripts — Proxmox VE logo" /></a>
|
||||
<!-- Editable artwork: misc/images/community-scripts.svg; PNG export: 512 × 512. -->
|
||||
<a href=".github/assets/community-scripts.svg"><img src=".github/assets/community-scripts.png" width="112" height="112" alt="Community Scripts — Proxmox VE logo" /></a>
|
||||
<!-- Editable artwork: .github/assets/community-scripts.svg; PNG export: 512 × 512. -->
|
||||
|
||||
<h1>Community Scripts — Proxmox VE</h1>
|
||||
<p><strong>One-command installations for services, containers and VMs on Proxmox VE</strong><br/>
|
||||
@@ -104,7 +104,6 @@ Virtual machine scripts need the same versions as containers.
|
||||
| `vm/` | Virtual machine scripts |
|
||||
| `tools/pve/` | Host tooling: post-install, hardware passthrough, maintenance |
|
||||
| `turnkey/` | TurnKey Linux appliance helper |
|
||||
| `misc/` | Legacy engine copies — current scripts load [core](https://github.com/community-scripts/core) at runtime, so changes here never reach a running install |
|
||||
|
||||
Application metadata — name, description, logo, tags — is managed on the website,
|
||||
not in this repository. Use the **Report Issue** link on any script page to
|
||||
|
||||
@@ -37,9 +37,9 @@ function update_script() {
|
||||
msg_ok "Services Stopped"
|
||||
|
||||
create_backup /opt/adventurelog/backend/server/.env \
|
||||
/opt/adventurelog/backend/server/media
|
||||
/opt/adventurelog/frontend/.env
|
||||
|
||||
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog" "tarball"
|
||||
CLEAN_INSTALL=1 CLEAN_INSTALL_KEEP="backend/server/media" fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog" "tarball"
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
|
||||
msg_info "Ensuring PostgreSQL Extensions"
|
||||
@@ -56,7 +56,6 @@ function update_script() {
|
||||
fi
|
||||
$STD .venv/bin/python -m pip install --upgrade pip
|
||||
$STD .venv/bin/python -m pip install -r requirements.txt
|
||||
$STD .venv/bin/python -m pip install 'djangorestframework<3.15'
|
||||
$STD .venv/bin/python -m manage collectstatic --noinput
|
||||
$STD .venv/bin/python -m manage migrate
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://aws.amazon.com/linux/
|
||||
|
||||
APP="Amazon Linux"
|
||||
var_tags="${var_tags:-os}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-amazonlinux}"
|
||||
var_version="${var_version:-2023}"
|
||||
var_arm64="${var_arm64:-no}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
msg_info "Updating Amazon Linux LXC"
|
||||
$STD dnf -y upgrade
|
||||
msg_ok "Updated Amazon Linux LXC"
|
||||
cleanup_lxc
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!"
|
||||
msg_custom "🚀" "${GN}" "${APP} setup has been successfully initialized!"
|
||||
@@ -39,6 +39,7 @@ function update_script() {
|
||||
create_backup /opt/anchor/.env
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "anchor" "ZhFahim/anchor" "tarball"
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm" setup_nodejs
|
||||
|
||||
msg_info "Building Server"
|
||||
cd /opt/anchor/server
|
||||
|
||||
@@ -51,40 +51,37 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Stopping Tomcat service"
|
||||
systemctl stop tomcat
|
||||
msg_ok "Stopped Tomcat service"
|
||||
|
||||
create_backup $TOMCAT_DIR/conf
|
||||
[[ -d $TOMCAT_DIR/webapps ]] && create_backup $TOMCAT_DIR/webapps
|
||||
[[ -d $TOMCAT_DIR/lib ]] && create_backup $TOMCAT_DIR/lib
|
||||
|
||||
msg_info "Downloading Tomcat ${LATEST_VERSION}"
|
||||
TOMCAT_URL="https://dlcdn.apache.org/tomcat/tomcat-${TOMCAT_MAJOR}/v${LATEST_VERSION}/bin/apache-tomcat-${LATEST_VERSION}.tar.gz"
|
||||
curl -fsSL "$TOMCAT_URL" -o /tmp/tomcat-update.tar.gz
|
||||
msg_ok "Downloaded Tomcat ${LATEST_VERSION}"
|
||||
|
||||
# Keep only the jars in lib that the new release does not ship (JDBC drivers
|
||||
# and the like). ecj and jakartaee-migration are Tomcat's own and change name
|
||||
# with each version, so they are never carried over.
|
||||
TOMCAT_FILES=$(tar -tzf /tmp/tomcat-update.tar.gz)
|
||||
BACKUP_PATHS=("$TOMCAT_DIR/conf")
|
||||
[[ -d $TOMCAT_DIR/webapps ]] && BACKUP_PATHS+=("$TOMCAT_DIR/webapps")
|
||||
for jar in "$TOMCAT_DIR"/lib/*.jar; do
|
||||
[[ -f $jar ]] || continue
|
||||
case "${jar##*/}" in ecj-*.jar | jakartaee-migration-*.jar) continue ;; esac
|
||||
grep -qxF "apache-tomcat-${LATEST_VERSION}/lib/${jar##*/}" <<<"$TOMCAT_FILES" || BACKUP_PATHS+=("$jar")
|
||||
done
|
||||
|
||||
msg_info "Stopping Tomcat service"
|
||||
systemctl stop tomcat
|
||||
msg_ok "Stopped Tomcat service"
|
||||
|
||||
create_backup "${BACKUP_PATHS[@]}"
|
||||
|
||||
msg_info "Installing update"
|
||||
rm -rf "${TOMCAT_DIR:?}"/*
|
||||
tar --strip-components=1 -xzf /tmp/tomcat-update.tar.gz -C "$TOMCAT_DIR"
|
||||
rm -f /tmp/tomcat-update.tar.gz
|
||||
msg_ok "Installed update"
|
||||
|
||||
msg_info "Restoring configuration and applications"
|
||||
cp -a "$BACKUP_DIR/conf"/* "$TOMCAT_DIR/conf/"
|
||||
cp -a "$BACKUP_DIR/webapps"/* "$TOMCAT_DIR/webapps/" 2>/dev/null || true
|
||||
if [[ -d "$BACKUP_DIR/lib" ]]; then
|
||||
for jar in "$BACKUP_DIR/lib"/*.jar; do
|
||||
[[ -f $jar ]] || continue
|
||||
jar_name=$(basename "$jar")
|
||||
if [[ ! -f "$TOMCAT_DIR/lib/$jar_name" ]]; then
|
||||
cp "$jar" "$TOMCAT_DIR/lib/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
rm -rf "$BACKUP_DIR"
|
||||
restore_backup
|
||||
chown -R root:root "$TOMCAT_DIR"
|
||||
msg_ok "Restored configuration and applications"
|
||||
|
||||
msg_info "Starting Tomcat service"
|
||||
systemctl start tomcat
|
||||
|
||||
@@ -37,19 +37,16 @@ function update_script() {
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "aurral" "lklynet/aurral" "tarball"
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm" setup_nodejs
|
||||
ensure_dependencies git
|
||||
|
||||
msg_info "Updating Aurral"
|
||||
cd /opt/aurral
|
||||
export VITE_APP_VERSION="$(cat ~/.aurral)"
|
||||
export VITE_GITHUB_REPO="lklynet/aurral"
|
||||
export VITE_RELEASE_CHANNEL="stable"
|
||||
# aurral's .npmrc sets engine-strict=true and pins an exact node patch (e.g. 26.8.x),
|
||||
# which NodeSource can't match since it only ships the latest patch per major.
|
||||
export npm_config_engine_strict=false
|
||||
$STD npm ci --workspace frontend --include-workspace-root=false
|
||||
$STD npm run build --workspace frontend
|
||||
$STD npm ci --workspace backend --omit=dev --include=optional --include-workspace-root=false
|
||||
$STD pnpm install --frozen-lockfile --config.engine-strict=false --filter aurral-frontend --filter aurral-backend
|
||||
$STD pnpm --filter aurral-frontend run build
|
||||
mkdir -p /opt/aurral_data
|
||||
cat <<EOF >/opt/aurral/aurral.env
|
||||
NODE_ENV=production
|
||||
@@ -57,6 +54,8 @@ PORT=3001
|
||||
AURRAL_DATA_DIR=/opt/aurral_data
|
||||
APP_VERSION=$(cat ~/.aurral)
|
||||
EOF
|
||||
sed -i 's#backend/server.js#backend/server.ts#' /etc/systemd/system/aurral.service
|
||||
systemctl daemon-reload
|
||||
msg_ok "Updated Aurral"
|
||||
|
||||
msg_info "Starting Service"
|
||||
|
||||
@@ -155,7 +155,8 @@ function update_script() {
|
||||
rm -r /opt/authentik/blueprints
|
||||
$STD find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +
|
||||
|
||||
if [[ $MAJOR == 2026 && $MINOR -lt 8 ]]; then
|
||||
# Also catch installs whose version marker already reads 2026.8.x but whose units were never migrated
|
||||
if [[ $MAJOR == 2026 && $MINOR -lt 8 ]] || grep -q "ExecStart=/opt/authentik/authentik-server" /etc/systemd/system/authentik-server.service; then
|
||||
msg_info "Updating Worker and Server config (from $MAJOR.$MINOR)"
|
||||
cat <<EOF >>/etc/default/authentik-server
|
||||
RUST_BACKTRACE=full
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/blinkospace/blinko
|
||||
|
||||
APP="Blinko"
|
||||
var_tags="${var_tags:-notes;ai;knowledge}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-6144}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
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/blinko ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "blinko" "blinkospace/blinko"; then
|
||||
msg_info "Stopping Blinko"
|
||||
systemctl stop blinko
|
||||
msg_ok "Stopped Blinko"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "blinko" "blinkospace/blinko" "tarball"
|
||||
|
||||
msg_info "Building Blinko"
|
||||
cd /opt/blinko
|
||||
$STD bun install
|
||||
$STD bunx prisma generate
|
||||
$STD bun run build:web
|
||||
$STD bun run build:seed
|
||||
mv dist/public server/public
|
||||
cp -r server/lute.min.js server/vditor dist/
|
||||
ln -s /opt/blinko_data/storage /opt/blinko/.blinko
|
||||
msg_ok "Built Blinko"
|
||||
|
||||
msg_info "Starting Blinko"
|
||||
systemctl start blinko
|
||||
msg_ok "Started Blinko"
|
||||
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 "${GATEWAY}${BGN}http://${IP}:1111${CL}"
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/chartdb/chartdb
|
||||
|
||||
APP="ChartDB"
|
||||
var_tags="${var_tags:-database;diagram;dev-tools}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-6144}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
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/chartdb ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "chartdb" "chartdb/chartdb"; then
|
||||
msg_info "Stopping ChartDB"
|
||||
systemctl stop nginx
|
||||
msg_ok "Stopped ChartDB"
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "chartdb" "chartdb/chartdb" "tarball"
|
||||
|
||||
msg_info "Building ChartDB"
|
||||
cd /opt/chartdb
|
||||
$STD npm ci
|
||||
NODE_OPTIONS="--max-old-space-size=4096" $STD npm run build
|
||||
rm -rf /opt/chartdb/node_modules
|
||||
msg_ok "Built ChartDB"
|
||||
|
||||
msg_info "Starting ChartDB"
|
||||
systemctl start nginx
|
||||
msg_ok "Started ChartDB"
|
||||
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 "${GATEWAY}${BGN}https://${IP}${CL}"
|
||||
@@ -48,7 +48,7 @@ function update_script() {
|
||||
msg_ok "Built Cinephage"
|
||||
|
||||
msg_info "Updating Camoufox"
|
||||
$STD /opt/cinephage/node_modules/.bin/camoufox-js fetch
|
||||
$STD /opt/cinephage/node_modules/.bin/camoufox fetch
|
||||
msg_ok "Updated Camoufox"
|
||||
|
||||
msg_info "Starting Cinephage"
|
||||
|
||||
@@ -33,6 +33,13 @@ function update_script() {
|
||||
|
||||
ensure_dependencies libgeos++-dev libxml2-dev libxslt-dev libjemalloc-dev
|
||||
|
||||
if [[ -f /etc/nginx/sites-available/dawarich.conf ]] && ! grep -q '\.mjs\$' /etc/nginx/sites-available/dawarich.conf; then
|
||||
msg_info "Fixing MapLibre delivery in Nginx"
|
||||
sed -i '/location ~ \^\/(assets|packs)\/ {/i\ location ~ \\.mjs$ {\n types { }\n default_type text/javascript;\n try_files $uri @rails;\n }\n' /etc/nginx/sites-available/dawarich.conf
|
||||
nginx_enable_site dawarich.conf
|
||||
msg_ok "Fixed MapLibre delivery in Nginx"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "dawarich" "Freika/dawarich"; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop dawarich-web dawarich-worker
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/bambanah/deemix
|
||||
|
||||
APP="Deemix"
|
||||
var_tags="${var_tags:-music;downloader}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-10}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
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/deemix ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "deemix" "bambanah/deemix" "" "" "deemix-webui@"; then
|
||||
msg_info "Stopping Deemix"
|
||||
systemctl stop deemix
|
||||
msg_ok "Stopped Deemix"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "deemix" "bambanah/deemix" "tarball" "latest" "/opt/deemix" "" "deemix-webui@"
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@$(sed -n 's/.*"packageManager": "pnpm@\([^"+]*\).*/\1/p' /opt/deemix/package.json)" setup_nodejs
|
||||
|
||||
msg_info "Building Deemix"
|
||||
cd /opt/deemix
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD=1 $STD pnpm install --frozen-lockfile
|
||||
$STD pnpm turbo build --filter=deemix-webui...
|
||||
msg_ok "Built Deemix"
|
||||
|
||||
msg_info "Starting Deemix"
|
||||
systemctl start deemix
|
||||
msg_ok "Started Deemix"
|
||||
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 "${GATEWAY}${BGN}http://${IP}:6595${CL}"
|
||||
@@ -51,16 +51,42 @@ function update_script() {
|
||||
cd /opt/discourse
|
||||
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
export BUNDLE_SILENCE_ROOT_WARNING=1
|
||||
set -a
|
||||
source /opt/discourse/.env
|
||||
set +a
|
||||
$STD git pull origin main
|
||||
$STD bundle install
|
||||
msg_ok "Updated Discourse"
|
||||
|
||||
if check_for_gh_release "libvips" "libvips/libvips"; then
|
||||
ensure_dependencies meson ninja-build pkg-config libglib2.0-dev libexpat1-dev libjpeg-dev libpng-dev libwebp-dev libtiff-dev libheif-dev libjxl-dev librsvg2-dev libcgif-dev libexif-dev liblcms2-dev liborc-0.4-dev libimagequant-dev libpango1.0-dev
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "libvips" "libvips/libvips" "prebuild" "latest" "/opt/libvips" "vips-*.tar.xz"
|
||||
msg_info "Building libvips"
|
||||
cd /opt/libvips
|
||||
$STD meson setup build --prefix=/usr/local --libdir=lib --buildtype=release -Dmodules=disabled -Dmagick=disabled -Dexamples=false
|
||||
$STD ninja -C build install
|
||||
ldconfig
|
||||
msg_ok "Built libvips"
|
||||
fi
|
||||
|
||||
msg_info "Updating Dependencies"
|
||||
RUBY_TARGET=$(grep -A1 '^RUBY VERSION' /opt/discourse/Gemfile.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
|
||||
RUBY_VERSION="${RUBY_TARGET:-4.0.7}" RUBY_INSTALL_RAILS="false" setup_ruby
|
||||
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
|
||||
hash -r
|
||||
cd /opt/discourse
|
||||
$STD bundle install -j"$(nproc)"
|
||||
$STD pnpm install
|
||||
msg_ok "Updated Dependencies"
|
||||
|
||||
msg_info "Running Database Migrations"
|
||||
$STD runuser -u postgres -- psql -d discourse -c "CREATE EXTENSION IF NOT EXISTS vector;"
|
||||
$STD bundle exec rails db:migrate
|
||||
msg_ok "Ran Database Migrations"
|
||||
|
||||
msg_info "Precompiling Assets"
|
||||
$STD bundle exec rails assets:precompile
|
||||
msg_ok "Updated Discourse"
|
||||
msg_ok "Precompiled Assets"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start discourse discourse-sidekiq
|
||||
|
||||
@@ -102,6 +102,7 @@ function update_script() {
|
||||
fi
|
||||
msg_ok "Ensured ASP.NET Core Runtime"
|
||||
|
||||
rm -rf /opt/fileflows/{Server,FlowRunner,Libraries,Agent}
|
||||
fetch_and_deploy_from_url "https://fileflows.com/downloads/ff-latest.tar.xz" "/opt/fileflows"
|
||||
|
||||
msg_info "Starting Service"
|
||||
|
||||
@@ -53,6 +53,8 @@ function update_script() {
|
||||
msg_ok "Restored Database"
|
||||
fi
|
||||
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
|
||||
msg_info "Updating Guardian"
|
||||
cd /opt/guardian/backend
|
||||
$STD npm ci
|
||||
|
||||
@@ -149,13 +149,13 @@ EOF
|
||||
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
||||
PG_VERSION=${PG_VERSION:-16}
|
||||
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
|
||||
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
|
||||
if check_for_gh_release "VectorChord" "supervc-stack/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
|
||||
# dead tuples in smart_search/face_search make the REINDEX below fail with
|
||||
# "missing chunk ... for toast value" on VectorChord 1.0.0 (#15588); must vacuum
|
||||
# while still on the old extension version, a post-upgrade vacuum errors instead
|
||||
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) smart_search;"
|
||||
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) face_search;"
|
||||
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||
fetch_and_deploy_gh_release "VectorChord" "supervc-stack/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||
systemctl restart postgresql
|
||||
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
|
||||
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vchord UPDATE;"
|
||||
@@ -232,7 +232,7 @@ EOF
|
||||
# plugins
|
||||
cd "$SRC_DIR"
|
||||
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg,java,terragrunt,opentofu,npm:@openapitools/openapi-generator-cli
|
||||
export MISE_LOCKFILE_MODE=merge MISE_LOCKFILE_PLATFORMS="linux-$(arch_resolve x64 arm64)"
|
||||
mise_ok=0
|
||||
for i in 1 2 3; do
|
||||
|
||||
@@ -39,6 +39,10 @@ function update_script() {
|
||||
echo "Seerr is the new unified Jellyseerr and Overseerr."
|
||||
echo "More info: https://docs.seerr.dev/blog/seerr-release"
|
||||
echo
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||
msg_warn "Seerr migration detected - skipping update, requires an interactive run"
|
||||
exit 75
|
||||
fi
|
||||
read -rp "Do you want to migrate to Seerr now? (y/N): " MIGRATE
|
||||
echo
|
||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
||||
|
||||
@@ -33,6 +33,15 @@ function update_script() {
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
SERVICE_FILE="/etc/systemd/system/matterjs-server.service"
|
||||
if [[ -f "$SERVICE_FILE" ]] && ! grep -Fxq 'Environment=ENABLE_TIME_SYNC=true' "$SERVICE_FILE"; then
|
||||
msg_info "Enabling MatterJS Time Sync"
|
||||
sed -i '/^ExecStart=/i Environment=ENABLE_TIME_SYNC=true' "$SERVICE_FILE"
|
||||
$STD systemctl daemon-reload
|
||||
$STD systemctl restart matterjs-server
|
||||
msg_ok "Enabled MatterJS Time Sync"
|
||||
fi
|
||||
|
||||
CURRENT=$(cat /opt/matter-server/node_modules/matter-server/package.json | grep '"version"' | head -1 | sed 's/.*"\([^"]*\)".*/\1/')
|
||||
LATEST=$(npm view matter-server version 2>/dev/null)
|
||||
if [[ $CURRENT != "$LATEST" ]]; then
|
||||
|
||||
@@ -46,7 +46,10 @@ EOF
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
$STD npm install -g n8n@latest
|
||||
# n8n-nodes-base 2.46.0 pins both @napi-rs/canvas musl binaries as hard
|
||||
# dependencies, which no os/cpu/libc combination can satisfy. Drop --force
|
||||
# once upstream makes them optional again.
|
||||
$STD npm install -g n8n@latest --force
|
||||
systemctl restart n8n
|
||||
msg_ok "Updated n8n"
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
@@ -9,7 +9,7 @@ source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_
|
||||
APP="Nametag"
|
||||
var_tags="${var_tags:-contacts;crm}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
@@ -37,10 +37,9 @@ function update_script() {
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
create_backup /opt/nametag/.env
|
||||
|
||||
CLEAN_INSTALL=1 CLEAN_INSTALL_KEEP="data" fetch_and_deploy_gh_release "nametag" "mattogodoy/nametag" "tarball" "latest" "/opt/nametag"
|
||||
|
||||
restore_backup
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
msg_info "Rebuilding Application"
|
||||
cd /opt/nametag
|
||||
|
||||
@@ -37,9 +37,9 @@ function update_script() {
|
||||
msg_ok "Stopped Norish"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "norish" "norish-recipes/norish" "tarball"
|
||||
NODE_VERSION="22" NODE_MODULE="pnpm@$(jq -r '.packageManager | split("@")[1]' /opt/norish/package.json)" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm@$(jq -r '.packageManager | split("@")[1]' /opt/norish/package.json)" setup_nodejs
|
||||
PYTHON_VERSION="3.14" setup_uv
|
||||
fetch_and_deploy_gh_release "obscura" "h4ckf0r0day/obscura" "prebuild" "v$(sed -n 's/^OBSCURA_VERSION=//p' /opt/norish/docker/obscura/pin.env)" "/opt/obscura" "obscura-$(arch_resolve "x86_64" "aarch64")-linux-stealth.tar.gz"
|
||||
fetch_and_deploy_gh_release "obscura" "$(sed -n 's#^OBSCURA_REPO=https://github.com/##p' /opt/norish/docker/obscura/pin.env)" "prebuild" "v$(sed -n 's/^OBSCURA_VERSION=//p' /opt/norish/docker/obscura/pin.env)" "/opt/obscura" "obscura-$(arch_resolve "x86_64" "aarch64")-linux-stealth.tar.gz"
|
||||
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp" "singlefile" "latest" "/usr/local/bin" "$(arch_resolve "yt-dlp_linux" "yt-dlp_linux_aarch64")"
|
||||
|
||||
msg_info "Building Norish"
|
||||
@@ -48,6 +48,8 @@ function update_script() {
|
||||
$STD uv sync --project /opt/norish/apps/parser-api --locked
|
||||
NODE_ENV=production SKIP_ENV_VALIDATION=1 NEXT_TELEMETRY_DISABLED=1 $STD pnpm turbo run build --filter "@norish/web"
|
||||
rm -rf /opt/norish/apps/web/.next/cache /opt/norish/apps/web/.next/standalone
|
||||
sed -i -e "s|^WorkingDirectory=.*|WorkingDirectory=/opt/norish/apps/web|" -e "s|^ExecStart=.*|ExecStart=/usr/bin/node --import tsx server/index.ts|" /etc/systemd/system/norish.service
|
||||
systemctl daemon-reload
|
||||
msg_ok "Built Norish"
|
||||
|
||||
msg_info "Starting Norish"
|
||||
|
||||
@@ -40,9 +40,12 @@ function update_script() {
|
||||
|
||||
JAVA_VERSION="21" setup_java
|
||||
|
||||
OMADA_URL=$(curl -fsSL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" "https://support.omadanetworks.com/en/download/software/omada-controller/" |
|
||||
OMADA_URL=$(curl -fsSL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" \
|
||||
"https://support.omadanetworks.com/en/product/omada-software-controller/?resourceType=download" \
|
||||
"https://support.omadanetworks.com/en/download/software/omada-controller/" |
|
||||
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
|
||||
head -n1)
|
||||
sed -n 's/.*_v\([0-9.]*\)_linux.*/\1 &/p' |
|
||||
sort -V | tail -n1 | cut -d' ' -f2)
|
||||
OMADA_PKG=$(basename "${OMADA_URL}")
|
||||
VERSION=$(sed -n 's/.*_v\([0-9.]*\)_linux.*/\1/p' <<<"${OMADA_PKG}")
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ function update_script() {
|
||||
echo "Seerr is the new unified Jellyseerr and Overseerr."
|
||||
echo "More info: https://docs.seerr.dev/blog/seerr-release"
|
||||
echo
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||
msg_warn "Seerr migration detected - skipping update, requires an interactive run"
|
||||
exit 75
|
||||
fi
|
||||
read -rp "Do you want to migrate to Seerr now? (y/N): " MIGRATE
|
||||
echo
|
||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
||||
@@ -82,6 +86,12 @@ EOF
|
||||
exit
|
||||
}
|
||||
|
||||
if [[ ! -d /opt/overseerr ]]; then
|
||||
msg_error "Overseerr is now Seerr and can no longer be installed with this script."
|
||||
msg_warn "Install Seerr instead: https://community-scripts.org/scripts/seerr"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
@@ -63,6 +63,10 @@ function update_script() {
|
||||
echo -e "${GATEWAY}${BGN}https://docs.paperless-ngx.com/migration-v3/#encryption-support${CL}"
|
||||
msg_warn "Before continuing make sure that you do not use encryption or have decrypted all documents."
|
||||
echo ""
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||
msg_warn "Paperless-ngx v3 migration detected - skipping update, requires an interactive run"
|
||||
exit 75
|
||||
fi
|
||||
read -rp "Do you want to continue with the update? (y/N): " MIGRATE
|
||||
echo
|
||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
||||
@@ -71,6 +75,11 @@ function update_script() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]] && ! grep -q "uv run" /etc/systemd/system/paperless-webserver.service; then
|
||||
msg_warn "Paperless-ngx uv migration detected - skipping update, requires an interactive run"
|
||||
exit 75
|
||||
fi
|
||||
|
||||
msg_info "Stopping all Paperless-ngx Services"
|
||||
systemctl stop paperless-consumer paperless-webserver paperless-scheduler paperless-task-queue
|
||||
msg_ok "Stopped all Paperless-ngx Services"
|
||||
|
||||
@@ -9,7 +9,7 @@ source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_
|
||||
APP="PS5-MQTT"
|
||||
var_tags="${var_tags:-smarthome;automation}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-3}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
@@ -37,12 +37,16 @@ function update_script() {
|
||||
systemctl stop ps5-mqtt
|
||||
msg_ok "Stopped service"
|
||||
|
||||
fetch_and_deploy_gh_release "ps5-mqtt" "FunkeyFlo/ps5-mqtt" "tarball"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ps5-mqtt" "FunkeyFlo/ps5-mqtt" "tarball"
|
||||
|
||||
msg_info "Configuring ${APP}"
|
||||
cd /opt/ps5-mqtt/ps5-mqtt/
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cd /opt/ps5-mqtt
|
||||
$STD corepack yarn install --immutable
|
||||
$STD env PREPARE_ONLY=1 corepack yarn workspace @ps5-mqtt/server run package
|
||||
cd /opt/ps5-mqtt/ps5-mqtt/server/.packaged/server
|
||||
$STD npm install --omit=dev --omit=optional
|
||||
sed -i 's|^WorkingDirectory=.*|WorkingDirectory=/opt/ps5-mqtt/ps5-mqtt/server/.packaged|' /etc/systemd/system/ps5-mqtt.service
|
||||
systemctl daemon-reload
|
||||
msg_ok "Configured ${APP}"
|
||||
|
||||
msg_info "Starting service"
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Owen Voke (owenvoke)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Ralex91/Razzia
|
||||
|
||||
APP="Razzia"
|
||||
var_tags="${var_tags:-quiz;games}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
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/razzia ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "razzia" "Ralex91/Razzia"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop razzia
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
create_backup /opt/razzia/.env
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "razzia" "Ralex91/Razzia" "tarball"
|
||||
|
||||
restore_backup
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@11" setup_nodejs
|
||||
|
||||
msg_info "Building Razzia"
|
||||
cd /opt/razzia
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm build
|
||||
msg_ok "Built Razzia"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start razzia
|
||||
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 "${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://readarr.com/
|
||||
# Source: https://github.com/Dyneteq/reconya
|
||||
|
||||
APP="Readarr"
|
||||
var_tags="${var_tags:-media;comic;eBook}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
APP="Reconya"
|
||||
var_tags="${var_tags:-network;discovery;security}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
@@ -25,15 +25,24 @@ function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /var/lib/readarr/ ]]; then
|
||||
|
||||
if [[ ! -d /opt/reconya ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_info "Updating $APP LXC"
|
||||
apt_update_safe
|
||||
$STD apt -y upgrade
|
||||
msg_ok "Updated $APP LXC"
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
if check_for_gh_release "reconya" "Dyneteq/reconya"; then
|
||||
msg_info "Stopping Reconya"
|
||||
systemctl stop reconya
|
||||
msg_ok "Stopped Reconya"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "reconya" "Dyneteq/reconya" "prebuild" "latest" "/opt/reconya" "reconya-linux-$(arch_resolve "amd64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Starting Reconya"
|
||||
systemctl start reconya
|
||||
msg_ok "Started Reconya"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
@@ -41,7 +50,7 @@ start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
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 "${GATEWAY}${BGN}http://${IP}:8787${CL}"
|
||||
echo -e "${GATEWAY}${BGN}http://${IP}:3008${CL}"
|
||||
@@ -31,12 +31,13 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "stalwart" "stalwartlabs/stalwart"; then
|
||||
RELEASE="v0.16.27"
|
||||
if check_for_gh_release "stalwart" "stalwartlabs/stalwart" "${RELEASE}" "Stalwart v1 changes the data store layout and requires an offline migration with stalwartlabs/stalwart-migrate; pinned until this script supports it"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop stalwart
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "stalwart" "stalwartlabs/stalwart" "prebuild" "latest" "/opt/stalwart" "stalwart-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "stalwart" "stalwartlabs/stalwart" "prebuild" "${RELEASE}" "/opt/stalwart" "stalwart-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||
chmod +x /opt/stalwart/stalwart
|
||||
|
||||
msg_info "Starting Service"
|
||||
|
||||
@@ -60,6 +60,15 @@ function update_script() {
|
||||
systemctl stop stirlingpdf unoserver
|
||||
msg_ok "Stopped Services"
|
||||
|
||||
if grep -q '^ExecStart=/usr/bin/java -jar Stirling-PDF.jar$' /etc/systemd/system/stirlingpdf.service; then
|
||||
msg_info "Limiting Java Heap to Container Memory"
|
||||
sed -i '/^ExecStop=\/bin\/kill -15 %n$/d' /etc/systemd/system/stirlingpdf.service
|
||||
sed -i "s|^ExecStart=/usr/bin/java -jar Stirling-PDF.jar$|ExecStart=/bin/bash -c 'exec /usr/bin/java -XX:MaxRAM=\$\$(grep -m1 -o \"[0-9][0-9]*\" /proc/meminfo)k \$\$JAVA_BASE_OPTS \$\$JAVA_CUSTOM_OPTS -jar Stirling-PDF.jar'|" /etc/systemd/system/stirlingpdf.service
|
||||
sed -i 's/-XX:MaxRAMPercentage=75/-XX:MaxRAMPercentage=50/' /opt/Stirling-PDF/.env
|
||||
systemctl daemon-reload
|
||||
msg_ok "Limited Java Heap to Container Memory"
|
||||
fi
|
||||
|
||||
if [[ -f ~/.Stirling-PDF-login ]]; then
|
||||
USE_ORIGINAL_FILENAME=true fetch_and_deploy_gh_release "stirling-pdf" "Stirling-Tools/Stirling-PDF" "singlefile" "latest" "/opt/Stirling-PDF" "Stirling-PDF-with-login.jar"
|
||||
mv /opt/Stirling-PDF/Stirling-PDF-with-login.jar /opt/Stirling-PDF/Stirling-PDF.jar
|
||||
|
||||
@@ -10,7 +10,7 @@ APP="Tdarr"
|
||||
var_tags="${var_tags:-arr}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_disk="${var_disk:-15}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
|
||||
@@ -32,6 +32,16 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
ensure_dependencies redis-server
|
||||
systemctl enable -q --now redis-server
|
||||
if ! grep -q "BACKEND_CACHE_REDIS_URI" /opt/teable/.env; then
|
||||
sed -i '/^BACKEND_CACHE_SQLITE_URI=/d' /opt/teable/.env
|
||||
sed -i 's|^BACKEND_CACHE_PROVIDER=.*|BACKEND_CACHE_PROVIDER=redis\nBACKEND_CACHE_REDIS_URI=redis://127.0.0.1:6379/0|' /opt/teable/.env
|
||||
sed -i 's|^After=network.target postgresql.service$|After=network.target postgresql.service redis-server.service|' /etc/systemd/system/teable.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart teable
|
||||
fi
|
||||
|
||||
if check_for_gh_release "teable" "teableio/teable"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop teable
|
||||
|
||||
@@ -30,7 +30,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
|
||||
msg_info "Updating prestart script"
|
||||
cat <<EOF >/data/tracearr/prestart.sh
|
||||
|
||||
@@ -32,7 +32,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="corepack" setup_nodejs
|
||||
|
||||
if check_for_gh_release "twenty" "twentyhq/twenty"; then
|
||||
msg_info "Stopping Services"
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
|
||||
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Nicolas Pastorello (opastorello)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://victoriametrics.com/products/victorialogs/
|
||||
|
||||
APP="VictoriaLogs"
|
||||
var_tags="${var_tags:-logging;monitoring}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-10}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/victorialogs ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! grep -q -- '-syslog.listenAddr' /etc/systemd/system/victorialogs.service; then
|
||||
msg_info "Enabling Syslog Ingestion"
|
||||
sed -i '/^ExecStart=/ s|$| -syslog.listenAddr.tcp=:514 -syslog.listenAddr.udp=:514|' /etc/systemd/system/victorialogs.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart victorialogs
|
||||
msg_ok "Enabled Syslog Ingestion (TCP/UDP 514)"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "victorialogs" "VictoriaMetrics/VictoriaLogs"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop victorialogs
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "victorialogs" "VictoriaMetrics/VictoriaLogs" "prebuild" "latest" "/opt/victorialogs" "victoria-logs-linux-$(arch_resolve amd64 arm64)-v*[0-9].tar.gz"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "vlutils" "VictoriaMetrics/VictoriaLogs" "prebuild" "latest" "/opt/vlutils" "vlutils-linux-$(arch_resolve amd64 arm64)-v*[0-9].tar.gz"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start victorialogs
|
||||
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 "${GATEWAY}${BGN}http://${IP}:9428${CL}"
|
||||
echo -e "${INFO}${YW}Syslog ingestion (TCP/UDP):${CL}"
|
||||
echo -e "${GATEWAY}${BGN}${IP}:514${CL}"
|
||||
@@ -36,6 +36,10 @@ function update_script() {
|
||||
msg_warn "This requires MANUAL config changes in /etc/vikunja/config.yml."
|
||||
msg_warn "See: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
|
||||
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||
msg_warn "Vikunja 1.0 config migration detected - skipping update, requires an interactive run"
|
||||
exit 75
|
||||
fi
|
||||
read -rp "Continue with update? (y to proceed): " -t 30 CONFIRM1 || exit 254
|
||||
[[ "$CONFIRM1" =~ ^[yY]$ ]] || exit 0
|
||||
|
||||
@@ -47,13 +51,24 @@ function update_script() {
|
||||
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
||||
fi
|
||||
|
||||
if [[ $(grep -c '^service:' /etc/vikunja/config.yml || true) -gt 1 ]]; then
|
||||
msg_info "Merging duplicate service section in config.yml"
|
||||
sed -i '0,/^service:/!{/^service:/d}' /etc/vikunja/config.yml
|
||||
systemctl restart vikunja
|
||||
msg_ok "Merged duplicate service section in config.yml"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "vikunja" "go-vikunja/vikunja"; then
|
||||
echo
|
||||
msg_warn "The package update may include config file changes."
|
||||
echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}"
|
||||
echo -e "${TAB} 1) Keep your current config"
|
||||
echo -e "${TAB} 2) Install the new package maintainer's config"
|
||||
read -rp " Choose [1/2] (default: 1): " -t 60 CONFIG_CHOICE || CONFIG_CHOICE="1"
|
||||
if [[ "${PHS_SILENT:-0}" == "1" ]]; then
|
||||
CONFIG_CHOICE="1"
|
||||
else
|
||||
read -rp " Choose [1/2] (default: 1): " -t 60 CONFIG_CHOICE || CONFIG_CHOICE="1"
|
||||
fi
|
||||
[[ -z "$CONFIG_CHOICE" ]] && CONFIG_CHOICE="1"
|
||||
|
||||
if [[ "$CONFIG_CHOICE" == "2" ]]; then
|
||||
|
||||
@@ -30,6 +30,41 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
if [[ -d /opt/wikijs/backend ]]; then
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
|
||||
if check_for_gh_release "wikijs" "requarks/wiki"; then
|
||||
PUPPETEER_INSTALLED=$([[ -d /opt/wikijs/backend/node_modules/puppeteer ]] && echo "true" || echo "false")
|
||||
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop wikijs
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
create_backup /opt/wikijs/config.yml
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
|
||||
restore_backup
|
||||
|
||||
cd /opt/wikijs/backend
|
||||
if [[ "$(arch_resolve)" == "arm64" ]]; then
|
||||
msg_info "Building Wiki.js Dependencies"
|
||||
$STD npm ci --omit=dev
|
||||
msg_ok "Built Wiki.js Dependencies"
|
||||
fi
|
||||
if [[ "$PUPPETEER_INSTALLED" == "true" ]]; then
|
||||
msg_info "Reinstalling Puppeteer"
|
||||
$STD npm install --no-save --force --include=optional --no-ignore-scripts --no-audit --no-fund "puppeteer@$(sed -n 's/^installVersion: *//p' modules/extensions/puppeteer/definition.yml)"
|
||||
msg_ok "Reinstalled Puppeteer"
|
||||
fi
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start wikijs
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_warn "Wiki.js 3 cannot update a 2.x install in place. Export it under Administration > Utilities > Export for Wiki.js 3.x and import it into a new Wiki.js 3 container."
|
||||
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
|
||||
if check_for_gh_release "wikijs" "requarks/wiki-v2"; then
|
||||
|
||||
@@ -22,7 +22,7 @@ if [[ "${var_os:-}" == "alpine" ]]; then
|
||||
var_disk="${var_disk:-1}"
|
||||
var_version="${var_version:-3.24}"
|
||||
else
|
||||
var_ram="${var_ram:-512}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_version="${var_version:-13}"
|
||||
fi
|
||||
|
||||
@@ -53,6 +53,7 @@ function update_script() {
|
||||
cd /opt/zerobyte
|
||||
$STD bun install
|
||||
$STD node ./node_modules/vite/bin/vite.js build
|
||||
$STD bun build apps/agent/src/index.ts --outfile .output/agent/index.mjs --target bun
|
||||
msg_ok "Built Zerobyte"
|
||||
|
||||
msg_info "Starting Service"
|
||||
|
||||
@@ -62,7 +62,6 @@ $STD uv venv --clear /opt/adventurelog/backend/server/.venv
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m ensurepip --upgrade
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m pip install --upgrade pip
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m pip install -r requirements.txt
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m pip install 'djangorestframework<3.15'
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m manage collectstatic --noinput
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m manage migrate
|
||||
$STD /opt/adventurelog/backend/server/.venv/bin/python -m manage download-countries
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://aws.amazon.com/linux/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Base Dependencies"
|
||||
$STD dnf install -y hostname procps-ng
|
||||
msg_ok "Installed Base Dependencies"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -13,7 +13,7 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="anchor" PG_DB_USER="anchor" setup_postgresql_db
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ service:
|
||||
url: community-scripts/ProxmoxVE
|
||||
use_prerelease: false
|
||||
dashboard:
|
||||
icon: https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/images/logo.png
|
||||
icon: https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/.github/assets/logo.png
|
||||
icon_link_to: https://community-scripts.org/
|
||||
web_url: https://github.com/community-scripts/ProxmoxVE/releases
|
||||
EOF
|
||||
|
||||
@@ -16,13 +16,14 @@ update_os
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
build-essential \
|
||||
git \
|
||||
python3 \
|
||||
ffmpeg \
|
||||
fontconfig \
|
||||
fonts-dejavu-core
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm" setup_nodejs
|
||||
|
||||
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp" "singlefile" "latest" "/usr/local/bin" "yt-dlp"
|
||||
fetch_and_deploy_gh_release "aurral" "lklynet/aurral" "tarball"
|
||||
@@ -32,12 +33,8 @@ cd /opt/aurral
|
||||
export VITE_APP_VERSION="$(cat ~/.aurral)"
|
||||
export VITE_GITHUB_REPO="lklynet/aurral"
|
||||
export VITE_RELEASE_CHANNEL="stable"
|
||||
# aurral's .npmrc sets engine-strict=true and pins an exact node patch (e.g. 26.8.x),
|
||||
# which NodeSource can't match since it only ships the latest patch per major.
|
||||
export npm_config_engine_strict=false
|
||||
$STD npm ci --workspace frontend --include-workspace-root=false
|
||||
$STD npm run build --workspace frontend
|
||||
$STD npm ci --workspace backend --omit=dev --include=optional --include-workspace-root=false
|
||||
$STD pnpm install --frozen-lockfile --config.engine-strict=false --filter aurral-frontend --filter aurral-backend
|
||||
$STD pnpm --filter aurral-frontend run build
|
||||
msg_ok "Built Aurral"
|
||||
|
||||
msg_info "Creating Service"
|
||||
@@ -58,7 +55,7 @@ Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/aurral
|
||||
EnvironmentFile=/opt/aurral/aurral.env
|
||||
ExecStart=/usr/bin/node backend/server.js
|
||||
ExecStart=/usr/bin/node backend/server.ts
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/blinkospace/blinko
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="blinko" PG_DB_USER="blinko" setup_postgresql_db
|
||||
|
||||
fetch_and_deploy_gh_release "blinko" "blinkospace/blinko" "tarball"
|
||||
|
||||
msg_info "Building Blinko"
|
||||
cd /opt/blinko
|
||||
$STD bun install
|
||||
$STD bunx prisma generate
|
||||
$STD bun run build:web
|
||||
$STD bun run build:seed
|
||||
# The server resolves its web root as ../server/public and lute/vditor next to its own bundle
|
||||
mv dist/public server/public
|
||||
cp -r server/lute.min.js server/vditor dist/
|
||||
msg_ok "Built Blinko"
|
||||
|
||||
msg_info "Configuring Blinko"
|
||||
mkdir -p /opt/blinko_data/storage
|
||||
# Blinko keeps uploads, the vector index and backups in .blinko under its working directory
|
||||
ln -s /opt/blinko_data/storage /opt/blinko/.blinko
|
||||
cat <<EOF >/opt/blinko_data/.env
|
||||
NODE_ENV=production
|
||||
DATABASE_URL=postgresql://blinko:${PG_DB_PASS}@localhost:5432/blinko
|
||||
TRUST_PROXY=1
|
||||
EOF
|
||||
chmod 600 /opt/blinko_data/.env
|
||||
msg_ok "Configured Blinko"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/blinko.service
|
||||
[Unit]
|
||||
Description=Blinko
|
||||
After=network.target postgresql.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/blinko
|
||||
EnvironmentFile=/opt/blinko_data/.env
|
||||
ExecStartPre=/opt/blinko/node_modules/.bin/prisma migrate deploy
|
||||
ExecStartPre=/usr/bin/node /opt/blinko/dist/seed.js
|
||||
ExecStart=/usr/bin/node /opt/blinko/dist/index.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now blinko
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/chartdb/chartdb
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y nginx
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
fetch_and_deploy_gh_release "chartdb" "chartdb/chartdb" "tarball"
|
||||
|
||||
msg_info "Building ChartDB"
|
||||
cd /opt/chartdb
|
||||
$STD npm ci
|
||||
NODE_OPTIONS="--max-old-space-size=4096" $STD npm run build
|
||||
rm -rf /opt/chartdb/node_modules
|
||||
msg_ok "Built ChartDB"
|
||||
|
||||
msg_info "Configuring ChartDB"
|
||||
mkdir -p /opt/chartdb_data
|
||||
cat <<'EOF' >/opt/chartdb_data/config.js
|
||||
window.env = {
|
||||
DISABLE_ANALYTICS: "true",
|
||||
// OPENAI_API_KEY: "",
|
||||
// OPENAI_API_ENDPOINT: "https://ollama.example.com/v1",
|
||||
// LLM_MODEL_NAME: "qwen2.5-coder:7b",
|
||||
};
|
||||
EOF
|
||||
create_self_signed_cert "chartdb"
|
||||
# HTTPS because the AI export (crypto.subtle) and the copy buttons need a secure context
|
||||
cat <<'EOF' >/etc/nginx/sites-available/chartdb
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl default_server;
|
||||
http2 on;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate /etc/ssl/chartdb/chartdb.crt;
|
||||
ssl_certificate_key /etc/ssl/chartdb/chartdb.key;
|
||||
|
||||
root /opt/chartdb/dist;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location = /config.js {
|
||||
alias /opt/chartdb_data/config.js;
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
}
|
||||
EOF
|
||||
nginx_enable_site "chartdb"
|
||||
msg_ok "Configured ChartDB"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -35,7 +35,7 @@ $STD npm prune --omit=dev
|
||||
msg_ok "Built Cinephage"
|
||||
|
||||
msg_info "Installing Camoufox"
|
||||
$STD /opt/cinephage/node_modules/.bin/camoufox-js fetch
|
||||
$STD /opt/cinephage/node_modules/.bin/camoufox fetch
|
||||
msg_ok "Installed Camoufox"
|
||||
|
||||
msg_info "Configuring Cinephage"
|
||||
|
||||
@@ -150,6 +150,12 @@ server {
|
||||
root /opt/dawarich/app/public;
|
||||
client_max_body_size 100M;
|
||||
|
||||
location ~ \.mjs\$ {
|
||||
types { }
|
||||
default_type text/javascript;
|
||||
try_files \$uri @rails;
|
||||
}
|
||||
|
||||
location ~ ^/(assets|packs)/ {
|
||||
expires max;
|
||||
add_header Cache-Control "public, immutable";
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/bambanah/deemix
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y build-essential
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "deemix" "bambanah/deemix" "tarball" "latest" "/opt/deemix" "" "deemix-webui@"
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@$(sed -n 's/.*"packageManager": "pnpm@\([^"+]*\).*/\1/p' /opt/deemix/package.json)" setup_nodejs
|
||||
|
||||
msg_info "Building Deemix"
|
||||
cd /opt/deemix
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD=1 $STD pnpm install --frozen-lockfile
|
||||
$STD pnpm turbo build --filter=deemix-webui...
|
||||
msg_ok "Built Deemix"
|
||||
|
||||
msg_info "Creating Service"
|
||||
mkdir -p /opt/deemix_data/{config,music}
|
||||
cat <<EOF >/etc/systemd/system/deemix.service
|
||||
[Unit]
|
||||
Description=Deemix
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/deemix
|
||||
Environment=NODE_ENV=production
|
||||
Environment=DEEMIX_DATA_DIR=/opt/deemix_data/config
|
||||
Environment=DEEMIX_MUSIC_DIR=/opt/deemix_data/music
|
||||
Environment=DEEMIX_SERVER_PORT=6595
|
||||
Environment=DEEMIX_HOST=0.0.0.0
|
||||
Environment=DEEMIX_SINGLE_USER=true
|
||||
ExecStart=/usr/bin/node /opt/deemix/packages/webui/dist/main.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now deemix
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -25,12 +25,44 @@ $STD apt install -y \
|
||||
gsfonts \
|
||||
brotli \
|
||||
nginx \
|
||||
redis-server
|
||||
redis-server \
|
||||
meson \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
libglib2.0-dev \
|
||||
libexpat1-dev \
|
||||
libjpeg-dev \
|
||||
libpng-dev \
|
||||
libwebp-dev \
|
||||
libtiff-dev \
|
||||
libheif-dev \
|
||||
libjxl-dev \
|
||||
librsvg2-dev \
|
||||
libcgif-dev \
|
||||
libexif-dev \
|
||||
liblcms2-dev \
|
||||
liborc-0.4-dev \
|
||||
libimagequant-dev \
|
||||
libpango1.0-dev
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "libvips" "libvips/libvips" "prebuild" "latest" "/opt/libvips" "vips-*.tar.xz"
|
||||
|
||||
msg_info "Building libvips"
|
||||
cd /opt/libvips
|
||||
$STD meson setup build --prefix=/usr/local --libdir=lib --buildtype=release -Dmodules=disabled -Dmagick=disabled -Dexamples=false
|
||||
$STD ninja -C build install
|
||||
ldconfig
|
||||
msg_ok "Built libvips"
|
||||
|
||||
msg_info "Cloning Discourse"
|
||||
$STD git clone --depth 1 https://github.com/discourse/discourse.git /opt/discourse
|
||||
msg_ok "Cloned Discourse"
|
||||
|
||||
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
RUBY_VERSION="3.4.4" setup_ruby
|
||||
RUBY_TARGET=$(grep -A1 '^RUBY VERSION' /opt/discourse/Gemfile.lock | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
|
||||
RUBY_VERSION="${RUBY_TARGET:-4.0.7}" RUBY_INSTALL_RAILS="false" setup_ruby
|
||||
|
||||
msg_info "Configuring PostgreSQL for Discourse"
|
||||
DISCOURSE_DB_PASS=$(random_password 13)
|
||||
@@ -42,7 +74,6 @@ msg_ok "Configured PostgreSQL for Discourse"
|
||||
|
||||
msg_info "Configuring Discourse"
|
||||
DISCOURSE_SECRET_KEY=$(openssl rand -hex 64)
|
||||
$STD git clone --depth 1 https://github.com/discourse/discourse.git /opt/discourse
|
||||
cd /opt/discourse
|
||||
cat <<EOF >/opt/discourse/.env
|
||||
RAILS_ENV=production
|
||||
@@ -77,6 +108,7 @@ export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
|
||||
eval "$(rbenv init - bash)" 2>/dev/null || true
|
||||
export RAILS_ENV=production
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
export BUNDLE_SILENCE_ROOT_WARNING=1
|
||||
$STD corepack enable
|
||||
$STD bundle config set --local deployment true
|
||||
$STD bundle config set --local without 'test development'
|
||||
|
||||
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y sqlite3
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
fetch_and_deploy_gh_release "guardian" "HydroshieldMKII/Guardian" "tarball" "latest" "/opt/guardian"
|
||||
|
||||
msg_info "Configuring ${APPLICATION}"
|
||||
|
||||
@@ -18,6 +18,11 @@ if is_debian && [[ "$(get_os_version_major)" -lt 13 ]]; then
|
||||
exit 238
|
||||
fi
|
||||
|
||||
if [[ "$(arch_resolve)" == "amd64" ]] && ! grep -qm1 sse4_2 /proc/cpuinfo; then
|
||||
msg_error "Immich needs a CPU with SSE4.2: its web build stops with 'Illegal instruction' on older ones."
|
||||
exit 236
|
||||
fi
|
||||
|
||||
RELEASE="v3.3.5"
|
||||
if lscpu | grep -q 'GenuineIntel'; then
|
||||
echo ""
|
||||
@@ -108,6 +113,7 @@ $STD apt install --no-install-recommends -y \
|
||||
libhwy-dev \
|
||||
libwebp-dev \
|
||||
libaom-dev \
|
||||
unzip \
|
||||
ccache
|
||||
|
||||
setup_deb822_repo \
|
||||
@@ -129,6 +135,28 @@ if [[ "$CTTYPE" == "0" && -d /dev/dri ]]; then
|
||||
fi
|
||||
msg_ok "Dependencies Installed"
|
||||
|
||||
INSTALL_DIR="/opt/${APPLICATION}"
|
||||
UPLOAD_DIR="${INSTALL_DIR}/upload"
|
||||
SRC_DIR="${INSTALL_DIR}/source"
|
||||
APP_DIR="${INSTALL_DIR}/app"
|
||||
PLUGIN_DIR="${APP_DIR}/plugins/immich-plugin-core"
|
||||
ML_DIR="${APP_DIR}/machine-learning"
|
||||
GEO_DIR="${INSTALL_DIR}/geodata"
|
||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||
|
||||
msg_info "Installing GeoNames data"
|
||||
cd "$GEO_DIR"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
curl_with_retry "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson" "ne_10m_admin_0_countries.geojson"
|
||||
unzip -q cities500.zip
|
||||
date --iso-8601=seconds | tr -d "\n" >geodata-date.txt
|
||||
rm cities500.zip
|
||||
cd ~
|
||||
msg_ok "Installed GeoNames data"
|
||||
|
||||
MISE_ARCH="x64"
|
||||
[[ "$(arch_resolve)" == "arm64" ]] && MISE_ARCH="arm64"
|
||||
fetch_and_deploy_gh_release "mise" "jdx/mise" "singlefile" "latest" "/usr/local/bin" "mise-v*-linux-${MISE_ARCH}"
|
||||
@@ -167,7 +195,7 @@ ACTUAL_PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
||||
ACTUAL_PG_VERSION=${ACTUAL_PG_VERSION:-16}
|
||||
|
||||
VCHORD_RELEASE="1.1.1"
|
||||
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${ACTUAL_PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||
fetch_and_deploy_gh_release "VectorChord" "supervc-stack/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${ACTUAL_PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||
|
||||
sed -i "s/^#shared_preload.*/shared_preload_libraries = 'vchord.so'/" /etc/postgresql/${ACTUAL_PG_VERSION}/main/postgresql.conf
|
||||
systemctl restart postgresql.service
|
||||
@@ -347,15 +375,6 @@ libvips: $LIBVIPS_REVISION
|
||||
EOF
|
||||
msg_ok "Custom Photo-processing Libraries Compiled Successfully"
|
||||
|
||||
INSTALL_DIR="/opt/${APPLICATION}"
|
||||
UPLOAD_DIR="${INSTALL_DIR}/upload"
|
||||
SRC_DIR="${INSTALL_DIR}/source"
|
||||
APP_DIR="${INSTALL_DIR}/app"
|
||||
PLUGIN_DIR="${APP_DIR}/plugins/immich-plugin-core"
|
||||
ML_DIR="${APP_DIR}/machine-learning"
|
||||
GEO_DIR="${INSTALL_DIR}/geodata"
|
||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||
|
||||
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "${RELEASE}" "$SRC_DIR"
|
||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
@@ -396,7 +415,7 @@ cp -a web/build "$APP_DIR"/www
|
||||
cp LICENSE "$APP_DIR"
|
||||
cd "$SRC_DIR"
|
||||
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg,java,terragrunt,opentofu,npm:@openapitools/openapi-generator-cli
|
||||
export MISE_LOCKFILE_MODE=merge MISE_LOCKFILE_PLATFORMS="linux-$(arch_resolve x64 arm64)"
|
||||
mise_ok=0
|
||||
for i in 1 2 3; do
|
||||
@@ -481,20 +500,8 @@ grep -rlE "'/build'" | xargs -n1 sed -i "s|'/build'|'$APP_DIR'|g"
|
||||
sed -i "s@\"/cache\"@\"$INSTALL_DIR/cache\"@g" "$ML_DIR"/immich_ml/config.py
|
||||
ln -s "$UPLOAD_DIR" "$APP_DIR"/upload
|
||||
ln -s "$UPLOAD_DIR" "$ML_DIR"/upload
|
||||
|
||||
msg_info "Installing GeoNames data"
|
||||
cd "$GEO_DIR"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
curl_with_retry "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson" "ne_10m_admin_0_countries.geojson"
|
||||
unzip -q cities500.zip
|
||||
date --iso-8601=seconds | tr -d "\n" >geodata-date.txt
|
||||
rm cities500.zip
|
||||
cd "$INSTALL_DIR"
|
||||
ln -s "$GEO_DIR" "$APP_DIR"
|
||||
msg_ok "Installed GeoNames data"
|
||||
|
||||
# MickLesk temporary patch for HEIC thumbnail gen
|
||||
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
|
||||
|
||||
@@ -24,7 +24,7 @@ $STD apt install -y \
|
||||
ffmpeg
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
fetch_and_deploy_gh_release "monolith" "Y2Z/monolith" "singlefile" "latest" "/usr/bin" "monolith-gnu-linux-$(arch_resolve "x86_64" "aarch64")"
|
||||
fetch_and_deploy_gh_release "monolith" "Y2Z/monolith" "singlefile" "latest" "/usr/bin" "monolith-cli-linux-$(arch_resolve "x86_64" "aarch64")"
|
||||
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp-nightly-builds" "singlefile" "latest" "/usr/bin" "yt-dlp_linux"
|
||||
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(uname -m)-unknown-linux-gnu.zip"
|
||||
setup_meilisearch
|
||||
|
||||
@@ -41,7 +41,7 @@ while [[ $attempt -lt $max_attempts ]]; do
|
||||
fi
|
||||
|
||||
if [[ "$lang_code" =~ [[:space:]] ]]; then
|
||||
((attempt++))
|
||||
attempt=$((attempt + 1))
|
||||
remaining=$((max_attempts - attempt))
|
||||
lang_code=""
|
||||
if [[ $remaining -gt 0 ]]; then
|
||||
|
||||
@@ -43,6 +43,7 @@ After=network.target
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Environment=ENABLE_TIME_SYNC=true
|
||||
ExecStart=/usr/bin/node /opt/matter-server/node_modules/matter-server/dist/esm/MatterServer.js --storage-path /var/lib/matterjs-server
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
@@ -23,7 +23,10 @@ msg_ok "Installed Dependencies"
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
msg_info "Installing n8n (Patience)"
|
||||
$STD npm install -g n8n@latest
|
||||
# n8n-nodes-base 2.46.0 pins both @napi-rs/canvas musl binaries as hard
|
||||
# dependencies, which no os/cpu/libc combination can satisfy. Drop --force
|
||||
# once upstream makes them optional again.
|
||||
$STD npm install -g n8n@latest --force
|
||||
msg_ok "Installed n8n"
|
||||
|
||||
msg_info "Creating Service"
|
||||
|
||||
@@ -15,7 +15,7 @@ update_os
|
||||
|
||||
PG_VERSION="16" setup_postgresql
|
||||
PG_DB_NAME="nametag_db" PG_DB_USER="nametag" setup_postgresql_db
|
||||
NODE_VERSION="20" setup_nodejs
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
fetch_and_deploy_gh_release "nametag" "mattogodoy/nametag" "tarball" "latest" "/opt/nametag"
|
||||
|
||||
msg_info "Setting up Application"
|
||||
|
||||
@@ -22,8 +22,8 @@ PG_DB_NAME="norish" PG_DB_USER="norish" setup_postgresql_db
|
||||
PYTHON_VERSION="3.14" setup_uv
|
||||
|
||||
fetch_and_deploy_gh_release "norish" "norish-recipes/norish" "tarball"
|
||||
NODE_VERSION="22" NODE_MODULE="pnpm@$(jq -r '.packageManager | split("@")[1]' /opt/norish/package.json)" setup_nodejs
|
||||
fetch_and_deploy_gh_release "obscura" "h4ckf0r0day/obscura" "prebuild" "v$(sed -n 's/^OBSCURA_VERSION=//p' /opt/norish/docker/obscura/pin.env)" "/opt/obscura" "obscura-$(arch_resolve "x86_64" "aarch64")-linux-stealth.tar.gz"
|
||||
NODE_VERSION="26" NODE_MODULE="pnpm@$(jq -r '.packageManager | split("@")[1]' /opt/norish/package.json)" setup_nodejs
|
||||
fetch_and_deploy_gh_release "obscura" "$(sed -n 's#^OBSCURA_REPO=https://github.com/##p' /opt/norish/docker/obscura/pin.env)" "prebuild" "v$(sed -n 's/^OBSCURA_VERSION=//p' /opt/norish/docker/obscura/pin.env)" "/opt/obscura" "obscura-$(arch_resolve "x86_64" "aarch64")-linux-stealth.tar.gz"
|
||||
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp" "singlefile" "latest" "/usr/local/bin" "$(arch_resolve "yt-dlp_linux" "yt-dlp_linux_aarch64")"
|
||||
|
||||
msg_info "Building Norish"
|
||||
@@ -75,9 +75,9 @@ Wants=obscura.service
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/norish
|
||||
WorkingDirectory=/opt/norish/apps/web
|
||||
EnvironmentFile=/opt/norish_data/.env
|
||||
ExecStart=/usr/bin/node /opt/norish/dist-server/index.mjs
|
||||
ExecStart=/usr/bin/node --import tsx server/index.ts
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
|
||||
@@ -55,8 +55,7 @@ while true; do
|
||||
done
|
||||
|
||||
ACME_EMAIL_INPUT="${var_npmplus_acme_email:-}"
|
||||
[[ -n "$ACME_EMAIL_INPUT" ]] || read -r -p "${TAB3}Enter your ACME Email: " ACME_EMAIL_INPUT || true
|
||||
[[ -n "$ACME_EMAIL_INPUT" ]] || { msg_error "No ACME e-mail given; set var_npmplus_acme_email or answer the prompt"; exit 64; }
|
||||
[[ -n "$ACME_EMAIL_INPUT" ]] || read -r -p "${TAB3}Enter your ACME Email (optional, press ENTER to skip): " ACME_EMAIL_INPUT || true
|
||||
|
||||
yq -i "
|
||||
.services.npmplus.environment |=
|
||||
|
||||
@@ -59,9 +59,12 @@ if ! dpkg -l | grep -q 'libssl1.1'; then
|
||||
fi
|
||||
|
||||
msg_info "Installing Omada Controller"
|
||||
OMADA_URL=$(curl -fsSL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" "https://support.omadanetworks.com/en/download/software/omada-controller/" |
|
||||
OMADA_URL=$(curl -fsSL -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" \
|
||||
"https://support.omadanetworks.com/en/product/omada-software-controller/?resourceType=download" \
|
||||
"https://support.omadanetworks.com/en/download/software/omada-controller/" |
|
||||
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
|
||||
head -n1)
|
||||
sed -n 's/.*_v\([0-9.]*\)_linux.*/\1 &/p' |
|
||||
sort -V | tail -n1 | cut -d' ' -f2)
|
||||
OMADA_PKG=$(basename "${OMADA_URL}")
|
||||
curl_download "${OMADA_PKG}" "${OMADA_URL}"
|
||||
$STD dpkg -i "${OMADA_PKG}"
|
||||
|
||||
@@ -23,9 +23,11 @@ NODE_VERSION="24" NODE_MODULE="playactor" setup_nodejs
|
||||
fetch_and_deploy_gh_release "ps5-mqtt" "FunkeyFlo/ps5-mqtt" "tarball"
|
||||
|
||||
msg_info "Configuring PS5-MQTT"
|
||||
cd /opt/ps5-mqtt/ps5-mqtt/
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
cd /opt/ps5-mqtt
|
||||
$STD corepack yarn install --immutable
|
||||
$STD env PREPARE_ONLY=1 corepack yarn workspace @ps5-mqtt/server run package
|
||||
cd /opt/ps5-mqtt/ps5-mqtt/server/.packaged/server
|
||||
$STD npm install --omit=dev --omit=optional
|
||||
mkdir -p /opt/.config/ps5-mqtt/
|
||||
mkdir -p /opt/.config/ps5-mqtt/playactor
|
||||
cat <<EOF >/opt/.config/ps5-mqtt/config.json
|
||||
@@ -66,7 +68,7 @@ Description=PS5-MQTT Daemon
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/ps5-mqtt/ps5-mqtt
|
||||
WorkingDirectory=/opt/ps5-mqtt/ps5-mqtt/server/.packaged
|
||||
Environment="CONFIG_PATH=/opt/.config/ps5-mqtt/config.json"
|
||||
Environment="DEBUG='@ha:ps5:*'"
|
||||
Restart=always
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Owen Voke (owenvoke)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Ralex91/Razzia
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y nginx
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@11" setup_nodejs
|
||||
fetch_and_deploy_gh_release "razzia" "Ralex91/Razzia" "tarball"
|
||||
|
||||
msg_info "Building Razzia"
|
||||
cd /opt/razzia
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm build
|
||||
msg_ok "Built Razzia"
|
||||
|
||||
msg_info "Configuring Razzia"
|
||||
mkdir -p /opt/razzia-config
|
||||
cat <<EOF >/opt/razzia/.env
|
||||
MANAGER_PASSWORD=$(random_password 16)
|
||||
JWT_SECRET=$(openssl rand -hex 32)
|
||||
EOF
|
||||
msg_ok "Configured Razzia"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/razzia.service
|
||||
[Unit]
|
||||
Description=Razzia Socket Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/razzia/packages/socket
|
||||
EnvironmentFile=/opt/razzia/.env
|
||||
Environment=NODE_ENV=production
|
||||
Environment=CONFIG_PATH=/opt/razzia-config
|
||||
ExecStart=/usr/bin/node /opt/razzia/packages/socket/dist/index.cjs
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now razzia
|
||||
msg_ok "Created Service"
|
||||
|
||||
msg_info "Configuring Nginx"
|
||||
cat <<EOF >/etc/nginx/sites-available/razzia
|
||||
server {
|
||||
listen 3000;
|
||||
server_name _;
|
||||
|
||||
root /opt/razzia/packages/web/dist;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.html;
|
||||
}
|
||||
|
||||
location /branding/ {
|
||||
alias /opt/razzia-config/branding/;
|
||||
}
|
||||
|
||||
location /media/ {
|
||||
alias /opt/razzia-config/media/;
|
||||
types {
|
||||
image/png png;
|
||||
image/jpeg jpg;
|
||||
image/webp webp;
|
||||
image/gif gif;
|
||||
audio/mpeg mp3;
|
||||
audio/ogg ogg;
|
||||
audio/wav wav;
|
||||
video/mp4 mp4;
|
||||
video/webm webm;
|
||||
}
|
||||
default_type application/octet-stream;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
}
|
||||
|
||||
location /api {
|
||||
client_max_body_size 101m;
|
||||
proxy_pass http://127.0.0.1:3001;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://127.0.0.1:3001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
nginx_enable_site razzia
|
||||
msg_ok "Configured Nginx"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://readarr.com/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y sqlite3 libicu-dev
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
msg_info "Installing Readarr"
|
||||
mkdir -p /var/lib/readarr/
|
||||
chmod 775 /var/lib/readarr/
|
||||
cd /var/lib/readarr/
|
||||
$STD curl -fsSL "https://readarr.servarr.com/v1/update/develop/updatefile?os=linux&runtime=netcore&arch=$(arch_resolve "x64" "arm64")" -o readarr.tar.gz
|
||||
$STD tar -xvzf readarr.tar.gz
|
||||
mv Readarr /opt
|
||||
chmod 775 /opt/Readarr
|
||||
rm -rf Readarr.develop.*.tar.gz
|
||||
msg_ok "Installed Readarr"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/readarr.service
|
||||
[Unit]
|
||||
Description=Readarr Daemon
|
||||
After=syslog.target network.target
|
||||
[Service]
|
||||
UMask=0002
|
||||
Type=simple
|
||||
ExecStart=/opt/Readarr/Readarr -nobrowser -data=/var/lib/readarr/
|
||||
TimeoutStopSec=20
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl -q daemon-reload
|
||||
systemctl enable --now -q readarr
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Dyneteq/reconya
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "reconya" "Dyneteq/reconya" "prebuild" "latest" "/opt/reconya" "reconya-linux-$(arch_resolve "amd64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Configuring Reconya"
|
||||
mkdir -p /opt/reconya_data
|
||||
cat <<EOF >/opt/reconya_data/.env
|
||||
PORT=3008
|
||||
LOGIN_USERNAME=admin
|
||||
LOGIN_PASSWORD=$(random_password)
|
||||
DATABASE_NAME=reconya
|
||||
SQLITE_PATH=/opt/reconya_data/reconya.db
|
||||
PUBLIC_IP_LOOKUP_ENABLED=false
|
||||
GEOLOCATION_ENABLED=false
|
||||
VENDOR_LOOKUP_ONLINE_ENABLED=false
|
||||
OUI_DOWNLOAD_ENABLED=false
|
||||
EOF
|
||||
chmod 600 /opt/reconya_data/.env
|
||||
msg_ok "Configured Reconya"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/reconya.service
|
||||
[Unit]
|
||||
Description=Reconya
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/reconya_data
|
||||
EnvironmentFile=/opt/reconya_data/.env
|
||||
ExecStart=/opt/reconya/reconya-linux-$(arch_resolve "amd64" "arm64")
|
||||
# Reconya ignores SIGTERM and only shuts down on SIGINT
|
||||
KillSignal=SIGINT
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now reconya
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -13,7 +13,7 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "stalwart" "stalwartlabs/stalwart" "prebuild" "latest" "/opt/stalwart" "stalwart-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||
fetch_and_deploy_gh_release "stalwart" "stalwartlabs/stalwart" "prebuild" "v0.16.27" "/opt/stalwart" "stalwart-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||
chmod +x /opt/stalwart/stalwart
|
||||
|
||||
msg_info "Configuring Stalwart"
|
||||
|
||||
@@ -92,7 +92,7 @@ msg_ok "Installed Language Packs"
|
||||
msg_info "Creating Environment Variables"
|
||||
cat <<EOF >/opt/Stirling-PDF/.env
|
||||
# Java tuning
|
||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70"
|
||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=50 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70"
|
||||
JAVA_CUSTOM_OPTS=""
|
||||
|
||||
# LibreOffice
|
||||
@@ -135,7 +135,8 @@ msg_ok "Font Cache Updated"
|
||||
msg_info "Creating Service"
|
||||
# unoserver starts and supervises its own LibreOffice on UNO port 2002, so a separate
|
||||
# listener on that port only collides with it. Do not reintroduce one.
|
||||
cat <<EOF >/etc/systemd/system/stirlingpdf.service
|
||||
# MaxRAM: inside LXC the JVM sizes its heap from host RAM; /proc/meminfo (lxcfs) reports the CT limit
|
||||
cat <<'EOF' >/etc/systemd/system/stirlingpdf.service
|
||||
[Unit]
|
||||
Description=Stirling-PDF service
|
||||
After=syslog.target network.target unoserver.service
|
||||
@@ -147,7 +148,7 @@ User=root
|
||||
Group=root
|
||||
EnvironmentFile=/opt/Stirling-PDF/.env
|
||||
WorkingDirectory=/opt/Stirling-PDF
|
||||
ExecStart=/usr/bin/java -jar Stirling-PDF.jar
|
||||
ExecStart=/bin/bash -c 'exec /usr/bin/java -XX:MaxRAM=$$(grep -m1 -o "[0-9][0-9]*" /proc/meminfo)k $$JAVA_BASE_OPTS $$JAVA_CUSTOM_OPTS -jar Stirling-PDF.jar'
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
build-essential \
|
||||
python3 \
|
||||
git
|
||||
git \
|
||||
redis-server
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
|
||||
@@ -56,8 +57,8 @@ SECRET_KEY=${SECRET_KEY}
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
NEXT_TELEMETRY_DISABLED=1
|
||||
BACKEND_CACHE_PROVIDER=sqlite
|
||||
BACKEND_CACHE_SQLITE_URI=sqlite:///opt/teable/.assets/.cache.db
|
||||
BACKEND_CACHE_PROVIDER=redis
|
||||
BACKEND_CACHE_REDIS_URI=redis://127.0.0.1:6379/0
|
||||
NEXTJS_DIR=apps/nextjs-app
|
||||
EOF
|
||||
ln -sf /opt/teable /app
|
||||
@@ -70,10 +71,11 @@ fi
|
||||
msg_ok "Configured Teable"
|
||||
|
||||
msg_info "Creating Service"
|
||||
systemctl enable -q --now redis-server
|
||||
cat <<EOF >/etc/systemd/system/teable.service
|
||||
[Unit]
|
||||
Description=Teable
|
||||
After=network.target postgresql.service
|
||||
After=network.target postgresql.service redis-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -24,7 +24,11 @@ msg_info "Configuring Teleport"
|
||||
$STD apt install -y teleport
|
||||
$STD teleport configure -o /etc/teleport.yaml
|
||||
systemctl enable -q --now teleport
|
||||
sleep 10
|
||||
SECONDS=0
|
||||
until teleport debug readyz &>/dev/null; do
|
||||
sleep 2
|
||||
((SECONDS >= 120)) && { msg_error "Teleport did not become ready in time"; exit 1; }
|
||||
done
|
||||
tctl users add teleport-admin --roles=editor,access --logins=root >~/teleportadmin.txt
|
||||
sed -i "s|https://[^:]*:3080|https://${LOCAL_IP}:3080|g" ~/teleportadmin.txt
|
||||
msg_ok "Configured Teleport"
|
||||
|
||||
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y redis-server
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="corepack" setup_nodejs
|
||||
PG_VERSION="18" setup_postgresql
|
||||
|
||||
msg_info "Installing pnpm"
|
||||
|
||||
@@ -21,7 +21,7 @@ msg_ok "Installed Dependencies"
|
||||
|
||||
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
||||
PG_DB_NAME="twenty_db" PG_DB_USER="twenty" PG_DB_SCHEMA_PERMS="true" PG_DB_EXTENSIONS="vector" setup_postgresql_db
|
||||
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
||||
NODE_VERSION="26" NODE_MODULE="corepack" setup_nodejs
|
||||
|
||||
fetch_and_deploy_gh_release "twenty" "twentyhq/twenty" "tarball"
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: Nicolas Pastorello (opastorello)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://victoriametrics.com/products/victorialogs/
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "victorialogs" "VictoriaMetrics/VictoriaLogs" "prebuild" "latest" "/opt/victorialogs" "victoria-logs-linux-$(arch_resolve amd64 arm64)-v*[0-9].tar.gz"
|
||||
fetch_and_deploy_gh_release "vlutils" "VictoriaMetrics/VictoriaLogs" "prebuild" "latest" "/opt/vlutils" "vlutils-linux-$(arch_resolve amd64 arm64)-v*[0-9].tar.gz"
|
||||
|
||||
msg_info "Creating Service"
|
||||
mkdir -p /opt/victorialogs_data
|
||||
cat <<EOF >/etc/systemd/system/victorialogs.service
|
||||
[Unit]
|
||||
Description=VictoriaLogs Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/victorialogs
|
||||
ExecStart=/opt/victorialogs/victoria-logs-prod -storageDataPath=/opt/victorialogs_data -httpListenAddr=:9428 -syslog.listenAddr.tcp=:514 -syslog.listenAddr.udp=:514
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now victorialogs
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -17,6 +17,7 @@ fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" ""
|
||||
|
||||
msg_info "Setting up Vikunja"
|
||||
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
|
||||
sed -i '0,/^service:/!{/^service:/d}' /etc/vikunja/config.yml
|
||||
sed -i "s|^ # \(publicurl: \).*| \1\"http://$LOCAL_IP\"|" /etc/vikunja/config.yml
|
||||
sed -i "0,/^ # \(timezone: \).*/s|| \1${tz}|" /etc/vikunja/config.yml
|
||||
systemctl enable -q --now vikunja
|
||||
|
||||
@@ -21,7 +21,11 @@ msg_info "Setup Wazuh"
|
||||
curl -fsSL https://packages.wazuh.com/$RELEASE/wazuh-install.sh -o wazuh-install.sh
|
||||
chmod +x wazuh-install.sh
|
||||
if [ "$STD" = "silent" ]; then
|
||||
bash wazuh-install.sh -a >>~/wazuh-install.output
|
||||
bash wazuh-install.sh -a >>~/wazuh-install.output || {
|
||||
$STD tail -n 25 ~/wazuh-install.output
|
||||
msg_error "The Wazuh installer failed, see its output above or in ~/wazuh-install.output"
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
bash wazuh-install.sh -a | tee -a ~/wazuh-install.output
|
||||
fi
|
||||
|
||||
@@ -17,26 +17,44 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y git
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
|
||||
NODE_VERSION="26" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="wiki" PG_DB_USER="wikijs_user" PG_DB_EXTENSIONS="pg_trgm" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "wikijs" "requarks/wiki-v2" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
|
||||
PG_DB_NAME="wiki" PG_DB_USER="wikijs_user" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
|
||||
|
||||
if [[ "$(arch_resolve)" == "arm64" ]]; then
|
||||
msg_info "Building Wiki.js Dependencies"
|
||||
cd /opt/wikijs/backend
|
||||
$STD npm ci --omit=dev
|
||||
msg_ok "Built Wiki.js Dependencies"
|
||||
fi
|
||||
|
||||
msg_info "Configuring Wiki.js"
|
||||
mv /opt/wikijs/config.sample.yml /opt/wikijs/config.yml
|
||||
sed -i -E 's|^( *user: ).*|\1'"$PG_DB_USER"'|' /opt/wikijs/config.yml
|
||||
sed -i -E 's|^( *pass: ).*|\1'"$PG_DB_PASS"'|' /opt/wikijs/config.yml
|
||||
mkdir -p /opt/wikijs_data
|
||||
cp /opt/wikijs/config.sample.yml /opt/wikijs/config.yml
|
||||
sed -i \
|
||||
-e "s|^ user: .*| user: wikijs_user|" \
|
||||
-e "s|^ pass: .*| pass: ${PG_DB_PASS}|" \
|
||||
-e "s|^ db: .*| db: wiki|" \
|
||||
-e "s|^dataPath: .*|dataPath: /opt/wikijs_data|" \
|
||||
/opt/wikijs/config.yml
|
||||
ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-16)
|
||||
cat <<EOF >~/wikijs.creds
|
||||
Wiki.js Admin
|
||||
Email: admin@example.com
|
||||
Password: ${ADMIN_PASS}
|
||||
EOF
|
||||
msg_ok "Configured Wiki.js"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/wikijs.service
|
||||
[Unit]
|
||||
Description=Wiki.js
|
||||
After=network.target
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/node server
|
||||
ExecStart=/usr/bin/node --no-experimental-webstorage backend
|
||||
Restart=always
|
||||
User=root
|
||||
Environment=NODE_ENV=production
|
||||
@@ -45,7 +63,13 @@ WorkingDirectory=/opt/wikijs
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl set-environment ADMIN_PASS="${ADMIN_PASS}"
|
||||
systemctl enable -q --now wikijs
|
||||
for _ in $(seq 60); do
|
||||
curl -fs -o /dev/null http://127.0.0.1:3000 && break
|
||||
sleep 2
|
||||
done
|
||||
systemctl unset-environment ADMIN_PASS
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
|
||||
@@ -36,17 +36,17 @@ cd /tmp
|
||||
ZABBIX_REPO_DIR="debian"
|
||||
[[ "$ZABBIX_VERSION" == "7.0" && "$(arch_resolve)" == "arm64" ]] && ZABBIX_REPO_DIR="debian-arm64"
|
||||
if [[ "$ZABBIX_VERSION" == "7.0" ]]; then
|
||||
ZABBIX_DEB_URL="https://repo.zabbix.com/zabbix/${ZABBIX_VERSION}/${ZABBIX_REPO_DIR}/pool/main/z/zabbix-release/zabbix-release_latest_${ZABBIX_VERSION}+debian13_all.deb"
|
||||
ZABBIX_DEB_FILE="zabbix-release_latest_${ZABBIX_VERSION}+debian13_all.deb"
|
||||
ZABBIX_DEB_URL="https://repo.zabbix.com/zabbix/${ZABBIX_VERSION}/${ZABBIX_REPO_DIR}/pool/main/z/zabbix-release/zabbix-release_latest_${ZABBIX_VERSION}+debian$(get_os_version_major)_all.deb"
|
||||
ZABBIX_DEB_FILE="zabbix-release_latest_${ZABBIX_VERSION}+debian$(get_os_version_major)_all.deb"
|
||||
else
|
||||
ZABBIX_DEB_URL="https://repo.zabbix.com/zabbix/${ZABBIX_VERSION}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian13_all.deb"
|
||||
ZABBIX_DEB_FILE="zabbix-release_latest+debian13_all.deb"
|
||||
ZABBIX_DEB_URL="https://repo.zabbix.com/zabbix/${ZABBIX_VERSION}/release/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian$(get_os_version_major)_all.deb"
|
||||
ZABBIX_DEB_FILE="zabbix-release_latest+debian$(get_os_version_major)_all.deb"
|
||||
fi
|
||||
|
||||
curl -fsSL "$ZABBIX_DEB_URL" -o /tmp/"$ZABBIX_DEB_FILE"
|
||||
$STD dpkg -i /tmp/"$ZABBIX_DEB_FILE"
|
||||
apt_update_safe
|
||||
$STD apt install -y zabbix-server-pgsql zabbix-frontend-php php8.4-pgsql zabbix-apache-conf zabbix-sql-scripts
|
||||
$STD apt install -y zabbix-server-pgsql zabbix-frontend-php php-pgsql zabbix-apache-conf zabbix-sql-scripts
|
||||
|
||||
if [[ "$ZABBIX_VERSION" == "7.0" ]]; then
|
||||
ZABBIX_SQL="/usr/share/zabbix-sql-scripts/postgresql/server.sql.gz"
|
||||
@@ -83,23 +83,20 @@ msg_ok "Selected $AGENT_PKG"
|
||||
if [ "$AGENT_PKG" = "zabbix-agent2" ]; then
|
||||
echo "Choose plugins for Zabbix Agent2:"
|
||||
echo "1) PostgreSQL only (default, recommended)"
|
||||
echo "2) All plugins (may cause issues)"
|
||||
echo "2) All plugins except NVIDIA GPU (may cause issues)"
|
||||
PLUGIN_CHOICE="${var_zabbix_plugins:-}"
|
||||
[[ -n "$PLUGIN_CHOICE" ]] || read -rp "Choose option [1-2]: " PLUGIN_CHOICE || true
|
||||
|
||||
case "$PLUGIN_CHOICE" in
|
||||
2)
|
||||
$STD apt install -y zabbix-agent2 zabbix-agent2-plugin-*
|
||||
# The NVIDIA plugin fails the agent's config test without NVML, which aborts the package install
|
||||
mapfile -t AGENT2_PLUGINS < <(apt-cache search --names-only '^zabbix-agent2-plugin-' | awk '{print $1}' | grep -v nvidia)
|
||||
$STD apt install -y zabbix-agent2 "${AGENT2_PLUGINS[@]}"
|
||||
;;
|
||||
*)
|
||||
$STD apt install -y zabbix-agent2 zabbix-agent2-plugin-postgresql
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf ]; then
|
||||
sed -i 's|^Plugins.NVIDIA.System.Path=.*|# Plugins.NVIDIA.System.Path=/usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu|' \
|
||||
/etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf
|
||||
fi
|
||||
else
|
||||
$STD apt install -y zabbix-agent
|
||||
fi
|
||||
|
||||
@@ -53,6 +53,7 @@ export VITE_SHOUTRRR_VERSION=$(cat ~/.shoutrrr)
|
||||
export NODE_OPTIONS="--max-old-space-size=3072"
|
||||
$STD bun install
|
||||
$STD node ./node_modules/vite/bin/vite.js build
|
||||
$STD bun build apps/agent/src/index.ts --outfile .output/agent/index.mjs --target bun
|
||||
msg_ok "Built Zerobyte"
|
||||
|
||||
msg_info "Configuring Zerobyte"
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: tteck (tteckster)
|
||||
# Co-Author: MickLesk
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
apk update && apk add curl >/dev/null 2>&1
|
||||
fi
|
||||
# Mark container context BEFORE error handling starts: error_handler/on_exit
|
||||
# must write local failure artifacts instead of talking to the telemetry API
|
||||
# (the host is the single telemetry reporter).
|
||||
export TELEMETRY_CONTEXT="container"
|
||||
# A freshly booted container may not have DNS up yet. `source <(curl ...)` hides
|
||||
# curl's exit code, so a failed download would silently source an empty stream.
|
||||
_bootstrap_die() {
|
||||
if declare -f msg_error >/dev/null 2>&1; then
|
||||
msg_error "$1"
|
||||
else
|
||||
echo "FATAL: $1" >&2
|
||||
fi
|
||||
exit 115
|
||||
}
|
||||
|
||||
_bootstrap_source() {
|
||||
local url="$1" probe="$2" content
|
||||
content=$(curl -fsSL --connect-timeout 10 --retry 5 --retry-connrefused --retry-delay 2 "$url") ||
|
||||
_bootstrap_die "Failed to download ${url##*/}"
|
||||
source /dev/stdin <<<"$content"
|
||||
declare -f "$probe" >/dev/null 2>&1 ||
|
||||
_bootstrap_die "${url##*/} loaded but incomplete (missing ${probe})"
|
||||
}
|
||||
|
||||
_FUNC_BASE="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc"
|
||||
_bootstrap_source "$_FUNC_BASE/core.func" load_functions
|
||||
_bootstrap_source "$_FUNC_BASE/error_handler.func" catch_errors
|
||||
load_functions
|
||||
catch_errors
|
||||
|
||||
# Persist diagnostics setting inside container (exported from build.func)
|
||||
# so addon scripts running later can find the user's choice
|
||||
if [[ ! -f /usr/local/community-scripts/diagnostics ]]; then
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=${DIAGNOSTICS:-no}" >/usr/local/community-scripts/diagnostics
|
||||
fi
|
||||
|
||||
# Get LXC IP address (must be called INSIDE container, after network is up)
|
||||
get_lxc_ip
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# post_progress_to_api()
|
||||
#
|
||||
# - Lightweight progress ping from inside the container
|
||||
# - Updates the existing telemetry record status
|
||||
# - Arguments:
|
||||
# * $1: status (optional, default: "configuring")
|
||||
# - Signals that the installation is actively progressing (not stuck)
|
||||
# - Fire-and-forget: never blocks or fails the script
|
||||
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
|
||||
# ------------------------------------------------------------------------------
|
||||
post_progress_to_api() {
|
||||
command -v curl &>/dev/null || return 0
|
||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
||||
|
||||
local progress_status="${1:-configuring}"
|
||||
|
||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\",\"platform\":\"${TELEMETRY_PLATFORM:-}\",\"repo_source\":\"${REPO_SOURCE:-}\",\"repo_slug\":\"${REPO_SLUG:-}\"}" &>/dev/null || true
|
||||
}
|
||||
|
||||
# This function enables IPv6 if it's not disabled and sets verbose mode
|
||||
verb_ip6() {
|
||||
set_std_mode # Set STD mode based on VERBOSE
|
||||
|
||||
if [ "${IPV6_METHOD:-}" = "disable" ]; then
|
||||
msg_info "Disabling IPv6 (this may affect some services)"
|
||||
$STD sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||
$STD sysctl -w net.ipv6.conf.default.disable_ipv6=1
|
||||
$STD sysctl -w net.ipv6.conf.lo.disable_ipv6=1
|
||||
mkdir -p /etc/sysctl.d
|
||||
$STD tee /etc/sysctl.d/99-disable-ipv6.conf >/dev/null <<EOF
|
||||
net.ipv6.conf.all.disable_ipv6 = 1
|
||||
net.ipv6.conf.default.disable_ipv6 = 1
|
||||
net.ipv6.conf.lo.disable_ipv6 = 1
|
||||
EOF
|
||||
$STD rc-update add sysctl default
|
||||
msg_ok "Disabled IPv6"
|
||||
fi
|
||||
}
|
||||
|
||||
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
|
||||
setting_up_container() {
|
||||
msg_info "Setting up Container OS"
|
||||
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 "${CROSS}${RD} 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${CROSS}${RD} No Network After $RETRY_NUM Tries${CL}"
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 121
|
||||
fi
|
||||
msg_ok "Set up Container OS"
|
||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||
post_progress_to_api
|
||||
}
|
||||
|
||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
||||
network_check() {
|
||||
set +e
|
||||
trap - ERR
|
||||
ipv4_connected=false
|
||||
|
||||
# Check IPv4 connectivity to Cloudflare, Google & Quad9 DNS servers
|
||||
if ping -c 1 -W 1 1.1.1.1 &>/dev/null || ping -c 1 -W 1 8.8.8.8 &>/dev/null || ping -c 1 -W 1 9.9.9.9 &>/dev/null; then
|
||||
msg_ok "IPv4 Internet Connected"
|
||||
ipv4_connected=true
|
||||
else
|
||||
msg_error "IPv4 Internet Not Connected"
|
||||
fi
|
||||
|
||||
if [[ $ipv4_connected == false ]]; then
|
||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
|
||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||
else
|
||||
echo -e "${NETWORK}Check Network Settings"
|
||||
exit 122
|
||||
fi
|
||||
fi
|
||||
|
||||
# DNS resolution checks for GitHub-related domains
|
||||
GIT_HOSTS=("github.com" "raw.githubusercontent.com" "api.github.com")
|
||||
GIT_STATUS="Git DNS:"
|
||||
DNS_FAILED=false
|
||||
|
||||
for HOST in "${GIT_HOSTS[@]}"; do
|
||||
RESOLVEDIP=$(getent hosts "$HOST" | awk '{ print $1 }' | grep -E '(^([0-9]{1,3}\.){3}[0-9]{1,3}$)|(^[a-fA-F0-9:]+$)' | head -n1)
|
||||
if [[ -z "$RESOLVEDIP" ]]; then
|
||||
GIT_STATUS+="$HOST:($DNSFAIL)"
|
||||
DNS_FAILED=true
|
||||
else
|
||||
GIT_STATUS+=" $HOST:($DNSOK)"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$DNS_FAILED" == true ]]; then
|
||||
fatal "$GIT_STATUS"
|
||||
else
|
||||
msg_ok "$GIT_STATUS"
|
||||
fi
|
||||
|
||||
set -e
|
||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||
}
|
||||
|
||||
# This function updates the Container OS by running apk upgrade with mirror fallback
|
||||
update_os() {
|
||||
msg_info "Updating Container OS"
|
||||
configure_http_proxy
|
||||
if ! $STD apk -U upgrade; then
|
||||
msg_warn "apk update failed (dl-cdn.alpinelinux.org), trying alternate mirrors..."
|
||||
local alpine_mirrors="mirror.init7.net ftp.halifax.rwth-aachen.de mirrors.edge.kernel.org alpine.mirror.wearetriple.com mirror.leaseweb.com uk.alpinelinux.org dl-2.alpinelinux.org dl-4.alpinelinux.org"
|
||||
local apk_ok=false
|
||||
for m in $(printf '%s\n' $alpine_mirrors | shuf); do
|
||||
if timeout 2 bash -c "echo >/dev/tcp/$m/80" 2>/dev/null; then
|
||||
msg_custom "${INFO}" "${YW}" "Attempting mirror: ${m}"
|
||||
cat <<EOF >/etc/apk/repositories
|
||||
http://$m/alpine/latest-stable/main
|
||||
http://$m/alpine/latest-stable/community
|
||||
EOF
|
||||
if $STD apk -U upgrade; then
|
||||
msg_ok "CDN set to ${m}: tests passed"
|
||||
apk_ok=true
|
||||
break
|
||||
else
|
||||
msg_warn "Mirror ${m} failed"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [[ "$apk_ok" != true ]]; then
|
||||
msg_error "All Alpine mirrors failed. Check network or try again later."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
local tools_content
|
||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
||||
msg_error "Failed to download tools.func"
|
||||
exit 115
|
||||
}
|
||||
source /dev/stdin <<<"$tools_content"
|
||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
||||
exit 115
|
||||
fi
|
||||
msg_ok "Updated Container OS"
|
||||
post_progress_to_api
|
||||
}
|
||||
|
||||
# This function modifies the message of the day (motd) and SSH settings
|
||||
motd_ssh() {
|
||||
echo "export TERM='xterm-256color'" >>/root/.bashrc
|
||||
|
||||
PROFILE_FILE="/etc/profile.d/00_lxc-details.sh"
|
||||
|
||||
echo "[ -t 1 ] || return 0" >"$PROFILE_FILE"
|
||||
echo "echo -e \"\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${BOLD}${APPLICATION} LXC Container${CL}"\" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${TAB}${GATEWAY}${YW} Provided by: ${GN}community-scripts ORG ${YW}| GitHub: ${GN}https://github.com/community-scripts/ProxmoxVE${CL}\"" >>"$PROFILE_FILE"
|
||||
echo "echo \"\"" >>"$PROFILE_FILE"
|
||||
cat <<EOF >>"$PROFILE_FILE"
|
||||
os_display="Unknown OS"
|
||||
if [ -r /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
os_display="\${PRETTY_NAME:-\${NAME:-Unknown OS}}"
|
||||
fi
|
||||
echo -e "${TAB}${OS}${YW} OS: ${GN}\${os_display}${CL}"
|
||||
EOF
|
||||
echo -e "echo -e \"${TAB}${HOSTNAME}${YW} Hostname: ${GN}\$(hostname)${CL}\"" >>"$PROFILE_FILE"
|
||||
echo -e "echo -e \"${TAB}${INFO}${YW} IP Address: ${GN}\$(ip -4 addr show eth0 | awk '/inet / {print \$2}' | cut -d/ -f1 | head -n 1)${CL}\"" >>"$PROFILE_FILE"
|
||||
|
||||
# Configure SSH if enabled
|
||||
if [[ "${SSH_ROOT}" == "yes" ]]; then
|
||||
# Enable sshd service
|
||||
$STD rc-update add sshd
|
||||
# Allow root login via SSH
|
||||
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
|
||||
# Start the sshd service
|
||||
$STD /etc/init.d/sshd start
|
||||
fi
|
||||
post_progress_to_api
|
||||
}
|
||||
|
||||
# Validate Timezone for some LXC's
|
||||
validate_tz() {
|
||||
[[ -f "/usr/share/zoneinfo/$1" ]]
|
||||
}
|
||||
|
||||
# This function customizes the container and enables passwordless login for the root user
|
||||
customize() {
|
||||
if [[ "$PASSWORD" == "" ]]; then
|
||||
msg_info "Customizing Container"
|
||||
passwd -d root >/dev/null 2>&1
|
||||
|
||||
# Ensure agetty is available
|
||||
apk add --no-cache --force-broken-world util-linux >/dev/null 2>&1
|
||||
|
||||
# Create persistent autologin boot script
|
||||
mkdir -p /etc/local.d
|
||||
cat <<'EOF' >/etc/local.d/autologin.start
|
||||
#!/bin/sh
|
||||
sed -i 's|^tty1::respawn:.*|tty1::respawn:/sbin/agetty --autologin root --noclear tty1 38400 linux|' /etc/inittab
|
||||
kill -HUP 1
|
||||
EOF
|
||||
touch /root/.hushlogin
|
||||
|
||||
chmod +x /etc/local.d/autologin.start
|
||||
rc-update add local >/dev/null 2>&1
|
||||
|
||||
# Apply autologin immediately for current session
|
||||
/etc/local.d/autologin.start
|
||||
|
||||
msg_ok "Customized Container"
|
||||
fi
|
||||
|
||||
echo 'set -a; [ -f /etc/profile.d/90-http-proxy.sh ] && . /etc/profile.d/90-http-proxy.sh; set +a; bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/'"${app}"'.sh)"' >/usr/bin/update
|
||||
chmod +x /usr/bin/update
|
||||
post_progress_to_api
|
||||
}
|
||||
@@ -1,515 +0,0 @@
|
||||
#!/bin/ash
|
||||
# shellcheck shell=ash
|
||||
|
||||
# Expects existing msg_* functions and optional $STD from the framework.
|
||||
|
||||
# ------------------------------
|
||||
# helpers
|
||||
# ------------------------------
|
||||
lower() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; }
|
||||
has() { command -v "$1" >/dev/null 2>&1; }
|
||||
|
||||
need_tool() {
|
||||
# usage: need_tool curl jq unzip ...
|
||||
# setup missing tools via apk
|
||||
local missing=0 t
|
||||
for t in "$@"; do
|
||||
if ! has "$t"; then missing=1; fi
|
||||
done
|
||||
if [ "$missing" -eq 1 ]; then
|
||||
msg_info "Installing tools: $*"
|
||||
apk add --no-cache "$@" >/dev/null 2>&1 || {
|
||||
msg_error "apk add failed for: $*"
|
||||
return 100
|
||||
}
|
||||
msg_ok "Tools ready: $*"
|
||||
fi
|
||||
}
|
||||
|
||||
net_resolves() {
|
||||
# better handling for missing getent on Alpine
|
||||
# usage: net_resolves api.github.com
|
||||
local host="$1"
|
||||
ping -c1 -W1 "$host" >/dev/null 2>&1 || nslookup "$host" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
ensure_usr_local_bin_persist() {
|
||||
# Login shells: /etc/profile.d/
|
||||
local PROFILE_FILE="/etc/profile.d/10-localbin.sh"
|
||||
if [ ! -f "$PROFILE_FILE" ]; then
|
||||
echo 'case ":$PATH:" in *:/usr/local/bin:*) ;; *) export PATH="/usr/local/bin:$PATH";; esac' >"$PROFILE_FILE"
|
||||
chmod +x "$PROFILE_FILE"
|
||||
fi
|
||||
|
||||
# Non-login shells (pct enter): /root/.profile and /root/.bashrc
|
||||
for rc_file in /root/.profile /root/.bashrc; do
|
||||
if [ -f "$rc_file" ] && ! grep -q '/usr/local/bin' "$rc_file"; then
|
||||
echo 'export PATH="/usr/local/bin:$PATH"' >>"$rc_file"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
download_with_progress() {
|
||||
# $1 url, $2 dest
|
||||
local url="$1" out="$2" cl
|
||||
need_tool curl pv || return 127
|
||||
cl=$(curl -fsSLI "$url" 2>/dev/null | awk 'tolower($0) ~ /^content-length:/ {print $2}' | tr -d '\r')
|
||||
if [ -n "$cl" ]; then
|
||||
curl -fsSL "$url" | pv -s "$cl" >"$out" || {
|
||||
msg_error "Download failed: $url"
|
||||
return 250
|
||||
}
|
||||
else
|
||||
curl -fL# -o "$out" "$url" || {
|
||||
msg_error "Download failed: $url"
|
||||
return 250
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# GitHub: check Release
|
||||
# ------------------------------
|
||||
check_for_gh_release() {
|
||||
# app, repo, [pinned]
|
||||
local app="$1" source="$2" pinned="${3:-}"
|
||||
local app_lc
|
||||
app_lc="$(lower "$app" | tr -d ' ')"
|
||||
local current_file="$HOME/.${app_lc}"
|
||||
local current="" release tag
|
||||
|
||||
msg_info "Check for update: $app"
|
||||
|
||||
net_resolves api.github.com || {
|
||||
msg_error "DNS/network error: api.github.com"
|
||||
return 6
|
||||
}
|
||||
need_tool curl jq || return 127
|
||||
|
||||
tag=$(curl -fsSL "https://api.github.com/repos/${source}/releases/latest" | jq -r '.tag_name // empty')
|
||||
[ -z "$tag" ] && {
|
||||
msg_error "Unable to fetch latest tag for $app"
|
||||
return 22
|
||||
}
|
||||
release="${tag#v}"
|
||||
|
||||
[ -f "$current_file" ] && current="$(cat "$current_file")"
|
||||
|
||||
if [ -n "$pinned" ]; then
|
||||
if [ "$pinned" = "$release" ]; then
|
||||
msg_ok "$app pinned to v$pinned (no update)"
|
||||
return 1
|
||||
fi
|
||||
if [ "$current" = "$pinned" ]; then
|
||||
msg_ok "$app pinned v$pinned installed (upstream v$release)"
|
||||
return 1
|
||||
fi
|
||||
msg_info "$app pinned v$pinned (upstream v$release) → update/downgrade"
|
||||
CHECK_UPDATE_RELEASE="$pinned"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$release" != "$current" ] || [ ! -f "$current_file" ]; then
|
||||
CHECK_UPDATE_RELEASE="$release"
|
||||
msg_info "New release available: v$release (current: v${current:-none})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$app is up to date (v$release)"
|
||||
return 1
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# GitHub: get Release & deploy (Alpine)
|
||||
# modes: tarball | prebuild | singlefile
|
||||
# ------------------------------
|
||||
fetch_and_deploy_gh() {
|
||||
# $1 app, $2 repo, [$3 mode], [$4 version], [$5 target], [$6 asset_pattern
|
||||
local app="$1" repo="$2" mode="${3:-tarball}" version="${4:-latest}" target="${5:-/opt/$1}" pattern="${6:-}"
|
||||
local app_lc
|
||||
app_lc="$(lower "$app" | tr -d ' ')"
|
||||
local vfile="$HOME/.${app_lc}"
|
||||
local json url filename tmpd unpack
|
||||
|
||||
net_resolves api.github.com || {
|
||||
msg_error "DNS/network error"
|
||||
return 6
|
||||
}
|
||||
need_tool curl jq tar || return 127
|
||||
[ "$mode" = "prebuild" ] || [ "$mode" = "singlefile" ] && need_tool unzip >/dev/null 2>&1 || true
|
||||
|
||||
tmpd="$(mktemp -d)" || return 252
|
||||
mkdir -p "$target"
|
||||
|
||||
# Release JSON
|
||||
if [ "$version" = "latest" ]; then
|
||||
json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/latest")" || {
|
||||
msg_error "GitHub API failed"
|
||||
rm -rf "$tmpd"
|
||||
return 22
|
||||
}
|
||||
else
|
||||
json="$(curl -fsSL "https://api.github.com/repos/$repo/releases/tags/$version")" || {
|
||||
msg_error "GitHub API failed"
|
||||
rm -rf "$tmpd"
|
||||
return 22
|
||||
}
|
||||
fi
|
||||
|
||||
# correct Version
|
||||
version="$(printf '%s' "$json" | jq -r '.tag_name // empty')"
|
||||
version="${version#v}"
|
||||
|
||||
[ -z "$version" ] && {
|
||||
msg_error "No tag in release json"
|
||||
rm -rf "$tmpd"
|
||||
return 65
|
||||
}
|
||||
|
||||
case "$mode" in
|
||||
tarball | source)
|
||||
url="$(printf '%s' "$json" | jq -r '.tarball_url // empty')"
|
||||
[ -z "$url" ] && url="https://github.com/$repo/archive/refs/tags/v$version.tar.gz"
|
||||
filename="${app_lc}-${version}.tar.gz"
|
||||
download_with_progress "$url" "$tmpd/$filename" || {
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
tar -xzf "$tmpd/$filename" -C "$tmpd" || {
|
||||
msg_error "tar extract failed"
|
||||
rm -rf "$tmpd"
|
||||
return 251
|
||||
}
|
||||
unpack="$(find "$tmpd" -mindepth 1 -maxdepth 1 -type d | head -n1)"
|
||||
# copy content of unpack to target
|
||||
(cd "$unpack" && tar -cf - .) | (cd "$target" && tar -xf -) || {
|
||||
msg_error "copy failed"
|
||||
rm -rf "$tmpd"
|
||||
return 252
|
||||
}
|
||||
;;
|
||||
prebuild)
|
||||
[ -n "$pattern" ] || {
|
||||
msg_error "prebuild requires asset pattern"
|
||||
rm -rf "$tmpd"
|
||||
return 65
|
||||
}
|
||||
url="$(printf '%s' "$json" | jq -r '.assets[].browser_download_url' | awk -v p="$pattern" '
|
||||
BEGIN{IGNORECASE=1}
|
||||
$0 ~ p {print; exit}
|
||||
')"
|
||||
[ -z "$url" ] && {
|
||||
msg_error "asset not found for pattern: $pattern"
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
filename="${url##*/}"
|
||||
download_with_progress "$url" "$tmpd/$filename" || {
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
# unpack archive (Zip or tarball)
|
||||
case "$filename" in
|
||||
*.zip)
|
||||
need_tool unzip || {
|
||||
rm -rf "$tmpd"
|
||||
return 127
|
||||
}
|
||||
mkdir -p "$tmpd/unp"
|
||||
unzip -q "$tmpd/$filename" -d "$tmpd/unp"
|
||||
;;
|
||||
*.tar.gz | *.tgz | *.tar.xz | *.tar.zst | *.tar.bz2)
|
||||
mkdir -p "$tmpd/unp"
|
||||
tar -xf "$tmpd/$filename" -C "$tmpd/unp"
|
||||
;;
|
||||
*)
|
||||
msg_error "unsupported archive: $filename"
|
||||
rm -rf "$tmpd"
|
||||
return 251
|
||||
;;
|
||||
esac
|
||||
# top-level folder strippen
|
||||
if [ "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d | wc -l)" -eq 1 ] && [ -z "$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type f | head -n1)" ]; then
|
||||
unpack="$(find "$tmpd/unp" -mindepth 1 -maxdepth 1 -type d)"
|
||||
(cd "$unpack" && tar -cf - .) | (cd "$target" && tar -xf -) || {
|
||||
msg_error "copy failed"
|
||||
rm -rf "$tmpd"
|
||||
return 252
|
||||
}
|
||||
else
|
||||
(cd "$tmpd/unp" && tar -cf - .) | (cd "$target" && tar -xf -) || {
|
||||
msg_error "copy failed"
|
||||
rm -rf "$tmpd"
|
||||
return 252
|
||||
}
|
||||
fi
|
||||
;;
|
||||
singlefile)
|
||||
[ -n "$pattern" ] || {
|
||||
msg_error "singlefile requires asset pattern"
|
||||
rm -rf "$tmpd"
|
||||
return 65
|
||||
}
|
||||
url="$(printf '%s' "$json" | jq -r '.assets[].browser_download_url' | awk -v p="$pattern" '
|
||||
BEGIN{IGNORECASE=1}
|
||||
$0 ~ p {print; exit}
|
||||
')"
|
||||
[ -z "$url" ] && {
|
||||
msg_error "asset not found for pattern: $pattern"
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
filename="${url##*/}"
|
||||
download_with_progress "$url" "$target/$app" || {
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
chmod +x "$target/$app"
|
||||
;;
|
||||
*)
|
||||
msg_error "Unknown mode: $mode"
|
||||
rm -rf "$tmpd"
|
||||
return 65
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$version" >"$vfile"
|
||||
ensure_usr_local_bin_persist
|
||||
rm -rf "$tmpd"
|
||||
msg_ok "Deployed $app ($version) → $target"
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# yq (mikefarah) – Alpine
|
||||
# ------------------------------
|
||||
setup_yq() {
|
||||
# prefer apk, unless FORCE_GH=1
|
||||
if [ "${FORCE_GH:-0}" != "1" ] && apk info -e yq >/dev/null 2>&1; then
|
||||
msg_info "Updating yq via apk"
|
||||
apk add --no-cache --upgrade yq >/dev/null 2>&1 || true
|
||||
msg_ok "yq ready ($(yq --version 2>/dev/null))"
|
||||
return 0
|
||||
fi
|
||||
|
||||
need_tool curl || return 127
|
||||
local arch bin url tmp
|
||||
case "$(uname -m)" in
|
||||
x86_64) arch="amd64" ;;
|
||||
aarch64) arch="arm64" ;;
|
||||
*)
|
||||
msg_error "Unsupported arch for yq: $(uname -m)"
|
||||
return 238
|
||||
;;
|
||||
esac
|
||||
url="https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${arch}"
|
||||
tmp="$(mktemp)"
|
||||
download_with_progress "$url" "$tmp" || return 250
|
||||
/usr/bin/install -m 0755 "$tmp" /usr/local/bin/yq
|
||||
rm -f "$tmp"
|
||||
msg_ok "Setup yq ($(yq --version 2>/dev/null))"
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# Adminer – Alpine
|
||||
# ------------------------------
|
||||
setup_adminer() {
|
||||
need_tool curl || return 127
|
||||
msg_info "Setup Adminer (Alpine)"
|
||||
mkdir -p /var/www/localhost/htdocs/adminer
|
||||
curl -fsSL https://github.com/vrana/adminer/releases/latest/download/adminer.php \
|
||||
-o /var/www/localhost/htdocs/adminer/index.php || {
|
||||
msg_error "Adminer download failed"
|
||||
return 250
|
||||
}
|
||||
msg_ok "Adminer at /adminer (served by your webserver)"
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# uv – Alpine (musl tarball)
|
||||
# optional: PYTHON_VERSION="3.12"
|
||||
# ------------------------------
|
||||
setup_uv() {
|
||||
need_tool curl tar || return 127
|
||||
local UV_BIN="/usr/local/bin/uv"
|
||||
local arch tarball url tmpd ver installed
|
||||
|
||||
case "$(uname -m)" in
|
||||
x86_64) arch="x86_64-unknown-linux-musl" ;;
|
||||
aarch64) arch="aarch64-unknown-linux-musl" ;;
|
||||
*)
|
||||
msg_error "Unsupported arch for uv: $(uname -m)"
|
||||
return 238
|
||||
;;
|
||||
esac
|
||||
|
||||
ver="$(curl -fsSL https://api.github.com/repos/astral-sh/uv/releases/latest | jq -r '.tag_name' 2>/dev/null)"
|
||||
ver="${ver#v}"
|
||||
[ -z "$ver" ] && {
|
||||
msg_error "uv: cannot determine latest version"
|
||||
return 250
|
||||
}
|
||||
|
||||
if has "$UV_BIN"; then
|
||||
installed="$($UV_BIN -V 2>/dev/null | awk '{print $2}')"
|
||||
[ "$installed" = "$ver" ] && {
|
||||
msg_ok "uv $ver already installed"
|
||||
return 0
|
||||
}
|
||||
msg_info "Updating uv $installed → $ver"
|
||||
else
|
||||
msg_info "Setup uv $ver"
|
||||
fi
|
||||
|
||||
tmpd="$(mktemp -d)" || return 252
|
||||
tarball="uv-${arch}.tar.gz"
|
||||
url="https://github.com/astral-sh/uv/releases/download/v${ver}/${tarball}"
|
||||
|
||||
download_with_progress "$url" "$tmpd/uv.tar.gz" || {
|
||||
rm -rf "$tmpd"
|
||||
return 250
|
||||
}
|
||||
tar -xzf "$tmpd/uv.tar.gz" -C "$tmpd" || {
|
||||
msg_error "uv: extract failed"
|
||||
rm -rf "$tmpd"
|
||||
return 251
|
||||
}
|
||||
|
||||
# tar contains ./uv
|
||||
if [ -x "$tmpd/uv" ]; then
|
||||
/usr/bin/install -m 0755 "$tmpd/uv" "$UV_BIN"
|
||||
else
|
||||
# fallback: in subfolder
|
||||
/usr/bin/install -m 0755 "$tmpd"/*/uv "$UV_BIN" 2>/dev/null || {
|
||||
msg_error "uv binary not found in tar"
|
||||
rm -rf "$tmpd"
|
||||
return 252
|
||||
}
|
||||
fi
|
||||
rm -rf "$tmpd"
|
||||
ensure_usr_local_bin_persist
|
||||
msg_ok "Setup uv $ver"
|
||||
|
||||
if [ -n "${PYTHON_VERSION:-}" ]; then
|
||||
local match
|
||||
match="$(uv python list --only-downloads 2>/dev/null | awk -v maj="$PYTHON_VERSION" '
|
||||
$0 ~ "^cpython-"maj"\\." { print $0 }' | awk -F- '{print $2}' | sort -V | tail -n1)"
|
||||
[ -z "$match" ] && {
|
||||
msg_error "No matching Python for $PYTHON_VERSION"
|
||||
return 250
|
||||
}
|
||||
if ! uv python list | grep -q "cpython-${match}-linux"; then
|
||||
msg_info "Installing Python $match via uv"
|
||||
uv python install "$match" || {
|
||||
msg_error "uv python install failed"
|
||||
return 150
|
||||
}
|
||||
msg_ok "Python $match installed (uv)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# Java – Alpine (OpenJDK)
|
||||
# JAVA_VERSION: 17|21 (Default 21)
|
||||
# ------------------------------
|
||||
setup_java() {
|
||||
local JAVA_VERSION="${JAVA_VERSION:-21}" pkg
|
||||
case "$JAVA_VERSION" in
|
||||
17) pkg="openjdk17-jdk" ;;
|
||||
21 | *) pkg="openjdk21-jdk" ;;
|
||||
esac
|
||||
msg_info "Setup Java (OpenJDK $JAVA_VERSION)"
|
||||
apk add --no-cache "$pkg" >/dev/null 2>&1 || {
|
||||
msg_error "apk add $pkg failed"
|
||||
return 100
|
||||
}
|
||||
# set JAVA_HOME
|
||||
local prof="/etc/profile.d/20-java.sh"
|
||||
if [ ! -f "$prof" ]; then
|
||||
echo 'export JAVA_HOME=$(dirname $(dirname $(readlink -f $(command -v java))))' >"$prof"
|
||||
echo 'case ":$PATH:" in *:$JAVA_HOME/bin:*) ;; *) export PATH="$JAVA_HOME/bin:$PATH";; esac' >>"$prof"
|
||||
chmod +x "$prof"
|
||||
fi
|
||||
msg_ok "Java ready: $(java -version 2>&1 | head -n1)"
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# Go – Alpine (apk prefers, else tarball)
|
||||
# ------------------------------
|
||||
setup_go() {
|
||||
if [ -z "${GO_VERSION:-}" ]; then
|
||||
msg_info "Setup Go (apk)"
|
||||
apk add --no-cache go >/dev/null 2>&1 || {
|
||||
msg_error "apk add go failed"
|
||||
return 100
|
||||
}
|
||||
msg_ok "Go ready: $(go version 2>/dev/null)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
need_tool curl tar || return 127
|
||||
local ARCH TARBALL URL TMP
|
||||
case "$(uname -m)" in
|
||||
x86_64) ARCH="amd64" ;;
|
||||
aarch64) ARCH="arm64" ;;
|
||||
*)
|
||||
msg_error "Unsupported arch for Go: $(uname -m)"
|
||||
return 238
|
||||
;;
|
||||
esac
|
||||
TARBALL="go${GO_VERSION}.linux-${ARCH}.tar.gz"
|
||||
URL="https://go.dev/dl/${TARBALL}"
|
||||
msg_info "Setup Go $GO_VERSION (tarball)"
|
||||
TMP="$(mktemp)"
|
||||
download_with_progress "$URL" "$TMP" || return 250
|
||||
rm -rf /usr/local/go
|
||||
tar -C /usr/local -xzf "$TMP" || {
|
||||
msg_error "extract go failed"
|
||||
rm -f "$TMP"
|
||||
return 251
|
||||
}
|
||||
rm -f "$TMP"
|
||||
ln -sf /usr/local/go/bin/go /usr/local/bin/go
|
||||
ln -sf /usr/local/go/bin/gofmt /usr/local/bin/gofmt
|
||||
ensure_usr_local_bin_persist
|
||||
msg_ok "Go ready: $(go version 2>/dev/null)"
|
||||
}
|
||||
|
||||
# ------------------------------
|
||||
# Composer – Alpine
|
||||
# uses php83-cli + openssl + phar
|
||||
# ------------------------------
|
||||
setup_composer() {
|
||||
local COMPOSER_BIN="/usr/local/bin/composer"
|
||||
if ! has php; then
|
||||
# prefers php83
|
||||
msg_info "Installing PHP CLI for Composer"
|
||||
apk add --no-cache php83-cli php83-openssl php83-phar php83-iconv >/dev/null 2>&1 || {
|
||||
# Fallback to generic php if 83 not available
|
||||
apk add --no-cache php-cli php-openssl php-phar php-iconv >/dev/null 2>&1 || {
|
||||
msg_error "Failed to install php-cli for composer"
|
||||
return 100
|
||||
}
|
||||
}
|
||||
msg_ok "PHP CLI ready: $(php -v | head -n1)"
|
||||
fi
|
||||
|
||||
if [ -x "$COMPOSER_BIN" ]; then
|
||||
msg_info "Updating Composer"
|
||||
else
|
||||
msg_info "Setup Composer"
|
||||
fi
|
||||
|
||||
need_tool curl || return 127
|
||||
curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php || {
|
||||
msg_error "composer installer download failed"
|
||||
return 250
|
||||
}
|
||||
php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer >/dev/null 2>&1 || {
|
||||
msg_error "composer install failed"
|
||||
return 150
|
||||
}
|
||||
rm -f /tmp/composer-setup.php
|
||||
ensure_usr_local_bin_persist
|
||||
msg_ok "Composer ready: $(composer --version 2>/dev/null)"
|
||||
}
|
||||