Compare commits
129 Commits
2026-10-25
...
2026-11-01
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| d4613af2ed | |||
| 63790a944c | |||
| b8a8d6a572 | |||
| 876731e6fd | |||
| 23d0c904a3 | |||
| 5d477b0b6e | |||
| 8a4ff0e7ce | |||
| ddc1278115 | |||
| f07237f231 | |||
| 2fe0acad6e | |||
| e44c353ddf | |||
| 7012e50e42 | |||
| 5c754fc681 | |||
| 7d5857f1b9 | |||
| 9a0863d319 | |||
| 0d271df31e | |||
| 4905357546 | |||
| f920569ced | |||
| 176bd660e1 | |||
| db6a42d8bb | |||
| 17e81ea5c4 | |||
| a62b0ce9a7 | |||
| 162286ef4d | |||
| 31d56c7a25 | |||
| 82f59203fd | |||
| 2415d6bf92 | |||
| 7a3445daff | |||
| e9e607f1e0 | |||
| 3a3ddb64b5 | |||
| fd8a3a6e3f | |||
| 99f49260c0 | |||
| 11254f9554 | |||
| 86dc405a5d | |||
| c9e4f5de0c | |||
| 3de0ba9e1d | |||
| 6078770a68 |
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Community Scripts - CS Amber</title>
|
||||
<desc id="desc">A continuous ivory C interlocks with a warm orange S on charcoal. Both letterforms use rounded, folded geometry.</desc>
|
||||
<rect width="512" height="512" rx="112" fill="#29262b"/>
|
||||
<defs>
|
||||
<mask id="weave-clearance" maskUnits="userSpaceOnUse" x="0" y="0" width="512" height="512">
|
||||
<rect width="512" height="512" fill="white"/>
|
||||
<path d="M390 142H322L270 172V220L322 250H348L392 276V338L338 370H284" fill="none" stroke="black" stroke-width="72" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</mask>
|
||||
</defs>
|
||||
<g fill="none" stroke-width="56" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M254 142H186L118 182V330L186 370H254" stroke="#f5f4eb" mask="url(#weave-clearance)"/>
|
||||
<path d="M390 142H322L270 172V220L322 250H348L392 276V338L338 370H284" stroke="#f29a67"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 997 B |
|
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 |
|
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
|
||||
|
||||
@@ -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`.',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,185 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 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
|
||||
|
||||
- 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
|
||||
@@ -1171,167 +1353,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))
|
||||
@@ -191,7 +191,6 @@ create` still ran and the container was still built.
|
||||
## Notes
|
||||
|
||||
- **Website metadata** (name, description, logo, tags) is managed via the website — use the "Report Issue" link on any script page to request changes. Do not submit metadata changes via repo files.
|
||||
- **JSON files** in `json/` define script properties used by the website. See existing files for structure reference.
|
||||
- Keep PRs small and focused. One fix or feature per PR is ideal.
|
||||
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [DevScripts](https://github.com/community-scripts/DevScripts) instead.
|
||||
- PRs that fail CI checks will not be merged.
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="112px" alt="Proxmox VE Helper-Scripts Logo" />
|
||||
<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>Proxmox VE Helper-Scripts</h1>
|
||||
<p><strong>One-command installations for services, containers, and VMs on Proxmox VE</strong><br/>
|
||||
<h1>Community Scripts — Proxmox VE</h1>
|
||||
<p><strong>One-command installations for services, containers and VMs on Proxmox VE</strong><br/>
|
||||
A community project — built on the foundation of <a href="https://github.com/tteck">@tteck</a>'s original work</p>
|
||||
|
||||
<p>
|
||||
<a href="https://community-scripts.org"><img src="https://img.shields.io/badge/Website-community--scripts.org-4c9b3f?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/3AnUqsXnmK"><img src="https://img.shields.io/badge/Discord-Join_us-7289da?style=flat-square&logo=discord&logoColor=white" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/stargazers"><img src="https://img.shields.io/github/stars/community-scripts/ProxmoxVE?style=flat-square&label=Stars&color=f5a623" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/Changelog-view-6c5ce7?style=flat-square" /></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=flat-square" /></a>
|
||||
<a href="https://community-scripts.org"><img src="https://img.shields.io/badge/Website-community--scripts.org-4c9b3f?style=flat-square" alt="Website" /></a>
|
||||
<a href="https://discord.gg/3AnUqsXnmK"><img src="https://img.shields.io/badge/Discord-Join_us-7289da?style=flat-square&logo=discord&logoColor=white" alt="Discord" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/stargazers"><img src="https://img.shields.io/github/stars/community-scripts/ProxmoxVE?style=flat-square&label=Stars&color=f5a623" alt="Stars" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/Changelog-view-6c5ce7?style=flat-square" alt="Changelog" /></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=flat-square" alt="License" /></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -18,94 +19,146 @@
|
||||
|
||||
## What is this?
|
||||
|
||||
**Simplify your Proxmox VE setup with community-driven automation scripts.**
|
||||
**The canonical application scripts.** More than 700 of them, covering home
|
||||
automation, media, networking, databases, monitoring, security and developer
|
||||
tooling. Paste one command into your Proxmox shell and the container or VM is
|
||||
built, configured and running.
|
||||
|
||||
Install and configure popular self-hosted services with a single command — no manual package hunting, no config file archaeology. Paste a command into your Proxmox shell, answer a few prompts, and your container or VM is up and running.
|
||||
A script only describes *what* to install. Creating the container, asking the
|
||||
questions and handling the errors is the job of the shared engine in
|
||||
[core](https://github.com/community-scripts/core), which every script loads at
|
||||
start-up. The same scripts run unchanged on an Incus host through
|
||||
[the Incus repository](https://github.com/community-scripts/Incus).
|
||||
|
||||
The collection covers hundreds of services across categories like home automation, media servers, networking tools, databases, monitoring stacks, and more.
|
||||
Ready-made commands for every application are on
|
||||
[community-scripts.org](https://community-scripts.org).
|
||||
|
||||
---
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Go to **[community-scripts.org](https://community-scripts.org)**
|
||||
2. Search for the service you want — Home Assistant, Nginx Proxy Manager, Jellyfin
|
||||
3. Copy the one-line install command from the script page
|
||||
4. Open your **Proxmox shell** and paste it
|
||||
5. Choose **Default** or **Advanced** and follow the prompts
|
||||
|
||||
Each script page lists what the container includes, the default resources and
|
||||
the post-install notes.
|
||||
|
||||
> These commands run as root on your host. Every script is readable in this
|
||||
> repository, and each script page links to its source — read it before you
|
||||
> paste it, as you would with any installer.
|
||||
|
||||
---
|
||||
|
||||
## How scripts work
|
||||
|
||||
**Default** picks sensible resources and asks only what it has to. Most installs
|
||||
finish in a few minutes.
|
||||
|
||||
**Advanced** hands you container settings, networking, storage backend and
|
||||
application options before anything is created.
|
||||
|
||||
Every container gets an `update` command. Type it in the container console:
|
||||
|
||||
```bash
|
||||
update
|
||||
```
|
||||
|
||||
It updates the installed application and reaches settings that would otherwise
|
||||
mean editing config files by hand. VM scripts have no built-in updater — use the
|
||||
guest's own package manager.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
| Component | Details |
|
||||
| -------------- | ------------------------------------------------ |
|
||||
| **Proxmox VE** | Version 8.4, 9.0, 9.1, or 9.2 |
|
||||
| **Host OS** | Proxmox VE (Debian-based) |
|
||||
| **Access** | Root shell access on the Proxmox host |
|
||||
| **Network** | Internet connection required during installation |
|
||||
| Component | Details |
|
||||
| --------- | ------- |
|
||||
| **Proxmox VE** | 8.0 – 8.4, or 9.0 – 9.2 |
|
||||
| **Access** | Root shell on the Proxmox host |
|
||||
| **Network** | Internet access during installation |
|
||||
|
||||
Virtual machine scripts need the same versions as containers.
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
## Repository map
|
||||
|
||||
The fastest way to find and run scripts:
|
||||
|
||||
1. Go to **[community-scripts.org](https://community-scripts.org)**
|
||||
2. Search for the service you want (e.g. "Home Assistant", "Nginx Proxy Manager", "Jellyfin")
|
||||
3. Copy the one-line install command from the script page
|
||||
4. Open your **Proxmox Shell** and paste it
|
||||
5. Choose between **Default** or **Advanced** setup and follow the prompts
|
||||
|
||||
Each script page documents what the container includes, default resource allocation, and post-install notes.
|
||||
| Repository | Contains |
|
||||
| ---------- | -------- |
|
||||
| [core](https://github.com/community-scripts/core) | The engine — container and VM creation, the wizard, error handling |
|
||||
| **ProxmoxVE** (this repo) | Canonical application scripts, plus `tools/pve/`, `vm/` and `turnkey/` |
|
||||
| [Incus](https://github.com/community-scripts/Incus) | The same scripts on an Incus host, plus Incus VMs and host tooling |
|
||||
| [DevScripts](https://github.com/community-scripts/DevScripts) | Where new scripts are tested before they land here |
|
||||
|
||||
---
|
||||
|
||||
## How Scripts Work
|
||||
## Layout
|
||||
|
||||
Every script follows the same pattern:
|
||||
| Folder | Contents |
|
||||
| ------ | -------- |
|
||||
| `ct/` | Application scripts — the command you paste |
|
||||
| `install/` | What each script installs inside the container |
|
||||
| `vm/` | Virtual machine scripts |
|
||||
| `tools/pve/` | Host tooling: post-install, hardware passthrough, maintenance |
|
||||
| `turnkey/` | TurnKey Linux appliance helper |
|
||||
|
||||
**Default mode** — Picks sensible resource defaults (CPU, RAM, storage) and asks only the minimum required questions. Most installs finish in under five minutes.
|
||||
|
||||
**Advanced mode** — Gives you full control over container settings, networking, storage backends, and application-level configuration before anything is installed.
|
||||
|
||||
After installation, each container ships with a **post-install helper** accessible from the Proxmox shell. It handles common tasks like:
|
||||
|
||||
- Applying updates to the installed service
|
||||
- Changing application settings without manually editing config files
|
||||
- Basic troubleshooting and log access
|
||||
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
|
||||
request a change.
|
||||
|
||||
---
|
||||
|
||||
## What's Included
|
||||
## Testing a fork or branch
|
||||
|
||||
The repository covers a wide range of categories. A few examples:
|
||||
Engine and scripts resolve independently, so either can point somewhere else.
|
||||
Put the variable on the command itself — nothing needs exporting.
|
||||
|
||||
| Category | Examples |
|
||||
| --------------- | --------------------------------------------------- |
|
||||
| Home Automation | Home Assistant, Zigbee2MQTT, ESPHome, Node-RED |
|
||||
| Media | Jellyfin, Plex, Radarr, Sonarr, Immich |
|
||||
| Networking | AdGuard Home, Nginx Proxy Manager, Pi-hole, Traefik |
|
||||
| Monitoring | Grafana, Prometheus, Uptime Kuma, Netdata |
|
||||
| Databases | PostgreSQL, MariaDB, Redis, InfluxDB |
|
||||
| Security | Vaultwarden, CrowdSec, Authentik |
|
||||
| Dev & Tools | Gitea, Portainer, VS Code Server, n8n |
|
||||
To run your own copy of the scripts:
|
||||
|
||||
> Browse the full list at **[community-scripts.org/categories](https://community-scripts.org/categories)** — new scripts are added regularly.
|
||||
```bash
|
||||
COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/YOU/ProxmoxVE/my-branch \
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOU/ProxmoxVE/my-branch/ct/debian.sh)"
|
||||
```
|
||||
|
||||
A `ct/` script fetched with `curl` cannot tell the engine where it came from, so
|
||||
without that variable it would look for its `install/` half upstream.
|
||||
|
||||
Only when you are changing the engine itself:
|
||||
|
||||
```bash
|
||||
COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/YOU/core/my-branch \
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"
|
||||
```
|
||||
|
||||
A local checkout of core wins over both — point at it with
|
||||
`COMMUNITY_SCRIPTS_CORE_DIR`.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
This project runs on community contributions. Whether you want to write new scripts, improve existing ones, or just report a bug — every bit helps.
|
||||
This project runs on community contributions. New scripts, fixes, bug reports —
|
||||
all of it helps.
|
||||
|
||||
### Where to start
|
||||
|
||||
| I want to… | Go here |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| Add a **new** script | [DevScripts](https://github.com/community-scripts/DevScripts) — new scripts are tested here first |
|
||||
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR in this repo |
|
||||
| Report a bug or broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
| Request a new script or feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
|
||||
| Report a security vulnerability | [Security Policy](SECURITY.md) |
|
||||
| Get help or chat with other users | [Discord](https://discord.gg/3AnUqsXnmK) |
|
||||
| I want to… | Go here |
|
||||
| ---------- | ------- |
|
||||
| Add a **new** script | [DevScripts](https://github.com/community-scripts/DevScripts) — new scripts are tested there first |
|
||||
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR here |
|
||||
| Change how containers are built | [core](https://github.com/community-scripts/core) |
|
||||
| Report a bug or a broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
| Request a script or a feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
|
||||
| Report a security vulnerability | [Security Policy](SECURITY.md) |
|
||||
| Ask a question | [Discord](https://discord.gg/3AnUqsXnmK) |
|
||||
|
||||
### Before you open a PR
|
||||
|
||||
- **New scripts go to [DevScripts](https://github.com/community-scripts/DevScripts), not here.** PRs with new scripts opened directly against this repo will be closed.
|
||||
- Bug fixes and improvements to existing scripts belong in this repo — read the [Contributing Guidelines](CONTRIBUTING.md) first.
|
||||
- Keep PRs focused. One fix or feature per PR.
|
||||
- Document what your script installs and any non-obvious decisions in the corresponding JSON metadata file.
|
||||
- **New scripts go to [DevScripts](https://github.com/community-scripts/DevScripts), not here.** PRs adding new scripts to this repository will be closed.
|
||||
- Keep a PR to one fix or one feature.
|
||||
- A bug that also happens on Incus is an application or engine bug — say so in the report.
|
||||
- Read the [Contributing Guidelines](CONTRIBUTING.md) before your first PR.
|
||||
|
||||
---
|
||||
|
||||
@@ -137,6 +190,8 @@ This project runs on community contributions. Whether you want to write new scri
|
||||
<sub><b>CrazyWolf13</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/tremor021">
|
||||
<img src="https://github.com/tremor021.png" width="80" height="80" style="border-radius:50%" alt="tremor021" /><br/>
|
||||
@@ -155,6 +210,7 @@ This project runs on community contributions. Whether you want to write new scri
|
||||
<sub><b>asylumexp</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -194,9 +250,11 @@ This project runs on community contributions. Whether you want to write new scri
|
||||
|
||||
## Support the Project
|
||||
|
||||
This project is maintained by volunteers. All infrastructure costs come out of pocket, and the work is done in people's spare time.
|
||||
This project is maintained by volunteers. Infrastructure costs come out of
|
||||
pocket and the work happens in people's spare time.
|
||||
|
||||
**30% of all donations are forwarded directly to cancer research and hospice care** — a cause that was important to tteck.
|
||||
**30% of all donations are forwarded directly to cancer research and hospice
|
||||
care** — a cause that was important to tteck.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://ko-fi.com/community_scripts">
|
||||
@@ -212,14 +270,13 @@ This project is maintained by volunteers. All infrastructure costs come out of p
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](LICENSE) — free to use, modify, and redistribute for personal and commercial purposes.
|
||||
|
||||
See the full license text in [LICENSE](LICENSE).
|
||||
MIT — free to use, modify and redistribute, for personal and commercial
|
||||
purposes. See [LICENSE](LICENSE).
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Built on the foundation of <a href="https://github.com/tteck">tteck</a>'s original work · <a href="https://github.com/tteck/Proxmox">Original Repository</a></sub><br/>
|
||||
<sub>Maintained and expanded by the community · In memory of tteck</sub><br/>
|
||||
<sub><i>Proxmox® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a></i></sub>
|
||||
<sub><i>This is an independent community project. <b>Proxmox</b>® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a>.</i></sub>
|
||||
</div>
|
||||
|
||||
@@ -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!"
|
||||
@@ -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}"
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/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/casdoor/casdoor
|
||||
|
||||
APP="Readarr"
|
||||
var_tags="${var_tags:-media;comic;eBook}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
APP="Casdoor"
|
||||
var_tags="${var_tags:-auth;sso;iam}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-debian}"
|
||||
@@ -25,15 +25,24 @@ function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /var/lib/readarr/ ]]; then
|
||||
|
||||
if [[ ! -d /opt/casdoor ]]; 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 "casdoor" "casdoor/casdoor"; then
|
||||
msg_info "Stopping Casdoor"
|
||||
systemctl stop casdoor
|
||||
msg_ok "Stopped Casdoor"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "casdoor" "casdoor/casdoor" "prebuild" "latest" "/opt/casdoor" "casdoor_Linux_$(arch_resolve "x86_64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Starting Casdoor"
|
||||
systemctl start casdoor
|
||||
msg_ok "Started Casdoor"
|
||||
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}:8000${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}"
|
||||
@@ -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,31 @@ 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"
|
||||
|
||||
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
|
||||
|
||||
@@ -35,7 +35,8 @@ function update_script() {
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop excalidash
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "excalidash" "ZimengXiong/ExcaliDash" "tarball"
|
||||
ln -sf /opt/excalidash_data/.env /opt/excalidash/backend/.env
|
||||
set -a && source /opt/excalidash_data/.env && set +a
|
||||
|
||||
@@ -30,7 +30,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@latest" setup_nodejs
|
||||
ensure_dependencies jq
|
||||
|
||||
if check_for_gh_release "homepage" "gethomepage/homepage"; then
|
||||
|
||||
@@ -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/EgalitarianMonkey/hometube
|
||||
|
||||
APP="HomeTube"
|
||||
var_tags="${var_tags:-media;youtube;downloader}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-20}"
|
||||
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/hometube ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating yt-dlp"
|
||||
$STD yt-dlp -U
|
||||
msg_ok "Updated yt-dlp"
|
||||
|
||||
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
|
||||
|
||||
if check_for_gh_release "hometube" "EgalitarianMonkey/hometube"; then
|
||||
msg_info "Stopping HomeTube"
|
||||
systemctl stop hometube
|
||||
msg_ok "Stopped HomeTube"
|
||||
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hometube" "EgalitarianMonkey/hometube" "tarball"
|
||||
|
||||
msg_info "Updating HomeTube"
|
||||
cd /opt/hometube
|
||||
$STD uv sync --locked --no-dev --no-install-project --no-install-package pyarrow
|
||||
msg_ok "Updated HomeTube"
|
||||
|
||||
msg_info "Starting HomeTube"
|
||||
systemctl start hometube
|
||||
msg_ok "Started HomeTube"
|
||||
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}:8501${CL}"
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/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/plastic-labs/honcho
|
||||
|
||||
APP="Honcho"
|
||||
var_tags="${var_tags:-ai;memory;agents}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-6}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_arm64="${var_arm64:-yes}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
export var_honcho_provider="${var_honcho_provider:-}"
|
||||
export var_honcho_api_key="${var_honcho_api_key:-}"
|
||||
export var_honcho_base_url="${var_honcho_base_url:-}"
|
||||
export var_honcho_model="${var_honcho_model:-}"
|
||||
export var_honcho_embedding_key="${var_honcho_embedding_key:-}"
|
||||
export var_honcho_embedding_model="${var_honcho_embedding_model:-}"
|
||||
export var_honcho_embedding_dims="${var_honcho_embedding_dims:-}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
if [[ -n "${var_honcho_provider}" && ! "${var_honcho_provider}" =~ ^(openai|anthropic|gemini)$ ]]; then
|
||||
msg_error "var_honcho_provider must be openai, anthropic or gemini"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/honcho ]]; then
|
||||
msg_error "No Honcho Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "honcho" "plastic-labs/honcho" "" "" "v"; then
|
||||
msg_info "Stopping Honcho"
|
||||
systemctl stop honcho-deriver honcho
|
||||
msg_ok "Stopped Honcho"
|
||||
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
CLEAN_INSTALL=1 CLEAN_INSTALL_KEEP=".env" fetch_and_deploy_gh_release "honcho" "plastic-labs/honcho" "tarball" "latest" "/opt/honcho" "" "v"
|
||||
|
||||
msg_info "Updating Honcho"
|
||||
cd /opt/honcho
|
||||
$STD uv sync --frozen --no-dev
|
||||
$STD .venv/bin/python scripts/provision_db.py
|
||||
msg_ok "Updated Honcho"
|
||||
|
||||
if systemctl is-enabled -q honcho; then
|
||||
msg_info "Starting Honcho"
|
||||
systemctl start honcho honcho-deriver
|
||||
msg_ok "Started Honcho"
|
||||
fi
|
||||
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 the API (interactive docs at /docs) using the following URL:${CL}"
|
||||
echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
||||
echo -e "${INFO}${YW}Admin key, sent as Authorization: Bearer <key> (more with: cd /opt/honcho && .venv/bin/python scripts/generate_jwt.py --admin):${CL}"
|
||||
echo -e "${INFO}${YW}Without an LLM provider key Honcho stays stopped: set one in /opt/honcho_data/.env, then run: systemctl enable --now honcho honcho-deriver${CL}"
|
||||
@@ -233,6 +233,7 @@ EOF
|
||||
cd "$SRC_DIR"
|
||||
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
||||
export MISE_LOCKFILE_MODE=merge MISE_LOCKFILE_PLATFORMS="linux-$(arch_resolve x64 arm64)"
|
||||
mise_ok=0
|
||||
for i in 1 2 3; do
|
||||
$STD mise install && {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -22,18 +22,40 @@ color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /opt/meshcentral ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_info "Updating ${APP} LXC"
|
||||
apt_update_safe
|
||||
$STD apt -y upgrade
|
||||
msg_ok "Updated successfully!"
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /opt/meshcentral ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
CURRENT=$(node -p "require('/opt/meshcentral/node_modules/meshcentral/package.json').version" 2>/dev/null)
|
||||
LATEST=$(npm view meshcentral version 2>/dev/null)
|
||||
if [[ -z "$LATEST" ]]; then
|
||||
msg_error "Could not determine the latest MeshCentral version from npm"
|
||||
exit 250
|
||||
fi
|
||||
if [[ "$CURRENT" != "$LATEST" ]]; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop meshcentral
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Updating ${APP} from v${CURRENT} to v${LATEST}"
|
||||
cd /opt/meshcentral
|
||||
$STD npm install "meshcentral@${LATEST}"
|
||||
msg_ok "Updated ${APP} to v${LATEST}"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start meshcentral
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
else
|
||||
msg_ok "${APP} is already at v${CURRENT}"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
|
||||
@@ -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}"
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/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/Dyneteq/reconya
|
||||
|
||||
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}"
|
||||
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/reconya ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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}: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
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/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/fredrikburmester/streamystats
|
||||
|
||||
APP="Streamystats"
|
||||
var_tags="${var_tags:-analytics;jellyfin}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
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/streamystats ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "streamystats" "fredrikburmester/streamystats"; then
|
||||
msg_info "Stopping Streamystats"
|
||||
systemctl stop streamystats-nextjs-app streamystats-job-server
|
||||
msg_ok "Stopped Streamystats"
|
||||
|
||||
msg_info "Updating Bun"
|
||||
$STD bun upgrade
|
||||
msg_ok "Updated Bun"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "streamystats" "fredrikburmester/streamystats" "tarball"
|
||||
|
||||
msg_info "Building Streamystats"
|
||||
cd /opt/streamystats
|
||||
$STD bun install --frozen-lockfile
|
||||
NEXT_TELEMETRY_DISABLED=1 NEXT_PUBLIC_VERSION="v$(cat ~/.streamystats)" $STD bun run build
|
||||
msg_ok "Built Streamystats"
|
||||
|
||||
msg_info "Migrating Streamystats Database"
|
||||
$STD bun --env-file=/opt/streamystats_data/.env run db:migrate
|
||||
msg_ok "Migrated Streamystats Database"
|
||||
|
||||
msg_info "Starting Streamystats"
|
||||
systemctl start streamystats-job-server streamystats-nextjs-app
|
||||
msg_ok "Started Streamystats"
|
||||
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}"
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/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/stumpapp/stump
|
||||
|
||||
APP="Stump"
|
||||
var_tags="${var_tags:-comics;manga;ebook}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_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
|
||||
|
||||
if [[ ! -d /opt/stump ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "stump" "stumpapp/stump"; then
|
||||
msg_info "Stopping Stump"
|
||||
systemctl stop stump
|
||||
msg_ok "Stopped Stump"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "stump" "stumpapp/stump" "prebuild" "latest" "/opt/stump" "linux-build-results.zip"
|
||||
chmod +x /opt/stump/stump_server
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pdfium" "bblanchon/pdfium-binaries" "prebuild" "latest" "/opt/pdfium" "pdfium-linux-x64.tgz"
|
||||
|
||||
msg_info "Starting Stump"
|
||||
systemctl start stump
|
||||
msg_ok "Started Stump"
|
||||
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}:10801${CL}"
|
||||
@@ -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,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,89 @@
|
||||
#!/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/ItzCrazyKns/Vane
|
||||
|
||||
APP="Vane"
|
||||
var_tags="${var_tags:-ai;search}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-4096}"
|
||||
var_disk="${var_disk:-12}"
|
||||
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/vane ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "vane" "ItzCrazyKns/Vane"; then
|
||||
msg_info "Stopping Vane"
|
||||
systemctl stop vane
|
||||
msg_ok "Stopped Vane"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "vane" "ItzCrazyKns/Vane" "tarball"
|
||||
|
||||
msg_info "Building Vane"
|
||||
cd /opt/vane
|
||||
$STD yarn install --frozen-lockfile --network-timeout 600000
|
||||
$STD yarn build
|
||||
$STD yarn cache clean
|
||||
rm -rf .next/cache
|
||||
cp -r public .next/standalone/
|
||||
cp -r .next/static .next/standalone/.next/
|
||||
cp -r drizzle .next/standalone/
|
||||
ln -s /opt/vane_data .next/standalone/data
|
||||
$STD npx playwright install --with-deps --only-shell chromium
|
||||
msg_ok "Built Vane"
|
||||
|
||||
msg_info "Starting Vane"
|
||||
systemctl start vane
|
||||
msg_ok "Started Vane"
|
||||
msg_ok "Updated Vane successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_branch "searxng" "searxng/searxng" "master"; then
|
||||
msg_info "Stopping SearXNG"
|
||||
systemctl stop searxng
|
||||
msg_ok "Stopped SearXNG"
|
||||
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
fetch_and_deploy_gh_branch "searxng" "searxng/searxng" "master"
|
||||
|
||||
msg_info "Updating SearXNG"
|
||||
cd /opt/searxng
|
||||
$STD uv pip install -p /opt/searxng/.venv/bin/python -r requirements.txt -r requirements-server.txt
|
||||
msg_ok "Updated SearXNG"
|
||||
|
||||
msg_info "Starting SearXNG"
|
||||
systemctl start searxng
|
||||
msg_ok "Started SearXNG"
|
||||
msg_ok "Updated SearXNG 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}"
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/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/arabcoders/ytptube
|
||||
|
||||
APP="YTPTube"
|
||||
var_tags="${var_tags:-media;youtube;downloader}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-3072}"
|
||||
var_disk="${var_disk:-20}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_gpu="${var_gpu:-yes}"
|
||||
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/ytptube ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
|
||||
|
||||
if check_for_gh_release "ytptube" "arabcoders/ytptube"; then
|
||||
msg_info "Stopping YTPTube"
|
||||
systemctl stop ytptube
|
||||
msg_ok "Stopped YTPTube"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ytptube" "arabcoders/ytptube" "tarball"
|
||||
|
||||
msg_info "Building YTPTube"
|
||||
cd /opt/ytptube/ui
|
||||
$STD bun install --frozen-lockfile --production
|
||||
NODE_ENV=production $STD bun run generate
|
||||
rm -rf /opt/ytptube/ui/node_modules
|
||||
cd /opt/ytptube
|
||||
sed -i "s/^APP_VERSION = .*/APP_VERSION = \"v$(cat ~/.ytptube)\"/" app/library/version.py
|
||||
$STD uv sync --locked --no-dev
|
||||
$STD uv pip install --python .venv/bin/python pip
|
||||
msg_ok "Built YTPTube"
|
||||
|
||||
msg_info "Starting YTPTube"
|
||||
systemctl start ytptube
|
||||
msg_ok "Started YTPTube"
|
||||
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}:8081${CL}"
|
||||
echo -e "${INFO}${YW}The first visitor creates the admin account - open the URL right away${CL}"
|
||||
@@ -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
|
||||
@@ -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,93 @@
|
||||
#!/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/casdoor/casdoor
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="casdoor" PG_DB_USER="casdoor" setup_postgresql_db
|
||||
|
||||
fetch_and_deploy_gh_release "casdoor" "casdoor/casdoor" "prebuild" "latest" "/opt/casdoor" "casdoor_Linux_$(arch_resolve "x86_64" "arm64").tar.gz"
|
||||
|
||||
msg_info "Configuring Casdoor"
|
||||
mkdir -p /opt/casdoor_data/conf
|
||||
cat <<EOF >/opt/casdoor_data/conf/app.conf
|
||||
appname = casdoor
|
||||
httpport = 8000
|
||||
runmode = prod
|
||||
copyrequestbody = true
|
||||
driverName = postgres
|
||||
dataSourceName = user=casdoor password=${PG_DB_PASS} host=localhost port=5432 sslmode=disable dbname=casdoor
|
||||
dbName = casdoor
|
||||
tableNamePrefix =
|
||||
showSql = false
|
||||
redisEndpoint =
|
||||
defaultStorageProvider =
|
||||
isCloudIntranet = false
|
||||
authState = "casdoor"
|
||||
socks5Proxy =
|
||||
verificationCodeTimeout = 10
|
||||
initScore = 0
|
||||
logPostOnly = true
|
||||
isUsernameLowered = false
|
||||
origin = http://${LOCAL_IP}:8000
|
||||
originFrontend =
|
||||
staticBaseUrl = "https://cdn.casbin.org"
|
||||
isDemoMode = false
|
||||
batchSize = 100
|
||||
showGithubCorner = false
|
||||
forceLanguage = ""
|
||||
defaultLanguage = "en"
|
||||
defaultApplication = "app-built-in"
|
||||
maxItemsForFlatMenu = 7
|
||||
enableErrorMask = false
|
||||
enableGzip = true
|
||||
inactiveTimeoutMinutes =
|
||||
ldapServerPort = 389
|
||||
ldapsCertId = ""
|
||||
ldapsServerPort = 636
|
||||
radiusServerPort = 1812
|
||||
radiusDefaultOrganization = "built-in"
|
||||
radiusSecret = "$(random_password)"
|
||||
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
|
||||
logConfig = {"adapter":"console", "color":false}
|
||||
initDataNewOnly = false
|
||||
initDataFile = "./init_data.json"
|
||||
frontendBaseDir = "/opt/casdoor/web/build"
|
||||
EOF
|
||||
chmod 600 /opt/casdoor_data/conf/app.conf
|
||||
msg_ok "Configured Casdoor"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/casdoor.service
|
||||
[Unit]
|
||||
Description=Casdoor
|
||||
After=network.target postgresql.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/casdoor_data
|
||||
ExecStart=/opt/casdoor/casdoor
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now casdoor
|
||||
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
|
||||
@@ -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
|
||||
@@ -28,9 +28,14 @@ $STD apt install -y \
|
||||
redis-server
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
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 +47,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 +81,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'
|
||||
|
||||
@@ -19,7 +19,7 @@ $STD apt install -y \
|
||||
nginx
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="20" setup_nodejs
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
PG_VERSION="18" setup_postgresql
|
||||
PG_DB_NAME="excalidash" PG_DB_USER="excalidash" setup_postgresql_db
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y jq
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm@latest" setup_nodejs
|
||||
fetch_and_deploy_gh_release "homepage" "gethomepage/homepage" "tarball"
|
||||
RELEASE=$(get_latest_github_release "gethomepage/homepage")
|
||||
|
||||
|
||||
@@ -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/EgalitarianMonkey/hometube
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
setup_ffmpeg
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
|
||||
fetch_and_deploy_gh_release "yt-dlp" "yt-dlp/yt-dlp" "singlefile" "latest" "/usr/local/bin" "yt-dlp_$(arch_resolve "linux" "linux_aarch64")"
|
||||
fetch_and_deploy_gh_release "hometube" "EgalitarianMonkey/hometube" "tarball"
|
||||
|
||||
msg_info "Installing HomeTube"
|
||||
cd /opt/hometube
|
||||
$STD uv sync --locked --no-dev --no-install-project --no-install-package pyarrow
|
||||
mkdir -p /opt/hometube_data/{videos,tmp,cookies}
|
||||
cat <<EOF >/opt/hometube_data/.env
|
||||
VIDEOS_FOLDER=/opt/hometube_data/videos
|
||||
TMP_DOWNLOAD_FOLDER=/opt/hometube_data/tmp
|
||||
YOUTUBE_COOKIES_FILE_PATH=/opt/hometube_data/cookies/youtube_cookies.txt
|
||||
REMOVE_TMP_FILES_AFTER_DOWNLOAD=true
|
||||
EOF
|
||||
msg_ok "Installed HomeTube"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/hometube.service
|
||||
[Unit]
|
||||
Description=HomeTube
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/hometube
|
||||
EnvironmentFile=/opt/hometube_data/.env
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
ExecStartPre=-/usr/local/bin/yt-dlp -U
|
||||
ExecStart=/opt/hometube/.venv/bin/python -m streamlit run app/main.py --server.port=8501 --server.address=0.0.0.0 --server.headless=true --server.enableCORS=false --server.enableXsrfProtection=false
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now hometube
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -0,0 +1,168 @@
|
||||
#!/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/plastic-labs/honcho
|
||||
|
||||
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 redis-server
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
||||
PG_DB_NAME="honcho" PG_DB_USER="honcho" PG_DB_EXTENSIONS="vector,pg_trgm" setup_postgresql_db
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
fetch_and_deploy_gh_release "honcho" "plastic-labs/honcho" "tarball" "latest" "/opt/honcho" "" "v"
|
||||
|
||||
msg_info "Installing Honcho"
|
||||
cd /opt/honcho
|
||||
$STD uv sync --frozen --no-dev
|
||||
msg_ok "Installed Honcho"
|
||||
|
||||
if [[ -t 0 && -z "${var_honcho_provider:-}${var_honcho_api_key:-}${var_honcho_base_url:-}" ]]; then
|
||||
echo -e "${INFO}${YW} Honcho needs an LLM provider for memory, embeddings and chat; without a key it is installed but not started.${CL}"
|
||||
read -t 300 -rsp "${TAB3}OpenAI API key (Enter to set up a provider later): " var_honcho_api_key || true
|
||||
echo
|
||||
fi
|
||||
|
||||
declare -A HONCHO_KEY=([openai]="" [anthropic]="" [gemini]="")
|
||||
case "${var_honcho_provider:-openai}" in
|
||||
anthropic)
|
||||
HONCHO_TRANSPORT="anthropic" HONCHO_MODEL="${var_honcho_model:-claude-haiku-4-5}"
|
||||
HONCHO_EMBEDDING="openai" HONCHO_EMBEDDING_MODEL="${var_honcho_embedding_model:-text-embedding-3-small}"
|
||||
HONCHO_KEY[anthropic]="${var_honcho_api_key:-}"
|
||||
HONCHO_KEY[openai]="${var_honcho_embedding_key:-}"
|
||||
;;
|
||||
gemini)
|
||||
HONCHO_TRANSPORT="gemini" HONCHO_MODEL="${var_honcho_model:-gemini-2.5-flash}"
|
||||
HONCHO_EMBEDDING="gemini" HONCHO_EMBEDDING_MODEL="${var_honcho_embedding_model:-gemini-embedding-001}"
|
||||
HONCHO_KEY[gemini]="${var_honcho_api_key:-}"
|
||||
;;
|
||||
*)
|
||||
HONCHO_TRANSPORT="openai" HONCHO_MODEL="${var_honcho_model:-gpt-5.4-mini}"
|
||||
HONCHO_EMBEDDING="openai" HONCHO_EMBEDDING_MODEL="${var_honcho_embedding_model:-text-embedding-3-small}"
|
||||
HONCHO_KEY[openai]="${var_honcho_api_key:-${var_honcho_base_url:+not-needed}}"
|
||||
;;
|
||||
esac
|
||||
|
||||
msg_info "Configuring Honcho"
|
||||
mkdir -p /opt/honcho_data
|
||||
cat <<EOF >/opt/honcho_data/.env
|
||||
DB_CONNECTION_URI=postgresql+psycopg://honcho:${PG_DB_PASS}@localhost:5432/honcho
|
||||
CACHE_ENABLED=true
|
||||
CACHE_URL=redis://localhost:6379/0?suppress=true
|
||||
|
||||
# Every /v3 API request needs a JWT signed with this secret. Mint one with:
|
||||
# cd /opt/honcho && .venv/bin/python scripts/generate_jwt.py --admin
|
||||
AUTH_USE_AUTH=true
|
||||
AUTH_JWT_SECRET=$(openssl rand -hex 32)
|
||||
WEBHOOK_SECRET=$(openssl rand -hex 32)
|
||||
|
||||
# Transports: openai (OpenAI or any OpenAI-compatible endpoint), anthropic, gemini.
|
||||
# Embeddings run on openai or gemini only. Apply changes with: systemctl restart honcho honcho-deriver
|
||||
LLM_OPENAI_API_KEY=${HONCHO_KEY[openai]}
|
||||
LLM_ANTHROPIC_API_KEY=${HONCHO_KEY[anthropic]}
|
||||
LLM_GEMINI_API_KEY=${HONCHO_KEY[gemini]}
|
||||
|
||||
# An OpenAI-compatible endpoint (OpenRouter, Ollama, vLLM, LiteLLM) replaces api.openai.com through both lines:
|
||||
#LLM_OPENAI_BASE_URL=http://192.168.1.50:11434/v1
|
||||
#EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL=http://192.168.1.50:11434/v1
|
||||
# Endpoints without OpenAI Structured Outputs need:
|
||||
#DERIVER_MODEL_CONFIG__STRUCTURED_OUTPUT_MODE=json_object
|
||||
|
||||
EMBEDDING_MODEL_CONFIG__TRANSPORT=${HONCHO_EMBEDDING}
|
||||
EMBEDDING_MODEL_CONFIG__MODEL=${HONCHO_EMBEDDING_MODEL}
|
||||
# A model with another vector size works only while nothing is embedded yet: set it here, then run
|
||||
# cd /opt/honcho && .venv/bin/python scripts/configure_embeddings.py --yes
|
||||
#EMBEDDING_VECTOR_DIMENSIONS=1536
|
||||
|
||||
# The deriver waits for about 512 new tokens per peer, or 30 minutes, before it calls the LLM
|
||||
#DERIVER_FLUSH_ENABLED=true
|
||||
|
||||
# Models for the deriver, summaries, dreams and dialectic chat; they must support tool calling
|
||||
EOF
|
||||
for prefix in DERIVER SUMMARY DREAM_DEDUCTION DREAM_INDUCTION DIALECTIC_LEVELS__{minimal,low,medium,high,max}_; do
|
||||
cat <<EOF >>/opt/honcho_data/.env
|
||||
${prefix}_MODEL_CONFIG__TRANSPORT=${HONCHO_TRANSPORT}
|
||||
${prefix}_MODEL_CONFIG__MODEL=${HONCHO_MODEL}
|
||||
EOF
|
||||
done
|
||||
if [[ -n "${var_honcho_base_url:-}" ]]; then
|
||||
cat <<EOF >>/opt/honcho_data/.env
|
||||
|
||||
LLM_OPENAI_BASE_URL=${var_honcho_base_url}
|
||||
EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL=${var_honcho_base_url}
|
||||
EOF
|
||||
fi
|
||||
if [[ -n "${var_honcho_embedding_dims:-}" ]]; then
|
||||
cat <<EOF >>/opt/honcho_data/.env
|
||||
EMBEDDING_VECTOR_DIMENSIONS=${var_honcho_embedding_dims}
|
||||
EOF
|
||||
fi
|
||||
chmod 600 /opt/honcho_data/.env
|
||||
ln -sf /opt/honcho_data/.env /opt/honcho/.env
|
||||
msg_ok "Configured Honcho"
|
||||
|
||||
msg_info "Migrating Honcho Database"
|
||||
$STD .venv/bin/python scripts/provision_db.py
|
||||
$STD .venv/bin/python scripts/configure_embeddings.py --yes
|
||||
msg_ok "Migrated Honcho Database"
|
||||
|
||||
msg_info "Creating Honcho Services"
|
||||
cat <<EOF >/etc/systemd/system/honcho.service
|
||||
[Unit]
|
||||
Description=Honcho API
|
||||
After=network.target postgresql.service redis-server.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/honcho
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
ExecStart=/opt/honcho/.venv/bin/fastapi run --host 0.0.0.0 --port 8000 src/main.py
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/honcho-deriver.service
|
||||
[Unit]
|
||||
Description=Honcho Deriver
|
||||
After=network.target postgresql.service redis-server.service honcho.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/honcho
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
ExecStart=/opt/honcho/.venv/bin/python -m src.deriver
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
msg_ok "Created Honcho Services"
|
||||
|
||||
if [[ -n "${HONCHO_KEY[$HONCHO_TRANSPORT]}" && -n "${HONCHO_KEY[$HONCHO_EMBEDDING]}" ]]; then
|
||||
msg_info "Starting Honcho"
|
||||
systemctl enable -q --now honcho honcho-deriver
|
||||
msg_ok "Started Honcho"
|
||||
else
|
||||
msg_warn "No LLM provider key (with Anthropic also an OpenAI key for embeddings): Honcho stays stopped until it is set in /opt/honcho_data/.env"
|
||||
fi
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -397,6 +397,7 @@ 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_LOCKFILE_MODE=merge MISE_LOCKFILE_PLATFORMS="linux-$(arch_resolve x64 arm64)"
|
||||
mise_ok=0
|
||||
for i in 1 2 3; do
|
||||
$STD mise install && {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y ca-certificates
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
msg_info "Installing MeshCentral"
|
||||
mkdir /opt/meshcentral
|
||||
|
||||
@@ -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
|
||||
@@ -24,7 +24,7 @@ msg_ok "Installed Dependencies"
|
||||
setup_ffmpeg
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="readmeabook" PG_DB_USER="readmeabook" setup_postgresql_db
|
||||
NODE_VERSION="20" setup_nodejs
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
fetch_and_deploy_gh_release "readmeabook" "kikootwo/ReadMeABook" "tarball"
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -92,7 +92,7 @@ $STD /opt/splunk/bin/splunk enable boot-start \
|
||||
--no-prompt
|
||||
chown -R splunk:splunk /opt/splunk
|
||||
$STD systemctl daemon-reload
|
||||
$STD systemctl enable --now Splunkd
|
||||
$STD systemctl enable --now splunkd
|
||||
msg_ok "Started Service"
|
||||
|
||||
motd_ssh
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#!/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/fredrikburmester/streamystats
|
||||
|
||||
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 unzip
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
||||
PG_DB_NAME="streamystats" PG_DB_USER="streamystats" PG_DB_EXTENSIONS="vector,pg_trgm,uuid-ossp" setup_postgresql_db
|
||||
|
||||
msg_info "Installing Bun"
|
||||
export BUN_INSTALL="/root/.bun"
|
||||
curl -fsSL https://bun.sh/install | $STD bash
|
||||
ln -sf /root/.bun/bin/bun /usr/local/bin/bun
|
||||
ln -sf /root/.bun/bin/bunx /usr/local/bin/bunx
|
||||
msg_ok "Installed Bun"
|
||||
|
||||
fetch_and_deploy_gh_release "streamystats" "fredrikburmester/streamystats" "tarball"
|
||||
|
||||
msg_info "Building Streamystats"
|
||||
cd /opt/streamystats
|
||||
$STD bun install --frozen-lockfile
|
||||
NEXT_TELEMETRY_DISABLED=1 NEXT_PUBLIC_VERSION="v$(cat ~/.streamystats)" $STD bun run build
|
||||
msg_ok "Built Streamystats"
|
||||
|
||||
msg_info "Configuring Streamystats"
|
||||
mkdir -p /opt/streamystats_data
|
||||
cat <<EOF >/opt/streamystats_data/.env
|
||||
NODE_ENV=production
|
||||
NEXT_TELEMETRY_DISABLED=1
|
||||
DATABASE_URL=postgresql://streamystats:${PG_DB_PASS}@127.0.0.1:5432/streamystats
|
||||
JOB_SERVER_URL=http://127.0.0.1:3005
|
||||
NEXTJS_URL=http://127.0.0.1:3000
|
||||
SESSION_SECRET=$(openssl rand -hex 64)
|
||||
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||
EOF
|
||||
chmod 600 /opt/streamystats_data/.env
|
||||
msg_ok "Configured Streamystats"
|
||||
|
||||
msg_info "Migrating Streamystats Database"
|
||||
$STD bun --env-file=/opt/streamystats_data/.env run db:migrate
|
||||
msg_ok "Migrated Streamystats Database"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<EOF >/etc/systemd/system/streamystats-job-server.service
|
||||
[Unit]
|
||||
Description=Streamystats Job Server
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/streamystats/apps/job-server
|
||||
EnvironmentFile=/opt/streamystats_data/.env
|
||||
Environment=HOST=127.0.0.1
|
||||
Environment=PORT=3005
|
||||
ExecStart=/usr/local/bin/bun run start
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/streamystats-nextjs-app.service
|
||||
[Unit]
|
||||
Description=Streamystats Web
|
||||
After=network.target streamystats-job-server.service
|
||||
Wants=streamystats-job-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/streamystats/apps/nextjs-app
|
||||
EnvironmentFile=/opt/streamystats_data/.env
|
||||
Environment=PORT=3000
|
||||
ExecStart=/usr/local/bin/bun run start
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now streamystats-job-server streamystats-nextjs-app
|
||||
msg_ok "Created Services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/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/stumpapp/stump
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
fetch_and_deploy_gh_release "stump" "stumpapp/stump" "prebuild" "latest" "/opt/stump" "linux-build-results.zip"
|
||||
chmod +x /opt/stump/stump_server
|
||||
fetch_and_deploy_gh_release "pdfium" "bblanchon/pdfium-binaries" "prebuild" "latest" "/opt/pdfium" "pdfium-linux-x64.tgz"
|
||||
|
||||
msg_info "Creating Stump Service"
|
||||
mkdir -p /opt/stump_data/{config,library}
|
||||
cat <<EOF >/etc/systemd/system/stump.service
|
||||
[Unit]
|
||||
Description=Stump
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/stump
|
||||
Environment=STUMP_CONFIG_DIR=/opt/stump_data/config
|
||||
Environment=STUMP_CLIENT_DIR=/opt/stump/client
|
||||
Environment=PDFIUM_PATH=/opt/pdfium/lib/libpdfium.so
|
||||
ExecStart=/opt/stump/stump_server
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now stump
|
||||
msg_ok "Created Stump Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -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,116 @@
|
||||
#!/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/ItzCrazyKns/Vane
|
||||
|
||||
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"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
|
||||
fetch_and_deploy_gh_branch "searxng" "searxng/searxng" "master"
|
||||
|
||||
msg_info "Setting up SearXNG"
|
||||
cd /opt/searxng
|
||||
$STD uv venv /opt/searxng/.venv
|
||||
$STD uv pip install -p /opt/searxng/.venv/bin/python -r requirements.txt -r requirements-server.txt
|
||||
mkdir -p /etc/searxng
|
||||
cat <<EOF >/etc/searxng/settings.yml
|
||||
use_default_settings: true
|
||||
general:
|
||||
instance_name: "SearXNG"
|
||||
server:
|
||||
bind_address: "127.0.0.1"
|
||||
port: 8888
|
||||
secret_key: "$(openssl rand -hex 32)"
|
||||
limiter: false
|
||||
image_proxy: false
|
||||
search:
|
||||
autocomplete: "google"
|
||||
formats:
|
||||
- html
|
||||
- json
|
||||
engines:
|
||||
- name: wolframalpha
|
||||
disabled: false
|
||||
EOF
|
||||
chmod 600 /etc/searxng/settings.yml
|
||||
msg_ok "Set up SearXNG"
|
||||
|
||||
fetch_and_deploy_gh_release "vane" "ItzCrazyKns/Vane" "tarball"
|
||||
|
||||
msg_info "Building Vane"
|
||||
cd /opt/vane
|
||||
$STD yarn install --frozen-lockfile --network-timeout 600000
|
||||
$STD yarn build
|
||||
$STD yarn cache clean
|
||||
rm -rf .next/cache
|
||||
cp -r public .next/standalone/
|
||||
cp -r .next/static .next/standalone/.next/
|
||||
cp -r drizzle .next/standalone/
|
||||
mkdir -p /opt/vane_data
|
||||
# The standalone server chdirs into its own directory and keeps config.json, db.sqlite and uploads in ./data
|
||||
ln -s /opt/vane_data .next/standalone/data
|
||||
msg_ok "Built Vane"
|
||||
|
||||
msg_info "Installing Chromium for Vane"
|
||||
$STD npx playwright install --with-deps --only-shell chromium
|
||||
msg_ok "Installed Chromium for Vane"
|
||||
|
||||
msg_info "Creating Services"
|
||||
cat <<EOF >/etc/systemd/system/searxng.service
|
||||
[Unit]
|
||||
Description=SearXNG for Vane
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/searxng
|
||||
Environment=SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml
|
||||
ExecStart=/opt/searxng/.venv/bin/granian --interface wsgi --host 127.0.0.1 --port 8888 searx.webapp:app
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
cat <<EOF >/etc/systemd/system/vane.service
|
||||
[Unit]
|
||||
Description=Vane
|
||||
After=network.target searxng.service
|
||||
Wants=searxng.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/vane/.next/standalone
|
||||
Environment=NODE_ENV=production
|
||||
Environment=HOSTNAME=0.0.0.0
|
||||
Environment=PORT=3000
|
||||
Environment=SEARXNG_API_URL=http://127.0.0.1:8888
|
||||
ExecStart=/usr/bin/node /opt/vane/.next/standalone/server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now searxng vane
|
||||
msg_ok "Created Services"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: BrynnJKnight
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://verdaccio.org/ | Github: https://github.com/verdaccio/verdaccio
|
||||
|
||||
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"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="verdaccio" setup_nodejs
|
||||
|
||||
msg_info "Configuring Verdaccio"
|
||||
mkdir -p /opt/verdaccio/config
|
||||
mkdir -p /opt/verdaccio/storage
|
||||
cat <<EOF >/opt/verdaccio/config/config.yaml
|
||||
# Verdaccio configuration
|
||||
storage: /opt/verdaccio/storage
|
||||
auth:
|
||||
htpasswd:
|
||||
file: /opt/verdaccio/storage/htpasswd
|
||||
max_users: 1000
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
packages:
|
||||
'@*/*':
|
||||
access: \$all
|
||||
publish: \$authenticated
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: \$all
|
||||
publish: \$authenticated
|
||||
proxy: npmjs
|
||||
middlewares:
|
||||
audit:
|
||||
enabled: true
|
||||
logs:
|
||||
- {type: stdout, format: pretty, level: http}
|
||||
listen:
|
||||
- 0.0.0.0:4873
|
||||
web:
|
||||
enable: true
|
||||
title: Verdaccio
|
||||
gravatar: true
|
||||
sort_packages: asc
|
||||
login: true
|
||||
EOF
|
||||
chown -R root:root /opt/verdaccio
|
||||
chmod -R 755 /opt/verdaccio
|
||||
msg_ok "Configured Verdaccio"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/verdaccio.service
|
||||
[Unit]
|
||||
Description=Verdaccio lightweight private npm proxy registry
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/verdaccio --config /opt/verdaccio/config/config.yaml
|
||||
Restart=on-failure
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=verdaccio
|
||||
KillMode=control-group
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now verdaccio
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/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/arabcoders/ytptube
|
||||
|
||||
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 libmagic1
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
setup_ffmpeg
|
||||
setup_hwaccel
|
||||
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
|
||||
PYTHON_VERSION="3.13" setup_uv
|
||||
fetch_and_deploy_gh_release "deno" "denoland/deno" "prebuild" "latest" "/usr/local/bin" "deno-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
|
||||
fetch_and_deploy_gh_release "ytptube" "arabcoders/ytptube" "tarball"
|
||||
|
||||
msg_info "Building YTPTube"
|
||||
cd /opt/ytptube/ui
|
||||
$STD bun install --frozen-lockfile --production
|
||||
NODE_ENV=production $STD bun run generate
|
||||
rm -rf /opt/ytptube/ui/node_modules
|
||||
cd /opt/ytptube
|
||||
sed -i "s/^APP_VERSION = .*/APP_VERSION = \"v$(cat ~/.ytptube)\"/" app/library/version.py
|
||||
$STD uv sync --locked --no-dev
|
||||
$STD uv pip install --python .venv/bin/python pip
|
||||
msg_ok "Built YTPTube"
|
||||
|
||||
msg_info "Configuring YTPTube"
|
||||
mkdir -p /opt/ytptube_data/{config,downloads,tmp}
|
||||
cat <<EOF >/opt/ytptube_data/config/.env
|
||||
YTP_PORT=8081
|
||||
YTP_CONFIG_PATH=/opt/ytptube_data/config
|
||||
YTP_DOWNLOAD_PATH=/opt/ytptube_data/downloads
|
||||
YTP_TEMP_PATH=/opt/ytptube_data/tmp
|
||||
EOF
|
||||
msg_ok "Configured YTPTube"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/ytptube.service
|
||||
[Unit]
|
||||
Description=YTPTube
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/ytptube
|
||||
EnvironmentFile=/opt/ytptube_data/config/.env
|
||||
Environment=PATH=/opt/ytptube/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
|
||||
ExecStartPre=-/opt/ytptube/.venv/bin/python /opt/ytptube/app/upgrader.py
|
||||
ExecStart=/opt/ytptube/.venv/bin/python /opt/ytptube/app/main.py
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now ytptube
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -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)"
|
||||
}
|
||||
@@ -1,708 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: community-scripts ORG
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/branch/main/LICENSE
|
||||
# Revision: 1
|
||||
|
||||
# ==============================================================================
|
||||
# CLOUD-INIT.FUNC - VM CLOUD-INIT CONFIGURATION LIBRARY
|
||||
# ==============================================================================
|
||||
#
|
||||
# Universal helper library for Cloud-Init configuration in Proxmox VMs.
|
||||
# Provides functions for:
|
||||
#
|
||||
# - Native Proxmox Cloud-Init setup (user, password, network, SSH keys)
|
||||
# - Interactive configuration dialogs (whiptail)
|
||||
# - IP address retrieval via qemu-guest-agent
|
||||
# - Cloud-Init status monitoring and waiting
|
||||
#
|
||||
# Usage:
|
||||
# source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/cloud-init.func)
|
||||
# setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
||||
#
|
||||
# Compatible with: Debian, Ubuntu, and all Cloud-Init enabled distributions
|
||||
# ==============================================================================
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 1: CONFIGURATION DEFAULTS
|
||||
# ==============================================================================
|
||||
# These can be overridden before sourcing this library
|
||||
|
||||
# Disable 'unbound variable' errors for this library (restored at end)
|
||||
_OLD_SET_STATE=$(set +o | grep -E 'set -(e|u|o)')
|
||||
set +u
|
||||
|
||||
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
||||
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
||||
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-}" # Empty by default - user must explicitly provide keys
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 2: SSH KEY DISCOVERY AND SELECTION
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_extract_keys_from_file - Extracts valid SSH public keys from a file
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_extract_keys_from_file() {
|
||||
local file="$1"
|
||||
[[ -f "$file" && -r "$file" ]] || return 0
|
||||
grep -E '^(ssh-(rsa|ed25519|dss|ecdsa)|ecdsa-sha2-)' "$file" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_discover_files - Scans standard paths for SSH keys
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_discover_files() {
|
||||
local -a cand=()
|
||||
shopt -s nullglob
|
||||
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
|
||||
cand+=(/root/.ssh/*.pub)
|
||||
cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
|
||||
shopt -u nullglob
|
||||
printf '%s\0' "${cand[@]}"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_ssh_build_choices - Builds whiptail checklist from SSH key files
|
||||
#
|
||||
# Sets: CI_SSH_CHOICES (array), CI_SSH_COUNT (int), CI_SSH_MAPFILE (path)
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_ssh_build_choices() {
|
||||
local -a files=("$@")
|
||||
CI_SSH_CHOICES=()
|
||||
CI_SSH_COUNT=0
|
||||
CI_SSH_MAPFILE="$(mktemp)"
|
||||
local id key typ fp cmt base
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
[[ -f "$f" && -r "$f" ]] || continue
|
||||
base="$(basename -- "$f")"
|
||||
# Skip known_hosts and private keys
|
||||
case "$base" in
|
||||
known_hosts | known_hosts.* | config) continue ;;
|
||||
id_*) [[ "$f" != *.pub ]] && continue ;;
|
||||
esac
|
||||
|
||||
while IFS= read -r key; do
|
||||
[[ -n "$key" ]] || continue
|
||||
|
||||
typ=""
|
||||
fp=""
|
||||
cmt=""
|
||||
read -r _typ _b64 _cmt <<<"$key"
|
||||
typ="${_typ:-key}"
|
||||
cmt="${_cmt:-}"
|
||||
|
||||
# Get fingerprint via ssh-keygen if available
|
||||
if command -v ssh-keygen >/dev/null 2>&1; then
|
||||
fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
|
||||
fi
|
||||
|
||||
# Shorten long comments
|
||||
[[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
|
||||
|
||||
CI_SSH_COUNT=$((CI_SSH_COUNT + 1))
|
||||
id="K${CI_SSH_COUNT}"
|
||||
echo "${id}|${key}" >>"$CI_SSH_MAPFILE"
|
||||
CI_SSH_CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
|
||||
done < <(_ci_ssh_extract_keys_from_file "$f")
|
||||
done
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# configure_cloudinit_ssh_keys - Interactive SSH key selection for Cloud-Init
|
||||
#
|
||||
# Usage: configure_cloudinit_ssh_keys
|
||||
# Sets: CLOUDINIT_SSH_KEYS (path to temporary file with selected keys)
|
||||
# ------------------------------------------------------------------------------
|
||||
function configure_cloudinit_ssh_keys() {
|
||||
local backtitle="Proxmox VE Helper Scripts"
|
||||
local ssh_key_mode
|
||||
|
||||
# Create temp file for selected keys
|
||||
CLOUDINIT_SSH_KEYS_TEMP="$(mktemp)"
|
||||
: >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
|
||||
# Discover keys and build choices
|
||||
IFS=$'\0' read -r -d '' -a _def_files < <(_ci_ssh_discover_files && printf '\0')
|
||||
_ci_ssh_build_choices "${_def_files[@]}"
|
||||
local default_key_count="$CI_SSH_COUNT"
|
||||
|
||||
if [[ "$default_key_count" -gt 0 ]]; then
|
||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||
"Provision SSH keys for Cloud-Init VM:" 14 72 4 \
|
||||
"found" "Select from detected keys (${default_key_count})" \
|
||||
"manual" "Paste a single public key" \
|
||||
"folder" "Scan another folder (path or glob)" \
|
||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||
else
|
||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||
"No host keys detected. Choose:" 12 72 3 \
|
||||
"manual" "Paste a single public key" \
|
||||
"folder" "Scan another folder (path or glob)" \
|
||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||
fi
|
||||
|
||||
case "$ssh_key_mode" in
|
||||
found)
|
||||
# Show checklist with individual keys
|
||||
local selection
|
||||
selection=$(whiptail --backtitle "$backtitle" --title "SELECT SSH KEYS" \
|
||||
--checklist "Select one or more keys to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||
|
||||
for tag in $selection; do
|
||||
tag="${tag%\"}"
|
||||
tag="${tag#\"}"
|
||||
local line
|
||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
done
|
||||
local imported
|
||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) selected${CL}"
|
||||
;;
|
||||
manual)
|
||||
local pubkey
|
||||
pubkey=$(whiptail --backtitle "$backtitle" --title "PASTE SSH PUBLIC KEY" \
|
||||
--inputbox "Paste your SSH public key (ssh-rsa, ssh-ed25519, etc.):" 10 76 3>&1 1>&2 2>&3) || return 1
|
||||
if [[ -n "$pubkey" ]]; then
|
||||
echo "$pubkey" >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}1 key added manually${CL}"
|
||||
else
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (empty input)${CL}"
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
folder)
|
||||
local glob_path
|
||||
glob_path=$(whiptail --backtitle "$backtitle" --title "SCAN FOLDER/GLOB" \
|
||||
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub):" 10 72 3>&1 1>&2 2>&3) || return 1
|
||||
if [[ -n "$glob_path" ]]; then
|
||||
shopt -s nullglob
|
||||
local -a _scan_files=($glob_path)
|
||||
shopt -u nullglob
|
||||
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
||||
_ci_ssh_build_choices "${_scan_files[@]}"
|
||||
if [[ "$CI_SSH_COUNT" -gt 0 ]]; then
|
||||
local folder_selection
|
||||
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
|
||||
--checklist "Select key(s) to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||
for tag in $folder_selection; do
|
||||
tag="${tag%\"}"
|
||||
tag="${tag#\"}"
|
||||
local line
|
||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
done
|
||||
local imported
|
||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) from folder${CL}"
|
||||
else
|
||||
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
|
||||
fi
|
||||
else
|
||||
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
none | *)
|
||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (password auth only)${CL}"
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Cleanup mapfile
|
||||
rm -f "$CI_SSH_MAPFILE" 2>/dev/null
|
||||
|
||||
# Set the variable for setup_cloud_init to use
|
||||
if [[ -s "$CLOUDINIT_SSH_KEYS_TEMP" ]]; then
|
||||
CLOUDINIT_SSH_KEYS="$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
else
|
||||
CLOUDINIT_SSH_KEYS=""
|
||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 3: HELPER FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# _ci_msg - Internal message helper with fallback
|
||||
# ------------------------------------------------------------------------------
|
||||
function _ci_msg_info() { msg_info "$1" 2>/dev/null || echo "[INFO] $1"; }
|
||||
function _ci_msg_ok() { msg_ok "$1" 2>/dev/null || echo "[OK] $1"; }
|
||||
function _ci_msg_warn() { msg_warn "$1" 2>/dev/null || echo "[WARN] $1"; }
|
||||
function _ci_msg_error() { msg_error "$1" 2>/dev/null || echo "[ERROR] $1"; }
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_ip_cidr - Validate IP address in CIDR format
|
||||
# Usage: validate_ip_cidr "192.168.1.100/24" && echo "Valid"
|
||||
# Returns: 0 if valid, 1 if invalid
|
||||
# ------------------------------------------------------------------------------
|
||||
function validate_ip_cidr() {
|
||||
local ip_cidr="$1"
|
||||
# Match: 0-255.0-255.0-255.0-255/0-32
|
||||
if [[ "$ip_cidr" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then
|
||||
# Validate each octet is 0-255
|
||||
local ip="${ip_cidr%/*}"
|
||||
IFS='.' read -ra octets <<<"$ip"
|
||||
for octet in "${octets[@]}"; do
|
||||
((octet > 255)) && return 1
|
||||
done
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# validate_ip - Validate plain IP address (no CIDR)
|
||||
# Usage: validate_ip "192.168.1.1" && echo "Valid"
|
||||
# ------------------------------------------------------------------------------
|
||||
function validate_ip() {
|
||||
local ip="$1"
|
||||
if [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||
IFS='.' read -ra octets <<<"$ip"
|
||||
for octet in "${octets[@]}"; do
|
||||
((octet > 255)) && return 1
|
||||
done
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 3: MAIN CLOUD-INIT FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# setup_cloud_init - Configures Proxmox Native Cloud-Init
|
||||
# ------------------------------------------------------------------------------
|
||||
# Parameters:
|
||||
# $1 - VMID (required)
|
||||
# $2 - Storage name (required)
|
||||
# $3 - Hostname (optional, default: vm-<vmid>)
|
||||
# $4 - Enable Cloud-Init (yes/no, default: no)
|
||||
# $5 - User (optional, default: root)
|
||||
# $6 - Network mode (dhcp/static, default: dhcp)
|
||||
# $7 - Static IP (optional, format: 192.168.1.100/24)
|
||||
# $8 - Gateway (optional)
|
||||
# $9 - Nameservers (optional, default: 1.1.1.1 8.8.8.8)
|
||||
#
|
||||
# Returns: 0 on success, 1 on failure
|
||||
# Exports: CLOUDINIT_USER, CLOUDINIT_PASSWORD, CLOUDINIT_CRED_FILE
|
||||
# ==============================================================================
|
||||
function setup_cloud_init() {
|
||||
local vmid="$1"
|
||||
local storage="$2"
|
||||
local hostname="${3:-vm-${vmid}}"
|
||||
local enable="${4:-no}"
|
||||
local ciuser="${5:-$CLOUDINIT_DEFAULT_USER}"
|
||||
local network_mode="${6:-dhcp}"
|
||||
local static_ip="${7:-}"
|
||||
local gateway="${8:-}"
|
||||
local nameservers="${9:-$CLOUDINIT_DNS_SERVERS}"
|
||||
|
||||
# Skip if not enabled
|
||||
if [ "$enable" != "yes" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Validate static IP if provided
|
||||
if [ "$network_mode" = "static" ]; then
|
||||
if [ -n "$static_ip" ] && ! validate_ip_cidr "$static_ip"; then
|
||||
_ci_msg_error "Invalid static IP format: $static_ip (expected: x.x.x.x/xx)"
|
||||
return 65
|
||||
fi
|
||||
if [ -n "$gateway" ] && ! validate_ip "$gateway"; then
|
||||
_ci_msg_error "Invalid gateway IP format: $gateway"
|
||||
return 65
|
||||
fi
|
||||
fi
|
||||
|
||||
_ci_msg_info "Configuring Cloud-Init"
|
||||
|
||||
# Create Cloud-Init drive (try ide2 first, then scsi1 as fallback)
|
||||
if ! qm set "$vmid" --ide2 "${storage}:cloudinit" >/dev/null 2>&1; then
|
||||
qm set "$vmid" --scsi1 "${storage}:cloudinit" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Set user
|
||||
qm set "$vmid" --ciuser "$ciuser" >/dev/null
|
||||
|
||||
# Generate and set secure random password
|
||||
local cipassword=$(openssl rand -base64 16)
|
||||
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
||||
|
||||
# Add SSH keys only if explicitly provided (not auto-imported from host)
|
||||
if [ -n "${CLOUDINIT_SSH_KEYS:-}" ] && [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
||||
_ci_msg_info "SSH keys imported from: $CLOUDINIT_SSH_KEYS"
|
||||
fi
|
||||
|
||||
# Configure network
|
||||
if [ "$network_mode" = "static" ] && [ -n "$static_ip" ] && [ -n "$gateway" ]; then
|
||||
qm set "$vmid" --ipconfig0 "ip=${static_ip},gw=${gateway}" >/dev/null
|
||||
else
|
||||
qm set "$vmid" --ipconfig0 "ip=dhcp" >/dev/null
|
||||
fi
|
||||
|
||||
# Set DNS servers
|
||||
qm set "$vmid" --nameserver "$nameservers" >/dev/null
|
||||
|
||||
# Set search domain
|
||||
qm set "$vmid" --searchdomain "$CLOUDINIT_SEARCH_DOMAIN" >/dev/null
|
||||
|
||||
# Enable package upgrades on first boot (if supported by Proxmox version)
|
||||
qm set "$vmid" --ciupgrade 1 >/dev/null 2>&1 || true
|
||||
|
||||
# Save credentials to file (with restrictive permissions)
|
||||
local cred_file="/tmp/${hostname}-${vmid}-cloud-init-credentials.txt"
|
||||
umask 077
|
||||
cat >"$cred_file" <<EOF
|
||||
╔══════════════════════════════════════════════════════════════════╗
|
||||
║ ⚠️ SECURITY WARNING: DELETE THIS FILE AFTER NOTING CREDENTIALS ║
|
||||
╚══════════════════════════════════════════════════════════════════╝
|
||||
|
||||
Cloud-Init Credentials
|
||||
────────────────────────────────────────
|
||||
VM ID: ${vmid}
|
||||
Hostname: ${hostname}
|
||||
Created: $(date)
|
||||
|
||||
Username: ${ciuser}
|
||||
Password: ${cipassword}
|
||||
|
||||
Network: ${network_mode}$([ "$network_mode" = "static" ] && echo " (IP: ${static_ip}, GW: ${gateway})" || echo " (DHCP)")
|
||||
DNS: ${nameservers}
|
||||
|
||||
────────────────────────────────────────
|
||||
SSH Access (if keys configured):
|
||||
ssh ${ciuser}@<vm-ip>
|
||||
|
||||
Proxmox UI Configuration:
|
||||
VM ${vmid} > Cloud-Init > Edit
|
||||
- User, Password, SSH Keys
|
||||
- Network (IP Config)
|
||||
- DNS, Search Domain
|
||||
|
||||
────────────────────────────────────────
|
||||
🗑️ To delete this file:
|
||||
rm -f ${cred_file}
|
||||
────────────────────────────────────────
|
||||
EOF
|
||||
chmod 600 "$cred_file"
|
||||
|
||||
_ci_msg_ok "Cloud-Init configured (User: ${ciuser})"
|
||||
|
||||
# Export for use in calling script (DO NOT display password here - will be shown in summary)
|
||||
export CLOUDINIT_USER="$ciuser"
|
||||
export CLOUDINIT_PASSWORD="$cipassword"
|
||||
export CLOUDINIT_CRED_FILE="$cred_file"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 4: INTERACTIVE CONFIGURATION
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# configure_cloud_init_interactive - Whiptail dialog for Cloud-Init setup
|
||||
# ------------------------------------------------------------------------------
|
||||
# Prompts user for Cloud-Init configuration choices
|
||||
# Returns configuration via exported variables:
|
||||
# - CLOUDINIT_ENABLE (yes/no)
|
||||
# - CLOUDINIT_USER
|
||||
# - CLOUDINIT_NETWORK_MODE (dhcp/static)
|
||||
# - CLOUDINIT_IP (if static)
|
||||
# - CLOUDINIT_GW (if static)
|
||||
# - CLOUDINIT_DNS
|
||||
# ------------------------------------------------------------------------------
|
||||
function configure_cloud_init_interactive() {
|
||||
local default_user="${1:-root}"
|
||||
|
||||
# Check if whiptail is available
|
||||
if ! command -v whiptail >/dev/null 2>&1; then
|
||||
echo "Warning: whiptail not available, skipping interactive configuration"
|
||||
export CLOUDINIT_ENABLE="no"
|
||||
return 127
|
||||
fi
|
||||
|
||||
# Ask if user wants to enable Cloud-Init
|
||||
if ! (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLOUD-INIT" \
|
||||
--yesno "Enable Cloud-Init for VM configuration?\n\nCloud-Init allows automatic configuration of:\n• User accounts and passwords\n• SSH keys\n• Network settings (DHCP/Static)\n• DNS configuration\n\nYou can also configure these settings later in Proxmox UI." 16 68); then
|
||||
export CLOUDINIT_ENABLE="no"
|
||||
return 0
|
||||
fi
|
||||
|
||||
export CLOUDINIT_ENABLE="yes"
|
||||
|
||||
# Username
|
||||
if CLOUDINIT_USER=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox \
|
||||
"Cloud-Init Username" 8 58 "$default_user" --title "USERNAME" 3>&1 1>&2 2>&3); then
|
||||
export CLOUDINIT_USER="${CLOUDINIT_USER:-$default_user}"
|
||||
else
|
||||
export CLOUDINIT_USER="$default_user"
|
||||
fi
|
||||
|
||||
# Network configuration
|
||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "NETWORK MODE" \
|
||||
--yesno "Use DHCP for network configuration?\n\nSelect 'No' for static IP configuration." 10 58); then
|
||||
export CLOUDINIT_NETWORK_MODE="dhcp"
|
||||
else
|
||||
export CLOUDINIT_NETWORK_MODE="static"
|
||||
|
||||
# Static IP with validation
|
||||
while true; do
|
||||
if CLOUDINIT_IP=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox \
|
||||
"Static IP Address (CIDR format)\nExample: 192.168.1.100/24" 9 58 "" --title "IP ADDRESS" 3>&1 1>&2 2>&3); then
|
||||
if validate_ip_cidr "$CLOUDINIT_IP"; then
|
||||
export CLOUDINIT_IP
|
||||
break
|
||||
else
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID IP" \
|
||||
--msgbox "Invalid IP format: $CLOUDINIT_IP\n\nPlease use CIDR format: x.x.x.x/xx\nExample: 192.168.1.100/24" 10 50
|
||||
fi
|
||||
else
|
||||
_ci_msg_warn "Static IP required, falling back to DHCP"
|
||||
export CLOUDINIT_NETWORK_MODE="dhcp"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Gateway with validation
|
||||
if [ "$CLOUDINIT_NETWORK_MODE" = "static" ]; then
|
||||
while true; do
|
||||
if CLOUDINIT_GW=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox \
|
||||
"Gateway IP Address\nExample: 192.168.1.1" 8 58 "" --title "GATEWAY" 3>&1 1>&2 2>&3); then
|
||||
if validate_ip "$CLOUDINIT_GW"; then
|
||||
export CLOUDINIT_GW
|
||||
break
|
||||
else
|
||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID GATEWAY" \
|
||||
--msgbox "Invalid gateway format: $CLOUDINIT_GW\n\nPlease use format: x.x.x.x\nExample: 192.168.1.1" 10 50
|
||||
fi
|
||||
else
|
||||
_ci_msg_warn "Gateway required, falling back to DHCP"
|
||||
export CLOUDINIT_NETWORK_MODE="dhcp"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# DNS Servers
|
||||
if CLOUDINIT_DNS=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox \
|
||||
"DNS Servers (space-separated)" 8 58 "1.1.1.1 8.8.8.8" --title "DNS SERVERS" 3>&1 1>&2 2>&3); then
|
||||
export CLOUDINIT_DNS="${CLOUDINIT_DNS:-1.1.1.1 8.8.8.8}"
|
||||
else
|
||||
export CLOUDINIT_DNS="1.1.1.1 8.8.8.8"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 5: UTILITY FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# display_cloud_init_info - Show Cloud-Init summary after setup
|
||||
# ------------------------------------------------------------------------------
|
||||
function display_cloud_init_info() {
|
||||
local vmid="$1"
|
||||
local hostname="${2:-}"
|
||||
|
||||
if [ -n "$CLOUDINIT_CRED_FILE" ] && [ -f "$CLOUDINIT_CRED_FILE" ]; then
|
||||
if [ -n "${INFO:-}" ]; then
|
||||
echo -e "\n${INFO}${BOLD:-}${GN:-} Cloud-Init Configuration:${CL:-}"
|
||||
echo -e "${TAB:- }${DGN:-}User: ${BGN:-}${CLOUDINIT_USER:-root}${CL:-}"
|
||||
echo -e "${TAB:- }${DGN:-}Password: ${BGN:-}${CLOUDINIT_PASSWORD}${CL:-}"
|
||||
echo -e "${TAB:- }${DGN:-}Credentials: ${BL:-}${CLOUDINIT_CRED_FILE}${CL:-}"
|
||||
echo -e "${TAB:- }${RD:-}⚠️ Delete credentials file after noting password!${CL:-}"
|
||||
echo -e "${TAB:- }${YW:-}💡 Configure in Proxmox UI: VM ${vmid} > Cloud-Init${CL:-}"
|
||||
else
|
||||
echo ""
|
||||
echo "[INFO] Cloud-Init Configuration:"
|
||||
echo " User: ${CLOUDINIT_USER:-root}"
|
||||
echo " Password: ${CLOUDINIT_PASSWORD}"
|
||||
echo " Credentials: ${CLOUDINIT_CRED_FILE}"
|
||||
echo " ⚠️ Delete credentials file after noting password!"
|
||||
echo " Configure in Proxmox UI: VM ${vmid} > Cloud-Init"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# cleanup_cloud_init_credentials - Remove credentials file
|
||||
# ------------------------------------------------------------------------------
|
||||
# Usage: cleanup_cloud_init_credentials
|
||||
# Call this after user has noted/saved the credentials
|
||||
# ------------------------------------------------------------------------------
|
||||
function cleanup_cloud_init_credentials() {
|
||||
if [ -n "$CLOUDINIT_CRED_FILE" ] && [ -f "$CLOUDINIT_CRED_FILE" ]; then
|
||||
rm -f "$CLOUDINIT_CRED_FILE"
|
||||
_ci_msg_ok "Credentials file removed: $CLOUDINIT_CRED_FILE"
|
||||
unset CLOUDINIT_CRED_FILE
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# has_cloud_init - Check if VM has Cloud-Init configured
|
||||
# ------------------------------------------------------------------------------
|
||||
function has_cloud_init() {
|
||||
local vmid="$1"
|
||||
qm config "$vmid" 2>/dev/null | grep -qE "(ide2|scsi1):.*cloudinit"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# regenerate_cloud_init - Regenerate Cloud-Init configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
function regenerate_cloud_init() {
|
||||
local vmid="$1"
|
||||
|
||||
if has_cloud_init "$vmid"; then
|
||||
_ci_msg_info "Regenerating Cloud-Init configuration"
|
||||
qm cloudinit update "$vmid" >/dev/null 2>&1 || true
|
||||
_ci_msg_ok "Cloud-Init configuration regenerated"
|
||||
return 0
|
||||
else
|
||||
_ci_msg_warn "VM $vmid does not have Cloud-Init configured"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# get_vm_ip - Get VM IP address via qemu-guest-agent
|
||||
# ------------------------------------------------------------------------------
|
||||
function get_vm_ip() {
|
||||
local vmid="$1"
|
||||
local timeout="${2:-30}"
|
||||
|
||||
local elapsed=0
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
local vm_ip=$(qm guest cmd "$vmid" network-get-interfaces 2>/dev/null |
|
||||
jq -r '.[] | select(.name != "lo") | ."ip-addresses"[]? | select(."ip-address-type" == "ipv4") | ."ip-address"' 2>/dev/null | head -1)
|
||||
|
||||
if [ -n "$vm_ip" ]; then
|
||||
echo "$vm_ip"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
done
|
||||
|
||||
return 7
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# wait_for_cloud_init - Wait for Cloud-Init to complete (requires SSH access)
|
||||
# ------------------------------------------------------------------------------
|
||||
function wait_for_cloud_init() {
|
||||
local vmid="$1"
|
||||
local timeout="${2:-300}"
|
||||
local vm_ip="${3:-}"
|
||||
|
||||
# Get IP if not provided
|
||||
if [ -z "$vm_ip" ]; then
|
||||
vm_ip=$(get_vm_ip "$vmid" 60)
|
||||
fi
|
||||
|
||||
if [ -z "$vm_ip" ]; then
|
||||
_ci_msg_warn "Unable to determine VM IP address"
|
||||
return 7
|
||||
fi
|
||||
|
||||
_ci_msg_info "Waiting for Cloud-Init to complete on ${vm_ip}"
|
||||
|
||||
local elapsed=0
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
if timeout 10 ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
"${CLOUDINIT_USER:-root}@${vm_ip}" "cloud-init status --wait" 2>/dev/null; then
|
||||
_ci_msg_ok "Cloud-Init completed successfully"
|
||||
return 0
|
||||
fi
|
||||
sleep 10
|
||||
elapsed=$((elapsed + 10))
|
||||
done
|
||||
|
||||
_ci_msg_warn "Cloud-Init did not complete within ${timeout}s"
|
||||
return 150
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 6: EXPORTS
|
||||
# ==============================================================================
|
||||
# Export all functions for use in other scripts
|
||||
|
||||
export -f setup_cloud_init 2>/dev/null || true
|
||||
export -f configure_cloud_init_interactive 2>/dev/null || true
|
||||
export -f display_cloud_init_info 2>/dev/null || true
|
||||
export -f cleanup_cloud_init_credentials 2>/dev/null || true
|
||||
export -f has_cloud_init 2>/dev/null || true
|
||||
export -f regenerate_cloud_init 2>/dev/null || true
|
||||
export -f get_vm_ip 2>/dev/null || true
|
||||
export -f wait_for_cloud_init 2>/dev/null || true
|
||||
export -f validate_ip_cidr 2>/dev/null || true
|
||||
export -f validate_ip 2>/dev/null || true
|
||||
|
||||
# Restore previous shell options if they were saved
|
||||
if [ -n "${_OLD_SET_STATE:-}" ]; then
|
||||
eval "$_OLD_SET_STATE"
|
||||
fi
|
||||
|
||||
# ==============================================================================
|
||||
# SECTION 7: EXAMPLES & DOCUMENTATION
|
||||
# ==============================================================================
|
||||
: <<'EXAMPLES'
|
||||
|
||||
# Example 1: Simple DHCP setup (most common)
|
||||
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
||||
|
||||
# Example 2: Static IP setup
|
||||
setup_cloud_init "$VMID" "$STORAGE" "myserver" "yes" "root" "static" "192.168.1.100/24" "192.168.1.1"
|
||||
|
||||
# Example 3: Interactive configuration in advanced_settings()
|
||||
configure_cloud_init_interactive "admin"
|
||||
if [ "$CLOUDINIT_ENABLE" = "yes" ]; then
|
||||
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes" "$CLOUDINIT_USER" \
|
||||
"$CLOUDINIT_NETWORK_MODE" "$CLOUDINIT_IP" "$CLOUDINIT_GW" "$CLOUDINIT_DNS"
|
||||
fi
|
||||
|
||||
# Example 4: Display info after VM creation
|
||||
display_cloud_init_info "$VMID" "$HN"
|
||||
|
||||
# Example 5: Check if VM has Cloud-Init
|
||||
if has_cloud_init "$VMID"; then
|
||||
echo "Cloud-Init is configured"
|
||||
fi
|
||||
|
||||
# Example 6: Wait for Cloud-Init to complete after VM start
|
||||
if [ "$START_VM" = "yes" ]; then
|
||||
qm start "$VMID"
|
||||
sleep 30
|
||||
wait_for_cloud_init "$VMID" 300
|
||||
fi
|
||||
|
||||
# Example 7: Cleanup credentials file after user has noted password
|
||||
display_cloud_init_info "$VMID" "$HN"
|
||||
read -p "Have you saved the credentials? (y/N): " -r
|
||||
[[ $REPLY =~ ^[Yy]$ ]] && cleanup_cloud_init_credentials
|
||||
|
||||
# Example 8: Validate IP before using
|
||||
if validate_ip_cidr "192.168.1.100/24"; then
|
||||
echo "Valid IP/CIDR"
|
||||
fi
|
||||
|
||||
EXAMPLES
|
||||