diff --git a/.github/DISCUSSION_TEMPLATE/request-script.yml b/.github/DISCUSSION_TEMPLATE/request-script.yml
index a2cf93136..64d694c97 100644
--- a/.github/DISCUSSION_TEMPLATE/request-script.yml
+++ b/.github/DISCUSSION_TEMPLATE/request-script.yml
@@ -12,17 +12,13 @@ body:
Requests may be closed if the application is out of scope, abandoned, too new, not publicly verifiable, or not suitable for a reliable Proxmox VE Helper-Scripts integration.
General requirements:
- - The application must be self-hosted.
- - The project must have an official public source repository.
- - The project must provide official releases, tags, or release tarballs.
- - The project must be actively maintained.
- - The official source repository must have at least 1,000 stars.
- - The latest official release or tag must not be older than 6 months.
- - The project itself must be at least 6 months old.
-
- Projects that do not meet these requirements may be closed without further evaluation.
-
- Exceptions to the 1,000-star requirement are rare and require a clearly verifiable, significant public adoption signal.
+ - The application should be self-hosted.
+ - The project should have an official public source repository.
+ - The project should provide official releases, tags, or release tarballs.
+ - The project should be actively maintained.
+ - The project should generally have at least 1,000 stars or a comparable public adoption signal.
+ - The latest official release or tag should not be older than 6 months.
+ - The project itself should be at least 6 months old.
- type: input
id: application-name
@@ -51,35 +47,6 @@ body:
validations:
required: true
- - type: markdown
- attributes:
- value: |
- ## ⚠️ Project Eligibility
-
- Before continuing, verify that the requested project meets the minimum requirements below.
-
- **Projects with fewer than 1,000 stars are generally not eligible for a script request.**
-
- Exceptions are only considered where there is a clearly verifiable, significant public adoption signal.
-
- - type: input
- id: repository-stars
- attributes:
- label: Repository Stars
- description: Enter the current number of stars of the official source repository.
- placeholder: "e.g., 15,000"
- validations:
- required: true
-
- - type: checkboxes
- id: minimum-stars
- attributes:
- label: Minimum Adoption Requirement
- description: Confirm that you have verified the project's public adoption.
- options:
- - label: The official source repository has at least 1,000 stars.
- required: true
-
- type: textarea
id: app-description
attributes:
diff --git a/.github/changelogs/2026/07.md b/.github/changelogs/2026/07.md
index 36a2207bc..4c20ca3e6 100644
--- a/.github/changelogs/2026/07.md
+++ b/.github/changelogs/2026/07.md
@@ -1,264 +1,3 @@
-## 2026-07-18
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - core: add configurable host CA inheritance during bootstrap [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15840](https://github.com/community-scripts/ProxmoxVE/pull/15840))
-
- - #### 🔧 Refactor
-
- - tools.func: Safe Delete Directorys & Update PYTHON_VERSION with setup_uv [@MickLesk](https://github.com/MickLesk) ([#15870](https://github.com/community-scripts/ProxmoxVE/pull/15870))
-
-### 🧰 Tools
-
- - #### ✨ New Features
-
- - [tools.update-lxcs] feat: optional reporting success/failures to heathchecks.io (or others) [@sir106](https://github.com/sir106) ([#15701](https://github.com/community-scripts/ProxmoxVE/pull/15701))
-
-## 2026-07-17
-
-### 🆕 New Scripts
-
- - Invidious ([#15824](https://github.com/community-scripts/ProxmoxVE/pull/15824))
-- OxiCloud ([#15823](https://github.com/community-scripts/ProxmoxVE/pull/15823))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - webtrees: initialize database schema before admin user creation [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15837](https://github.com/community-scripts/ProxmoxVE/pull/15837))
- - Fix DocuSeal missing Leptonica deps on install and update [@Copilot](https://github.com/Copilot) ([#15858](https://github.com/community-scripts/ProxmoxVE/pull/15858))
- - apache-guacamole: detect installed extensions during update [@TowyTowy](https://github.com/TowyTowy) ([#15841](https://github.com/community-scripts/ProxmoxVE/pull/15841))
- - CLIProxyAPI: fix update deleting config.yaml [@austinpilz](https://github.com/austinpilz) ([#15834](https://github.com/community-scripts/ProxmoxVE/pull/15834))
- - esphome: install libusb-1.0-0 for ESP-IDF native builds [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15838](https://github.com/community-scripts/ProxmoxVE/pull/15838))
-
- - #### ✨ New Features
-
- - AFFiNE: Bump to 0.27.0 [@MickLesk](https://github.com/MickLesk) ([#15848](https://github.com/community-scripts/ProxmoxVE/pull/15848))
- - n8n: unpin / use latest release [@MickLesk](https://github.com/MickLesk) ([#15817](https://github.com/community-scripts/ProxmoxVE/pull/15817))
- - Pin Opencloud to v7.3.0 [@vhsdream](https://github.com/vhsdream) ([#15826](https://github.com/community-scripts/ProxmoxVE/pull/15826))
-
- - #### 🔧 Refactor
-
- - SFTPGo: Update APT Repo & Re-Enable Script [@MickLesk](https://github.com/MickLesk) ([#15829](https://github.com/community-scripts/ProxmoxVE/pull/15829))
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - tools.func: enhance rbenv with profile updates / bundle in bashrc [@MickLesk](https://github.com/MickLesk) ([#15822](https://github.com/community-scripts/ProxmoxVE/pull/15822))
- - feat(build.func): notify users when already on a pinned script version [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15819](https://github.com/community-scripts/ProxmoxVE/pull/15819))
-
- - #### 💥 Breaking Changes
-
- - MongoDB: Implement kernel version check and patch [@MickLesk](https://github.com/MickLesk) ([#15821](https://github.com/community-scripts/ProxmoxVE/pull/15821))
-
-### 🧰 Tools
-
- - #### ✨ New Features
-
- - update-lxc: autoremove and autoclean after apt full-upgrade [@soupy-boy](https://github.com/soupy-boy) ([#15831](https://github.com/community-scripts/ProxmoxVE/pull/15831))
-
-## 2026-07-16
-
-### 🆕 New Scripts
-
- - Sync-In ([#15812](https://github.com/community-scripts/ProxmoxVE/pull/15812))
-- Beaverhabits ([#15813](https://github.com/community-scripts/ProxmoxVE/pull/15813))
-- Notediscovery ([#15811](https://github.com/community-scripts/ProxmoxVE/pull/15811))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Pin Immich to v3.0.3 [@vhsdream](https://github.com/vhsdream) ([#15790](https://github.com/community-scripts/ProxmoxVE/pull/15790))
-
-## 2026-07-15
-
-### 🆕 New Scripts
-
- - Nexterm ([#15688](https://github.com/community-scripts/ProxmoxVE/pull/15688))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - 2fauth: minor fixes for 8.0.0 [@MickLesk](https://github.com/MickLesk) ([#15795](https://github.com/community-scripts/ProxmoxVE/pull/15795))
- - SnapOtter: refactor update process to prebuild [@MickLesk](https://github.com/MickLesk) ([#15797](https://github.com/community-scripts/ProxmoxVE/pull/15797))
-
-### 💾 Core
-
- - #### 🔧 Refactor
-
- - tools.func: default Docker setup to official repo [@MickLesk](https://github.com/MickLesk) ([#15794](https://github.com/community-scripts/ProxmoxVE/pull/15794))
-
-## 2026-07-14
-
-### 🆕 New Scripts
-
- - Grav ([#15773](https://github.com/community-scripts/ProxmoxVE/pull/15773))
-- Yuvomi ([#15772](https://github.com/community-scripts/ProxmoxVE/pull/15772))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Lychee: Preserve uploads and ownership during update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15768](https://github.com/community-scripts/ProxmoxVE/pull/15768))
- - Wanderer: Clean deploy and install plugins for v0.20.0 update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15759](https://github.com/community-scripts/ProxmoxVE/pull/15759))
- - FileFlows: Handle update API 401, force update, and Node install [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15766](https://github.com/community-scripts/ProxmoxVE/pull/15766))
- - BirdNET-Go: Match new upstream release asset naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15758](https://github.com/community-scripts/ProxmoxVE/pull/15758))
- - [Upstream Fix] Immich: Fix loader priority [@vhsdream](https://github.com/vhsdream) ([#15755](https://github.com/community-scripts/ProxmoxVE/pull/15755))
-
- - #### ✨ New Features
-
- - Bump OpenCloud version to v7.2.2 [@MickLesk](https://github.com/MickLesk) ([#15769](https://github.com/community-scripts/ProxmoxVE/pull/15769))
- - Silverbullet: Add optional Runtime API install via Chromium [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15761](https://github.com/community-scripts/ProxmoxVE/pull/15761))
-
- - #### 💥 Breaking Changes
-
- - Pangolin: Bump to 1.20.0 | BREAKING: Switch to PostgreSQL [@MickLesk](https://github.com/MickLesk) ([#15682](https://github.com/community-scripts/ProxmoxVE/pull/15682))
-
- - #### 🔧 Refactor
-
- - AFFiNE: Pin to v0.26.3 [@MickLesk](https://github.com/MickLesk) ([#15782](https://github.com/community-scripts/ProxmoxVE/pull/15782))
-
-## 2026-07-13
-
-### 🆕 New Scripts
-
- - LeafWiki ([#15748](https://github.com/community-scripts/ProxmoxVE/pull/15748))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - fix(hyperion): keep service running after container reboot [@TowyTowy](https://github.com/TowyTowy) ([#15653](https://github.com/community-scripts/ProxmoxVE/pull/15653))
- - Change sign-in URL to admin URL in affine.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15741](https://github.com/community-scripts/ProxmoxVE/pull/15741))
- - immich: use actual PostgreSQL version for VectorChord package lookup [@mnavon](https://github.com/mnavon) ([#15705](https://github.com/community-scripts/ProxmoxVE/pull/15705))
- - fix storyteller release selection for stable web tags [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15736](https://github.com/community-scripts/ProxmoxVE/pull/15736))
- - Docmost: Fix update procedure [@MickLesk](https://github.com/MickLesk) ([#15732](https://github.com/community-scripts/ProxmoxVE/pull/15732))
- - fix(shinobi): remove obsolete --unsafe-perm npm flag [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15730](https://github.com/community-scripts/ProxmoxVE/pull/15730))
-
- - #### 💥 Breaking Changes
-
- - reitti: update to v5 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15635](https://github.com/community-scripts/ProxmoxVE/pull/15635))
-
-### 💾 Core
-
- - #### 🐞 Bug Fixes
-
- - fix(build.func): parse script status without jq dependency [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15729](https://github.com/community-scripts/ProxmoxVE/pull/15729))
-
- - #### 🔧 Refactor
-
- - tools.func: some improvements (sql injection / command injection / guard) [@MickLesk](https://github.com/MickLesk) ([#15661](https://github.com/community-scripts/ProxmoxVE/pull/15661))
-
-## 2026-07-12
-
-### 🆕 New Scripts
-
- - AFFiNE ([#15690](https://github.com/community-scripts/ProxmoxVE/pull/15690))
-
-### 🚀 Updated Scripts
-
- - Immich: Bump version to 3.0.2 [@vhsdream](https://github.com/vhsdream) ([#15668](https://github.com/community-scripts/ProxmoxVE/pull/15668))
-
-### ❔ Uncategorized
-
- - fix(immich): correct Python indentation error in ct/immich.sh heredoc patch [@Copilot](https://github.com/Copilot) ([#15723](https://github.com/community-scripts/ProxmoxVE/pull/15723))
-
-## 2026-07-11
-
-### 🆕 New Scripts
-
- - LocalAGI ([#15687](https://github.com/community-scripts/ProxmoxVE/pull/15687))
-
-### 🚀 Updated Scripts
-
- - fix(adventurelog): allow pnpm build scripts so install/update doesn't abort [@TowyTowy](https://github.com/TowyTowy) ([#15681](https://github.com/community-scripts/ProxmoxVE/pull/15681))
-
- - #### 🐞 Bug Fixes
-
- - fix(fileflows): install .NET 10 ASP.NET Core Runtime to match current release [@TowyTowy](https://github.com/TowyTowy) ([#15702](https://github.com/community-scripts/ProxmoxVE/pull/15702))
- - Fix spacing on VLAN Input Box in haos-vm.sh [@pumrum](https://github.com/pumrum) ([#15696](https://github.com/community-scripts/ProxmoxVE/pull/15696))
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - [tools.func]: Add function to handle deployment via GitLab release tags [@tremor021](https://github.com/tremor021) ([#15641](https://github.com/community-scripts/ProxmoxVE/pull/15641))
-
-## 2026-07-10
-
-### 🆕 New Scripts
-
- - Squid ([#15605](https://github.com/community-scripts/ProxmoxVE/pull/15605))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
- - Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
- - Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
-
-## 2026-07-09
-
-### 🚀 Updated Scripts
-
- - fix(pihole): repair Unbound DNS-over-TLS (DoT) forwarding config [@TowyTowy](https://github.com/TowyTowy) ([#15654](https://github.com/community-scripts/ProxmoxVE/pull/15654))
-
-## 2026-07-08
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Opencloud: Bump version to 7.2.1 [@vhsdream](https://github.com/vhsdream) ([#15655](https://github.com/community-scripts/ProxmoxVE/pull/15655))
- - BabyBuddy: Harden update script [@MickLesk](https://github.com/MickLesk) ([#15642](https://github.com/community-scripts/ProxmoxVE/pull/15642))
-
-## 2026-07-07
-
-### 🆕 New Scripts
-
- - Forgejo-Runner ([#15046](https://github.com/community-scripts/ProxmoxVE/pull/15046))
-
-## 2026-07-06
-
-### 🚀 Updated Scripts
-
- - Fix alignment in various ct end messages [@tremor021](https://github.com/tremor021) ([#15632](https://github.com/community-scripts/ProxmoxVE/pull/15632))
-- Immich: Update libvips to 8.18.4 [@vhsdream](https://github.com/vhsdream) ([#15619](https://github.com/community-scripts/ProxmoxVE/pull/15619))
-
- - #### 🐞 Bug Fixes
-
- - Wizarr: Build JS and CSS static assets [@vhsdream](https://github.com/vhsdream) ([#15634](https://github.com/community-scripts/ProxmoxVE/pull/15634))
- - RustDesk Server: Update URL format in rustdeskserver.sh [@tremor021](https://github.com/tremor021) ([#15626](https://github.com/community-scripts/ProxmoxVE/pull/15626))
- - attempt to port docker-vm to support arm64 [@asylumexp](https://github.com/asylumexp) ([#15611](https://github.com/community-scripts/ProxmoxVE/pull/15611))
- - fix(plane): don't clobber global app var, breaking /usr/bin/update [@asylumexp](https://github.com/asylumexp) ([#15612](https://github.com/community-scripts/ProxmoxVE/pull/15612))
-
- - #### 🔧 Refactor
-
- - cliproxyapi: point setup message at /management.html [@austinpilz](https://github.com/austinpilz) ([#15628](https://github.com/community-scripts/ProxmoxVE/pull/15628))
-
-### 🗑️ Deleted Scripts
-
- - Remove: FlowiseAI [@MickLesk](https://github.com/MickLesk) ([#15624](https://github.com/community-scripts/ProxmoxVE/pull/15624))
-
-## 2026-07-05
-
-### 🆕 New Scripts
-
- - excalidash ([#15604](https://github.com/community-scripts/ProxmoxVE/pull/15604))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - fix: homarr: cli [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15603](https://github.com/community-scripts/ProxmoxVE/pull/15603))
- - immich: vacuum smart_search/face_search before VectorChord bump [@irishpadres](https://github.com/irishpadres) ([#15607](https://github.com/community-scripts/ProxmoxVE/pull/15607))
-
## 2026-07-04
### 🚀 Updated Scripts
diff --git a/.github/workflows/close-invalid-pr-template.yml b/.github/workflows/close-invalid-pr-template.yml
deleted file mode 100644
index ce4c9a1bb..000000000
--- a/.github/workflows/close-invalid-pr-template.yml
+++ /dev/null
@@ -1,163 +0,0 @@
-name: Close PRs Missing Template
-
-on:
- pull_request_target:
- branches: ["main"]
- types: [opened, edited, reopened, synchronize, labeled]
-
-jobs:
- validate-pr-template:
- if: github.repository == 'community-scripts/ProxmoxVE'
- runs-on: ubuntu-latest
- permissions:
- pull-requests: write
- issues: write
- contents: read
- steps:
- - name: Close PR if it does not follow the PR template
- uses: actions/github-script@v7
- with:
- script: |
- const pr = context.payload.pull_request;
- const prNumber = pr.number;
- const author = pr.user.login;
- const owner = context.repo.owner;
- const repo = context.repo.repo;
-
- const allowedBots = [
- "push-app-to-main[bot]",
- "push-app-to-main",
- "community-scripts-pr-app",
- "github-actions[bot]",
- "dependabot[bot]",
- ];
-
- if (allowedBots.includes(author) || author.endsWith("[bot]")) {
- core.info(`PR #${prNumber} by bot "${author}" — skipping template validation.`);
- return;
- }
-
- const association = pr.author_association;
- const exemptAssociations = ["OWNER", "MEMBER", "COLLABORATOR"];
- if (exemptAssociations.includes(association)) {
- core.info(`PR #${prNumber} by ${association} "${author}" — skipping template validation.`);
- return;
- }
-
- const labels = pr.labels.map((label) => label.name);
- const skipLabels = ["automated pr", "keep open"];
-
- if (skipLabels.some((label) => labels.includes(label))) {
- core.info(`PR #${prNumber} has a skip label (${labels.join(", ")}) — skipping template validation.`);
- return;
- }
-
- if (pr.draft) {
- core.info(`PR #${prNumber} is a draft — skipping template validation.`);
- return;
- }
-
- const body = pr.body || "";
- const failures = [];
-
- const requiredSections = [
- "## ✍️ Description",
- "## ✅ Prerequisites",
- "## 🛠️ Type of Change",
- ];
-
- for (const section of requiredSections) {
- if (!body.includes(section)) {
- failures.push(`Missing required section: \`${section}\``);
- }
- }
-
- const descriptionMatch = body.match(
- /## ✍️ Description\s*\n+([\s\S]*?)(?=\n## )/i
- );
- const description = (descriptionMatch?.[1] || "").trim();
- if (!description) {
- failures.push("The **Description** section is empty.");
- }
-
- const prerequisiteCheckboxes = [
- "**Self-review completed**",
- "**Tested thoroughly**",
- "**No security risks**",
- ];
-
- for (const checkbox of prerequisiteCheckboxes) {
- const escaped = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
- const regex = new RegExp(`- \\[(x|X)\\]\\s*${escaped}`, "i");
- if (!regex.test(body)) {
- failures.push(`Prerequisite not checked: ${checkbox}`);
- }
- }
-
- const typeOfChangeCheckboxes = [
- "🐞 **Bug fix**",
- "✨ **New feature**",
- "💥 **Breaking change**",
- "🆕 **New script**",
- "🌍 **Website update**",
- "🔧 **Refactoring / Code Cleanup**",
- "📝 **Documentation update**",
- ];
-
- const hasTypeChecked = typeOfChangeCheckboxes.some((checkbox) => {
- const escaped = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
- const regex = new RegExp(`- \\[(x|X)\\]\\s*${escaped}`, "i");
- return regex.test(body);
- });
-
- if (!hasTypeChecked) {
- failures.push("At least one **Type of Change** checkbox must be checked.");
- }
-
- if (failures.length === 0) {
- core.info(`PR #${prNumber} follows the PR template.`);
- return;
- }
-
- core.info(`Closing PR #${prNumber} — template validation failed.`);
-
- const templateUrl =
- "https://github.com/community-scripts/ProxmoxVE/blob/main/.github/pull_request_template.md";
- const failureList = failures.map((item) => `- ${item}`).join("\n");
-
- const comment = [
- `👋 Hi @${author},`,
- ``,
- `This pull request was closed because it does not follow the [PR template](${templateUrl}).`,
- ``,
- `Please fix the following and open a new PR (or reopen this one after updating the description):`,
- ``,
- failureList,
- ``,
- `> Use the template sections, fill in the description, check all prerequisite boxes, and select at least one type of change.`,
- ``,
- `Maintainers can add the \`keep open\` label to exempt a PR from this check.`,
- ``,
- `Thank you for contributing! 🙏`,
- ].join("\n");
-
- await github.rest.issues.createComment({
- owner,
- repo,
- issue_number: prNumber,
- body: comment,
- });
-
- await github.rest.pulls.update({
- owner,
- repo,
- pull_number: prNumber,
- state: "closed",
- });
-
- await github.rest.issues.addLabels({
- owner,
- repo,
- issue_number: prNumber,
- labels: ["missing pr template"],
- });
diff --git a/.github/workflows/delete-merged-branches.yml b/.github/workflows/delete-merged-branches.yml
index 09a9f8ab1..aafaf2b44 100644
--- a/.github/workflows/delete-merged-branches.yml
+++ b/.github/workflows/delete-merged-branches.yml
@@ -91,30 +91,6 @@ jobs:
let skipped = 0;
for (const branch of candidates) {
- // A branch name can be reused after an earlier PR was merged. Never delete a
- // branch while it is the head of a current open PR, even if it is also a
- // candidate from an older merged PR.
- try {
- const { data: openPrs } = await github.rest.pulls.list({
- owner,
- repo,
- state: "open",
- head: `${owner}:${branch}`,
- per_page: 1,
- });
-
- if (openPrs.length > 0) {
- console.log(`Skipped "${branch}" (head of open PR #${openPrs[0].number})`);
- skipped++;
- continue;
- }
- } catch (error) {
- // Do not risk deleting a branch if GitHub cannot confirm it has no open PR.
- console.log(`Failed to check open PRs for "${branch}": ${error.message}`);
- skipped++;
- continue;
- }
-
// Confirm the branch still exists and isn't protected.
let branchData;
try {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b3332fdf..4c48a7a4b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -71,12 +71,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
-
-
-
-
-
-
@@ -93,7 +87,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
-July (18 entries)
+July (4 entries)
[View July 2026 Changelog](.github/changelogs/2026/07.md)
@@ -505,256 +499,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
-## 2026-07-19
-
-## 2026-07-18
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - core: add configurable host CA inheritance during bootstrap [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15840](https://github.com/community-scripts/ProxmoxVE/pull/15840))
-
- - #### 🔧 Refactor
-
- - tools.func: Safe Delete Directorys & Update PYTHON_VERSION with setup_uv [@MickLesk](https://github.com/MickLesk) ([#15870](https://github.com/community-scripts/ProxmoxVE/pull/15870))
-
-### 🧰 Tools
-
- - #### ✨ New Features
-
- - [tools.update-lxcs] feat: optional reporting success/failures to heathchecks.io (or others) [@sir106](https://github.com/sir106) ([#15701](https://github.com/community-scripts/ProxmoxVE/pull/15701))
-
-## 2026-07-17
-
-### 🆕 New Scripts
-
- - Invidious ([#15824](https://github.com/community-scripts/ProxmoxVE/pull/15824))
-- OxiCloud ([#15823](https://github.com/community-scripts/ProxmoxVE/pull/15823))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - webtrees: initialize database schema before admin user creation [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15837](https://github.com/community-scripts/ProxmoxVE/pull/15837))
- - Fix DocuSeal missing Leptonica deps on install and update [@Copilot](https://github.com/Copilot) ([#15858](https://github.com/community-scripts/ProxmoxVE/pull/15858))
- - apache-guacamole: detect installed extensions during update [@TowyTowy](https://github.com/TowyTowy) ([#15841](https://github.com/community-scripts/ProxmoxVE/pull/15841))
- - CLIProxyAPI: fix update deleting config.yaml [@austinpilz](https://github.com/austinpilz) ([#15834](https://github.com/community-scripts/ProxmoxVE/pull/15834))
- - esphome: install libusb-1.0-0 for ESP-IDF native builds [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15838](https://github.com/community-scripts/ProxmoxVE/pull/15838))
-
- - #### ✨ New Features
-
- - AFFiNE: Bump to 0.27.0 [@MickLesk](https://github.com/MickLesk) ([#15848](https://github.com/community-scripts/ProxmoxVE/pull/15848))
- - n8n: unpin / use latest release [@MickLesk](https://github.com/MickLesk) ([#15817](https://github.com/community-scripts/ProxmoxVE/pull/15817))
- - Pin Opencloud to v7.3.0 [@vhsdream](https://github.com/vhsdream) ([#15826](https://github.com/community-scripts/ProxmoxVE/pull/15826))
-
- - #### 🔧 Refactor
-
- - SFTPGo: Update APT Repo & Re-Enable Script [@MickLesk](https://github.com/MickLesk) ([#15829](https://github.com/community-scripts/ProxmoxVE/pull/15829))
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - tools.func: enhance rbenv with profile updates / bundle in bashrc [@MickLesk](https://github.com/MickLesk) ([#15822](https://github.com/community-scripts/ProxmoxVE/pull/15822))
- - feat(build.func): notify users when already on a pinned script version [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15819](https://github.com/community-scripts/ProxmoxVE/pull/15819))
-
- - #### 💥 Breaking Changes
-
- - MongoDB: Implement kernel version check and patch [@MickLesk](https://github.com/MickLesk) ([#15821](https://github.com/community-scripts/ProxmoxVE/pull/15821))
-
-### 🧰 Tools
-
- - #### ✨ New Features
-
- - update-lxc: autoremove and autoclean after apt full-upgrade [@soupy-boy](https://github.com/soupy-boy) ([#15831](https://github.com/community-scripts/ProxmoxVE/pull/15831))
-
-## 2026-07-16
-
-### 🆕 New Scripts
-
- - Sync-In ([#15812](https://github.com/community-scripts/ProxmoxVE/pull/15812))
-- Beaverhabits ([#15813](https://github.com/community-scripts/ProxmoxVE/pull/15813))
-- Notediscovery ([#15811](https://github.com/community-scripts/ProxmoxVE/pull/15811))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Pin Immich to v3.0.3 [@vhsdream](https://github.com/vhsdream) ([#15790](https://github.com/community-scripts/ProxmoxVE/pull/15790))
-
-## 2026-07-15
-
-### 🆕 New Scripts
-
- - Nexterm ([#15688](https://github.com/community-scripts/ProxmoxVE/pull/15688))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - 2fauth: minor fixes for 8.0.0 [@MickLesk](https://github.com/MickLesk) ([#15795](https://github.com/community-scripts/ProxmoxVE/pull/15795))
- - SnapOtter: refactor update process to prebuild [@MickLesk](https://github.com/MickLesk) ([#15797](https://github.com/community-scripts/ProxmoxVE/pull/15797))
-
-### 💾 Core
-
- - #### 🔧 Refactor
-
- - tools.func: default Docker setup to official repo [@MickLesk](https://github.com/MickLesk) ([#15794](https://github.com/community-scripts/ProxmoxVE/pull/15794))
-
-## 2026-07-14
-
-### 🆕 New Scripts
-
- - Grav ([#15773](https://github.com/community-scripts/ProxmoxVE/pull/15773))
-- Yuvomi ([#15772](https://github.com/community-scripts/ProxmoxVE/pull/15772))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Lychee: Preserve uploads and ownership during update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15768](https://github.com/community-scripts/ProxmoxVE/pull/15768))
- - Wanderer: Clean deploy and install plugins for v0.20.0 update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15759](https://github.com/community-scripts/ProxmoxVE/pull/15759))
- - FileFlows: Handle update API 401, force update, and Node install [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15766](https://github.com/community-scripts/ProxmoxVE/pull/15766))
- - BirdNET-Go: Match new upstream release asset naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15758](https://github.com/community-scripts/ProxmoxVE/pull/15758))
- - [Upstream Fix] Immich: Fix loader priority [@vhsdream](https://github.com/vhsdream) ([#15755](https://github.com/community-scripts/ProxmoxVE/pull/15755))
-
- - #### ✨ New Features
-
- - Bump OpenCloud version to v7.2.2 [@MickLesk](https://github.com/MickLesk) ([#15769](https://github.com/community-scripts/ProxmoxVE/pull/15769))
- - Silverbullet: Add optional Runtime API install via Chromium [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15761](https://github.com/community-scripts/ProxmoxVE/pull/15761))
-
- - #### 💥 Breaking Changes
-
- - Pangolin: Bump to 1.20.0 | BREAKING: Switch to PostgreSQL [@MickLesk](https://github.com/MickLesk) ([#15682](https://github.com/community-scripts/ProxmoxVE/pull/15682))
-
- - #### 🔧 Refactor
-
- - AFFiNE: Pin to v0.26.3 [@MickLesk](https://github.com/MickLesk) ([#15782](https://github.com/community-scripts/ProxmoxVE/pull/15782))
-
-## 2026-07-13
-
-### 🆕 New Scripts
-
- - LeafWiki ([#15748](https://github.com/community-scripts/ProxmoxVE/pull/15748))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - fix(hyperion): keep service running after container reboot [@TowyTowy](https://github.com/TowyTowy) ([#15653](https://github.com/community-scripts/ProxmoxVE/pull/15653))
- - Change sign-in URL to admin URL in affine.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15741](https://github.com/community-scripts/ProxmoxVE/pull/15741))
- - immich: use actual PostgreSQL version for VectorChord package lookup [@mnavon](https://github.com/mnavon) ([#15705](https://github.com/community-scripts/ProxmoxVE/pull/15705))
- - fix storyteller release selection for stable web tags [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15736](https://github.com/community-scripts/ProxmoxVE/pull/15736))
- - Docmost: Fix update procedure [@MickLesk](https://github.com/MickLesk) ([#15732](https://github.com/community-scripts/ProxmoxVE/pull/15732))
- - fix(shinobi): remove obsolete --unsafe-perm npm flag [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15730](https://github.com/community-scripts/ProxmoxVE/pull/15730))
-
- - #### 💥 Breaking Changes
-
- - reitti: update to v5 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15635](https://github.com/community-scripts/ProxmoxVE/pull/15635))
-
-### 💾 Core
-
- - #### 🐞 Bug Fixes
-
- - fix(build.func): parse script status without jq dependency [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15729](https://github.com/community-scripts/ProxmoxVE/pull/15729))
-
- - #### 🔧 Refactor
-
- - tools.func: some improvements (sql injection / command injection / guard) [@MickLesk](https://github.com/MickLesk) ([#15661](https://github.com/community-scripts/ProxmoxVE/pull/15661))
-
-## 2026-07-12
-
-### 🆕 New Scripts
-
- - AFFiNE ([#15690](https://github.com/community-scripts/ProxmoxVE/pull/15690))
-
-### 🚀 Updated Scripts
-
- - Immich: Bump version to 3.0.2 [@vhsdream](https://github.com/vhsdream) ([#15668](https://github.com/community-scripts/ProxmoxVE/pull/15668))
-
-### ❔ Uncategorized
-
- - fix(immich): correct Python indentation error in ct/immich.sh heredoc patch [@Copilot](https://github.com/Copilot) ([#15723](https://github.com/community-scripts/ProxmoxVE/pull/15723))
-
-## 2026-07-11
-
-### 🆕 New Scripts
-
- - LocalAGI ([#15687](https://github.com/community-scripts/ProxmoxVE/pull/15687))
-
-### 🚀 Updated Scripts
-
- - fix(adventurelog): allow pnpm build scripts so install/update doesn't abort [@TowyTowy](https://github.com/TowyTowy) ([#15681](https://github.com/community-scripts/ProxmoxVE/pull/15681))
-
- - #### 🐞 Bug Fixes
-
- - fix(fileflows): install .NET 10 ASP.NET Core Runtime to match current release [@TowyTowy](https://github.com/TowyTowy) ([#15702](https://github.com/community-scripts/ProxmoxVE/pull/15702))
- - Fix spacing on VLAN Input Box in haos-vm.sh [@pumrum](https://github.com/pumrum) ([#15696](https://github.com/community-scripts/ProxmoxVE/pull/15696))
-
-### 💾 Core
-
- - #### ✨ New Features
-
- - [tools.func]: Add function to handle deployment via GitLab release tags [@tremor021](https://github.com/tremor021) ([#15641](https://github.com/community-scripts/ProxmoxVE/pull/15641))
-
-## 2026-07-10
-
-### 🆕 New Scripts
-
- - Squid ([#15605](https://github.com/community-scripts/ProxmoxVE/pull/15605))
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
- - Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
- - Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
-
-## 2026-07-09
-
-### 🚀 Updated Scripts
-
- - fix(pihole): repair Unbound DNS-over-TLS (DoT) forwarding config [@TowyTowy](https://github.com/TowyTowy) ([#15654](https://github.com/community-scripts/ProxmoxVE/pull/15654))
-
-## 2026-07-08
-
-### 🚀 Updated Scripts
-
- - #### 🐞 Bug Fixes
-
- - Opencloud: Bump version to 7.2.1 [@vhsdream](https://github.com/vhsdream) ([#15655](https://github.com/community-scripts/ProxmoxVE/pull/15655))
- - BabyBuddy: Harden update script [@MickLesk](https://github.com/MickLesk) ([#15642](https://github.com/community-scripts/ProxmoxVE/pull/15642))
-
-## 2026-07-07
-
-### 🆕 New Scripts
-
- - Forgejo-Runner ([#15046](https://github.com/community-scripts/ProxmoxVE/pull/15046))
-
-## 2026-07-06
-
-### 🚀 Updated Scripts
-
- - Fix alignment in various ct end messages [@tremor021](https://github.com/tremor021) ([#15632](https://github.com/community-scripts/ProxmoxVE/pull/15632))
-- Immich: Update libvips to 8.18.4 [@vhsdream](https://github.com/vhsdream) ([#15619](https://github.com/community-scripts/ProxmoxVE/pull/15619))
-
- - #### 🐞 Bug Fixes
-
- - Wizarr: Build JS and CSS static assets [@vhsdream](https://github.com/vhsdream) ([#15634](https://github.com/community-scripts/ProxmoxVE/pull/15634))
- - RustDesk Server: Update URL format in rustdeskserver.sh [@tremor021](https://github.com/tremor021) ([#15626](https://github.com/community-scripts/ProxmoxVE/pull/15626))
- - attempt to port docker-vm to support arm64 [@asylumexp](https://github.com/asylumexp) ([#15611](https://github.com/community-scripts/ProxmoxVE/pull/15611))
- - fix(plane): don't clobber global app var, breaking /usr/bin/update [@asylumexp](https://github.com/asylumexp) ([#15612](https://github.com/community-scripts/ProxmoxVE/pull/15612))
-
- - #### 🔧 Refactor
-
- - cliproxyapi: point setup message at /management.html [@austinpilz](https://github.com/austinpilz) ([#15628](https://github.com/community-scripts/ProxmoxVE/pull/15628))
-
-### 🗑️ Deleted Scripts
-
- - Remove: FlowiseAI [@MickLesk](https://github.com/MickLesk) ([#15624](https://github.com/community-scripts/ProxmoxVE/pull/15624))
-
## 2026-07-05
### 🆕 New Scripts
@@ -1158,4 +902,259 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- chore(ct): sync coredns defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15182](https://github.com/community-scripts/ProxmoxVE/pull/15182))
- chore(ct): sync gatus defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15184](https://github.com/community-scripts/ProxmoxVE/pull/15184))
-- chore(ct): sync bitmagnet defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15183](https://github.com/community-scripts/ProxmoxVE/pull/15183))
\ No newline at end of file
+- chore(ct): sync bitmagnet defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15183](https://github.com/community-scripts/ProxmoxVE/pull/15183))
+
+## 2026-06-18
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - flowise: add deps / uv / python 3.11 [@MickLesk](https://github.com/MickLesk) ([#15177](https://github.com/community-scripts/ProxmoxVE/pull/15177))
+
+ - #### 💥 Breaking Changes
+
+ - refactor: crafty-controller [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15178](https://github.com/community-scripts/ProxmoxVE/pull/15178))
+
+## 2026-06-17
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - kasm: fix release detection [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15151](https://github.com/community-scripts/ProxmoxVE/pull/15151))
+
+ - #### ✨ New Features
+
+ - trek: update install and upgrade workflow for v3.1.0 [@MickLesk](https://github.com/MickLesk) ([#15165](https://github.com/community-scripts/ProxmoxVE/pull/15165))
+
+ - #### 💥 Breaking Changes
+
+ - TREK: Pin version [@tremor021](https://github.com/tremor021) ([#15156](https://github.com/community-scripts/ProxmoxVE/pull/15156))
+
+ - #### 🔧 Refactor
+
+ - chore(paperless-ngx): pin version to prevent v3 update [@tomfrenzel](https://github.com/tomfrenzel) ([#15171](https://github.com/community-scripts/ProxmoxVE/pull/15171))
+
+### 🧰 Tools
+
+ - #### 🐞 Bug Fixes
+
+ - immich public proxy: replace npm install with npm ci for consistent dependency installation [@MickLesk](https://github.com/MickLesk) ([#15166](https://github.com/community-scripts/ProxmoxVE/pull/15166))
+
+## 2026-06-16
+
+### 🆕 New Scripts
+
+ - Feishin ([#15130](https://github.com/community-scripts/ProxmoxVE/pull/15130))
+- Kiwix ([#15131](https://github.com/community-scripts/ProxmoxVE/pull/15131))
+- Add runtime status guard and deleted script stubs [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15125](https://github.com/community-scripts/ProxmoxVE/pull/15125))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - fix(degoog): use localhost for valkey url [@ethan-hgwr](https://github.com/ethan-hgwr) ([#15149](https://github.com/community-scripts/ProxmoxVE/pull/15149))
+ - Fix InvoiceShelf install/update Yarn package manager mismatch [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15141](https://github.com/community-scripts/ProxmoxVE/pull/15141))
+ - fix storyteller install failure with yarn 4 corepack [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15140](https://github.com/community-scripts/ProxmoxVE/pull/15140))
+ - fix: generate policy-compliant OpenObserve root password [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15137](https://github.com/community-scripts/ProxmoxVE/pull/15137))
+
+## 2026-06-15
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Watcharr: Clean install on update [@tremor021](https://github.com/tremor021) ([#15119](https://github.com/community-scripts/ProxmoxVE/pull/15119))
+ - Vaultwarden: extend version check for VaultWarden update [@MickLesk](https://github.com/MickLesk) ([#15105](https://github.com/community-scripts/ProxmoxVE/pull/15105))
+
+ - #### ✨ New Features
+
+ - degoog: add curl-impersonate to script [@MickLesk](https://github.com/MickLesk) ([#15117](https://github.com/community-scripts/ProxmoxVE/pull/15117))
+
+### 💾 Core
+
+ - #### ✨ New Features
+
+ - tools.func: extend mesa-vulkan-drivers and vulkan-tools to installation for ARC GPU's [@MickLesk](https://github.com/MickLesk) ([#15106](https://github.com/community-scripts/ProxmoxVE/pull/15106))
+
+ - #### 🔧 Refactor
+
+ - core: improve mirror selection and error handling [@MickLesk](https://github.com/MickLesk) ([#15108](https://github.com/community-scripts/ProxmoxVE/pull/15108))
+ - core: implement gateway validation for DHCP and static networks [@MickLesk](https://github.com/MickLesk) ([#15107](https://github.com/community-scripts/ProxmoxVE/pull/15107))
+
+## 2026-06-14
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Iinvoiceninja: fix nginx setup assets port [@MickLesk](https://github.com/MickLesk) ([#15090](https://github.com/community-scripts/ProxmoxVE/pull/15090))
+ - CheckMK: remove stale backup site before creating new backup during update [@MickLesk](https://github.com/MickLesk) ([#15088](https://github.com/community-scripts/ProxmoxVE/pull/15088))
+
+ - #### 🔧 Refactor
+
+ - Refactor: Implement backup functions for scripts C-D [@tremor021](https://github.com/tremor021) ([#15096](https://github.com/community-scripts/ProxmoxVE/pull/15096))
+
+## 2026-06-13
+
+### 🆕 New Scripts
+
+ - BookOrbit ([#15080](https://github.com/community-scripts/ProxmoxVE/pull/15080))
+
+### 🚀 Updated Scripts
+
+ - Update authentik version to 2026.5.3 [@thieneret](https://github.com/thieneret) ([#15093](https://github.com/community-scripts/ProxmoxVE/pull/15093))
+
+ - #### 🐞 Bug Fixes
+
+ - Immich: Update image-processing libraries [@vhsdream](https://github.com/vhsdream) ([#15082](https://github.com/community-scripts/ProxmoxVE/pull/15082))
+ - HomeBox: Support v0.26.0 [@tomfrenzel](https://github.com/tomfrenzel) ([#15086](https://github.com/community-scripts/ProxmoxVE/pull/15086))
+
+ - #### 🔧 Refactor
+
+ - Refactor: Implement backup functions for scripts A-B [@tremor021](https://github.com/tremor021) ([#15075](https://github.com/community-scripts/ProxmoxVE/pull/15075))
+
+## 2026-06-12
+
+### 🆕 New Scripts
+
+ - Twenty ([#15047](https://github.com/community-scripts/ProxmoxVE/pull/15047))
+- Alpine-Cinny ([#15044](https://github.com/community-scripts/ProxmoxVE/pull/15044))
+
+### 💾 Core
+
+ - #### ✨ New Features
+
+ - [core] Implement backup and restore functions [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15067](https://github.com/community-scripts/ProxmoxVE/pull/15067))
+
+## 2026-06-11
+
+### 🆕 New Scripts
+
+ - Clickhouse ([#15045](https://github.com/community-scripts/ProxmoxVE/pull/15045))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Manyfold: add new dependency [@MickLesk](https://github.com/MickLesk) ([#15040](https://github.com/community-scripts/ProxmoxVE/pull/15040))
+ - OpenArchiver: switch Rebuild Function [@MickLesk](https://github.com/MickLesk) ([#15042](https://github.com/community-scripts/ProxmoxVE/pull/15042))
+ - CLIProxyAPI: Save management password to creds file [@tremor021](https://github.com/tremor021) ([#15051](https://github.com/community-scripts/ProxmoxVE/pull/15051))
+ - Jotty: Fix wrong path test in config restore [@vhsdream](https://github.com/vhsdream) ([#15038](https://github.com/community-scripts/ProxmoxVE/pull/15038))
+ - Fix for cross-seed after node upgrade [@TorinFrancis](https://github.com/TorinFrancis) ([#15025](https://github.com/community-scripts/ProxmoxVE/pull/15025))
+
+ - #### 🔧 Refactor
+
+ - Alpine-Nextcloud: Upgrade PHP and dependencies in installation script [@MickLesk](https://github.com/MickLesk) ([#15039](https://github.com/community-scripts/ProxmoxVE/pull/15039))
+ - [arm64] porting stage 1: set script arm64 statuses to yes [@asylumexp](https://github.com/asylumexp) ([#15052](https://github.com/community-scripts/ProxmoxVE/pull/15052))
+
+### 💾 Core
+
+ - #### ✨ New Features
+
+ - misc scripts: add support for arm64 [@asylumexp](https://github.com/asylumexp) ([#12639](https://github.com/community-scripts/ProxmoxVE/pull/12639))
+
+ - #### 🔧 Refactor
+
+ - [arm64] remove logic for custom debian arm64 template [@asylumexp](https://github.com/asylumexp) ([#15050](https://github.com/community-scripts/ProxmoxVE/pull/15050))
+
+### 📚 Documentation
+
+ - (github): Revise script request template [@MickLesk](https://github.com/MickLesk) ([#15058](https://github.com/community-scripts/ProxmoxVE/pull/15058))
+
+## 2026-06-10
+
+### 🆕 New Scripts
+
+ - Baserow ([#14968](https://github.com/community-scripts/ProxmoxVE/pull/14968))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Koillection: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15033](https://github.com/community-scripts/ProxmoxVE/pull/15033))
+
+## 2026-06-09
+
+### 🆕 New Scripts
+
+ - paperclip ([#14990](https://github.com/community-scripts/ProxmoxVE/pull/14990))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - endurain: Install pytz package during backend setup [@MickLesk](https://github.com/MickLesk) ([#15014](https://github.com/community-scripts/ProxmoxVE/pull/15014))
+
+ - #### 🔧 Refactor
+
+ - Refactor: Proxmox Backup Server - use deb822 [@MickLesk](https://github.com/MickLesk) ([#15013](https://github.com/community-scripts/ProxmoxVE/pull/15013))
+
+## 2026-06-08
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - security: Fix HTTP to HTTPS for all package and repository downloads [@MickLesk](https://github.com/MickLesk) ([#15009](https://github.com/community-scripts/ProxmoxVE/pull/15009))
+ - homelable: preserve MCP server config across updates [@ferr079](https://github.com/ferr079) ([#14996](https://github.com/community-scripts/ProxmoxVE/pull/14996))
+ - changedetection: migrate Python install to uv venv [@ferr079](https://github.com/ferr079) ([#14995](https://github.com/community-scripts/ProxmoxVE/pull/14995))
+
+ - #### 🔧 Refactor
+
+ - Update Flowwiseai to node 24 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#14999](https://github.com/community-scripts/ProxmoxVE/pull/14999))
+
+### 🧰 Tools
+
+ - #### 🐞 Bug Fixes
+
+ - security: Fix MITM RCE vulnerability in microcode scripts (CVE) [@MickLesk](https://github.com/MickLesk) ([#15007](https://github.com/community-scripts/ProxmoxVE/pull/15007))
+
+## 2026-06-07
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Immich: use actual installed PostgreSQL version for vchord package [@MickLesk](https://github.com/MickLesk) ([#14989](https://github.com/community-scripts/ProxmoxVE/pull/14989))
+
+ - #### 🔧 Refactor
+
+ - Navidrome: remove genereic filebrowser addon setup [@MickLesk](https://github.com/MickLesk) ([#14991](https://github.com/community-scripts/ProxmoxVE/pull/14991))
+
+## 2026-06-06
+
+### 🆕 New Scripts
+
+ - Spliit ([#14966](https://github.com/community-scripts/ProxmoxVE/pull/14966))
+- Tolgee ([#14965](https://github.com/community-scripts/ProxmoxVE/pull/14965))
+- XYOps ([#14967](https://github.com/community-scripts/ProxmoxVE/pull/14967))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Photoprism: Allow env variables with spaces [@Badintral](https://github.com/Badintral) ([#14969](https://github.com/community-scripts/ProxmoxVE/pull/14969))
+
+## 2026-06-05
+
+### 🆕 New Scripts
+
+ - MatterJS-Server ([#14951](https://github.com/community-scripts/ProxmoxVE/pull/14951))
+- CyberChef ([#14952](https://github.com/community-scripts/ProxmoxVE/pull/14952))
+
+### 🚀 Updated Scripts
+
+ - #### 🐞 Bug Fixes
+
+ - Jackett: Create missing .env file [@tremor021](https://github.com/tremor021) ([#14959](https://github.com/community-scripts/ProxmoxVE/pull/14959))
+ - OpenThread-BR: use systemd instead of init.d [@tomfrenzel](https://github.com/tomfrenzel) ([#14942](https://github.com/community-scripts/ProxmoxVE/pull/14942))
+
+ - #### ✨ New Features
+
+ - AMD IGPU support [@Learath](https://github.com/Learath) ([#14944](https://github.com/community-scripts/ProxmoxVE/pull/14944))
+
+ - #### 💥 Breaking Changes
+
+ - update authentik to 2026.5.2 [@thieneret](https://github.com/thieneret) ([#14846](https://github.com/community-scripts/ProxmoxVE/pull/14846))
\ No newline at end of file
diff --git a/ct/2fauth.sh b/ct/2fauth.sh
index 5b5dc3eb7..506f140d8 100644
--- a/ct/2fauth.sh
+++ b/ct/2fauth.sh
@@ -60,7 +60,6 @@ function update_script() {
php artisan 2fauth:install
chown -R www-data: /opt/2fauth
chmod -R 755 /opt/2fauth
- $STD php artisan 2fauth:fix-passport-key-permissions
$STD systemctl restart php8.4-fpm
$STD systemctl restart nginx
msg_ok "Configured 2FAuth"
diff --git a/ct/adventurelog.sh b/ct/adventurelog.sh
index 98327747e..0da4c09c0 100644
--- a/ct/adventurelog.sh
+++ b/ct/adventurelog.sh
@@ -60,7 +60,6 @@ function update_script() {
$STD .venv/bin/python -m manage migrate
cd /opt/adventurelog/frontend
- grep -q "^dangerouslyAllowAllBuilds:" ./pnpm-workspace.yaml 2>/dev/null || echo "dangerouslyAllowAllBuilds: true" >>./pnpm-workspace.yaml
$STD pnpm i
$STD pnpm build
msg_ok "Updated AdventureLog"
diff --git a/ct/affine.sh b/ct/affine.sh
deleted file mode 100644
index 1480c2a99..000000000
--- a/ct/affine.sh
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/toeverything/AFFiNE
-
-APP="AFFiNE"
-var_tags="${var_tags:-knowledge;notes;workspace}"
-var_cpu="${var_cpu:-4}"
-var_ram="${var_ram:-8192}"
-var_disk="${var_disk:-20}"
-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/affine ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- RELEASE="v0.27.0"
- if check_for_gh_release "affine_app" "toeverything/AFFiNE" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
- msg_info "Stopping Services"
- systemctl stop affine-web affine-worker
- msg_ok "Stopped Services"
-
- ensure_dependencies cmake
-
- create_backup /root/.affine/config /root/.affine/storage
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "affine_app" "toeverything/AFFiNE" "tarball" "${RELEASE}" "/opt/affine"
-
- msg_info "Rebuilding Application (Patience ~25 mins, don't close the console!)"
- cd /opt/affine
- source /root/.profile
- export PATH="/root/.cargo/bin:/root/.rbenv/shims:$PATH"
-
- set -a && source /opt/affine/.env && set +a
-
- export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
- export VITE_CORE_COMMIT_SHA=$(cat ~/.affine_app)
-
- # Initialize git repo (required for build process)
- export HUSKY=0
- $STD git init -q
- $STD git config user.email "build@local"
- $STD git config user.name "Build"
- $STD git add -A
- $STD git commit -q -m "update" --no-verify --allow-empty
-
- # Force Turbo to run sequentially
- mkdir -p /opt/affine/.turbo
- cat </opt/affine/.turbo/config.json
-{
- "concurrency": 1
-}
-TURBO
-
- $STD corepack enable
- $STD corepack prepare yarn@4.13.0 --activate
- $STD yarn config set enableTelemetry 0
-
- export NODE_OPTIONS="--max-old-space-size=2048"
- $STD yarn install
- $STD npm install -g typescript
-
- $STD yarn affine @affine/native build
- $STD yarn affine @affine/server-native build
-
- # Create architecture-specific symlinks
- ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.x64.node
- ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.arm64.node
- ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.armv7.node
-
- $STD yarn affine init
- $STD yarn affine build -p @affine/reader
- $STD yarn affine build -p @affine/server
-
- export NODE_OPTIONS="--max-old-space-size=4096"
- $STD yarn affine build -p @affine/web
- $STD yarn affine build -p @affine/admin
-
- # Copy web assets
- mkdir -p /opt/affine/packages/backend/server/static
- cp -r /opt/affine/packages/frontend/apps/web/dist/* /opt/affine/packages/backend/server/static/
- mkdir -p /opt/affine/packages/backend/server/static/admin
- cp -r /opt/affine/packages/frontend/admin/dist/* /opt/affine/packages/backend/server/static/admin/
-
- # Mobile manifest placeholder
- mkdir -p /opt/affine/packages/backend/server/static/mobile
- echo '{"publicPath":"/","js":[],"css":[],"gitHash":"","description":""}' \
- >/opt/affine/packages/backend/server/static/mobile/assets-manifest.json
-
- # Run migrations
- cd /opt/affine/packages/backend/server
- set -a && source /opt/affine/.env && set +a
- $STD node ./scripts/self-host-predeploy.js
-
- restore_backup
-
- msg_info "Starting Services"
- systemctl start affine-web affine-worker
- msg_ok "Started Services"
- msg_ok "Updated Successfully!"
- fi
- exit
-}
-
-start
-build_container
-description
-
-msg_ok "Completed Successfully!\n"
-echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access it using the following URL:${CL}"
-echo -e "${GATEWAY}${BGN}http://${IP}:3010/admin${CL}"
diff --git a/ct/alpine-cinny.sh b/ct/alpine-cinny.sh
index 17a6019ae..72c93f3e6 100644
--- a/ct/alpine-cinny.sh
+++ b/ct/alpine-cinny.sh
@@ -54,5 +54,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access it using the following IP:${CL}"
-echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
+echo -e "${INFO}${YW} Access it using the following IP:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/apache-airflow.sh b/ct/apache-airflow.sh
index 2a97f914d..d6a331177 100644
--- a/ct/apache-airflow.sh
+++ b/ct/apache-airflow.sh
@@ -33,7 +33,7 @@ function update_script() {
INSTALLED=$(cat ~/.airflow 2>/dev/null || echo "0")
LATEST=$(curl -fsSL "https://pypi.org/pypi/apache-airflow/json" | jq -r '.info.version')
- if [[ $INSTALLED == "$LATEST" ]]; then
+ if [[ "$INSTALLED" == "$LATEST" ]]; then
msg_ok "Already on the latest version (${LATEST})"
exit
fi
@@ -71,5 +71,5 @@ 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}:8080${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/apache-guacamole.sh b/ct/apache-guacamole.sh
index 89f1b973b..bbd9673cc 100644
--- a/ct/apache-guacamole.sh
+++ b/ct/apache-guacamole.sh
@@ -146,7 +146,7 @@ function update_script() {
# Check and upgrade optional extensions
# TOTP Extension
- if compgen -G "/etc/guacamole/extensions/guacamole-auth-totp-*.jar" >/dev/null; then
+ if [[ -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar ]]; then
msg_info "Updating TOTP Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar
curl_download "/tmp/guacamole-auth-totp.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-totp-${LATEST_SERVER}.tar.gz"
@@ -158,7 +158,7 @@ function update_script() {
fi
# DUO Extension
- if compgen -G "/etc/guacamole/extensions/guacamole-auth-duo-*.jar" >/dev/null; then
+ if [[ -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar ]]; then
msg_info "Updating DUO Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar
curl_download "/tmp/guacamole-auth-duo.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-duo-${LATEST_SERVER}.tar.gz"
@@ -170,7 +170,7 @@ function update_script() {
fi
# LDAP Extension
- if compgen -G "/etc/guacamole/extensions/guacamole-auth-ldap-*.jar" >/dev/null; then
+ if [[ -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar ]]; then
msg_info "Updating LDAP Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar
curl_download "/tmp/guacamole-auth-ldap.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-ldap-${LATEST_SERVER}.tar.gz"
@@ -182,7 +182,7 @@ function update_script() {
fi
# Quick Connect Extension
- if compgen -G "/etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar" >/dev/null; then
+ if [[ -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar ]]; then
msg_info "Updating Quick Connect Extension"
rm -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar
curl_download "/tmp/guacamole-auth-quickconnect.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-quickconnect-${LATEST_SERVER}.tar.gz"
@@ -194,7 +194,7 @@ function update_script() {
fi
# History Recording Storage Extension
- if compgen -G "/etc/guacamole/extensions/guacamole-history-recording-storage-*.jar" >/dev/null; then
+ if [[ -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar ]]; then
msg_info "Updating History Recording Storage Extension"
rm -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar
curl_download "/tmp/guacamole-history-recording-storage.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-history-recording-storage-${LATEST_SERVER}.tar.gz"
diff --git a/ct/authentik.sh b/ct/authentik.sh
index c8b99db82..b857bcff4 100644
--- a/ct/authentik.sh
+++ b/ct/authentik.sh
@@ -30,7 +30,7 @@ function update_script() {
exit
fi
- read -r MAJOR MINOR PATCH <<<"$(sed 's/^version\///; s/\./ /g' "$HOME/.authentik")"
+ read -r MAJOR MINOR PATCH <<< "$(sed 's/^version\///; s/\./ /g' "$HOME/.authentik")"
msg_info "Update dependencies"
ensure_dependencies crossbuild-essential-$(arch_resolve) gcc-$(arch_resolve "x86-64" "aarch64")-linux-gnu cmake clang libunwind-18-dev
@@ -66,26 +66,26 @@ function update_script() {
if check_for_gh_release "authentik" "goauthentik/authentik" "${AUTHENTIK_VERSION}"; then
msg_info "Stopping Services"
systemctl stop authentik-server authentik-worker
- if [[ $(systemctl is-active authentik-ldap) == active ]]; then
- systemctl stop authentik-ldap
- fi
- if [[ $(systemctl is-active authentik-rac) == active ]]; then
- systemctl stop authentik-rac
- fi
- if [[ $(systemctl is-active authentik-radius) == active ]]; then
- systemctl stop authentik-radius
- fi
+ if [[ $(systemctl is-active authentik-ldap) == active ]]; then
+ systemctl stop authentik-ldap
+ fi
+ if [[ $(systemctl is-active authentik-rac) == active ]]; then
+ systemctl stop authentik-rac
+ fi
+ if [[ $(systemctl is-active authentik-radius) == active ]]; then
+ systemctl stop authentik-radius
+ fi
msg_ok "Stopped Services"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
- msg_info "Configuring rust"
- cd /opt/authentik
- $STD rustup install
- $STD rustup default "$(sed -n 's/channel = "\(.*\)"/\1/p' rust-toolchain.toml)"
- msg_ok "Configured rust"
+ msg_info "Configuring rust"
+ cd /opt/authentik
+ $STD rustup install
+ $STD rustup default "$(sed -n 's/channel = "\(.*\)"/\1/p' rust-toolchain.toml)"
+ msg_ok "Configured rust"
- msg_info "Updating web"
+ msg_info "Updating web"
cd /opt/authentik/web
export NODE_ENV="production"
$STD npm install
@@ -99,18 +99,18 @@ function update_script() {
export CC="$(arch_resolve "x86_64" "aarch64")-linux-gnu-gcc"
$STD go mod download
$STD go build -o /opt/authentik/authentik-server ./cmd/server
- $STD go build -o /opt/authentik/ldap ./cmd/ldap
- $STD go build -o /opt/authentik/rac ./cmd/rac
- $STD go build -o /opt/authentik/radius ./cmd/radius
+ $STD go build -o /opt/authentik/ldap ./cmd/ldap
+ $STD go build -o /opt/authentik/rac ./cmd/rac
+ $STD go build -o /opt/authentik/radius ./cmd/radius
msg_ok "Updated go proxy"
- msg_info "Building worker"
- export AWS_LC_FIPS_SYS_CC="clang"
- cd /opt/authentik
- $STD cargo build --package authentik --no-default-features --features core --locked --release --jobs 1
- cp ./target/release/authentik /opt/authentik/authentik-worker
- rm -r ./target
- msg_ok "Built worker"
+ msg_info "Building worker"
+ export AWS_LC_FIPS_SYS_CC="clang"
+ cd /opt/authentik
+ $STD cargo build --package authentik --no-default-features --features core --locked --release --jobs 1
+ cp ./target/release/authentik /opt/authentik/authentik-worker
+ rm -r ./target
+ msg_ok "Built worker"
msg_info "Updating python server"
export UV_NO_BINARY_PACKAGE="cryptography lxml python-kadmin-rs xmlsec"
@@ -125,26 +125,26 @@ function update_script() {
msg_ok "Updated python server"
if [[ $MAJOR == 2026 && $MINOR -lt 5 ]]; then
- msg_info "Updating Worker and Server config"
- cp /etc/authentik/config.yml /etc/authentik/config.bak
- yq -i ".postgresql.conn_max_age = 0" /etc/authentik/config.yml
- yq -i ".postgresql.conn_health_checks = false" /etc/authentik/config.yml
- yq -i '.listen.debug_tokio = "[::]:6669"' /etc/authentik/config.yml
- yq -i '.log.rust_log.console_subscriber = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.h2 = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.hyper_util = "warn"' /etc/authentik/config.yml
- yq -i '.log.rust_log.mio = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.notify = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.reqwest = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.runtime = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.rustls = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.sqlx = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.sqlx_postgres = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.tokio = "info"' /etc/authentik/config.yml
- yq -i '.log.rust_log.tungstenite = "info"' /etc/authentik/config.yml
- yq -i ".web.workers = 2" /etc/authentik/config.yml
- mv /etc/default/authentik /etc/default/authentik.bak
- cat </etc/default/authentik-server
+ msg_info "Updating Worker and Server config"
+ cp /etc/authentik/config.yml /etc/authentik/config.bak
+ yq -i ".postgresql.conn_max_age = 0" /etc/authentik/config.yml
+ yq -i ".postgresql.conn_health_checks = false" /etc/authentik/config.yml
+ yq -i ".listen.debug_tokio = \"[::]:6669\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.console_subscriber = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.h2 = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.hyper_util = \"warn\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.mio = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.notify = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.reqwest = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.runtime = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.rustls = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.sqlx = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.sqlx_postgres = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.tokio = \"info\"" /etc/authentik/config.yml
+ yq -i ".log.rust_log.tungstenite = \"info\"" /etc/authentik/config.yml
+ yq -i ".web.workers = 2" /etc/authentik/config.yml
+ mv /etc/default/authentik /etc/default/authentik.bak
+ cat </etc/default/authentik-server
TMPDIR=/dev/shm/
UV_LINK_MODE=copy
UV_PYTHON_DOWNLOADS=0
@@ -159,7 +159,7 @@ AUTHENTIK_LISTEN__HTTP="[::]:9000"
AUTHENTIK_LISTEN__HTTPS="[::]:9443"
AUTHENTIK_LISTEN__METRICS="[::]:9300"
EOF
- cat </etc/default/authentik-worker
+ cat </etc/default/authentik-worker
TMPDIR=/dev/shm/
UV_LINK_MODE=copy
UV_PYTHON_DOWNLOADS=0
@@ -174,11 +174,11 @@ AUTHENTIK_LISTEN__HTTP="[::]:8000"
AUTHENTIK_LISTEN__HTTPS="[::]:8443"
AUTHENTIK_LISTEN__METRICS="[::]:8300"
EOF
- msg_ok "Updated Worker and Server config!"
- msg_warn "Please check /etc/default/authentik-worker and /etc/default/authentik-server config files for port configurations!"
+ msg_ok "Updated Worker and Server config!"
+ msg_warn "Please check /etc/default/authentik-worker and /etc/default/authentik-server config files for port configurations!"
- msg_info "Updating services"
- cat </etc/systemd/system/authentik-server.service
+ msg_info "Updating services"
+ cat </etc/systemd/system/authentik-server.service
[Unit]
Description=authentik Go Server (API Gateway)
After=network.target
@@ -198,7 +198,7 @@ EnvironmentFile=/etc/default/authentik-server
WantedBy=multi-user.target
EOF
- cat </etc/systemd/system/authentik-worker.service
+ cat </etc/systemd/system/authentik-worker.service
[Unit]
Description=authentik Worker
After=network.target postgresql.service
@@ -217,21 +217,21 @@ RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
- systemctl daemon-reload
- msg_ok "Updated services"
- fi
+ systemctl daemon-reload
+ msg_ok "Updated services"
+ fi
fi
msg_info "Starting Services"
systemctl start authentik-server authentik-worker
if [[ $(systemctl is-enabled authentik-ldap) == enabled ]]; then
- systemctl start authentik-ldap
+ systemctl start authentik-ldap
fi
if [[ $(systemctl is-enabled authentik-rac) == enabled ]]; then
- systemctl start authentik-rac
+ systemctl start authentik-rac
fi
if [[ $(systemctl is-enabled authentik-radius) == enabled ]]; then
- systemctl start authentik-radius
+ systemctl start authentik-radius
fi
msg_ok "Started Services"
msg_ok "Updated successfully!"
@@ -270,5 +270,5 @@ 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}:9443${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:9443${CL}"
diff --git a/ct/babybuddy.sh b/ct/babybuddy.sh
index b718a42ef..29fc7703a 100644
--- a/ct/babybuddy.sh
+++ b/ct/babybuddy.sh
@@ -40,8 +40,7 @@ function update_script() {
create_backup /opt/babybuddy/babybuddy/settings/production.py
msg_info "Cleaning old files"
- cd /opt/babybuddy || exit
- find . -mindepth 1 -maxdepth 1 ! -name '.venv' -exec rm -rf -- {} +
+ find . -mindepth 1 -maxdepth 1 ! -name '.venv' -exec rm -rf {} +
msg_ok "Cleaned old files"
fetch_and_deploy_gh_release "babybuddy" "babybuddy/babybuddy" "tarball"
@@ -52,7 +51,6 @@ function update_script() {
source .venv/bin/activate
$STD uv pip install -r requirements.txt
export DJANGO_SETTINGS_MODULE=babybuddy.settings.production
- $STD python manage.py makemigrations
$STD python manage.py migrate
msg_ok "Updated ${APP}"
diff --git a/ct/baserow.sh b/ct/baserow.sh
index 836ca4840..fa0d044db 100644
--- a/ct/baserow.sh
+++ b/ct/baserow.sh
@@ -71,5 +71,5 @@ 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}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/beaverhabits.sh b/ct/beaverhabits.sh
deleted file mode 100644
index 168be42d4..000000000
--- a/ct/beaverhabits.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/daya0576/beaverhabits
-
-APP="BeaverHabits"
-var_tags="${var_tags:-habits;tracking;productivity}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-1024}"
-var_disk="${var_disk:-4}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-13}"
-var_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/beaverhabits ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "beaverhabits" "daya0576/beaverhabits"; then
- msg_info "Stopping Service"
- systemctl stop beaverhabits
- msg_ok "Stopped Service"
-
- create_backup /opt/beaverhabits/.user
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "beaverhabits" "daya0576/beaverhabits" "tarball"
-
- msg_info "Syncing Dependencies"
- cd /opt/beaverhabits
- $STD uv sync --no-dev
- msg_ok "Synced Dependencies"
-
- restore_backup
-
- msg_info "Starting Service"
- systemctl start beaverhabits
- 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}:8080/register{CL}"
diff --git a/ct/birdnet-go.sh b/ct/birdnet-go.sh
index 6319219f9..39db9ca1f 100644
--- a/ct/birdnet-go.sh
+++ b/ct/birdnet-go.sh
@@ -37,7 +37,7 @@ function update_script() {
systemctl stop birdnet
msg_ok "Stopped Service"
- fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve)*.tar.gz"
+ fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve).tar.gz"
msg_info "Deploying Binary"
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
diff --git a/ct/bookorbit.sh b/ct/bookorbit.sh
index 7b0e95c13..16e330e24 100644
--- a/ct/bookorbit.sh
+++ b/ct/bookorbit.sh
@@ -75,5 +75,5 @@ 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}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/clickhouse.sh b/ct/clickhouse.sh
index 966dffa39..a0e49e619 100644
--- a/ct/clickhouse.sh
+++ b/ct/clickhouse.sh
@@ -41,5 +41,5 @@ 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}:8123${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8123${CL}"
diff --git a/ct/cliproxyapi.sh b/ct/cliproxyapi.sh
index 40f9f2b1f..cffa0fc17 100644
--- a/ct/cliproxyapi.sh
+++ b/ct/cliproxyapi.sh
@@ -36,12 +36,8 @@ function update_script() {
systemctl stop cliproxyapi
msg_ok "Stopped CLIProxyAPI"
- create_backup /opt/cliproxyapi/config.yaml
-
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cliproxyapi" "router-for-me/CLIProxyAPI" "prebuild" "latest" "/opt/cliproxyapi" "CLIProxyAPI_*_linux_$(arch_resolve "amd64" "aarch64").tar.gz"
- restore_backup
-
msg_info "Starting CLIProxyAPI"
systemctl start cliproxyapi
msg_ok "Started CLIProxyAPI"
@@ -56,5 +52,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Authenticate your AI providers via the management panel at:${CL}"
-echo -e "${GATEWAY}${BGN}http://${IP}:8317/management.html${CL}"
+echo -e "${INFO}${YW}Access it using the following URL:${CL}"
+echo -e "${GATEWAY}${BGN}http://${IP}:8317${CL}"
diff --git a/ct/cross-seed.sh b/ct/cross-seed.sh
index 7970657d8..a61f1274c 100644
--- a/ct/cross-seed.sh
+++ b/ct/cross-seed.sh
@@ -52,5 +52,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access cross-seed API using the following URL:${CL}"
+echo -e "${INFO}${YW} Access cross-seed API using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:2468${CL}"
diff --git a/ct/cyberchef.sh b/ct/cyberchef.sh
index d698f1c86..e50d1c7b3 100644
--- a/ct/cyberchef.sh
+++ b/ct/cyberchef.sh
@@ -26,8 +26,8 @@ function update_script() {
check_container_resources
if [[ ! -d /opt/cyberchef ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
+ msg_error "No ${APP} Installation Found!"
+ exit
fi
if check_for_gh_release "cyberchef" "gchq/CyberChef"; then
@@ -58,5 +58,5 @@ 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}${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/docmost.sh b/ct/docmost.sh
index 1c6271c98..c3392c585 100644
--- a/ct/docmost.sh
+++ b/ct/docmost.sh
@@ -39,6 +39,7 @@ function update_script() {
create_backup /opt/docmost/.env \
/opt/docmost/data
+
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
restore_backup
@@ -53,11 +54,9 @@ function update_script() {
sed -i '/^@Module({$/i @Global()' /opt/docmost/apps/server/src/core/core.module.ts
fi
- msg_info "Configuring Docmost"
- cd /opt/docmost
$STD pnpm install --force
$STD pnpm build
- msg_ok "Configured Docmost"
+ msg_ok "Updated ${APP}"
msg_info "Starting Service"
systemctl start docmost
diff --git a/ct/docuseal.sh b/ct/docuseal.sh
index 9fbdca313..d856d1694 100644
--- a/ct/docuseal.sh
+++ b/ct/docuseal.sh
@@ -35,8 +35,6 @@ function update_script() {
systemctl stop docuseal docuseal-sidekiq
msg_ok "Stopped Services"
- ensure_dependencies libleptonica-dev libleptonica6
-
create_backup /opt/docuseal/.env \
/opt/docuseal/data
diff --git a/ct/endurain.sh b/ct/endurain.sh
index cdfd6eb0a..934532aea 100644
--- a/ct/endurain.sh
+++ b/ct/endurain.sh
@@ -34,22 +34,31 @@ function update_script() {
systemctl stop endurain
msg_ok "Stopped Service"
- create_backup /opt/endurain/.env /opt/endurain/frontend/dist/env.js
+ msg_info "Creating Backup"
+ cp /opt/endurain/.env /opt/endurain.env
+ cp /opt/endurain/frontend/dist/env.js /opt/endurain.env.js
+ msg_ok "Created Backup"
+
CLEAN_INSTALL=1 fetch_and_deploy_codeberg_release "endurain" "endurain-project/endurain" "tarball" "latest" "/opt/endurain"
msg_info "Preparing Update"
cd /opt/endurain
- rm -rf /opt/endurain/{docs,example.env,screenshot_01.png} /opt/endurain/docker* /opt/endurain/*.yml
+ rm -rf \
+ /opt/endurain/{docs,example.env,screenshot_01.png} \
+ /opt/endurain/docker* \
+ /opt/endurain/*.yml
+ cp /opt/endurain.env /opt/endurain/.env
+ rm /opt/endurain.env
msg_ok "Prepared Update"
msg_info "Updating Frontend"
cd /opt/endurain/frontend
$STD npm ci
$STD npm run build
+ cp /opt/endurain.env.js /opt/endurain/frontend/dist/env.js
+ rm /opt/endurain.env.js
msg_ok "Updated Frontend"
- restore_backup
-
msg_info "Updating Backend"
cd /opt/endurain/backend
UV_VERSION=$(grep -Po 'required-version\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null || echo "0.11.18")
diff --git a/ct/esphome.sh b/ct/esphome.sh
index 086be0e83..4dcf1ea06 100644
--- a/ct/esphome.sh
+++ b/ct/esphome.sh
@@ -28,7 +28,6 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
- ensure_dependencies libusb-1.0-0
msg_info "Stopping Service"
systemctl stop esphome-device-builder 2>/dev/null || true
diff --git a/ct/etherpad.sh b/ct/etherpad.sh
index df7cd61bf..f5a63852d 100755
--- a/ct/etherpad.sh
+++ b/ct/etherpad.sh
@@ -61,5 +61,5 @@ 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}:9001${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9001${CL}"
diff --git a/ct/excalidash.sh b/ct/excalidash.sh
index 09a265fcd..07f2f1764 100644
--- a/ct/excalidash.sh
+++ b/ct/excalidash.sh
@@ -75,5 +75,5 @@ 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}:6767${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:6767${CL}"
diff --git a/ct/feishin.sh b/ct/feishin.sh
index dec1ece1b..4f3f8cd63 100644
--- a/ct/feishin.sh
+++ b/ct/feishin.sh
@@ -75,5 +75,5 @@ 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}:9180${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9180${CL}"
diff --git a/ct/fileflows.sh b/ct/fileflows.sh
index 3f72cef69..1f33d2dd0 100644
--- a/ct/fileflows.sh
+++ b/ct/fileflows.sh
@@ -31,83 +31,28 @@ function update_script() {
exit
fi
- local proceed=false
+ update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable)
+ if [[ "${update_available}" == "true" ]]; then
+ msg_info "Stopping Service"
+ systemctl --all stop 'fileflows*'
+ msg_info "Stopped Service"
- if systemctl list-unit-files 'fileflows.service' --no-legend 2>/dev/null | grep -q '^fileflows\.service'; then
- tmp=$(mktemp)
- http_code=$(curl -sSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' -o "$tmp" -w '%{http_code}' 2>/dev/null) || http_code="000"
- if [[ "$http_code" == "200" ]]; then
- update_available=$(jq -r '.UpdateAvailable // false' "$tmp" 2>/dev/null)
- rm -f "$tmp"
- if [[ "${update_available}" == "true" ]]; then
- proceed=true
- else
- msg_ok "No update required. ${APP} is already at latest version"
- exit
- fi
- else
- rm -f "$tmp"
- if [[ "$http_code" == "401" ]]; then
- msg_warn "Could not check for updates: API returned 401 (security may be enabled)."
- else
- msg_warn "Could not check for updates: API unreachable (HTTP ${http_code})."
- fi
- if [[ "${FORCE_UPDATE:-}" == "1" ]]; then
- proceed=true
- else
- read -r -p "${TAB3}Force update without version check? [y/N]: " CONFIRM
- if [[ "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
- proceed=true
- else
- msg_error "Update aborted."
- exit
- fi
- fi
- fi
+ msg_info "Creating Backup"
+ ls /opt/*.tar.gz &>/dev/null && rm -f /opt/*.tar.gz
+ backup_filename="/opt/${APP}_backup_$(date +%F).tar.gz"
+ tar -czf "$backup_filename" -C /opt/fileflows Data
+ msg_ok "Backup Created"
+
+ fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
+
+ msg_info "Starting Service"
+ systemctl --all start 'fileflows*'
+ msg_ok "Started Service"
+ msg_ok "Updated successfully!"
else
- proceed=true
+ msg_ok "No update required. ${APP} is already at latest version"
fi
- if [[ "$proceed" != "true" ]]; then
- exit
- fi
-
- msg_info "Stopping Service"
- systemctl --all stop 'fileflows*'
- msg_ok "Stopped Service"
-
- msg_info "Creating Backup"
- ls /opt/*.tar.gz &>/dev/null && rm -f /opt/*.tar.gz
- backup_filename="/opt/${APP}_backup_$(date +%F).tar.gz"
- tar -czf "$backup_filename" -C /opt/fileflows Data
- msg_ok "Backup Created"
-
- msg_info "Ensuring ASP.NET Core Runtime"
- if [[ "$(arch_resolve)" == "arm64" ]]; then
- if [[ ! -x /usr/lib/dotnet10/dotnet ]]; then
- curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
- $STD bash /tmp/dotnet-install.sh --channel 10.0 --runtime aspnetcore --install-dir /usr/lib/dotnet10
- ln -sf /usr/lib/dotnet10/dotnet /usr/bin/dotnet
- rm -f /tmp/dotnet-install.sh
- fi
- elif ! is_package_installed "aspnetcore-runtime-10.0"; then
- $STD apt remove -y aspnetcore-runtime-8.0 aspnetcore-runtime-9.0 2>/dev/null || true
- setup_deb822_repo \
- "microsoft" \
- "https://packages.microsoft.com/keys/microsoft-2025.asc" \
- "https://packages.microsoft.com/debian/13/prod/" \
- "trixie"
- $STD apt install -y aspnetcore-runtime-10.0
- fi
- msg_ok "Ensured ASP.NET Core Runtime"
-
- fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
-
- msg_info "Starting Service"
- systemctl --all start 'fileflows*'
- msg_ok "Started Service"
- msg_ok "Updated successfully!"
-
exit
}
diff --git a/ct/fireshare.sh b/ct/fireshare.sh
index f10be013b..296cb6c01 100644
--- a/ct/fireshare.sh
+++ b/ct/fireshare.sh
@@ -35,22 +35,12 @@ function update_script() {
systemctl stop fireshare
msg_ok "Stopped Service"
- create_backup /opt/fireshare/fireshare.env
+ mv /opt/fireshare/fireshare.env /opt
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "fireshare" "ShaneIsrael/fireshare" "tarball"
- restore_backup
+ mv /opt/fireshare.env /opt/fireshare
rm -f /usr/local/bin/fireshare
- if ! grep -q "__FIRESHARE_PORT__" /etc/nginx/nginx.conf; then
- cp /opt/fireshare/app/nginx/prod.conf /etc/nginx/nginx.conf
- sed -i 's|root /processed/|root /opt/fireshare-processed/|g' /etc/nginx/nginx.conf
- sed -i 's/^user[[:space:]]\+nginx;/user root;/' /etc/nginx/nginx.conf
- sed -i 's|root[[:space:]]\+/app/build;|root /opt/fireshare/app/client/build;|' /etc/nginx/nginx.conf
- sed -i 's/__FIRESHARE_PORT__/80/g' /etc/nginx/nginx.conf
- cp /opt/fireshare/app/nginx/error.html /etc/nginx/
- cp /opt/fireshare/app/nginx/api_unavailable.html /etc/nginx/
- fi
- msg_info "Configuring Fireshare"
-
+ msg_info "Updating Fireshare"
cd /opt/fireshare
$STD uv venv --clear
$STD .venv/bin/python -m ensurepip --upgrade
@@ -63,10 +53,13 @@ function update_script() {
export VIDEO_DIRECTORY=/opt/fireshare-videos
export PROCESSED_DIRECTORY=/opt/fireshare-processed
$STD uv run flask db upgrade
+
+ msg_info "Building Fireshare Client"
cd /opt/fireshare/app/client
$STD npm install
$STD npm run build
- msg_ok "Configured Fireshare"
+ msg_ok "Built Fireshare Client"
+ msg_ok "Updated Fireshare"
msg_info "Starting Service"
systemctl start fireshare
diff --git a/ct/flame.sh b/ct/flame.sh
index c903fcc4c..4378f4d10 100644
--- a/ct/flame.sh
+++ b/ct/flame.sh
@@ -36,7 +36,7 @@ function update_script() {
msg_ok "Stopped Service"
create_backup /opt/flame/.env \
- /opt/flame/data
+ /opt/flame/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "flame" "pawelmalak/flame" "tarball"
restore_backup
@@ -65,5 +65,5 @@ 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}:5005${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5005${CL}"
diff --git a/ct/flowiseai.sh b/ct/flowiseai.sh
new file mode 100644
index 000000000..7d4c6468e
--- /dev/null
+++ b/ct/flowiseai.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
+# Copyright (c) 2021-2026 tteck
+# Author: tteck (tteckster)
+# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
+# Source: https://flowiseai.com/ | Github: https://github.com/FlowiseAI/Flowise
+
+APP="FlowiseAI"
+var_tags="${var_tags:-low-code}"
+var_disk="${var_disk:-10}"
+var_cpu="${var_cpu:-4}"
+var_ram="${var_ram:-4096}"
+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 [[ ! -f /etc/systemd/system/flowise.service ]]; then
+ msg_error "No ${APP} Installation Found!"
+ exit
+ fi
+
+ NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
+
+ msg_info "Updating FlowiseAI (this may take some time)"
+ systemctl stop flowise
+ $STD pnpm add -g flowise
+ if grep -q 'ExecStart=npx flowise start' /etc/systemd/system/flowise.service; then
+ sed -i 's|ExecStart=npx flowise start|ExecStart=flowise start|' /etc/systemd/system/flowise.service
+ systemctl daemon-reload
+ fi
+ systemctl start flowise
+ msg_ok "Updated FlowiseAI"
+ msg_ok "Updated successfully!"
+ exit
+}
+
+start
+build_container
+description
+
+msg_ok "Completed successfully!\n"
+echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
+echo -e "${INFO}${YW}Access it using the following URL:${CL}"
+echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/fmd-server.sh b/ct/fmd-server.sh
index 0c8b75293..76a7bd96d 100644
--- a/ct/fmd-server.sh
+++ b/ct/fmd-server.sh
@@ -60,5 +60,5 @@ 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}:8443${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}"
diff --git a/ct/forgejo-runner.sh b/ct/forgejo-runner.sh
deleted file mode 100644
index 7c7c1774f..000000000
--- a/ct/forgejo-runner.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Simon Friedrich (lengschder97)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://forgejo.org/
-
-APP="Forgejo-Runner"
-var_tags="${var_tags:-ci}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-var_disk="${var_disk:-8}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-13}"
-var_arm64="${var_arm64:-yes}"
-var_unprivileged="${var_unprivileged:-1}"
-var_nesting="${var_nesting:-1}"
-var_keyctl="${var_keyctl:-1}"
-
-export var_forgejo_instance="${var_forgejo_instance:-}"
-export var_forgejo_runner_token="${var_forgejo_runner_token:-}"
-export var_runner_labels="${var_runner_labels:-}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -f /usr/local/bin/forgejo-runner ]]; then
- msg_error "No ${APP} installation found!"
- exit 1
- fi
-
- RELEASE=$(curl -fsSL https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | grep -oP '"tag_name":\s*"\K[^"]+' | sed 's/^v//')
- if [[ "${RELEASE}" == "$(cat ~/.forgejo-runner 2>/dev/null)" ]]; then
- msg_ok "No update required. ${APP} is already at v${RELEASE}"
- exit
- fi
-
- msg_info "Stopping Services"
- systemctl stop forgejo-runner
- msg_ok "Stopped Services"
-
- msg_info "Updating Forgejo Runner to v${RELEASE}"
- curl -fsSL "https://code.forgejo.org/forgejo/runner/releases/download/v${RELEASE}/forgejo-runner-${RELEASE}-linux-$(arch_resolve)" -o /usr/local/bin/forgejo-runner
- chmod +x /usr/local/bin/forgejo-runner
- echo "${RELEASE}" >~/.forgejo-runner
- msg_ok "Updated Forgejo Runner"
-
- msg_info "Starting Services"
- systemctl start forgejo-runner
- msg_ok "Started Services"
- msg_ok "Updated successfully!"
- exit
-}
-
-if [[ -n "${mode:-}" ]]; then
- if [[ -z "${var_forgejo_instance:-}" ]]; then
- msg_error "var_forgejo_instance is required for unattended installs."
- exit 1
- fi
- if [[ -z "${var_forgejo_runner_token:-}" ]]; then
- msg_error "var_forgejo_runner_token is required for unattended installs."
- exit 1
- fi
-fi
-
-start
-build_container
-description
-
-msg_ok "Completed successfully!\n"
-echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW} After first boot, check your Forgejo Instance for the new Runner.${CL}"
diff --git a/ct/grav.sh b/ct/grav.sh
deleted file mode 100644
index 9271a029e..000000000
--- a/ct/grav.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Raffaele (rafspiny)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://getgrav.org/
-
-APP="Grav"
-var_tags="${var_tags:-cms}"
-var_cpu="${var_cpu:-1}"
-var_ram="${var_ram:-2048}"
-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/grav" ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "grav" "getgrav/grav"; then
- msg_info "Creating Backup"
- cd /opt/grav
- bin/grav backup -nq
- msg_ok "Backup Created"
- bin/gpm self-upgrade -y
- cd -
- chown -R www-data:www-data /opt/grav
- msg_ok "Update Successful"
- 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}:80${CL}"
diff --git a/ct/headers/affine b/ct/headers/affine
deleted file mode 100644
index 0e1d759f0..000000000
--- a/ct/headers/affine
+++ /dev/null
@@ -1,6 +0,0 @@
- ___ _____________ _ ________
- / | / ____/ ____(_) | / / ____/
- / /| | / /_ / /_ / / |/ / __/
- / ___ |/ __/ / __/ / / /| / /___
-/_/ |_/_/ /_/ /_/_/ |_/_____/
-
diff --git a/ct/headers/beaverhabits b/ct/headers/beaverhabits
deleted file mode 100644
index 0a11d4242..000000000
--- a/ct/headers/beaverhabits
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ __ __ __ _ __
- / __ )___ ____ __ _____ _____/ / / /___ _/ /_ (_) /______
- / __ / _ \/ __ `/ | / / _ \/ ___/ /_/ / __ `/ __ \/ / __/ ___/
- / /_/ / __/ /_/ /| |/ / __/ / / __ / /_/ / /_/ / / /_(__ )
-/_____/\___/\__,_/ |___/\___/_/ /_/ /_/\__,_/_.___/_/\__/____/
-
diff --git a/ct/headers/flowiseai b/ct/headers/flowiseai
new file mode 100644
index 000000000..7011f22b4
--- /dev/null
+++ b/ct/headers/flowiseai
@@ -0,0 +1,6 @@
+ ________ _ ___ ____
+ / ____/ /___ _ __(_)_______ / | / _/
+ / /_ / / __ \ | /| / / / ___/ _ \/ /| | / /
+ / __/ / / /_/ / |/ |/ / (__ ) __/ ___ |_/ /
+/_/ /_/\____/|__/|__/_/____/\___/_/ |_/___/
+
diff --git a/ct/headers/forgejo-runner b/ct/headers/forgejo-runner
deleted file mode 100644
index 5be4a07fe..000000000
--- a/ct/headers/forgejo-runner
+++ /dev/null
@@ -1,6 +0,0 @@
- ______ _ ____
- / ____/___ _________ ____ (_)___ / __ \__ ______ ____ ___ _____
- / /_ / __ \/ ___/ __ `/ _ \ / / __ \______/ /_/ / / / / __ \/ __ \/ _ \/ ___/
- / __/ / /_/ / / / /_/ / __/ / / /_/ /_____/ _, _/ /_/ / / / / / / / __/ /
-/_/ \____/_/ \__, /\___/_/ /\____/ /_/ |_|\__,_/_/ /_/_/ /_/\___/_/
- /____/ /___/
diff --git a/ct/headers/grav b/ct/headers/grav
deleted file mode 100644
index 3e041ab1e..000000000
--- a/ct/headers/grav
+++ /dev/null
@@ -1,6 +0,0 @@
- ______
- / ____/________ __ __
- / / __/ ___/ __ `/ | / /
-/ /_/ / / / /_/ /| |/ /
-\____/_/ \__,_/ |___/
-
diff --git a/ct/headers/invidious b/ct/headers/invidious
deleted file mode 100644
index c858744dd..000000000
--- a/ct/headers/invidious
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ _ ___
- / _/___ _ __(_)___/ (_)___ __ _______
- / // __ \ | / / / __ / / __ \/ / / / ___/
- _/ // / / / |/ / / /_/ / / /_/ / /_/ (__ )
-/___/_/ /_/|___/_/\__,_/_/\____/\__,_/____/
-
diff --git a/ct/headers/leafwiki b/ct/headers/leafwiki
deleted file mode 100644
index dcfacbddf..000000000
--- a/ct/headers/leafwiki
+++ /dev/null
@@ -1,6 +0,0 @@
- __ _____ ___ __ _
- / / ___ ____ _/ __/ | / (_) /__(_)
- / / / _ \/ __ `/ /_ | | /| / / / //_/ /
- / /___/ __/ /_/ / __/ | |/ |/ / / ,< / /
-/_____/\___/\__,_/_/ |__/|__/_/_/|_/_/
-
diff --git a/ct/headers/localagi b/ct/headers/localagi
deleted file mode 100644
index c47da9aac..000000000
--- a/ct/headers/localagi
+++ /dev/null
@@ -1,6 +0,0 @@
- __ _____ __________
- / / ____ _________ _/ / | / ____/ _/
- / / / __ \/ ___/ __ `/ / /| |/ / __ / /
- / /___/ /_/ / /__/ /_/ / / ___ / /_/ // /
-/_____/\____/\___/\__,_/_/_/ |_\____/___/
-
diff --git a/ct/headers/nexterm b/ct/headers/nexterm
deleted file mode 100644
index 7d52bc561..000000000
--- a/ct/headers/nexterm
+++ /dev/null
@@ -1,6 +0,0 @@
- _ __ __
- / | / /__ _ __/ /____ _________ ___
- / |/ / _ \| |/_/ __/ _ \/ ___/ __ `__ \
- / /| / __/> /_/ __/ / / / / / / /
-/_/ |_/\___/_/|_|\__/\___/_/ /_/ /_/ /_/
-
diff --git a/ct/headers/notediscovery b/ct/headers/notediscovery
deleted file mode 100644
index df51d962d..000000000
--- a/ct/headers/notediscovery
+++ /dev/null
@@ -1,6 +0,0 @@
- _ __ __ ____ _
- / | / /___ / /____ / __ \(_)_____________ _ _____ _______ __
- / |/ / __ \/ __/ _ \/ / / / / ___/ ___/ __ \ | / / _ \/ ___/ / / /
- / /| / /_/ / /_/ __/ /_/ / (__ ) /__/ /_/ / |/ / __/ / / /_/ /
-/_/ |_/\____/\__/\___/_____/_/____/\___/\____/|___/\___/_/ \__, /
- /____/
diff --git a/ct/headers/oxicloud b/ct/headers/oxicloud
deleted file mode 100644
index b48c6ee29..000000000
--- a/ct/headers/oxicloud
+++ /dev/null
@@ -1,6 +0,0 @@
- ____ _ ________ __
- / __ \_ __(_) ____/ /___ __ ______/ /
- / / / / |/_/ / / / / __ \/ / / / __ /
-/ /_/ /> / /___/ / /_/ / /_/ / /_/ /
-\____/_/|_/_/\____/_/\____/\__,_/\__,_/
-
diff --git a/ct/headers/squid b/ct/headers/squid
deleted file mode 100644
index 3d826ef75..000000000
--- a/ct/headers/squid
+++ /dev/null
@@ -1,6 +0,0 @@
- _____ _ __
- / ___/____ ___ __(_)___/ /
- \__ \/ __ `/ / / / / __ /
- ___/ / /_/ / /_/ / / /_/ /
-/____/\__, /\__,_/_/\__,_/
- /_/
diff --git a/ct/headers/sync-in b/ct/headers/sync-in
deleted file mode 100644
index f5ae41c66..000000000
--- a/ct/headers/sync-in
+++ /dev/null
@@ -1,6 +0,0 @@
- _____ _
- / ___/__ ______ _____ (_)___
- \__ \/ / / / __ \/ ___/_____/ / __ \
- ___/ / /_/ / / / / /__/_____/ / / / /
-/____/\__, /_/ /_/\___/ /_/_/ /_/
- /____/
diff --git a/ct/headers/yuvomi b/ct/headers/yuvomi
deleted file mode 100644
index 3247d3dcc..000000000
--- a/ct/headers/yuvomi
+++ /dev/null
@@ -1,6 +0,0 @@
-__ __ _
-\ \/ /_ ___ ______ ____ ___ (_)
- \ / / / / | / / __ \/ __ `__ \/ /
- / / /_/ /| |/ / /_/ / / / / / / /
-/_/\__,_/ |___/\____/_/ /_/ /_/_/
-
diff --git a/ct/hev-socks5-server.sh b/ct/hev-socks5-server.sh
index b2a84616a..3b9ffe873 100644
--- a/ct/hev-socks5-server.sh
+++ b/ct/hev-socks5-server.sh
@@ -30,6 +30,7 @@ function update_script() {
exit
fi
+
if check_for_gh_release "hev-socks5-server" "heiher/hev-socks5-server"; then
msg_info "Stopping Service"
systemctl stop hev-socks5-server
@@ -51,6 +52,6 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access it with a SOCKS5 client using the following URL:${CL}"
+echo -e "${INFO}${YW} Access it with a SOCKS5 client using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}${IP}:1080${CL}"
echo -e "${INFO}${YW} and the credentials stored at /root/hev.creds${CL}"
diff --git a/ct/immich.sh b/ct/immich.sh
index 1ea66f467..77500920c 100644
--- a/ct/immich.sh
+++ b/ct/immich.sh
@@ -110,7 +110,7 @@ EOF
msg_ok "Image-processing libraries up to date"
fi
- RELEASE="v3.0.3"
+ RELEASE="v3.0.1"
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
@@ -124,9 +124,7 @@ EOF
systemctl stop immich-web
systemctl stop immich-ml
msg_ok "Stopped Services"
- VCHORD_RELEASE="1.1.1"
- PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
- PG_VERSION=${PG_VERSION:-16}
+ VCHORD_RELEASE="1.0.0"
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
# dead tuples in smart_search/face_search make the REINDEX below fail with
@@ -134,7 +132,7 @@ EOF
# while still on the old extension version, a post-upgrade vacuum errors instead
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) smart_search;"
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) face_search;"
- fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${PG_VERSION}-vchord_*_$(arch_resolve).deb"
+ fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-16-vchord_*_$(arch_resolve).deb"
systemctl restart postgresql
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vchord UPDATE;"
@@ -330,27 +328,6 @@ EOF
systemctl daemon-reload
fi
- # MickLesk temporary patch for HEIC thumbnail gen
- msg_info "Patching media.repository.js"
- MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
- if [[ -f "$MEDIA_REPO_JS" ]]; then
- python3 - <<'PY'
-from pathlib import Path
-p = Path('/opt/immich/app/dist/repositories/media.repository.js')
-s = p.read_text()
-old = "(0, sharp_1.default)(input).metadata()"
-new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
-if new in s:
- print('hotfix already there')
-elif old in s:
- p.write_text(s.replace(old, new, 1))
- print('hotfix applied')
-else:
- print('pattern not found, skipped')
-PY
- fi
- msg_ok "Patched media.repository.js"
-
# chown excluding upload dir contents (may be a mount with restricted permissions)
chown immich:immich "$INSTALL_DIR"
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
@@ -494,14 +471,13 @@ function compile_imagemagick() {
function compile_libvips() {
SOURCE=$SOURCE_DIR/libvips
- LIBVIPS_REVISION="e01a4797cabe77d457fdfa7d776b7a7e7ca6d6a7"
+ LIBVIPS_REVISION="3664cfc5dc2c5661288f5bf5a85ccc51c64c1626"
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
msg_info "Recompiling libvips"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBVIPS_REVISION"
- $STD git apply "$BASE_DIR"/server/sources/libvips-patches/0001-put-other-loaders-ahead-of-dcrawload.patch
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
cd build
$STD ninja install
diff --git a/ct/invidious.sh b/ct/invidious.sh
deleted file mode 100644
index b3b68a632..000000000
--- a/ct/invidious.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/iv-org/invidious
-
-APP="Invidious"
-var_tags="${var_tags:-streaming}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-4096}"
-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/invidious ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "Invidious" "iv-org/invidious"; then
- msg_info "Stopping services"
- $STD systemctl stop invidious-companion invidious
- msg_ok "Stopped services"
-
- create_backup /opt/invidious/config/config.yml
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious" "iv-org/invidious" "tarball" "latest" "/opt/invidious"
- if check_for_gh_release "Invidious-Companion" "iv-org/invidious-companion"; then
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious-Companion" "iv-org/invidious-companion" "prebuild" "latest" "/opt/invidious-companion" "invidious_companion-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
- fi
-
- msg_info "Rebuilding Invidious"
- cd /opt/invidious
- INVIDIOUS_VERSION="$(cat ~/.invidious 2>/dev/null || echo "unknown")"
- INVIDIOUS_VERSION="${INVIDIOUS_VERSION#v}"
- sed -i \
- -e "s~^\(\s*CURRENT_BRANCH\s*=\).*~\1 \"master\"~" \
- -e "s~^\(\s*CURRENT_COMMIT\s*=\).*~\1 \"\"~" \
- -e "s~^\(\s*CURRENT_VERSION\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
- -e "s~^\(\s*CURRENT_TAG\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
- -e "s~^\(\s*ASSET_COMMIT\s*=\).*~\1 \"\"~" \
- src/invidious.cr
- $STD make
- msg_ok "Rebuilt Invidious"
-
- restore_backup
-
- msg_info "Starting services"
- $STD systemctl start invidious invidious-companion
- msg_ok "Started services"
- msg_ok "Updated successfully!"
- fi
- exit
-}
-
-start
-build_container
-description
-
-msg_ok "Completed successfully!\n"
-echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access it using the following URL:${CL}"
-echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/iventoy.sh b/ct/iventoy.sh
index 89aac7813..441312c11 100644
--- a/ct/iventoy.sh
+++ b/ct/iventoy.sh
@@ -52,5 +52,5 @@ 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}:26000${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:26000${CL}"
diff --git a/ct/kiwix.sh b/ct/kiwix.sh
index ecde55d14..c66803e2e 100644
--- a/ct/kiwix.sh
+++ b/ct/kiwix.sh
@@ -37,12 +37,12 @@ function update_script() {
msg_ok "Updated Package Index"
CANDIDATE=$(apt-cache policy kiwix-tools | awk '/Candidate:/{print $2}')
- if [[ -z $CANDIDATE || $CANDIDATE == "(none)" ]]; then
+ if [[ -z "$CANDIDATE" || "$CANDIDATE" == "(none)" ]]; then
msg_error "No Candidate Version Found for kiwix-tools"
exit
fi
- if [[ $CURRENT == "$CANDIDATE" ]]; then
+ if [[ "$CURRENT" == "$CANDIDATE" ]]; then
echo "${CURRENT}" >/root/.kiwix
msg_ok "Already on latest version: ${CURRENT}"
exit
@@ -71,5 +71,5 @@ 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}:8080${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/koffan.sh b/ct/koffan.sh
index ec87a32b0..910070c7f 100644
--- a/ct/koffan.sh
+++ b/ct/koffan.sh
@@ -59,5 +59,5 @@ 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}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/kometa.sh b/ct/kometa.sh
index 965076f8c..b0a9e0caa 100644
--- a/ct/kometa.sh
+++ b/ct/kometa.sh
@@ -83,5 +83,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access Kometa Quickstart:${CL}"
+echo -e "${INFO}${YW} Access Kometa Quickstart:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:7171${CL}"
diff --git a/ct/leafwiki.sh b/ct/leafwiki.sh
deleted file mode 100644
index 20633cb57..000000000
--- a/ct/leafwiki.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/perber/leafwiki
-
-APP="LeafWiki"
-var_tags="${var_tags:-wiki;markdown;notes}"
-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 [[ ! -f /usr/local/bin/leafwiki ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "leafwiki" "perber/leafwiki"; then
- msg_info "Stopping Service"
- systemctl stop leafwiki
- msg_ok "Stopped Service"
-
- create_backup /opt/leafwiki/data
- fetch_and_deploy_gh_release "leafwiki" "perber/leafwiki" "singlefile" "latest" "/usr/local/bin" "leafwiki-v*-linux-$(arch_resolve)"
- restore_backup
-
- msg_info "Starting Service"
- systemctl start leafwiki
- 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}:8080${CL}"
diff --git a/ct/localagi.sh b/ct/localagi.sh
deleted file mode 100644
index b2f9fbe91..000000000
--- a/ct/localagi.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: BillyOutlast
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/mudler/LocalAGI
-
-APP="LocalAGI"
-var_tags="${var_tags:-ai}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-4096}"
-var_disk="${var_disk:-20}"
-var_os="${var_os:-debian}"
-var_version="${var_version:-13}"
-var_arm64="${var_arm64:-no}"
-var_unprivileged="${var_unprivileged:-1}"
-var_gpu="${var_gpu:-no}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -d /opt/localagi ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "localagi" "mudler/LocalAGI"; then
- msg_info "Stopping Service"
- systemctl stop localagi
- msg_ok "Stopped Service"
-
- create_backup /opt/localagi/.env
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "localagi" "mudler/LocalAGI" "tarball" "latest" "/opt/localagi"
- restore_backup
-
- msg_info "Building LocalAGI"
- cd /opt/localagi/webui/react-ui
- $STD bun install
- $STD bun run build
- cd /opt/localagi
- $STD go build -o /usr/local/bin/localagi
- msg_ok "Updated LocalAGI successfully"
-
- msg_info "Starting Service"
- systemctl start localagi
- msg_ok "Started Service"
- msg_ok "Updated successfully!"
- exit
- 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}"
diff --git a/ct/loki.sh b/ct/loki.sh
index d1c6a2570..2156eac5a 100644
--- a/ct/loki.sh
+++ b/ct/loki.sh
@@ -37,38 +37,38 @@ function update_script() {
case $CHOICE in
1)
- msg_info "Stopping Loki"
- systemctl stop loki
- msg_ok "Stopped Loki"
+ msg_info "Stopping Loki"
+ systemctl stop loki
+ msg_ok "Stopped Loki"
- msg_info "Updating Loki"
- $STD apt update
- $STD apt install -y --only-upgrade loki
- msg_ok "Updated Loki"
+ msg_info "Updating Loki"
+ $STD apt update
+ $STD apt install -y --only-upgrade loki
+ msg_ok "Updated Loki"
- msg_info "Starting Loki"
- systemctl start loki
- msg_ok "Started Loki"
- msg_ok "Updated successfully!"
- exit
- ;;
- 2)
- msg_info "Configuring Loki to listen on 0.0.0.0"
- sed -i 's/http_listen_address:.*/http_listen_address: 0.0.0.0/' /etc/loki/config.yml
- sed -i 's/http_listen_port:.*/http_listen_port: 3100/' /etc/loki/config.yml
- systemctl restart loki
- msg_ok "Configured Loki to listen on 0.0.0.0"
- exit
- ;;
- 3)
- msg_info "Configuring Loki to listen on ${LOCAL_IP}"
- sed -i "s/http_listen_address:.*/http_listen_address: $LOCAL_IP/" /etc/loki/config.yml
- sed -i 's/http_listen_port:.*/http_listen_port: 3100/' /etc/loki/config.yml
- systemctl restart loki
- msg_ok "Configured Loki to listen on ${LOCAL_IP}"
- exit
- ;;
- esac
+ msg_info "Starting Loki"
+ systemctl start loki
+ msg_ok "Started Loki"
+ msg_ok "Updated successfully!"
+ exit
+ ;;
+ 2)
+ msg_info "Configuring Loki to listen on 0.0.0.0"
+ sed -i 's/http_listen_address:.*/http_listen_address: 0.0.0.0/' /etc/loki/config.yml
+ sed -i 's/http_listen_port:.*/http_listen_port: 3100/' /etc/loki/config.yml
+ systemctl restart loki
+ msg_ok "Configured Loki to listen on 0.0.0.0"
+ exit
+ ;;
+ 3)
+ msg_info "Configuring Loki to listen on ${LOCAL_IP}"
+ sed -i "s/http_listen_address:.*/http_listen_address: $LOCAL_IP/" /etc/loki/config.yml
+ sed -i 's/http_listen_port:.*/http_listen_port: 3100/' /etc/loki/config.yml
+ systemctl restart loki
+ msg_ok "Configured Loki to listen on ${LOCAL_IP}"
+ exit
+ ;;
+ esac
exit 0
}
@@ -78,5 +78,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access loki using the following URL:${CL}"
+echo -e "${INFO}${YW} Access loki using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3100${CL}\n"
diff --git a/ct/lychee.sh b/ct/lychee.sh
index 7adfff87b..887d1f3ac 100644
--- a/ct/lychee.sh
+++ b/ct/lychee.sh
@@ -31,38 +31,33 @@ function update_script() {
fi
if check_for_gh_release "lychee" "LycheeOrg/Lychee"; then
- PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
-
msg_info "Stopping Services"
- systemctl stop caddy php${PHP_VER}-fpm
+ systemctl stop caddy
msg_ok "Stopped Services"
- create_backup /opt/lychee/.env \
- /opt/lychee/storage \
- /opt/lychee/public/uploads \
- /opt/lychee/public/dist
+ msg_info "Backing up Data"
+ cp /opt/lychee/.env /opt/lychee.env.bak
+ cp -r /opt/lychee/storage /opt/lychee_storage_backup
+ msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "lychee" "LycheeOrg/Lychee" "prebuild" "latest" "/opt/lychee" "Lychee.zip"
- restore_backup
+ msg_info "Restoring Data"
+ cp /opt/lychee.env.bak /opt/lychee/.env
+ rm -f /opt/lychee.env.bak
+ cp -r /opt/lychee_storage_backup/. /opt/lychee/storage
+ rm -rf /opt/lychee_storage_backup
+ msg_ok "Restored Data"
msg_info "Updating Application"
cd /opt/lychee
$STD php artisan migrate --force
- $STD php artisan config:clear
- $STD php artisan cache:clear
$STD php artisan optimize:clear
- $STD php artisan optimize
- chown -R www-data:www-data /opt/lychee
- chmod -R 775 /opt/lychee/storage /opt/lychee/bootstrap/cache \
- /opt/lychee/public/dist /opt/lychee/public/uploads
- if [[ "${VERBOSE:-no}" = "yes" ]]; then
- php artisan lychee:diagnostics || true
- fi
+ chmod -R 775 /opt/lychee/storage /opt/lychee/bootstrap/cache
msg_ok "Updated Application"
msg_info "Starting Services"
- systemctl start caddy php${PHP_VER}-fpm
+ systemctl start caddy
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
diff --git a/ct/lyrionmusicserver.sh b/ct/lyrionmusicserver.sh
index b14d0d791..8ef432b93 100644
--- a/ct/lyrionmusicserver.sh
+++ b/ct/lyrionmusicserver.sh
@@ -35,7 +35,7 @@ function update_script() {
DEB_URL=$(curl_with_retry 'https://lyrion.org/getting-started/' | grep -oP "]*href=\"\K[^\"]*${DEB_ARCH}\.deb(?=\"[^>]*>)" | head -n 1)
RELEASE=$(echo "$DEB_URL" | grep -oP "lyrionmusicserver_\K[0-9.]+(?=_${DEB_ARCH}\.deb)")
DEB_FILE="/tmp/lyrionmusicserver_${RELEASE}_${DEB_ARCH}.deb"
- if [[ ! -f /opt/lyrion_version.txt ]] || [[ ${RELEASE} != "$(cat /opt/lyrion_version.txt)" ]]; then
+ if [[ ! -f /opt/lyrion_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/lyrion_version.txt)" ]]; then
msg_info "Updating $APP to ${RELEASE}"
curl_with_retry "$DEB_URL" "$DEB_FILE"
$STD apt install "$DEB_FILE" -y
@@ -56,5 +56,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access the web interface at:${CL}"
+echo -e "${INFO}${YW} Access the web interface at:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:9000${CL}"
diff --git a/ct/matterjs-server.sh b/ct/matterjs-server.sh
index 0904c4974..65d53f5f5 100644
--- a/ct/matterjs-server.sh
+++ b/ct/matterjs-server.sh
@@ -31,10 +31,10 @@ function update_script() {
fi
NODE_VERSION="24" setup_nodejs
-
+
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
+ if [[ "$CURRENT" != "$LATEST" ]]; then
msg_info "Stopping Service"
systemctl stop matterjs-server
msg_ok "Stopped Service"
@@ -60,5 +60,5 @@ 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}:5580${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5580${CL}"
diff --git a/ct/n8n.sh b/ct/n8n.sh
index 658a19b6c..8f9cb483b 100644
--- a/ct/n8n.sh
+++ b/ct/n8n.sh
@@ -45,7 +45,7 @@ EOF
systemctl daemon-reload
fi
- $STD npm install -g n8n@latest
+ $STD npm install -g n8n@2.27.5
systemctl restart n8n
msg_ok "Updated n8n"
msg_ok "Updated successfully!"
diff --git a/ct/netbird.sh b/ct/netbird.sh
index 8359805be..336094791 100644
--- a/ct/netbird.sh
+++ b/ct/netbird.sh
@@ -44,5 +44,5 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access NetBird by entering the container and running:${CL}"
+echo -e "${INFO}${YW} Access NetBird by entering the container and running:${CL}"
echo -e "${GATEWAY}${BGN}netbird up${CL}"
diff --git a/ct/nexterm.sh b/ct/nexterm.sh
deleted file mode 100644
index dd67c4697..000000000
--- a/ct/nexterm.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Mathias Wagner (gnmyt)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://nexterm.dev/
-
-APP="Nexterm"
-var_tags="${var_tags:-server-management}"
-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}"
-
-header_info "$APP"
-variables
-color
-catch_errors
-
-function update_script() {
- header_info
- check_container_storage
- check_container_resources
-
- if [[ ! -f /opt/nexterm/server/nexterm-server ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "nexterm-engine" "gnmyt/Nexterm"; then
- msg_info "Stopping nexterm-engine"
- systemctl stop nexterm-engine
- msg_ok "Stopped nexterm-engine"
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-$(arch_resolve "x64" "arm64").tar.gz"
-
- msg_info "Starting nexterm-engine"
- systemctl start nexterm-engine
- msg_ok "Started nexterm-engine"
- fi
-
- if check_for_gh_release "nexterm-server" "gnmyt/Nexterm"; then
- msg_info "Stopping nexterm-server"
- systemctl stop nexterm-server
- msg_ok "Stopped nexterm-server"
-
- fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
-
- msg_info "Starting nexterm-server"
- systemctl start nexterm-server
- msg_ok "Started nexterm-server"
- 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}:6989${CL}"
diff --git a/ct/notediscovery.sh b/ct/notediscovery.sh
deleted file mode 100644
index 3b15fd0c7..000000000
--- a/ct/notediscovery.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/gamosoft/NoteDiscovery
-
-APP="NoteDiscovery"
-var_tags="${var_tags:-notes;wiki;knowledge-base}"
-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/notediscovery ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "notediscovery" "gamosoft/NoteDiscovery"; then
- msg_info "Stopping Service"
- systemctl stop notediscovery
- msg_ok "Stopped Service"
-
- create_backup /opt/notediscovery/data /opt/notediscovery/config.yaml
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "notediscovery" "gamosoft/NoteDiscovery" "tarball"
-
- msg_info "Syncing Dependencies"
- cd /opt/notediscovery
- $STD uv sync --no-dev
- msg_ok "Synced Dependencies"
-
- restore_backup
-
- msg_info "Starting Service"
- systemctl start notediscovery
- 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}:8000${CL}"
diff --git a/ct/opencloud.sh b/ct/opencloud.sh
index 51485fec3..b64dc34d0 100644
--- a/ct/opencloud.sh
+++ b/ct/opencloud.sh
@@ -30,7 +30,7 @@ function update_script() {
exit
fi
- RELEASE="v7.3.0"
+ RELEASE="v7.2.0"
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
msg_info "Stopping services"
systemctl stop opencloud opencloud-wopi
diff --git a/ct/oxicloud.sh b/ct/oxicloud.sh
deleted file mode 100644
index bee864391..000000000
--- a/ct/oxicloud.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/DioCrafts/OxiCloud
-
-APP="OxiCloud"
-var_tags="${var_tags:-files;documents}"
-var_cpu="${var_cpu:-4}"
-var_ram="${var_ram:-6144}"
-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/oxicloud ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "OxiCloud" "DioCrafts/OxiCloud"; then
- msg_info "Stopping OxiCloud"
- systemctl stop oxicloud
- msg_ok "Stopped OxiCloud"
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
- TOOLCHAIN="$(grep -oP 'FROM\s+rust:\K[0-9]+\.[0-9]+(\.[0-9]+)?' /opt/oxicloud/Dockerfile | head -1)"
- RUST_TOOLCHAIN="${TOOLCHAIN:-stable}" setup_rust
-
- msg_info "Building Frontend SPA"
- cd /opt/oxicloud/frontend
- $STD npm ci
- $STD npm run build
- msg_ok "Built Frontend SPA"
-
- msg_info "Updating OxiCloud (Patience)"
- set -a
- source /etc/oxicloud/.env
- set +a
- cd /opt/oxicloud
- export DATABASE_URL
- export RUSTFLAGS="-C target-cpu=native"
- RAM_MB=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo)
- CARGO_JOBS=$((RAM_MB / 2560))
- [[ $CARGO_JOBS -lt 1 ]] && CARGO_JOBS=1
- [[ $CARGO_JOBS -gt $(nproc) ]] && CARGO_JOBS=$(nproc)
- $STD cargo build --release -j "$CARGO_JOBS" --bin oxicloud --bin migrate-nfc-filenames
- mv target/release/oxicloud /usr/local/bin/oxicloud
- mv target/release/migrate-nfc-filenames /usr/local/bin/migrate-nfc-filenames
- chmod +x /usr/local/bin/oxicloud /usr/local/bin/migrate-nfc-filenames
- rm -f /usr/bin/oxicloud
- rm -rf /opt/oxicloud/static
- mv /opt/oxicloud/static-dist /opt/oxicloud/static
- rm -rf /opt/oxicloud/target /opt/oxicloud/frontend/node_modules
- msg_ok "Updated OxiCloud"
-
- msg_info "Starting OxiCloud"
- systemctl start oxicloud
- msg_ok "Started OxiCloud"
- 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}:8086${CL}"
diff --git a/ct/pangolin.sh b/ct/pangolin.sh
index fe5b787a9..08d604277 100644
--- a/ct/pangolin.sh
+++ b/ct/pangolin.sh
@@ -6,7 +6,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
APP="Pangolin"
-PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
+PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.18.4}"
var_tags="${var_tags:-proxy}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
@@ -33,15 +33,6 @@ function update_script() {
ensure_dependencies build-essential python3
- if ! command -v psql &>/dev/null; then
- msg_error "This installation uses SQLite and cannot be upgraded to Pangolin ${PANGOLIN_VERSION}."
- echo -e "${INFO}${YW}Starting with Pangolin 1.20.0, PostgreSQL is required as the database backend.${CL}"
- echo -e "${INFO}${YW}An automatic migration of your existing SQLite data is not supported.${CL}"
- echo -e "${INFO}${YW}Please create a new LXC with the Pangolin install script, which sets up PostgreSQL automatically.${CL}"
- echo -e "${INFO}${YW}Your current data is preserved in this container and can be manually migrated if needed.${CL}"
- exit 1
- fi
-
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "pangolin" "fosrl/pangolin" "$PANGOLIN_VERSION" "Pinned to a tested release because Pangolin's schema changes have repeatedly broken unattended updates. To try a newer version at your own risk, run: 'export PANGOLIN_VERSION=' and re-run update. If it breaks, please open an issue at https://github.com/community-scripts/ProxmoxVE/issues with the error log."; then
@@ -50,8 +41,13 @@ function update_script() {
systemctl stop gerbil
msg_info "Service stopped"
- DB_URL=$(sed -n 's/.*connection_string: "\(.*\)".*/\1/p' /opt/pangolin/config/config.yml)
- create_backup /opt/pangolin/config
+ msg_info "Creating backup"
+ tar -czf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin config
+ if [[ -f /opt/pangolin/config/db/db.sqlite ]]; then
+ cp -a /opt/pangolin/config/db/db.sqlite \
+ "/opt/pangolin/config/db/db.sqlite.pre-${PANGOLIN_VERSION}-$(date +%Y%m%d-%H%M%S).bak"
+ fi
+ msg_ok "Created backup"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
@@ -59,21 +55,23 @@ function update_script() {
msg_info "Updating Pangolin"
cd /opt/pangolin
$STD npm ci
- $STD npm run set:pg
+ $STD npm run set:sqlite
$STD npm run set:oss
rm -rf server/private
- DATABASE_URL="$DB_URL" $STD npm run db:generate
+ $STD npm run db:generate
$STD npm run build
$STD npm run build:cli
cp -R .next/standalone ./
- cp -r server/migrations ./dist/init
chmod +x ./dist/cli.mjs
cp server/db/names.json ./dist/names.json
cp server/db/ios_models.json ./dist/ios_models.json
cp server/db/mac_models.json ./dist/mac_models.json
msg_ok "Updated Pangolin"
- restore_backup
+ msg_info "Restoring config"
+ tar -xzf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin --overwrite
+ rm -f /opt/pangolin_config_backup.tar.gz
+ msg_ok "Restored config"
if ! grep -q '^ExecStartPre=/usr/bin/node dist/migrations.mjs' /etc/systemd/system/pangolin.service 2>/dev/null; then
msg_info "Adding migration step to pangolin.service"
@@ -84,8 +82,13 @@ function update_script() {
msg_info "Running database migrations"
cd /opt/pangolin
+ SQLITE_DB="/opt/pangolin/config/db/db.sqlite"
+ if [[ -f "$SQLITE_DB" ]]; then
+ if ! sqlite3 "$SQLITE_DB" ".tables" 2>/dev/null | tr ' ' '\n' | grep -qx "statusHistory"; then
+ sqlite3 "$SQLITE_DB" "DELETE FROM versionMigrations;" 2>/dev/null || true
+ fi
+ fi
ENVIRONMENT=prod $STD node dist/migrations.mjs
-
msg_ok "Ran database migrations"
msg_info "Updating Badger plugin version"
@@ -109,4 +112,4 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
-echo -e "${GATEWAY}${BGN}https:// or http://${IP}:3002${CL}"
+echo -e "${GATEWAY}${BGN}https://${CL}"
diff --git a/ct/paperclip.sh b/ct/paperclip.sh
index 10c27de23..e7c1f5101 100644
--- a/ct/paperclip.sh
+++ b/ct/paperclip.sh
@@ -79,5 +79,5 @@ 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}:3100${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3100${CL}"
diff --git a/ct/pinchflat.sh b/ct/pinchflat.sh
index c930b741a..7b696dd41 100644
--- a/ct/pinchflat.sh
+++ b/ct/pinchflat.sh
@@ -66,5 +66,5 @@ 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}:8945${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8945${CL}"
diff --git a/ct/plane.sh b/ct/plane.sh
index 0d8d9f6c9..13c29969c 100644
--- a/ct/plane.sh
+++ b/ct/plane.sh
@@ -38,10 +38,10 @@ function update_script() {
msg_ok "Stopped Services"
create_backup /opt/plane/.env \
- /opt/plane/apps/admin/.env \
- /opt/plane/apps/api/.env \
- /opt/plane/apps/space/.env \
- /opt/plane/apps/web/.env
+ /opt/plane/apps/admin/.env \
+ /opt/plane/apps/api/.env \
+ /opt/plane/apps/space/.env \
+ /opt/plane/apps/web/.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "plane" "makeplane/plane" "tarball"
@@ -86,5 +86,5 @@ 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}${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/pocketid.sh b/ct/pocketid.sh
index 9ffc54426..6153b40c0 100755
--- a/ct/pocketid.sh
+++ b/ct/pocketid.sh
@@ -71,7 +71,7 @@ function update_script() {
cp /opt/pocket-id/.env /opt/env
fi
- fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id_linux_$(arch_resolve)"
+ fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id-linux-$(arch_resolve)"
mv /opt/env /opt/pocket-id/.env
msg_info "Starting Service"
diff --git a/ct/postiz.sh b/ct/postiz.sh
index dc004abb5..cdfbc51b2 100644
--- a/ct/postiz.sh
+++ b/ct/postiz.sh
@@ -37,7 +37,7 @@ function update_script() {
msg_ok "Stopped Services"
create_backup /opt/postiz/.env \
- /opt/postiz/uploads
+ /opt/postiz/uploads
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "postiz" "gitroomhq/postiz-app" "tarball"
@@ -56,6 +56,7 @@ function update_script() {
$STD pnpm run prisma-db-push
msg_ok "Ran Database Migrations"
+
mkdir -p /opt/postiz/uploads
restore_backup
@@ -73,5 +74,5 @@ 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}${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/rackula.sh b/ct/rackula.sh
index c0b15a9b9..74f453c55 100755
--- a/ct/rackula.sh
+++ b/ct/rackula.sh
@@ -77,5 +77,5 @@ 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}${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
diff --git a/ct/reitti.sh b/ct/reitti.sh
index 5980e6ae7..f160176d4 100644
--- a/ct/reitti.sh
+++ b/ct/reitti.sh
@@ -106,6 +106,13 @@ spring.servlet.multipart.max-file-size=5GB
spring.servlet.multipart.max-request-size=5GB
server.tomcat.max-part-count=100
+# Rqueue configuration
+rqueue.web.enable=false
+rqueue.job.enabled=false
+rqueue.message.durability.in-terminal-state=0
+rqueue.key.prefix=\${spring.cache.redis.key-prefix}
+rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter
+
# Application-specific settings
reitti.server.advertise-uri=
@@ -161,81 +168,6 @@ PROPEOF
msg_ok "Rewrote application.properties (backup: application.properties.bak)"
fi
- # Migrate v4 -> v5: Remove Rqueue configuration (replaced by Quartz Scheduler)
- if grep -q "^rqueue\." /opt/reitti/application.properties 2>/dev/null; then
- msg_info "Migrating to v5: Removing Rqueue configuration"
- sed -i '/^# Rqueue configuration$/d; /^rqueue\./d' /opt/reitti/application.properties
- msg_ok "Removed Rqueue configuration"
- fi
-
- # Migrate v4 -> v5: Update application.properties and nginx tile cache for v5 compatibility
- if grep -q "^reitti\.process-data\.schedule=" /opt/reitti/application.properties 2>/dev/null; then
- msg_info "Migrating to v5: Updating application.properties"
- sed -i '/^reitti\.process-data\.schedule=/d' /opt/reitti/application.properties
- sed -i 's/^reitti\.import\.processing-idle-start-time=.*/reitti.import.grace-time-seconds=30/' /opt/reitti/application.properties
- sed -i 's/^spring\.datasource\.hikari\.maximum-pool-size=20$/spring.datasource.hikari.maximum-pool-size=30/' /opt/reitti/application.properties
- grep -q "devices" /opt/reitti/application.properties || \
- sed -i 's/^spring\.cache\.cache-names=\(.*\)$/spring.cache.cache-names=\1,devices,mapStyles,mapStyleJson/' /opt/reitti/application.properties
- grep -q "org.quartz.core.ErrorLogger" /opt/reitti/application.properties || \
- sed -i '/^logging\.level\.com\.dedicatedcode\.reitti=/a logging.level.org.quartz.core.ErrorLogger=FATAL' /opt/reitti/application.properties
- grep -q "^spring.servlet.multipart.resolve-lazily=" /opt/reitti/application.properties || \
- sed -i '/^spring\.servlet\.multipart\.max-request-size=/a spring.servlet.multipart.resolve-lazily=true' /opt/reitti/application.properties
- grep -q "^spring.mvc.async.request-timeout=" /opt/reitti/application.properties || \
- echo "spring.mvc.async.request-timeout=600000" >>/opt/reitti/application.properties
- if ! grep -q "^spring.quartz" /opt/reitti/application.properties; then
- cat >>/opt/reitti/application.properties <<'QUARTZEOF'
-
-# Quartz Scheduler configuration
-spring.quartz.job-store-type=jdbc
-spring.quartz.jdbc.initialize-schema=never
-spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-spring.quartz.properties.org.quartz.jobStore.isClustered=false
-spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
-spring.quartz.properties.org.quartz.threadPool.threadCount=5
-QUARTZEOF
- fi
- grep -q "^reitti.import.staging.cleanup.cron=" /opt/reitti/application.properties || \
- echo "reitti.import.staging.cleanup.cron=0 0 4 * * *" >>/opt/reitti/application.properties
- grep -q "^reitti.batching.max-batch-size=" /opt/reitti/application.properties || \
- printf "reitti.batching.max-batch-size=100\nreitti.batching.max-wait-time=5\n" >>/opt/reitti/application.properties
- grep -q "^reitti.jobs.cleanup.cron=" /opt/reitti/application.properties || \
- printf "reitti.jobs.cleanup.cron=0 0 4 * * ?\nreitti.jobs.cleanup.max-age-hours=24\n" >>/opt/reitti/application.properties
- grep -q "^reitti.db-janitor.schedule=" /opt/reitti/application.properties || \
- echo "reitti.db-janitor.schedule=0 0 4 * * ?" >>/opt/reitti/application.properties
- msg_ok "Updated application.properties for v5"
-
- if [[ -f /etc/nginx/nginx.conf ]]; then
- msg_info "Migrating to v5: Updating nginx tile cache configuration"
- cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.v5
- cat >/etc/nginx/nginx.conf <<'NGINXEOF'
-user www-data;
-
-events {
- worker_connections 1024;
-}
-http {
- resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off;
- proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
- server {
- listen 80;
- location /custom/ {
- set $upstream_url $http_x_reitti_upstream_url;
- proxy_pass $upstream_url;
- proxy_set_header Host $proxy_host;
- proxy_set_header User-Agent "Reitti/1.0";
- proxy_cache tiles;
- proxy_cache_key $upstream_url;
- proxy_cache_valid 200 30d;
- proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
- }
- }
-}
-NGINXEOF
- systemctl reload nginx
- msg_ok "Updated nginx tile cache configuration"
- fi
- fi
-
if check_for_gh_release "reitti" "dedicatedcode/reitti"; then
msg_info "Stopping Service"
systemctl stop reitti
@@ -247,12 +179,10 @@ NGINXEOF
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "reitti" "dedicatedcode/reitti" "singlefile" "latest" "/opt/reitti" "reitti-app.jar"
mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
- msg_warn "v5 runs a one-time database migration on first start (GPS points → device table). This may take several minutes on large datasets — do not interrupt the container."
msg_info "Starting Service"
systemctl start reitti
msg_ok "Started Service"
msg_ok "Updated successfully!"
- msg_warn "Post-upgrade: Verify each API token has a Device assigned in Settings → API Tokens. Tokens without a device cannot ingest location data in v5."
fi
exit
}
diff --git a/ct/rustdeskserver.sh b/ct/rustdeskserver.sh
index 8831bda20..921ab1130 100644
--- a/ct/rustdeskserver.sh
+++ b/ct/rustdeskserver.sh
@@ -60,4 +60,4 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
-echo -e "${GATEWAY}${BGN}http://${IP}:21114${CL}"
+echo -e "${GATEWAY}${BGN}${IP}:21114${CL}"
diff --git a/ct/sftpgo.sh b/ct/sftpgo.sh
index 5c6a79adf..d96f013d2 100644
--- a/ct/sftpgo.sh
+++ b/ct/sftpgo.sh
@@ -28,12 +28,6 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
-
- setup_deb822_repo \
- "sftpgo" \
- "https://oss.sftpgo.com/apt/gpg.key" \
- "https://oss.sftpgo.com/apt" \
- "trixie"
msg_info "Updating SFTPGo"
$STD apt update
diff --git a/ct/shlink.sh b/ct/shlink.sh
index a9238fe49..0d6a210dd 100644
--- a/ct/shlink.sh
+++ b/ct/shlink.sh
@@ -80,7 +80,7 @@ description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
-echo -e "${INFO}${YW}Access Shlink Web Client using the following URL:${CL}"
+echo -e "${INFO}${YW} Access Shlink Web Client using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW} Shlink HTTP API:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/snapotter.sh b/ct/snapotter.sh
index ce2323f8f..86671ab42 100644
--- a/ct/snapotter.sh
+++ b/ct/snapotter.sh
@@ -30,63 +30,19 @@ function update_script() {
exit
fi
- NEEDS_V2_MIGRATION=false
- grep -q '^DB_PATH=' /opt/snapotter_data/.env 2>/dev/null && NEEDS_V2_MIGRATION=true
- UPDATE_AVAILABLE=false
- check_for_gh_release "snapotter" "snapotter-hq/SnapOtter" && UPDATE_AVAILABLE=true
-
- if [[ "$NEEDS_V2_MIGRATION" == true || "$UPDATE_AVAILABLE" == true ]]; then
+ if check_for_gh_release "snapotter" "snapotter-hq/SnapOtter"; then
msg_info "Stopping Service"
systemctl stop snapotter
msg_ok "Stopped Service"
- PG_VERSION="17" setup_postgresql
- if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'snapotter'" | grep -qx '1'; then
- PG_DB_NAME="snapotter" PG_DB_USER="snapotter" setup_postgresql_db
- else
- PG_DB_NAME="snapotter"
- PG_DB_USER="snapotter"
- PG_DB_PASS=$(sed -n 's|^DATABASE_URL=postgres://snapotter:\([^@]*\)@.*|\1|p' /opt/snapotter_data/.env | head -n1)
- if [[ -z "$PG_DB_PASS" ]]; then
- msg_error "SnapOtter's PostgreSQL database exists, but its password is not available in /opt/snapotter_data/.env"
- exit 1
- fi
- fi
-
- msg_info "Installing Redis"
- $STD apt install -y redis-server
- if grep -q '^appendonly ' /etc/redis/redis.conf; then
- sed -i 's/^appendonly .*/appendonly yes/' /etc/redis/redis.conf
- else
- echo 'appendonly yes' >>/etc/redis/redis.conf
- fi
- $STD systemctl enable --now redis-server
- msg_ok "Installed Redis"
-
- msg_info "Migrating SnapOtter Configuration"
- sed -i '/^DB_PATH=/d; /^DATABASE_URL=/d; /^REDIS_URL=/d; /^SQLITE_MIGRATE_PATH=/d' /opt/snapotter_data/.env
- cat <>/opt/snapotter_data/.env
-DATABASE_URL=postgres://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
-REDIS_URL=redis://127.0.0.1:6379
-EOF
- if [[ -f /opt/snapotter_data/snapotter.db ]]; then
- echo 'SQLITE_MIGRATE_PATH=/opt/snapotter_data/snapotter.db' >>/opt/snapotter_data/.env
- fi
- if ! grep -q '^Requires=postgresql.service redis-server.service$' /etc/systemd/system/snapotter.service; then
- sed -i '/^After=/c\After=network-online.target postgresql.service redis-server.service' /etc/systemd/system/snapotter.service
- sed -i '/^\[Unit\]/a Wants=network-online.target\nRequires=postgresql.service redis-server.service' /etc/systemd/system/snapotter.service
- fi
- systemctl daemon-reload
- msg_ok "Migrated SnapOtter Configuration"
-
- if [[ "$UPDATE_AVAILABLE" == true ]]; then
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "prebuild" "latest" "/opt/snapotter" "snapotter-*-linux-amd64.tar.gz"
- fi
+ CLEAN_INSTALL=1 fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "tarball"
msg_info "Updating SnapOtter"
- $STD uv python install 3.11
- $STD uv venv --seed --python 3.11 /opt/snapotter_data/ai/venv
- ln -sfn /opt/snapotter /app
+ cd /opt/snapotter
+ $STD npm pkg delete scripts.prepare
+ $STD pnpm install --frozen-lockfile
+ $STD pnpm --filter @snapotter/web build
+ sed -i 's/mediapipe==0.10.21/mediapipe>=0.10.21/' /opt/snapotter/docker/feature-manifest.json
msg_ok "Updated SnapOtter"
msg_info "Starting Service"
@@ -103,5 +59,5 @@ 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}:1349${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:1349${CL}"
diff --git a/ct/spliit.sh b/ct/spliit.sh
index d039b75d9..33076cd42 100755
--- a/ct/spliit.sh
+++ b/ct/spliit.sh
@@ -72,5 +72,5 @@ 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}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/squid.sh b/ct/squid.sh
deleted file mode 100644
index 1698fc395..000000000
--- a/ct/squid.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: 007hacky007
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.squid-cache.org/
-
-APP="Squid"
-var_tags="${var_tags:-proxy}"
-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 [[ ! -f /etc/squid/squid.conf ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
- msg_info "Updating Squid"
- $STD apt update
- $STD apt upgrade -y
- msg_ok "Updated Squid"
-
- msg_info "Validating Squid Configuration"
- $STD squid -k parse
- msg_ok "Validated Squid Configuration"
-
- msg_info "Restarting Squid"
- systemctl restart squid
- msg_ok "Restarted Squid"
- 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} Proxy endpoint:${CL}"
-echo -e "${TAB}${GATEWAY}${BGN}${IP}:3128${CL}"
diff --git a/ct/storyteller.sh b/ct/storyteller.sh
index 0e49e0196..df2f915c9 100644
--- a/ct/storyteller.sh
+++ b/ct/storyteller.sh
@@ -32,7 +32,7 @@ function update_script() {
NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
- if check_for_gl_release "storyteller" "storyteller-platform/storyteller" "" "" "web-v2"; then
+ if check_for_gl_release "storyteller" "storyteller-platform/storyteller"; then
msg_info "Stopping Service"
systemctl stop storyteller
msg_ok "Stopped Service"
@@ -41,7 +41,7 @@ function update_script() {
cp /opt/storyteller/.env /opt/storyteller_env.bak
msg_ok "Backed up Data"
- CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2"
+ CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller"
msg_info "Restoring Configuration"
mv /opt/storyteller_env.bak /opt/storyteller/.env
diff --git a/ct/sync-in.sh b/ct/sync-in.sh
deleted file mode 100644
index 4b43c6dd4..000000000
--- a/ct/sync-in.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/Sync-in/server
-
-APP="Sync-in"
-var_tags="${var_tags:-files;sync;collaboration}"
-var_cpu="${var_cpu:-2}"
-var_ram="${var_ram:-2048}"
-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/sync-in/node_modules/@sync-in ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "sync-in" "Sync-in/server"; then
- msg_info "Stopping Service"
- systemctl stop sync-in
- msg_ok "Stopped Service"
-
- msg_info "Updating Sync-in"
- $STD npm install --prefix /opt/sync-in "@sync-in/server@${CHECK_UPDATE_RELEASE#v}"
- msg_ok "Updated Sync-in"
-
- msg_info "Running Database Migrations"
- cd /opt/sync-in
- $STD npx sync-in-server migrate-db
- msg_ok "Ran Database Migrations"
-
- VERSION=$(node -pe "require('/opt/sync-in/node_modules/@sync-in/server/package.json').version" 2>/dev/null || echo "")
- [[ -n "$VERSION" ]] && echo "$VERSION" >~/.sync-in
-
- msg_info "Starting Service"
- systemctl start sync-in
- 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}:8080${CL}"
diff --git a/ct/tolgee.sh b/ct/tolgee.sh
index 4455852ff..fab3dc278 100644
--- a/ct/tolgee.sh
+++ b/ct/tolgee.sh
@@ -52,5 +52,5 @@ 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}:8080${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
diff --git a/ct/twenty.sh b/ct/twenty.sh
index e1e9e35d3..0b212ef0f 100644
--- a/ct/twenty.sh
+++ b/ct/twenty.sh
@@ -39,10 +39,10 @@ function update_script() {
msg_ok "Stopped Services"
create_backup /opt/twenty/.env \
- /opt/twenty/packages/twenty-server/.local-storage
+ /opt/twenty/packages/twenty-server/.local-storage
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "twenty" "twentyhq/twenty" "tarball"
restore_backup
-
+
msg_info "Building Application"
cd /opt/twenty
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
@@ -63,6 +63,7 @@ function update_script() {
$STD npx -y typeorm migration:run -d dist/database/typeorm/core/core.datasource
msg_ok "Ran Database Migrations"
+
msg_info "Starting Services"
systemctl start twenty-server twenty-worker
msg_ok "Started Services"
@@ -77,5 +78,5 @@ 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}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
diff --git a/ct/wanderer.sh b/ct/wanderer.sh
index bb0ec71cd..432963379 100644
--- a/ct/wanderer.sh
+++ b/ct/wanderer.sh
@@ -30,14 +30,12 @@ function update_script() {
exit
fi
- if check_for_gh_release "wanderer" "open-wanderer/wanderer"; then
+ if check_for_gh_release "wanderer" "Flomp/wanderer"; then
msg_info "Stopping service"
systemctl stop wanderer-web
msg_ok "Stopped service"
- create_backup /opt/wanderer/source/search
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
- restore_backup
+ fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
msg_info "Updating wanderer"
cd /opt/wanderer/source/db
@@ -46,13 +44,6 @@ function update_script() {
cd /opt/wanderer/source/web
$STD npm ci
$STD npm run build
- mkdir -p /opt/wanderer/data/plugins
- [[ -e /data/plugins ]] || ln -sfn /opt/wanderer/data/plugins /data/plugins
- msg_info "Installing wanderer plugins"
- for plugin in hammerhead komoot strava; do
- fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer/data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
- done
- msg_ok "Installed wanderer plugins"
msg_ok "Updated wanderer"
msg_info "Starting service"
diff --git a/ct/wizarr.sh b/ct/wizarr.sh
index af6a2adac..febc1e4c3 100644
--- a/ct/wizarr.sh
+++ b/ct/wizarr.sh
@@ -50,38 +50,20 @@ function update_script() {
$STD /usr/local/bin/uv sync --frozen
$STD /usr/local/bin/uv run --frozen pybabel compile -d app/translations
$STD npm --prefix app/static install
- $STD npm --prefix app/static run build
+ $STD npm --prefix app/static run build:css
mkdir -p ./.cache
$STD tar -xf "$BACKUP_FILE" --directory=/
- if grep -q 'bind' /opt/wizarr/start.sh; then
- WIZARR_PORT=$(awk -F: '{print $2}' /opt/wizarr/start.sh | awk -F' ' '{print $1}' | tr -d '[:space:]')
+ if grep -q 'workers' /opt/wizarr/start.sh; then
+ sed -i 's/--workers 4//' /opt/wizarr/start.sh
fi
- sed -i -E -e 's/[[:space:]]+/ /g' \
- -e 's/--workers 4//' \
- -e 's/--bind 0.0.0.0:[0-9]+//' /opt/wizarr/start.sh
- KEYS=("FLASK" "WORKERS" "HOST" "PORT")
- for key in "${KEYS[@]}"; do
- if ! grep -q "$key" /opt/wizarr/.env; then
- cat </opt/wizarr/.env
-APP_URL=http://${LOCAL_IP}
-DISABLE_BUILTIN_AUTH=false
+ if ! grep -qE 'FLASK|WORKERS|VERSION' /opt/wizarr/.env; then
+ cat </opt/wizarr/.env
FLASK_ENV=production
GUNICORN_WORKERS=4
-HOST=0.0.0.0
-PORT=${WIZARR_PORT:-5690}
-LOG_LEVEL=info
-APP_VERSION=$(cat ~/.wizarr)
+APP_VERSION=$(sed 's/^20/v&/' ~/.wizarr)
EOF
- fi
- continue
- done
- sed -i "s/_VERSION=.*$/_VERSION=$(cat ~/.wizarr)/" /opt/wizarr/.env
- if grep -q 'abnormal' /etc/systemd/system/wizarr.service; then
- sed -i 's/on-abnormal/always \
-RestartSec=10 \
-KillMode=mixed \
-TimeoutStopSec=10/' /etc/systemd/system/wizarr.service
- systemctl daemon-reload
+ else
+ sed -i "s/_VERSION=v.*$/_VERSION=v$(cat ~/.wizarr)/" /opt/wizarr/.env
fi
rm -rf "$BACKUP_FILE"
export FLASK_SKIP_SCHEDULER=true
diff --git a/ct/xyops.sh b/ct/xyops.sh
index 2768a39ae..61f641119 100644
--- a/ct/xyops.sh
+++ b/ct/xyops.sh
@@ -69,5 +69,5 @@ 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}:5522${CL}"
+echo -e "${INFO}${YW} Access it using the following URL:${CL}"
+echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5522${CL}"
diff --git a/ct/yuvomi.sh b/ct/yuvomi.sh
deleted file mode 100644
index 625a0aa61..000000000
--- a/ct/yuvomi.sh
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env bash
-source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: MickLesk (CanbiZ)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/ulsklyc/yuvomi
-
-APP="Yuvomi"
-var_tags="${var_tags:-family;planner;calendar}"
-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:-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/yuvomi ]]; then
- msg_error "No ${APP} Installation Found!"
- exit
- fi
-
- if check_for_gh_release "yuvomi" "ulsklyc/yuvomi"; then
- msg_info "Stopping Service"
- systemctl stop yuvomi
- msg_ok "Stopped Service"
-
- create_backup /opt/yuvomi/data /opt/yuvomi/.env
-
- CLEAN_INSTALL=1 fetch_and_deploy_gh_release "yuvomi" "ulsklyc/yuvomi" "tarball"
-
- msg_info "Installing Node.js Dependencies"
- cd /opt/yuvomi
- $STD npm ci --omit=dev
- msg_ok "Installed Node.js Dependencies"
-
- restore_backup
-
- msg_info "Starting Service"
- systemctl start yuvomi
- 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}"
diff --git a/install/2fauth-install.sh b/install/2fauth-install.sh
index 61c8377ae..386b5c3de 100644
--- a/install/2fauth-install.sh
+++ b/install/2fauth-install.sh
@@ -43,7 +43,6 @@ $STD php artisan migrate:refresh
$STD php artisan passport:install -q -n
$STD php artisan storage:link
$STD php artisan config:cache
-$STD php artisan 2fauth:fix-passport-key-permissions
chown -R www-data: /opt/2fauth
chmod -R 755 /opt/2fauth
msg_ok "Setup 2fauth"
diff --git a/install/adventurelog-install.sh b/install/adventurelog-install.sh
index b480da0d9..10e664bc6 100644
--- a/install/adventurelog-install.sh
+++ b/install/adventurelog-install.sh
@@ -72,7 +72,6 @@ BODY_SIZE_LIMIT=Infinity
ORIGIN='http://$LOCAL_IP:3000'
EOF
cd /opt/adventurelog/frontend
-grep -q "^dangerouslyAllowAllBuilds:" ./pnpm-workspace.yaml 2>/dev/null || echo "dangerouslyAllowAllBuilds: true" >>./pnpm-workspace.yaml
$STD pnpm i
$STD pnpm build
msg_ok "Installed AdventureLog"
diff --git a/install/affine-install.sh b/install/affine-install.sh
deleted file mode 100644
index 50144d4e0..000000000
--- a/install/affine-install.sh
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/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/toeverything/AFFiNE
-
-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 \
- git \
- pkg-config \
- openssl \
- libssl-dev \
- libjemalloc2 \
- redis-server \
- nginx \
- cmake
-msg_ok "Installed Dependencies"
-
-PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
-PG_DB_NAME="affine" PG_DB_USER="affine" setup_postgresql_db
-NODE_VERSION="22" setup_nodejs
-setup_rust
-
-fetch_and_deploy_gh_release "affine_app" "toeverything/AFFiNE" "tarball" "v0.27.0" "/opt/affine"
-
-msg_info "Setting up Directories"
-rm -rf /root/.affine
-mkdir -p /root/.affine/{storage,config}
-msg_ok "Set up Directories"
-
-msg_info "Configuring Environment"
-SECRET_KEY=$(openssl rand -hex 32)
-cat </opt/affine/.env
-NODE_ENV=production
-AFFINE_SERVER_PORT=3010
-AFFINE_SERVER_HOST=${LOCAL_IP}
-AFFINE_SERVER_EXTERNAL_URL=http://${LOCAL_IP}
-DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}
-REDIS_SERVER_HOST=localhost
-REDIS_SERVER_PORT=6379
-AFFINE_INDEXER_ENABLED=false
-SECRET_KEY=${SECRET_KEY}
-EOF
-msg_ok "Configured Environment"
-
-msg_info "Building AFFiNE (Patience)"
-cd /opt/affine
-source /root/.profile
-export PATH="/root/.cargo/bin:$PATH"
-export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
-export VITE_CORE_COMMIT_SHA=$(cat ~/.affine_app)
-# # Initialize git repo (required for build process)
-export HUSKY=0
-$STD git init -q
-$STD git config user.email "build@local"
-$STD git config user.name "Build"
-$STD git add -A
-$STD git commit -q -m "update" --no-verify --allow-empty
-mkdir -p /opt/affine/.turbo
-cat </opt/affine/.turbo/config.json
-{
- "concurrency": 1
-}
-TURBO
-$STD corepack enable
-$STD corepack prepare yarn@4.13.0 --activate
-$STD yarn config set enableTelemetry 0
-export NODE_OPTIONS="--max-old-space-size=4096"
-export TSC_COMPILE_ON_ERROR=true
-$STD yarn install
-$STD npm install -g typescript
-$STD yarn affine @affine/native build
-$STD yarn affine @affine/server-native build
-
-# Create architecture-specific symlinks for server-native
-ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.x64.node
-ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.arm64.node
-ln -sf /opt/affine/packages/backend/native/server-native.node \
- /opt/affine/packages/backend/native/server-native.armv7.node
-
-$STD yarn affine init
-$STD yarn affine build -p @affine/reader
-$STD yarn affine build -p @affine/server
-export NODE_OPTIONS="--max-old-space-size=4096"
-$STD yarn affine build -p @affine/web
-$STD yarn affine build -p @affine/admin
-mkdir -p /opt/affine/packages/backend/server/static
-cp -r /opt/affine/packages/frontend/apps/web/dist/* /opt/affine/packages/backend/server/static/
-mkdir -p /opt/affine/packages/backend/server/static/admin
-cp -r /opt/affine/packages/frontend/admin/dist/* /opt/affine/packages/backend/server/static/admin/
-# Create empty mobile manifest (server expects it but we don't build mobile)
-mkdir -p /opt/affine/packages/backend/server/static/mobile
-cat <<'MANIFEST' >/opt/affine/packages/backend/server/static/mobile/assets-manifest.json
-{"publicPath":"/","js":[],"css":[],"gitHash":"","description":""}
-MANIFEST
-msg_ok "Built AFFiNE"
-
-msg_info "Running Initial Migration"
-cd /opt/affine/packages/backend/server
-set -a && source /opt/affine/.env && set +a
-$STD node ./scripts/self-host-predeploy.js
-msg_ok "Ran Initial Migration"
-
-msg_info "Creating Services"
-cat </etc/systemd/system/affine-web.service
-[Unit]
-Description=AFFiNE Web Server
-After=network.target postgresql.service redis-server.service
-Requires=postgresql.service redis-server.service
-
-[Service]
-Type=simple
-WorkingDirectory=/opt/affine/packages/backend/server
-EnvironmentFile=/opt/affine/.env
-Environment=LD_PRELOAD=libjemalloc.so.2
-Environment=NODE_OPTIONS=--max-old-space-size=1024
-ExecStart=/usr/bin/node ./dist/main.js
-Restart=always
-RestartSec=10
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-cat </etc/systemd/system/affine-worker.service
-[Unit]
-Description=AFFiNE Background Worker
-After=network.target postgresql.service redis-server.service
-Requires=postgresql.service redis-server.service
-
-[Service]
-Type=simple
-WorkingDirectory=/opt/affine/packages/backend/server
-EnvironmentFile=/opt/affine/.env
-Environment=LD_PRELOAD=libjemalloc.so.2
-Environment=NODE_OPTIONS=--max-old-space-size=1024
-ExecStart=/usr/bin/node ./dist/main.js --worker
-Restart=always
-RestartSec=10
-
-[Install]
-WantedBy=multi-user.target
-EOF
-
-systemctl enable -q --now redis-server affine-web affine-worker
-msg_ok "Created Services"
-
-msg_info "Creating Admin User"
-ADMIN_PASS=$(openssl rand -base64 12)
-for i in {1..30}; do
- if curl -s http://localhost:3010/info >/dev/null 2>&1; then
- break
- fi
- sleep 2
-done
-# Create admin via API
-ADMIN_RESPONSE=$(curl -s -X POST http://localhost:3010/api/setup/create-admin-user \
- -H "Content-Type: application/json" \
- -d "{\"email\":\"admin@affine.local\",\"password\":\"${ADMIN_PASS}\"}")
-if echo "$ADMIN_RESPONSE" | grep -q '"id"'; then
- {
- echo "AFFiNE Credentials"
- echo "=================="
- echo "Email: admin@affine.local"
- echo "Password: ${ADMIN_PASS}"
- } >~/affine.creds
- msg_ok "Created Admin User"
-else
- msg_warn "Admin creation skipped (may already exist)"
-fi
-
-msg_info "Configuring Nginx"
-cat </etc/nginx/sites-available/affine.conf
-upstream affine_backend {
- server 127.0.0.1:3010;
-}
-
-server {
- listen 80;
- server_name _;
-
- client_max_body_size 100M;
-
- location / {
- proxy_pass http://affine_backend;
- proxy_http_version 1.1;
- proxy_set_header Host \$host;
- proxy_set_header X-Real-IP \$remote_addr;
- proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto \$scheme;
- proxy_set_header Upgrade \$http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_redirect off;
- proxy_buffering off;
- }
-}
-EOF
-ln -sf /etc/nginx/sites-available/affine.conf /etc/nginx/sites-enabled/
-rm -f /etc/nginx/sites-enabled/default
-systemctl enable -q --now nginx
-msg_ok "Configured Nginx"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/beaverhabits-install.sh b/install/beaverhabits-install.sh
deleted file mode 100644
index f58f4003a..000000000
--- a/install/beaverhabits-install.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/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/daya0576/beaverhabits
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-PYTHON_VERSION="3.14" setup_uv
-
-fetch_and_deploy_gh_release "beaverhabits" "daya0576/beaverhabits" "tarball"
-
-msg_info "Installing Dependencies"
-cd /opt/beaverhabits
-$STD uv sync --no-dev
-msg_ok "Installed Dependencies"
-
-msg_info "Configuring BeaverHabits"
-mkdir -p /opt/beaverhabits/.user
-msg_ok "Configured BeaverHabits"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/beaverhabits.service
-[Unit]
-Description=BeaverHabits Habit Tracker
-After=network.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/beaverhabits
-Environment=HABITS_STORAGE=USER_DISK
-Environment=NICEGUI_STORAGE_PATH=/opt/beaverhabits/.user/.nicegui
-ExecStart=/opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now beaverhabits
-msg_ok "Created Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/birdnet-go-install.sh b/install/birdnet-go-install.sh
index df0a96058..b3dfcab8e 100644
--- a/install/birdnet-go-install.sh
+++ b/install/birdnet-go-install.sh
@@ -21,7 +21,7 @@ $STD apt install -y \
ffmpeg
msg_ok "Installed Dependencies"
-fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve)*.tar.gz"
+fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve).tar.gz"
msg_info "Setting up BirdNET-Go"
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
diff --git a/install/docuseal-install.sh b/install/docuseal-install.sh
index e502256e3..82c89bfc6 100644
--- a/install/docuseal-install.sh
+++ b/install/docuseal-install.sh
@@ -23,8 +23,6 @@ $STD apt install -y \
libreadline-dev \
zlib1g-dev \
libffi-dev \
- libleptonica-dev \
- libleptonica6 \
libvips42 \
libvips-dev \
libheif1 \
diff --git a/install/esphome-install.sh b/install/esphome-install.sh
index 02c46b155..1b5b7367d 100644
--- a/install/esphome-install.sh
+++ b/install/esphome-install.sh
@@ -14,8 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies"
-$STD apt install -y git \
- libusb-1.0-0
+$STD apt install -y git
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
diff --git a/install/fileflows-install.sh b/install/fileflows-install.sh
index 14efb6582..af93424b6 100644
--- a/install/fileflows-install.sh
+++ b/install/fileflows-install.sh
@@ -26,8 +26,8 @@ msg_info "Installing ASP.NET Core Runtime"
if [[ "$(arch_resolve)" == "arm64" ]]; then
# packages.microsoft.com only ships amd64 debs for Debian; use dotnet-install on arm64
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
- $STD bash /tmp/dotnet-install.sh --channel 10.0 --runtime aspnetcore --install-dir /usr/lib/dotnet10
- ln -sf /usr/lib/dotnet10/dotnet /usr/bin/dotnet
+ $STD bash /tmp/dotnet-install.sh --channel 8.0 --runtime aspnetcore --install-dir /usr/lib/dotnet8
+ ln -sf /usr/lib/dotnet8/dotnet /usr/bin/dotnet
rm -f /tmp/dotnet-install.sh
else
setup_deb822_repo \
@@ -35,7 +35,7 @@ else
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie"
- $STD apt install -y aspnetcore-runtime-10.0
+ $STD apt install -y aspnetcore-runtime-8.0
fi
msg_ok "Installed ASP.NET Core Runtime"
@@ -55,12 +55,9 @@ if [[ "$install_server" =~ ^[Ss]$ ]]; then
msg_ok "Installed FileFlows Server"
else
msg_info "Installing FileFlows Node"
- read -r -p "${TAB3}Enter FileFlows Server URL (e.g. http://192.168.1.10:19200): " server_url
- while [[ -z "${server_url// /}" ]]; do
- read -r -p "${TAB3}Enter FileFlows Server URL (e.g. http://192.168.1.10:19200): " server_url
- done
cd /opt/fileflows/Node
- $STD dotnet FileFlows.Node.dll --server "$server_url" --systemd install --root true
+ $STD dotnet FileFlows.Node.dll
+ $STD dotnet FileFlows.Node.dll --systemd install --root true
systemctl enable -q --now fileflows-node
msg_ok "Installed FileFlows Node"
fi
diff --git a/install/fireshare-install.sh b/install/fireshare-install.sh
index 311ba230b..982679c6e 100644
--- a/install/fireshare-install.sh
+++ b/install/fireshare-install.sh
@@ -141,9 +141,6 @@ cp /opt/fireshare/app/nginx/prod.conf /etc/nginx/nginx.conf
sed -i 's|root /processed/|root /opt/fireshare-processed/|g' /etc/nginx/nginx.conf
sed -i 's/^user[[:space:]]\+nginx;/user root;/' /etc/nginx/nginx.conf
sed -i 's|root[[:space:]]\+/app/build;|root /opt/fireshare/app/client/build;|' /etc/nginx/nginx.conf
-sed -i 's/__FIRESHARE_PORT__/80/g' /etc/nginx/nginx.conf
-cp /opt/fireshare/app/nginx/error.html /etc/nginx/
-cp /opt/fireshare/app/nginx/api_unavailable.html /etc/nginx/
systemctl start nginx
cat <~/fireshare.creds
diff --git a/install/flowiseai-install.sh b/install/flowiseai-install.sh
new file mode 100644
index 000000000..73cc8c1eb
--- /dev/null
+++ b/install/flowiseai-install.sh
@@ -0,0 +1,52 @@
+#!/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://flowiseai.com/ | Github: https://github.com/FlowiseAI/Flowise
+
+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 \
+ pkg-config
+msg_ok "Installed Dependencies"
+
+PYTHON_VERSION="3.11" setup_uv
+NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
+
+msg_info "Installing FlowiseAI (Patience)"
+PYTHON_BIN="$(uv python find 3.11)"
+export npm_config_python="$PYTHON_BIN"
+$STD pnpm add -g flowise
+mkdir -p /opt/flowiseai
+curl -fsSL "https://raw.githubusercontent.com/FlowiseAI/Flowise/main/packages/server/.env.example" -o "/opt/flowiseai/.env"
+msg_ok "Installed FlowiseAI"
+
+msg_info "Creating Service"
+cat </etc/systemd/system/flowise.service
+[Unit]
+Description=FlowiseAI
+After=network.target
+
+[Service]
+EnvironmentFile=/opt/flowiseai/.env
+ExecStart=flowise start
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl enable -q --now flowise
+msg_ok "Created Service"
+
+motd_ssh
+customize
+cleanup_lxc
diff --git a/install/forgejo-runner-install.sh b/install/forgejo-runner-install.sh
deleted file mode 100644
index 94ceb6877..000000000
--- a/install/forgejo-runner-install.sh
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Simon Friedrich (lengschder97)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://forgejo.org/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-setup_yq
-
-if [[ -z "${var_forgejo_instance:-}" ]]; then
- read -r -p "${TAB3}Forgejo Instance URL (e.g. https://codeberg.org): " var_forgejo_instance
- var_forgejo_instance="${var_forgejo_instance:-https://codeberg.org}"
-fi
-
-if [[ -z "${var_forgejo_runner_uuid:-}" ]]; then
- read -r -p "${TAB3}Forgejo Runner UUID: " var_forgejo_runner_uuid
-fi
-
-if [[ -z "${var_forgejo_runner_uuid:-}" ]]; then
- msg_error "No runner UUID provided. Cannot continue."
- exit 1
-fi
-
-if [[ -z "${var_forgejo_runner_token:-}" ]]; then
- read -r -p "${TAB3}Forgejo Runner Token: " var_forgejo_runner_token
-fi
-
-if [[ -z "${var_forgejo_runner_token:-}" ]]; then
- msg_error "No runner registration token provided. Cannot continue."
- exit 1
-fi
-
-DEFAULT_RUNNER_LABELS="linux-amd64:docker://node:22-bookworm"
-if [[ -z "${var_runner_labels:-}" ]]; then
- read -r -p "${TAB3}Additional runner labels (comma-separated, or leave blank for default only): " var_runner_labels
-fi
-if [[ -n "${var_runner_labels:-}" ]]; then
- RUNNER_LABELS="${DEFAULT_RUNNER_LABELS},${var_runner_labels}"
-else
- RUNNER_LABELS="${DEFAULT_RUNNER_LABELS}"
-fi
-
-export FORGEJO_INSTANCE="$var_forgejo_instance"
-export FORGEJO_RUNNER_TOKEN="$var_forgejo_runner_token"
-export FORGEJO_RUNNER_UUID="$var_forgejo_runner_uuid"
-export RUNNER_LABELS
-
-msg_info "Installing dependencies"
-$STD apt install -y \
- git \
- podman podman-docker
-msg_ok "Installed dependencies"
-
-msg_info "Enabling Podman socket"
-systemctl enable --now podman.socket
-msg_ok "Enabled Podman socket"
-
-msg_info "Installing Forgejo Runner"
-RUNNER_VERSION=$(curl -fsSL https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest | jq -r .name | sed 's/^v//')
-curl -fsSL "https://code.forgejo.org/forgejo/runner/releases/download/v${RUNNER_VERSION}/forgejo-runner-${RUNNER_VERSION}-linux-$(arch_resolve)" -o /usr/local/bin/forgejo-runner
-chmod +x /usr/local/bin/forgejo-runner
-echo "${RUNNER_VERSION}" >~/.forgejo-runner
-msg_ok "Installed Forgejo Runner"
-
-msg_info "Registering Forgejo Runner"
-export DOCKER_HOST="unix:///run/podman/podman.sock"
-
-msg_info "Generating Forgejo Runner Configuration"
-mkdir -p /etc/forgejo-runner
-CONFIG_FILE="/etc/forgejo-runner/config.yaml"
-forgejo-runner generate-config > $CONFIG_FILE
-yq -i '
- .container.docker_host = strenv(DOCKER_HOST) |
- .server.connections.forgejo.url = strenv(FORGEJO_INSTANCE) |
- .server.connections.forgejo.uuid = strenv(FORGEJO_RUNNER_UUID) |
- .server.connections.forgejo.token = strenv(FORGEJO_RUNNER_TOKEN) |
- .server.connections.forgejo.labels = (strenv(RUNNER_LABELS) | split(",") | map(select(length > 0)))
- ' $CONFIG_FILE
-msg_ok "Generated Forgejo Runner Configuration"
-
-
-msg_info "Creating Services"
-cat </etc/systemd/system/forgejo-runner.service
-[Unit]
-Description=Forgejo Runner
-Documentation=https://forgejo.org/docs/latest/admin/actions/
-After=podman.socket
-Requires=podman.socket
-
-[Service]
-User=root
-WorkingDirectory=/root
-Environment=DOCKER_HOST=unix:///run/podman/podman.sock
-ExecStart=/usr/local/bin/forgejo-runner daemon -c $CONFIG_FILE
-Restart=on-failure
-RestartSec=10
-TimeoutSec=0
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now forgejo-runner
-msg_ok "Created Services"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/grav-install.sh b/install/grav-install.sh
deleted file mode 100644
index 8b3c396cf..000000000
--- a/install/grav-install.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Raffaele (rafspiny)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://getgrav.org/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Installing Dependencies"
-$STD apt install -y \
- nginx \
- logrotate
-msg_ok "Installed Dependencies"
-
-PHP_FPM="YES" setup_php
-
-fetch_and_deploy_gh_release "grav" "getgrav/grav" "prebuild" "latest" "/opt/grav" "grav-admin-v*zip"
-chown -R www-data:www-data /opt/grav
-
-msg_info "Configuring Nginx"
-PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
-PHP_FPM_SOCK=$(find /run/php -maxdepth 1 -name "php*-fpm.sock" -type s | sort -V | tail -1)
-unlink /etc/nginx/sites-enabled/default
-rm -f /etc/nginx/sites-available/default
-cat </etc/nginx/sites-available/grav
-server {
- listen 80;
- server_name _;
- root /opt/grav;
- index index.html index.htm index.php;
-
- location / {
- try_files \$uri \$uri/ /index.html /index.htm /index.php\$is_args\$args;
- }
-
- ## Begin - Security
- location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
- location ~* /(system|vendor)/.*\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
- location ~* /user/.*\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
- location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
- ## End - Security
-
- ## Begin - API
- location ^~ /api/ {
- try_files \$uri \$uri/ /index.php\$is_args\$args;
- }
- ## End - API
-
- # deny all direct access to these sensitive user folders, whatever the file type
- location ~* /user/(accounts|config|env)/.*$ { return 403; }
- # allow public media uploads under user/data to be served directly;
- # this must come before the user/data deny so it wins the match
- location ~* /user/data/.*\.(jpe?g|png|gif|webp|avif|bmp|ico|mp4|webm|ogg|ogv|mov|mp3|wav|m4a|flac|pdf)$ { try_files \$uri =404; }
- # deny everything else under user/data
- location ~* /user/data/.*$ { return 403; }
-
-
- ## Begin - Caching
- location ~* ^/forms-basic-captcha-image.jpg$ {
- try_files \$uri \$uri/ /index.php\$is_args\$args;
- }
-
- location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
- expires 30d;
- add_header Vary Accept-Encoding;
- log_not_found off;
- }
-
- location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
- access_log off;
- expires 30d;
- add_header Cache-Control public;
- tcp_nodelay off;
- open_file_cache max=3000 inactive=120s;
- open_file_cache_valid 45s;
- open_file_cache_min_uses 2;
- open_file_cache_errors off;
- }
- ## End - Caching
-
- location ~ ^(.+\.php)(.*)$ {
- fastcgi_split_path_info ^(.+\.php)(.*)$;
- if (!-f \$document_root\$fastcgi_script_name) { return 404; }
- fastcgi_pass unix:${PHP_FPM_SOCK};
- fastcgi_index index.php;
- include /etc/nginx/fastcgi_params;
- fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
- }
-
- location ~ /\.ht {
- deny all;
- }
-}
-EOF
-ln -sf /etc/nginx/sites-available/grav /etc/nginx/sites-enabled/grav
-systemctl enable -q --now php${PHP_VER}-fpm
-$STD nginx -t
-systemctl enable -q --now nginx
-$STD nginx -s reload
-msg_ok "Configured Nginx"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/hyperion-install.sh b/install/hyperion-install.sh
index b58798f96..db5bf301f 100644
--- a/install/hyperion-install.sh
+++ b/install/hyperion-install.sh
@@ -24,12 +24,6 @@ msg_ok "Set up Hyperion repository"
msg_info "Installing Hyperion"
$STD apt install -y hyperion
-mkdir -p /etc/systemd/system/hyperion@.service.d
-cat </etc/systemd/system/hyperion@.service.d/override.conf
-[Unit]
-Requisite=
-EOF
-systemctl daemon-reload
systemctl enable -q --now hyperion@root
msg_ok "Installed Hyperion"
diff --git a/install/immich-install.sh b/install/immich-install.sh
index 688ae657e..9270b29e1 100644
--- a/install/immich-install.sh
+++ b/install/immich-install.sh
@@ -162,7 +162,7 @@ PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
ACTUAL_PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
ACTUAL_PG_VERSION=${ACTUAL_PG_VERSION:-16}
-VCHORD_RELEASE="1.1.1"
+VCHORD_RELEASE="1.0.0"
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${ACTUAL_PG_VERSION}-vchord_*_$(arch_resolve).deb"
sed -i "s/^#shared_preload.*/shared_preload_libraries = 'vchord.so'/" /etc/postgresql/${ACTUAL_PG_VERSION}/main/postgresql.conf
@@ -282,11 +282,10 @@ msg_ok "(4/5) Compiled imagemagick"
msg_info "(5/5) Compiling libvips"
SOURCE=$SOURCE_DIR/libvips
-LIBVIPS_REVISION="e01a4797cabe77d457fdfa7d776b7a7e7ca6d6a7"
+LIBVIPS_REVISION="3664cfc5dc2c5661288f5bf5a85ccc51c64c1626"
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
cd "$SOURCE"
$STD git reset --hard "$LIBVIPS_REVISION"
-$STD git apply "$BASE_DIR"/server/sources/libvips-patches/0001-put-other-loaders-ahead-of-dcrawload.patch
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
cd build
$STD ninja install
@@ -312,7 +311,7 @@ ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
-fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.0.3" "$SRC_DIR"
+fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.0.1" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
@@ -438,27 +437,6 @@ cd "$INSTALL_DIR"
ln -s "$GEO_DIR" "$APP_DIR"
msg_ok "Installed GeoNames data"
-# MickLesk temporary patch for HEIC thumbnail gen
-msg_info "Patching media.repository.js"
-MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
-if [[ -f "$MEDIA_REPO_JS" ]]; then
- python3 - <<'PY'
-from pathlib import Path
-p = Path('/opt/immich/app/dist/repositories/media.repository.js')
-s = p.read_text()
-old = "(0, sharp_1.default)(input).metadata()"
-new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
-if new in s:
- print('hotfix already there')
-elif old in s:
- p.write_text(s.replace(old, new, 1))
- print('hotfix applied')
-else:
- print('pattern not found, skipped')
-PY
-fi
-msg_ok "Patched media.repository.js"
-
mkdir -p /var/log/immich
touch /var/log/immich/{web.log,ml.log}
msg_ok "Installed Immich"
diff --git a/install/invidious-install.sh b/install/invidious-install.sh
deleted file mode 100644
index 798b09e92..000000000
--- a/install/invidious-install.sh
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/iv-org/invidious
-
-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 \
- git \
- pkg-config \
- libssl-dev \
- libxml2-dev \
- libyaml-dev \
- libgmp-dev \
- libreadline-dev \
- librsvg2-bin \
- libsqlite3-dev \
- zlib1g-dev \
- libpcre2-dev \
- libevent-dev \
- fonts-open-sans
-msg_ok "Installed Dependencies"
-
-if [[ "$(arch_resolve amd64 arm64)" == "amd64" ]]; then
- setup_deb822_repo "crystal" "https://download.opensuse.org/repositories/devel:/languages:/crystal/Debian_13/Release.key" "https://download.opensuse.org/repositories/devel:/languages:/crystal/Debian_13/" "./"
- $STD apt install -y crystal
-else
- fetch_and_deploy_gh_release "Crystal" "crystal-lang/crystal" "prebuild" "latest" "/opt/crystal" "crystal-*-linux-aarch64-bundled.tar.gz"
- ln -sf /opt/crystal/bin/crystal /usr/local/bin/crystal
- ln -sf /opt/crystal/bin/shards /usr/local/bin/shards
-fi
-
-PG_VERSION="17" setup_postgresql
-PG_DB_NAME="invidious" PG_DB_USER="invidious" setup_postgresql_db
-fetch_and_deploy_gh_release "Invidious" "iv-org/invidious" "tarball" "latest" "/opt/invidious"
-fetch_and_deploy_gh_release "Invidious Companion" "iv-org/invidious-companion" "prebuild" "latest" "/opt/invidious-companion" "invidious_companion-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
-
-msg_info "Building Invidious"
-cd /opt/invidious
-INVIDIOUS_VERSION="$(cat ~/.invidious 2>/dev/null || echo "unknown")"
-INVIDIOUS_VERSION="${INVIDIOUS_VERSION#v}"
-sed -i \
- -e "s~^\(\s*CURRENT_BRANCH\s*=\).*~\1 \"master\"~" \
- -e "s~^\(\s*CURRENT_COMMIT\s*=\).*~\1 \"\"~" \
- -e "s~^\(\s*CURRENT_VERSION\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
- -e "s~^\(\s*CURRENT_TAG\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
- -e "s~^\(\s*ASSET_COMMIT\s*=\).*~\1 \"\"~" \
- src/invidious.cr
-$STD make
-msg_ok "Built Invidious"
-
-msg_info "Configuring Invidious"
-SECRET_KEY="$(openssl rand -hex 8)"
-HMAC_KEY="$(openssl rand -hex 32)"
-sed -e '\~^db:~,\~dbname:~d' \
- -e "s~^#database_.*~database_url: postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}~" \
- -e 's~^#check_tables.*~check_tables: true~' \
- -e 's~^#invidious_companion:~invidious_companion:~' \
- -e 's~^# - private_~ - private_~' \
- -e "s~^#invidious_companion_key:.*~invidious_companion_key: \"${SECRET_KEY}\"~" \
- -e "s~^hmac_key:.*~hmac_key: \"${HMAC_KEY}\"~" \
- /opt/invidious/config/config.example.yml >/opt/invidious/config/config.yml
-chmod 600 /opt/invidious/config/config.yml
-
-cat </etc/logrotate.d/invidious.logrotate
-/opt/invidious/invidious.log {
- rotate 4
- weekly
- notifempty
- missingok
- compress
- minsize 1048576
-}
-EOF
-chmod 0644 /etc/logrotate.d/invidious.logrotate
-msg_ok "Configured Invidious"
-
-msg_info "Migrating database"
-$STD ./invidious --migrate
-msg_ok "Migrated database"
-
-msg_info "Configuring services"
-sed -e 's|^User=invidious|User=root|' \
- -e 's|^Group=invidious|Group=root|' \
- -e 's|/home/invidious/invidious|/opt/invidious|g' \
- /opt/invidious/invidious.service >/etc/systemd/system/invidious.service
-mkdir -p /var/tmp/youtubei.js
-cat </etc/systemd/system/invidious-companion.service
-[Unit]
-Description=Invidious Companion
-After=network.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/invidious-companion
-Environment=SERVER_SECRET_KEY=${SECRET_KEY}
-Environment=CACHE_DIRECTORY=/var/tmp/youtubei.js
-ExecStart=/opt/invidious-companion/invidious_companion
-Restart=always
-RestartSec=2s
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl -q enable --now invidious invidious-companion
-msg_ok "Configured services"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/leafwiki-install.sh b/install/leafwiki-install.sh
deleted file mode 100644
index 228ffc702..000000000
--- a/install/leafwiki-install.sh
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/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/perber/leafwiki
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-fetch_and_deploy_gh_release "leafwiki" "perber/leafwiki" "singlefile" "latest" "/usr/local/bin" "leafwiki-v*-linux-$(arch_resolve)"
-
-msg_info "Configuring LeafWiki"
-mkdir -p /opt/leafwiki/data
-mkdir -p /etc/leafwiki
-JWT_SECRET=$(openssl rand -hex 32)
-ADMIN_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c12)
-cat </etc/leafwiki/.env
-LEAFWIKI_DATA_DIR=/opt/leafwiki/data
-LEAFWIKI_HOST=0.0.0.0
-LEAFWIKI_PORT=8080
-LEAFWIKI_JWT_SECRET=${JWT_SECRET}
-LEAFWIKI_ADMIN_PASSWORD=${ADMIN_PASS}
-LEAFWIKI_ALLOW_INSECURE=true
-EOF
-msg_ok "Configured LeafWiki"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/leafwiki.service
-[Unit]
-Description=LeafWiki
-After=network.target
-
-[Service]
-Type=simple
-User=root
-EnvironmentFile=/etc/leafwiki/.env
-ExecStart=/usr/local/bin/leafwiki
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now leafwiki
-msg_ok "Created Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/localagi-install.sh b/install/localagi-install.sh
deleted file mode 100644
index 3589d1b8b..000000000
--- a/install/localagi-install.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: BillyOutlast
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/mudler/LocalAGI
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-APP="LocalAGI"
-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" setup_nodejs
-setup_go
-
-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 "localagi" "mudler/LocalAGI" "tarball" "latest" "/opt/localagi"
-
-msg_info "Configuring LocalAGI"
-mkdir -p /opt/localagi/pool
-cat <<'EOF' >/opt/localagi/.env
-LOCALAGI_MODEL=gemma-3-4b-it-qat
-LOCALAGI_MULTIMODAL_MODEL=moondream2-20250414
-LOCALAGI_IMAGE_MODEL=sd-1.5-ggml
-LOCALAGI_LLM_API_URL=http://127.0.0.1:11434/v1
-LOCALAGI_STATE_DIR=/opt/localagi/pool
-EOF
-msg_ok "Configured LocalAGI"
-
-msg_info "Setting up LocalAGI"
-cd /opt/localagi/webui/react-ui
-$STD bun install
-$STD bun run build
-cd /opt/localagi
-$STD go build -o /usr/local/bin/localagi
-msg_ok "Set up LocalAGI"
-
-msg_info "Creating LocalAGI systemd service"
-cat </etc/systemd/system/localagi.service
-[Unit]
-Description=LocalAGI
-After=network.target
-
-[Service]
-User=root
-Type=simple
-EnvironmentFile=/opt/localagi/.env
-
-WorkingDirectory=/opt/localagi
-ExecStart=/usr/local/bin/localagi
-Restart=on-failure
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now localagi
-msg_ok "Created LocalAGI systemd service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/n8n-install.sh b/install/n8n-install.sh
index c6f0d421a..8ddf37d0b 100644
--- a/install/n8n-install.sh
+++ b/install/n8n-install.sh
@@ -16,6 +16,7 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
+ python3 \
python3-setuptools \
graphicsmagick
msg_ok "Installed Dependencies"
@@ -23,7 +24,7 @@ msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
msg_info "Installing n8n (Patience)"
-$STD npm install -g n8n@latest
+$STD npm install -g n8n@2.27.5
msg_ok "Installed n8n"
msg_info "Creating Service"
diff --git a/install/nexterm-install.sh b/install/nexterm-install.sh
deleted file mode 100644
index 1ef0ecfe8..000000000
--- a/install/nexterm-install.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: Mathias Wagner (gnmyt)
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://nexterm.dev/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-$(arch_resolve "x64" "arm64").tar.gz"
-fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
-
-msg_info "Configuring Nexterm"
-LOCAL_ENGINE_TOKEN=$(tr -d '-' /etc/nexterm-engine/config.yaml
-server_host: "127.0.0.1"
-server_port: 7800
-registration_token: "${LOCAL_ENGINE_TOKEN}"
-tls: false
-EOF
-cat </etc/nexterm-server/server.env
-NODE_ENV=production
-SERVER_PORT=6989
-LOCAL_ENGINE_TOKEN=${LOCAL_ENGINE_TOKEN}
-ENCRYPTION_KEY=${ENCRYPTION_KEY}
-EOF
-chmod 0640 /etc/nexterm-engine/config.yaml /etc/nexterm-server/server.env
-msg_ok "Configured Nexterm"
-
-msg_info "Creating Services"
-cat </etc/systemd/system/nexterm-server.service
-[Unit]
-Description=Nexterm Server
-Documentation=https://docs.nexterm.dev/
-After=network-online.target
-Wants=network-online.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/nexterm/data
-EnvironmentFile=/etc/nexterm-server/server.env
-ExecStart=/opt/nexterm/server/nexterm-server
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-cat </etc/systemd/system/nexterm-engine.service
-[Unit]
-Description=Nexterm Engine
-Documentation=https://docs.nexterm.dev/
-After=network-online.target nexterm-server.service
-Wants=network-online.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/etc/nexterm-engine
-Environment=FREERDP_EXTENSION_PATH=/opt/nexterm/engine/lib/freerdp2
-Environment=LD_LIBRARY_PATH=/opt/nexterm/engine/lib
-ExecStart=/opt/nexterm/engine/nexterm-engine
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now nexterm-server
-sleep 5
-systemctl enable -q --now nexterm-engine
-msg_ok "Created Services"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/notediscovery-install.sh b/install/notediscovery-install.sh
deleted file mode 100644
index 26687f8c6..000000000
--- a/install/notediscovery-install.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/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/gamosoft/NoteDiscovery
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-setup_uv
-
-fetch_and_deploy_gh_release "notediscovery" "gamosoft/NoteDiscovery" "tarball"
-
-msg_info "Installing Dependencies"
-cd /opt/notediscovery
-$STD uv sync --no-dev
-msg_ok "Installed Dependencies"
-
-msg_info "Configuring NoteDiscovery"
-mkdir -p /opt/notediscovery/data
-msg_ok "Configured NoteDiscovery"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/notediscovery.service
-[Unit]
-Description=NoteDiscovery Knowledge Base
-After=network.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/notediscovery
-ExecStart=/opt/notediscovery/.venv/bin/python /opt/notediscovery/run.py
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now notediscovery
-msg_ok "Created Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/opencloud-install.sh b/install/opencloud-install.sh
index d0cb26994..608440062 100644
--- a/install/opencloud-install.sh
+++ b/install/opencloud-install.sh
@@ -64,7 +64,7 @@ $STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPA
echo "$COOLPASS" >~/.coolpass
msg_ok "Installed Collabora Online"
-fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.3.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
+fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.2.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
mv /usr/bin/OpenCloud /usr/bin/opencloud
msg_info "Configuring OpenCloud"
diff --git a/install/oxicloud-install.sh b/install/oxicloud-install.sh
deleted file mode 100644
index 1b80f103c..000000000
--- a/install/oxicloud-install.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: vhsdream
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://github.com/DioCrafts/OxiCloud
-
-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" setup_nodejs
-PG_VERSION="17" setup_postgresql
-PG_DB_NAME="oxicloud" PG_DB_USER="oxicloud" setup_postgresql_db
-fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
-TOOLCHAIN="$(grep -oP 'FROM\s+rust:\K[0-9]+\.[0-9]+(\.[0-9]+)?' /opt/oxicloud/Dockerfile | head -1)"
-RUST_TOOLCHAIN="${TOOLCHAIN:-stable}" setup_rust
-
-msg_info "Building Frontend SPA"
-cd /opt/oxicloud/frontend
-$STD npm ci
-$STD npm run build
-msg_ok "Built Frontend SPA"
-
-msg_info "Building OxiCloud (Patience)"
-cd /opt/oxicloud
-export DATABASE_URL="postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}"
-export RUSTFLAGS="-C target-cpu=native"
-RAM_MB=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo)
-CARGO_JOBS=$((RAM_MB / 2560))
-[[ $CARGO_JOBS -lt 1 ]] && CARGO_JOBS=1
-[[ $CARGO_JOBS -gt $(nproc) ]] && CARGO_JOBS=$(nproc)
-$STD cargo build --release -j "$CARGO_JOBS" --bin oxicloud --bin migrate-nfc-filenames
-mv target/release/oxicloud /usr/local/bin/oxicloud
-mv target/release/migrate-nfc-filenames /usr/local/bin/migrate-nfc-filenames
-rm -rf /opt/oxicloud/static
-mv /opt/oxicloud/static-dist /opt/oxicloud/static
-rm -rf /opt/oxicloud/target /opt/oxicloud/frontend/node_modules
-msg_ok "Built OxiCloud"
-
-msg_info "Configuring OxiCloud"
-mkdir -p {/mnt/oxicloud,/etc/oxicloud}
-sed -e 's|OXICLOUD_STORAGE_PATH=.*|OXICLOUD_STORAGE_PATH=/mnt/oxicloud|' \
- -e 's|OXICLOUD_SERVER_HOST=.*|OXICLOUD_SERVER_HOST=0.0.0.0|' \
- -e 's|OXICLOUD_STATIC_PATH=.*|OXICLOUD_STATIC_PATH=/opt/oxicloud/static|' \
- -e "s|^#OXICLOUD_BASE_URL=.*|OXICLOUD_BASE_URL=http://${LOCAL_IP}:8086|" \
- -e "s|OXICLOUD_DB_CONNECTION_STRING=.*|OXICLOUD_DB_CONNECTION_STRING=${DATABASE_URL}|" \
- -e "s|^DATABASE_URL=.*|DATABASE_URL=${DATABASE_URL}|" \
- -e "s|^#OXICLOUD_JWT_SECRET=.*|OXICLOUD_JWT_SECRET=$(openssl rand -hex 32)|" \
- /opt/oxicloud/example.env >/etc/oxicloud/.env
-chmod 600 /etc/oxicloud/.env
-msg_ok "Configured OxiCloud"
-
-msg_info "Creating OxiCloud Service"
-cat </etc/systemd/system/oxicloud.service
-[Unit]
-Description=OxiCloud Service
-After=network.target postgresql.service
-Requires=postgresql.service
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/oxicloud
-EnvironmentFile=/etc/oxicloud/.env
-ExecStart=/usr/local/bin/oxicloud
-Restart=always
-RestartSec=5
-StandardOutput=journal
-StandardError=journal
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now oxicloud
-msg_ok "Created OxiCloud Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/pangolin-install.sh b/install/pangolin-install.sh
index 0a8f008af..ab3fc5095 100644
--- a/install/pangolin-install.sh
+++ b/install/pangolin-install.sh
@@ -16,19 +16,18 @@ update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
+ python3 \
+ sqlite3 \
iptables
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
-PG_VERSION="17" setup_postgresql
-PG_DB_NAME="pangolin" PG_DB_USER="pangolin" setup_postgresql_db
-PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
+PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.18.4}"
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
-[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
read -rp "${TAB3}Enter your email address: " pango_email
msg_info "Setup Pangolin"
@@ -37,14 +36,13 @@ BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
cd /opt/pangolin
mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs}
$STD npm ci
-$STD npm run set:pg
+$STD npm run set:sqlite
$STD npm run set:oss
rm -rf server/private
-DATABASE_URL="postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin" $STD npm run db:generate
+$STD npm run db:generate
$STD npm run build
$STD npm run build:cli
cp -R .next/standalone ./
-cp -r server/migrations ./dist/init
cat </usr/local/bin/pangctl
#!/bin/sh
@@ -76,9 +74,6 @@ flags:
require_email_verification: false
disable_signup_without_invite: false
disable_user_create_org: false
-
-postgres:
- connection_string: "postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin"
EOF
cat </opt/pangolin/config/traefik/traefik_config.yml
@@ -186,8 +181,7 @@ http:
servers:
- url: "http://$LOCAL_IP:3000"
EOF
-export ENVIRONMENT=prod
-$STD node dist/migrations.mjs
+$STD npm run db:push
. /etc/os-release
if [ "$VERSION_CODENAME" = "trixie" ]; then
@@ -203,8 +197,7 @@ msg_info "Creating Services"
cat </etc/systemd/system/pangolin.service
[Unit]
Description=Pangolin Service
-After=network.target postgresql.service
-Wants=postgresql.service
+After=network.target
[Service]
Type=simple
diff --git a/install/pihole-install.sh b/install/pihole-install.sh
index 547d79f23..c88a7c997 100644
--- a/install/pihole-install.sh
+++ b/install/pihole-install.sh
@@ -119,8 +119,7 @@ edns-packet-max=1232
EOF
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
- cat <>/etc/unbound/unbound.conf.d/pi-hole.conf
-server:
+ cat </etc/unbound/unbound.conf.d/pi-hole.conf
tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
forward-zone:
name: "."
diff --git a/install/plane-install.sh b/install/plane-install.sh
index d481c6551..2c03938a3 100644
--- a/install/plane-install.sh
+++ b/install/plane-install.sh
@@ -85,8 +85,8 @@ VITE_SPACE_BASE_PATH=/spaces
VITE_LIVE_BASE_URL=http://${LOCAL_IP}
VITE_LIVE_BASE_PATH=/live"
# Each Vite app needs its own .env for the build
-for frontend_app in web admin space; do
- echo "$FRONTEND_ENV" >/opt/plane/apps/${frontend_app}/.env
+for app in web admin space; do
+ echo "$FRONTEND_ENV" >/opt/plane/apps/${app}/.env
done
export NODE_OPTIONS="--max-old-space-size=4096"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
diff --git a/install/pocketid-install.sh b/install/pocketid-install.sh
index 11b8fa591..47f945d3b 100644
--- a/install/pocketid-install.sh
+++ b/install/pocketid-install.sh
@@ -14,7 +14,7 @@ network_check
update_os
read -r -p "${TAB3}What public URL do you want to use (e.g. pocketid.mydomain.com)? " public_url
-fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id_linux_$(arch_resolve)"
+fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id-linux-$(arch_resolve)"
msg_info "Configuring Pocket ID"
ENCRYPTION_KEY=$(openssl rand -base64 32)
diff --git a/install/reitti-install.sh b/install/reitti-install.sh
index 512b0cd13..2810b1495 100644
--- a/install/reitti-install.sh
+++ b/install/reitti-install.sh
@@ -30,30 +30,27 @@ mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
msg_info "Installing Nginx Tile Cache"
mkdir -p /var/cache/nginx/tiles
-cat <<'NGINXEOF' >/etc/nginx/nginx.conf
+cat </etc/nginx/nginx.conf
user www-data;
events {
worker_connections 1024;
}
http {
- resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off;
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
server {
listen 80;
- location /custom/ {
- set $upstream_url $http_x_reitti_upstream_url;
- proxy_pass $upstream_url;
- proxy_set_header Host $proxy_host;
+ location / {
+ proxy_pass https://tile.openstreetmap.org/;
+ proxy_set_header Host tile.openstreetmap.org;
proxy_set_header User-Agent "Reitti/1.0";
proxy_cache tiles;
- proxy_cache_key $upstream_url;
proxy_cache_valid 200 30d;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
}
}
}
-NGINXEOF
+EOF
chown -R www-data:www-data /var/cache/nginx
chmod -R 750 /var/cache/nginx
systemctl restart nginx
@@ -74,7 +71,6 @@ server.compression.mime-types=text/plain,application/json
logging.level.root=INFO
logging.level.org.hibernate.engine.jdbc.spi.SqlExceptionHelper=FATAL
logging.level.com.dedicatedcode.reitti=INFO
-logging.level.org.quartz.core.ErrorLogger=FATAL
# Internationalization
spring.messages.basename=messages
@@ -86,7 +82,7 @@ spring.messages.fallback-to-system-locale=false
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/$PG_DB_NAME
spring.datasource.username=$PG_DB_USER
spring.datasource.password=$PG_DB_PASS
-spring.datasource.hikari.maximum-pool-size=30
+spring.datasource.hikari.maximum-pool-size=20
# Redis configuration
spring.data.redis.host=127.0.0.1
@@ -96,23 +92,20 @@ spring.data.redis.password=
spring.data.redis.database=0
spring.cache.redis.key-prefix=
-spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings,devices,mapStyles,mapStyleJson
+spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings
spring.cache.redis.time-to-live=1d
# Upload configuration
spring.servlet.multipart.max-file-size=5GB
spring.servlet.multipart.max-request-size=5GB
-spring.servlet.multipart.resolve-lazily=true
server.tomcat.max-part-count=100
-spring.mvc.async.request-timeout=600000
-# Quartz Scheduler configuration
-spring.quartz.job-store-type=jdbc
-spring.quartz.jdbc.initialize-schema=never
-spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
-spring.quartz.properties.org.quartz.jobStore.isClustered=false
-spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
-spring.quartz.properties.org.quartz.threadPool.threadCount=5
+# Rqueue configuration
+rqueue.web.enable=false
+rqueue.job.enabled=false
+rqueue.message.durability.in-terminal-state=0
+rqueue.key.prefix=\${spring.cache.redis.key-prefix}
+rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter
# Application-specific settings
reitti.server.advertise-uri=
@@ -124,25 +117,18 @@ reitti.security.oidc.enabled=false
reitti.security.oidc.registration.enabled=false
reitti.import.batch-size=10000
-reitti.import.grace-time-seconds=30
-reitti.import.staging.cleanup.cron=0 0 4 * * *
-
-reitti.batching.max-batch-size=100
-reitti.batching.max-wait-time=5
+reitti.import.processing-idle-start-time=10
reitti.geo-point-filter.max-speed-kmh=1000
reitti.geo-point-filter.max-accuracy-meters=100
reitti.geo-point-filter.history-lookback-hours=24
reitti.geo-point-filter.window-size=50
+reitti.process-data.schedule=0 */10 * * * *
reitti.process-data.refresh-views.schedule=0 0 4 * * *
reitti.imports.schedule=0 5/10 * * * *
reitti.imports.owntracks-recorder.schedule=\${reitti.imports.schedule}
-reitti.jobs.cleanup.cron=0 0 4 * * ?
-reitti.jobs.cleanup.max-age-hours=24
-reitti.db-janitor.schedule=0 0 4 * * ?
-
# Geocoding service configuration
reitti.geocoding.max-errors=10
reitti.geocoding.photon.base-url=
diff --git a/install/sftpgo-install.sh b/install/sftpgo-install.sh
index 5547d2e59..d27d4f761 100644
--- a/install/sftpgo-install.sh
+++ b/install/sftpgo-install.sh
@@ -19,8 +19,8 @@ msg_ok "Installed Dependencies"
setup_deb822_repo \
"sftpgo" \
- "https://oss.sftpgo.com/apt/gpg.key" \
- "https://oss.sftpgo.com/apt" \
+ "https://ftp.osuosl.org/pub/sftpgo/apt/gpg.key" \
+ "https://ftp.osuosl.org/pub/sftpgo/apt" \
"trixie"
msg_info "Installing SFTPGo"
diff --git a/install/shinobi-install.sh b/install/shinobi-install.sh
index 6107c6488..383325016 100644
--- a/install/shinobi-install.sh
+++ b/install/shinobi-install.sh
@@ -54,7 +54,7 @@ cronKey=$(head -c 1024 /etc/systemd/system/silverbullet.service
[Unit]
@@ -36,7 +25,6 @@ After=syslog.target network.target
[Service]
User=root
Type=simple
-${RUNTIME_API_ENV}
ExecStart=/opt/silverbullet/bin/silverbullet --hostname 0.0.0.0 --port 3000 /opt/silverbullet/space
WorkingDirectory=/opt/silverbullet
Restart=on-failure
diff --git a/install/snapotter-install.sh b/install/snapotter-install.sh
index b8330b7ca..7878c441a 100644
--- a/install/snapotter-install.sh
+++ b/install/snapotter-install.sh
@@ -39,19 +39,6 @@ msg_ok "Installed Dependencies"
PYTHON_VERSION="3.11" setup_uv
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
-PG_VERSION="17" setup_postgresql
-PG_DB_NAME="snapotter" PG_DB_USER="snapotter" setup_postgresql_db
-
-msg_info "Installing Redis"
-$STD apt install -y redis-server
-if grep -q '^appendonly ' /etc/redis/redis.conf; then
- sed -i 's/^appendonly .*/appendonly yes/' /etc/redis/redis.conf
-else
- echo 'appendonly yes' >>/etc/redis/redis.conf
-fi
-$STD systemctl enable --now redis-server
-msg_ok "Installed Redis"
-
fetch_and_deploy_gh_release "caire" "esimov/caire" "prebuild" "latest" "/usr/local/bin" "caire-*-linux-amd64.tar.gz"
fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "prebuild" "latest" "/opt/snapotter" "snapotter-*-linux-amd64.tar.gz"
@@ -74,8 +61,7 @@ mkdir -p /tmp/snapotter-workspace
cat </opt/snapotter_data/.env
PORT=1349
NODE_ENV=production
-DATABASE_URL=postgres://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
-REDIS_URL=redis://127.0.0.1:6379
+DB_PATH=/opt/snapotter_data/snapotter.db
WORKSPACE_PATH=/tmp/snapotter-workspace
FILES_STORAGE_PATH=/opt/snapotter_data/files
PYTHON_VENV_PATH=/opt/snapotter_data/ai/venv
@@ -99,9 +85,7 @@ PNPM_BIN="$(command -v pnpm)"
cat </etc/systemd/system/snapotter.service
[Unit]
Description=SnapOtter Service
-Wants=network-online.target
-After=network-online.target postgresql.service redis-server.service
-Requires=postgresql.service redis-server.service
+After=network.target
[Service]
Type=simple
@@ -115,7 +99,6 @@ RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
-systemctl daemon-reload
systemctl enable -q --now snapotter
msg_ok "Created Service"
diff --git a/install/squid-install.sh b/install/squid-install.sh
deleted file mode 100644
index aa0110820..000000000
--- a/install/squid-install.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2021-2026 community-scripts ORG
-# Author: 007hacky007
-# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
-# Source: https://www.squid-cache.org/
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-msg_info "Configuring Squid"
-mkdir -p /etc/squid
-cat </etc/squid/squid.conf
-acl localnet src 0.0.0.1-0.255.255.255
-acl localnet src 10.0.0.0/8
-acl localnet src 100.64.0.0/10
-acl localnet src 169.254.0.0/16
-acl localnet src 172.16.0.0/12
-acl localnet src 192.168.0.0/16
-acl localnet src fc00::/7
-acl localnet src fe80::/10
-
-acl SSL_ports port 443
-acl Safe_ports port 80
-acl Safe_ports port 21
-acl Safe_ports port 443
-acl Safe_ports port 70
-acl Safe_ports port 210
-acl Safe_ports port 1025-65535
-acl Safe_ports port 280
-acl Safe_ports port 488
-acl Safe_ports port 591
-acl Safe_ports port 777
-acl CONNECT method CONNECT
-
-http_access deny !Safe_ports
-http_access deny CONNECT !SSL_ports
-http_access allow localhost manager
-http_access deny manager
-
-auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwords
-auth_param basic realm proxy
-acl authenticated proxy_auth REQUIRED
-http_access allow authenticated
-http_access deny all
-
-http_port 3128
-
-coredump_dir /var/spool/squid
-
-refresh_pattern ^ftp: 1440 20% 10080
-refresh_pattern ^gopher: 1440 0% 1440
-refresh_pattern -i (/cgi-bin/|\\?) 0 0% 0
-refresh_pattern . 0 20% 4320
-
-# Privacy / hardening
-httpd_suppress_version_string on
-visible_hostname $(hostname)
-forwarded_for delete
-request_header_access X-Forwarded-For deny all
-EOF
-msg_ok "Configured Squid"
-
-msg_info "Installing Dependencies"
-$STD apt install -y \
- squid \
- apache2-utils
-msg_ok "Installed Dependencies"
-
-msg_info "Configuring Squid Authentication"
-touch /etc/squid/passwords
-chown proxy:proxy /etc/squid/passwords
-chmod 640 /etc/squid/passwords
-$STD squid -k parse
-msg_ok "Configured Squid Authentication"
-
-msg_info "Starting Service"
-systemctl enable -q --now squid
-msg_ok "Started Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/storyteller-install.sh b/install/storyteller-install.sh
index 1df32ec27..b3b343da6 100644
--- a/install/storyteller-install.sh
+++ b/install/storyteller-install.sh
@@ -28,7 +28,7 @@ NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "latest" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz"
ln -sf /opt/readium/readium /usr/local/bin/readium
-fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2"
+fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller"
msg_info "Setting up Storyteller"
cd /opt/storyteller
diff --git a/install/sync-in-install.sh b/install/sync-in-install.sh
deleted file mode 100644
index 0550fecca..000000000
--- a/install/sync-in-install.sh
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/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/Sync-in/server
-
-source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
-color
-verb_ip6
-catch_errors
-setting_up_container
-network_check
-update_os
-
-NODE_VERSION="22" setup_nodejs
-setup_mariadb
-MARIADB_DB_NAME="sync_in" MARIADB_DB_USER="sync_in" setup_mariadb_db
-
-msg_info "Installing Sync-in"
-mkdir -p /opt/sync-in/data
-$STD npm install --prefix /opt/sync-in @sync-in/server
-msg_ok "Installed Sync-in"
-
-msg_info "Configuring Sync-in"
-ENCRYPT_KEY=$(openssl rand -hex 32)
-ACCESS_SECRET=$(openssl rand -hex 32)
-REFRESH_SECRET=$(openssl rand -hex 32)
-cat </opt/sync-in/environment.yaml
-server:
- port: 8080
-mysql:
- url: 'mysql://${MARIADB_DB_USER}:${MARIADB_DB_PASS}@localhost:3306/${MARIADB_DB_NAME}'
-auth:
- encryptionKey: '${ENCRYPT_KEY}'
- token:
- access:
- secret: '${ACCESS_SECRET}'
- refresh:
- secret: '${REFRESH_SECRET}'
-applications:
- files:
- dataPath: '/opt/sync-in/data'
-EOF
-msg_ok "Configured Sync-in"
-
-msg_info "Running Database Migrations"
-cd /opt/sync-in
-$STD npx sync-in-server migrate-db
-msg_ok "Ran Database Migrations"
-
-msg_info "Creating Admin User"
-cd /opt/sync-in
-$STD npx sync-in-server create-user
-msg_ok "Created Admin User"
-
-VERSION=$(node -pe "require('/opt/sync-in/node_modules/@sync-in/server/package.json').version" 2>/dev/null || echo "")
-[[ -n "$VERSION" ]] && echo "$VERSION" >~/.sync-in
-
-msg_info "Creating Service"
-cat </etc/systemd/system/sync-in.service
-[Unit]
-Description=Sync-in Server
-After=network.target mariadb.service
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/sync-in
-ExecStart=/opt/sync-in/node_modules/.bin/sync-in-server start
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now sync-in
-msg_ok "Created Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/install/wanderer-install.sh b/install/wanderer-install.sh
index 6a8571bbf..3cebc9fef 100644
--- a/install/wanderer-install.sh
+++ b/install/wanderer-install.sh
@@ -20,8 +20,7 @@ if [[ "$(arch_resolve)" == "arm64" ]]; then
else
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" "latest" "/opt/wanderer/source/search"
fi
-mkdir -p /opt/wanderer/{source,data/pb_data,data/meili_data,data/plugins}
-[[ -e /data/plugins ]] || ln -sfn /opt/wanderer/data/plugins /data/plugins
+mkdir -p /opt/wanderer/{source,data/pb_data,data/meili_data}
fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
msg_info "Installing wanderer (patience)"
@@ -33,12 +32,6 @@ $STD npm ci
$STD npm run build
msg_ok "Installed wanderer"
-msg_info "Installing wanderer plugins"
-for plugin in hammerhead komoot strava; do
- fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer/data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
-done
-msg_ok "Installed wanderer plugins"
-
msg_info "Creating Service"
MEILI_KEY=$(openssl rand -hex 32)
POCKETBASE_KEY=$(openssl rand -hex 16)
diff --git a/install/webtrees-install.sh b/install/webtrees-install.sh
index 69b735e46..c2be2e79e 100644
--- a/install/webtrees-install.sh
+++ b/install/webtrees-install.sh
@@ -47,8 +47,6 @@ msg_ok "Configured Caddy"
msg_info "Automating Webtrees Setup"
cd /opt/webtrees
-mkdir -p /opt/webtrees/data
-chown -R www-data:www-data /opt/webtrees/data
WT_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c15)
$STD sudo -u www-data php /opt/webtrees/index.php config-ini \
--dbhost=127.0.0.1 \
@@ -58,15 +56,6 @@ $STD sudo -u www-data php /opt/webtrees/index.php config-ini \
--dbname=webtrees \
--tblpfx=wt_ \
--base-url="http://${LOCAL_IP}"
-msg_info "Initializing Webtrees database schema"
-for i in {1..15}; do
- if curl -sf "http://127.0.0.1/" >/dev/null 2>&1; then
- break
- fi
- sleep 2
-done
-$STD mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user
-msg_ok "Initialized Webtrees database schema"
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \
--create \
--real-name="Administrator" \
diff --git a/install/wizarr-install.sh b/install/wizarr-install.sh
index ba6bca712..57a152d11 100644
--- a/install/wizarr-install.sh
+++ b/install/wizarr-install.sh
@@ -27,17 +27,15 @@ cd /opt/wizarr
$STD /usr/local/bin/uv sync --frozen
$STD /usr/local/bin/uv run --frozen pybabel compile -d app/translations
$STD npm --prefix app/static install
-$STD npm --prefix app/static run build
+$STD npm --prefix app/static run build:css
mkdir -p ./.cache
cat </opt/wizarr/.env
FLASK_ENV=production
GUNICORN_WORKERS=4
APP_URL=http://${LOCAL_IP}
-HOST=0.0.0.0
-PORT=5690
DISABLE_BUILTIN_AUTH=false
LOG_LEVEL=INFO
-APP_VERSION=$(get_latest_github_release "wizarrrr/wizarr")
+APP_VERSION=v$(get_latest_github_release "wizarrrr/wizarr")
EOF
cat </opt/wizarr/start.sh
@@ -46,6 +44,7 @@ cat </opt/wizarr/start.sh
uv run --frozen gunicorn \
--config gunicorn.conf.py \
--preload \
+ --bind 0.0.0.0:5690 \
--umask 007 \
run:app
EOF
@@ -63,10 +62,7 @@ Type=simple
WorkingDirectory=/opt/wizarr
EnvironmentFile=/opt/wizarr/.env
ExecStart=/opt/wizarr/start.sh
-Restart=always
-RestartSec=10
-KillMode=mixed
-TimeoutStopSec=10
+Restart=on-abnormal
[Install]
WantedBy=multi-user.target
diff --git a/install/yuvomi-install.sh b/install/yuvomi-install.sh
deleted file mode 100644
index 521049586..000000000
--- a/install/yuvomi-install.sh
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/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/ulsklyc/yuvomi
-
-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 \
- python3 \
- make \
- g++ \
- libsqlcipher-dev
-msg_ok "Installed Dependencies"
-
-NODE_VERSION="22" setup_nodejs
-
-fetch_and_deploy_gh_release "yuvomi" "ulsklyc/yuvomi" "tarball"
-
-msg_info "Installing Node.js Dependencies"
-cd /opt/yuvomi
-$STD npm ci --omit=dev
-msg_ok "Installed Node.js Dependencies"
-
-msg_info "Configuring Yuvomi"
-mkdir -p /opt/yuvomi/data /opt/yuvomi/backups
-SESSION_SECRET=$(openssl rand -hex 32)
-DB_ENCRYPT_KEY=$(openssl rand -hex 32)
-cat </opt/yuvomi/.env
-PORT=3000
-NODE_ENV=production
-DB_PATH=/opt/yuvomi/data/yuvomi.db
-DB_ENCRYPTION_KEY=${DB_ENCRYPT_KEY}
-SESSION_SECRET=${SESSION_SECRET}
-RATE_LIMIT_WINDOW_MS=60000
-RATE_LIMIT_MAX_ATTEMPTS=5
-RATE_LIMIT_BLOCK_DURATION_MS=900000
-EOF
-msg_ok "Configured Yuvomi"
-
-msg_info "Creating Service"
-cat </etc/systemd/system/yuvomi.service
-[Unit]
-Description=Yuvomi Family Planner
-After=network.target
-
-[Service]
-Type=simple
-User=root
-WorkingDirectory=/opt/yuvomi
-EnvironmentFile=/opt/yuvomi/.env
-ExecStart=/usr/bin/node server/index.js
-Restart=on-failure
-RestartSec=5
-
-[Install]
-WantedBy=multi-user.target
-EOF
-systemctl enable -q --now yuvomi
-msg_ok "Created Service"
-
-motd_ssh
-customize
-cleanup_lxc
diff --git a/misc/build.func b/misc/build.func
index f22692d42..bf74bd3b6 100644
--- a/misc/build.func
+++ b/misc/build.func
@@ -1009,7 +1009,6 @@ base_settings() {
APT_CACHER=${var_apt_cacher:-""}
APT_CACHER_IP=${var_apt_cacher_ip:-""}
- INHERIT_HOST_CA="${var_inherit_host_ca:-auto}"
# Runtime check: Verify APT cacher is reachable if configured
if [[ -n "$APT_CACHER_IP" && "$APT_CACHER" == "yes" ]]; then
@@ -1089,7 +1088,7 @@ load_vars_file() {
# Allowed var_* keys
local VAR_WHITELIST=(
- var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
+ var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage var_searchdomain
@@ -1286,12 +1285,6 @@ load_vars_file() {
continue
fi
;;
- var_inherit_host_ca)
- if [[ "$var_val" != "yes" && "$var_val" != "no" && "$var_val" != "auto" ]]; then
- msg_warn "Invalid host CA inheritance value '$var_val' in $file (must be yes/no/auto), ignoring"
- continue
- fi
- ;;
var_container_storage | var_template_storage)
# Validate that the storage exists and is active on the current node
local _storage_status
@@ -1331,7 +1324,7 @@ default_var_settings() {
# Allowed var_* keys (alphabetically sorted)
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
local VAR_WHITELIST=(
- var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
+ var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
@@ -1414,7 +1407,6 @@ var_ssh=no
# HTTP/HTTPS proxy (optional - for networks requiring a proxy)
# var_http_proxy=http://proxy.local:8080
# var_http_no_proxy=localhost,127.0.0.1,.local
-# var_inherit_host_ca=auto
# Features/Tags/verbosity
var_fuse=no
@@ -1515,7 +1507,7 @@ get_app_defaults_path() {
if ! declare -p VAR_WHITELIST >/dev/null 2>&1; then
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
declare -ag VAR_WHITELIST=(
- var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_inherit_host_ca var_keyctl
+ var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_github_token var_gpu var_http_no_proxy var_http_proxy var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_os var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_version var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage var_searchdomain
@@ -1665,7 +1657,6 @@ _build_current_app_vars_tmp() {
_apt_cacher_ip="${APT_CACHER_IP:-}"
_http_proxy="${HTTP_PROXY:-${var_http_proxy:-}}"
_http_no_proxy="${HTTP_NO_PROXY:-${var_http_no_proxy:-}}"
- _inherit_host_ca="${INHERIT_HOST_CA:-${var_inherit_host_ca:-auto}}"
_fuse="${ENABLE_FUSE:-no}"
_tun="${ENABLE_TUN:-no}"
_gpu="${ENABLE_GPU:-no}"
@@ -1719,7 +1710,6 @@ _build_current_app_vars_tmp() {
[ -n "$_apt_cacher_ip" ] && echo "var_apt_cacher_ip=$(_sanitize_value "$_apt_cacher_ip")"
[ -n "$_http_proxy" ] && echo "var_http_proxy=$(_sanitize_value "$_http_proxy")"
[ -n "$_http_no_proxy" ] && echo "var_http_no_proxy=$(_sanitize_value "$_http_no_proxy")"
- [ -n "$_inherit_host_ca" ] && echo "var_inherit_host_ca=$(_sanitize_value "$_inherit_host_ca")"
[ -n "$_fuse" ] && echo "var_fuse=$(_sanitize_value "$_fuse")"
[ -n "$_tun" ] && echo "var_tun=$(_sanitize_value "$_tun")"
@@ -1884,7 +1874,7 @@ advanced_settings() {
TAGS="community-script${var_tags:+;${var_tags}}"
fi
local STEP=1
- local MAX_STEP=31
+ local MAX_STEP=30
# Store values for back navigation - inherit from var_* app defaults
local _ct_type="${var_unprivileged:-1}"
@@ -1906,7 +1896,6 @@ advanced_settings() {
local _apt_cacher_ip="${var_apt_cacher_ip:-}"
local _http_proxy="${var_http_proxy:-}"
local _http_no_proxy="${var_http_no_proxy:-}"
- local _inherit_host_ca="${var_inherit_host_ca:-auto}"
local _mtu="${var_mtu:-}"
local _sd="${var_searchdomain:-}"
local _ns="${var_ns:-}"
@@ -2736,47 +2725,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
- # STEP 25: Host CA Inheritance
+ # STEP 25: Container Timezone
# ═══════════════════════════════════════════════════════════════════════════
25)
- local host_ca_count=0
- local host_ca_dir="/usr/local/share/ca-certificates"
- local cert
- shopt -s nullglob
- for cert in "$host_ca_dir"/*.crt; do
- host_ca_count=$((host_ca_count + 1))
- done
- shopt -u nullglob
-
- if [[ $host_ca_count -eq 0 ]]; then
- _inherit_host_ca="auto"
- ((STEP++))
- continue
- fi
-
- local host_ca_default_flag=""
- [[ "$_inherit_host_ca" == "no" ]] && host_ca_default_flag="--defaultno"
- if whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
- --title "HOST CA INHERITANCE" \
- --ok-button "Next" --cancel-button "Back" \
- $host_ca_default_flag \
- --yesno "\nInherit host CA certificates into this container?\n\nDetected on host: ${host_ca_count} certificate(s) in:\n${host_ca_dir}\n\nRecommended for private PKI / TLS-inspection environments.\n\n(App default: ${var_inherit_host_ca:-auto})" 16 72; then
- _inherit_host_ca="yes"
- else
- if [ $? -eq 1 ]; then
- _inherit_host_ca="no"
- else
- ((STEP--))
- continue
- fi
- fi
- ((STEP++))
- ;;
-
- # ═══════════════════════════════════════════════════════════════════════════
- # STEP 26: Container Timezone
- # ═══════════════════════════════════════════════════════════════════════════
- 26)
local tz_hint="$_ct_timezone"
[[ -z "$tz_hint" ]] && tz_hint="(empty - will use host timezone)"
@@ -2799,9 +2750,9 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
- # STEP 27: Container Protection
+ # STEP 26: Container Protection
# ═══════════════════════════════════════════════════════════════════════════
- 27)
+ 26)
local protect_default_flag="--defaultno"
[[ "$_protect_ct" == "yes" || "$_protect_ct" == "1" ]] && protect_default_flag=""
@@ -2953,7 +2904,6 @@ Leave empty to skip."
local apt_display="${_apt_cacher:-no}"
[[ "$_apt_cacher" == "yes" && -n "$_apt_cacher_ip" ]] && apt_display="$_apt_cacher_ip"
local http_proxy_display="${_http_proxy:-(none)}"
- local inherit_ca_display="${_inherit_host_ca:-auto}"
local post_install_display="${_post_install:-(none)}"
local post_install_warn=""
@@ -2984,7 +2934,6 @@ Advanced:
Timezone: $tz_display
APT Cacher: $apt_display
HTTP Proxy: $http_proxy_display
- Inherit Host CAs: $inherit_ca_display
Verbose: $_verbose
Post-Install Script: ${post_install_display}${post_install_warn}"
@@ -3030,7 +2979,6 @@ Advanced:
APT_CACHER_IP="$_apt_cacher_ip"
HTTP_PROXY="$_http_proxy"
HTTP_NO_PROXY="$_http_no_proxy"
- INHERIT_HOST_CA="$_inherit_host_ca"
VERBOSE="$_verbose"
var_post_install="$_post_install"
@@ -3049,7 +2997,6 @@ Advanced:
var_sdn_vnet="$_sdn_vnet"
var_http_proxy="$_http_proxy"
var_http_no_proxy="$_http_no_proxy"
- var_inherit_host_ca="$_inherit_host_ca"
# Format optional values
[[ -n "$_mtu" ]] && MTU=",mtu=$_mtu" || MTU=""
@@ -3806,32 +3753,30 @@ run_addon_updates() {
}
runtime_script_status_guard() {
- local mode="${1:-}"
local script_slug="${SCRIPT_SLUG:-${NSAPP:-}}"
script_slug="$(echo "$script_slug" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')"
[[ -z "$script_slug" ]] && return 0
- local api_url="https://db.community-scripts.org/api/collections/script_scripts/records?filter=(slug='${script_slug}')&perPage=1&fields=slug,is_disabled,is_deleted,disable_message,deleted_message,pinned_version,pin_reason"
+ local api_url="https://db.community-scripts.org/api/collections/script_scripts/records?filter=(slug='${script_slug}')&perPage=1&fields=slug,is_disabled,is_deleted,disable_message,deleted_message"
local response
if ! response=$(curl -fsSL --connect-timeout 2 --max-time 3 "$api_url" 2>/dev/null); then
msg_warn "Script status check is unavailable. Continuing without status verification."
return 0
fi
- local is_deleted is_disabled deleted_message disable_message pinned_version pin_reason info_url
- if printf '%s' "$response" | grep -qE '"items":[[:space:]]*\[[[:space:]]*\]'; then
+ if ! command -v jq >/dev/null 2>&1; then
+ msg_warn "Missing jq for script status check. Continuing without status verification."
return 0
fi
- # PocketBase returns a flat, fixed-field JSON blob; sed is enough here (no jq needed).
- is_deleted=$(printf '%s' "$response" | sed -n 's/.*"is_deleted"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/p' | head -1)
- is_disabled=$(printf '%s' "$response" | sed -n 's/.*"is_disabled"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/p' | head -1)
- deleted_message=$(printf '%s' "$response" | sed -n 's/.*"deleted_message"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
- disable_message=$(printf '%s' "$response" | sed -n 's/.*"disable_message"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
- pinned_version=$(printf '%s' "$response" | sed -n 's/.*"pinned_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
- pin_reason=$(printf '%s' "$response" | sed -n 's/.*"pin_reason"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
- is_deleted=${is_deleted:-false}
- is_disabled=${is_disabled:-false}
+ local has_record is_deleted is_disabled deleted_message disable_message info_url
+ has_record=$(printf '%s' "$response" | jq -r '.items | length')
+ [[ "$has_record" == "0" ]] && return 0
+
+ is_deleted=$(printf '%s' "$response" | jq -r '.items[0].is_deleted // false')
+ is_disabled=$(printf '%s' "$response" | jq -r '.items[0].is_disabled // false')
+ deleted_message=$(printf '%s' "$response" | jq -r '.items[0].deleted_message // ""')
+ disable_message=$(printf '%s' "$response" | jq -r '.items[0].disable_message // ""')
info_url="https://community-scripts.org/scripts/${script_slug}"
if [[ "$is_deleted" == "true" ]]; then
@@ -3861,26 +3806,6 @@ runtime_script_status_guard() {
return 1
fi
- if [[ "$mode" == "update" && -n "$pinned_version" && -n "${NSAPP:-}" ]]; then
- local current_file="$HOME/.${NSAPP}"
- if [[ -f "$current_file" ]]; then
- local installed pinned_clean installed_clean
- installed="$(<"$current_file")"
- pinned_clean="$pinned_version"
- installed_clean="$installed"
- [[ "$pinned_clean" =~ ^v[0-9] ]] && pinned_clean="${pinned_clean:1}"
- [[ "$installed_clean" =~ ^v[0-9] ]] && installed_clean="${installed_clean:1}"
- if [[ "$installed_clean" == "$pinned_clean" ]]; then
- if [[ -n "$pin_reason" ]]; then
- msg_info "You are already on the pinned version (${pinned_version}). ${pin_reason}"
- else
- msg_info "You are already on the pinned version (${pinned_version}). No newer update is offered intentionally — please do not open an issue unless you see an actual error."
- fi
- msg_info "More info: ${info_url}"
- fi
- fi
- fi
-
return 0
}
@@ -3896,7 +3821,7 @@ runtime_script_status_guard() {
start() {
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
if command -v pveversion >/dev/null 2>&1; then
- runtime_script_status_guard install || return 0
+ runtime_script_status_guard || return 0
install_script || return 0
return 0
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
@@ -3904,7 +3829,7 @@ start() {
set_std_mode
ensure_profile_loaded
get_lxc_ip
- runtime_script_status_guard update || return 0
+ runtime_script_status_guard || return 0
update_script
run_addon_updates
update_motd_ip
@@ -3915,7 +3840,7 @@ start() {
set_std_mode
ensure_profile_loaded
get_lxc_ip
- runtime_script_status_guard update || return 0
+ runtime_script_status_guard || return 0
update_script
run_addon_updates
update_motd_ip
@@ -3945,7 +3870,7 @@ start() {
esac
ensure_profile_loaded
get_lxc_ip
- runtime_script_status_guard update || return 0
+ runtime_script_status_guard || return 0
update_script
run_addon_updates
update_motd_ip
@@ -3998,81 +3923,6 @@ EOF
msg_ok "Applied HTTP proxy in container"
}
-# ------------------------------------------------------------------------------
-# _apply_host_ca_certs_in_container()
-#
-# - Copies administrator-provided CA certificates from the Proxmox host into the
-# container before base package bootstrap
-# - Source: /usr/local/share/ca-certificates/*.crt (Debian convention)
-# - Refreshes the container trust store when update-ca-certificates is available
-# - No-op when no host certificates are present; failures are non-fatal
-# ------------------------------------------------------------------------------
-_apply_host_ca_certs_in_container() {
- local host_ca_dir="/usr/local/share/ca-certificates"
- [[ -z "${CTID:-}" ]] && return 0
- local inherit_host_ca="${INHERIT_HOST_CA:-${var_inherit_host_ca:-auto}}"
-
- local -a host_certs=()
- local cert
- shopt -s nullglob
- for cert in "$host_ca_dir"/*.crt; do
- host_certs+=("$cert")
- done
- shopt -u nullglob
-
- [[ ${#host_certs[@]} -eq 0 ]] && return 0
-
- case "${inherit_host_ca,,}" in
- no | false | 0 | off)
- msg_info "Skipping host CA inheritance by configuration"
- return 0
- ;;
- esac
-
- msg_info "Inheriting host CA certificates into container"
-
- local found=${#host_certs[@]}
- local copied=0
- local skipped=0
- local cert_name
-
- pct exec "$CTID" -- mkdir -p /usr/local/share/ca-certificates >/dev/null 2>&1 || {
- msg_warn "Failed to create CA certificate directory in container"
- return 0
- }
-
- for cert in "${host_certs[@]}"; do
- cert_name="$(basename "$cert")"
- if [[ ! -r "$cert" || "$cert_name" != *.crt ]]; then
- msg_warn "Skipping invalid or unreadable host CA certificate: ${cert_name}"
- skipped=$((skipped + 1))
- continue
- fi
-
- if pct push "$CTID" "$cert" "/usr/local/share/ca-certificates/${cert_name}" >/dev/null 2>&1; then
- pct exec "$CTID" -- chmod 644 "/usr/local/share/ca-certificates/${cert_name}" >/dev/null 2>&1 || true
- copied=$((copied + 1))
- else
- msg_warn "Failed to push host CA certificate: ${cert_name}"
- skipped=$((skipped + 1))
- fi
- done
-
- if [[ $copied -eq 0 ]]; then
- msg_warn "No host CA certificates were copied (${found} found, ${skipped} skipped)"
- return 0
- fi
-
- local refresh_shell="bash"
- [[ "$var_os" == "alpine" ]] && refresh_shell="ash"
-
- if pct exec "$CTID" -- "$refresh_shell" -c 'command -v update-ca-certificates >/dev/null 2>&1 && update-ca-certificates' >/dev/null 2>&1; then
- msg_ok "Inherited ${copied} host CA certificate(s) and updated trust store (${skipped} skipped)"
- else
- msg_warn "Copied ${copied} host CA certificate(s), but trust store update failed or update-ca-certificates is unavailable (${skipped} skipped)"
- fi
-}
-
# ------------------------------------------------------------------------------
# build_container()
#
@@ -4693,7 +4543,6 @@ EOF
local install_exit_code=0
_apply_http_proxy_in_container
- _apply_host_ca_certs_in_container
# Continue with standard container setup
if [ "$var_os" == "alpine" ]; then
diff --git a/misc/tools.func b/misc/tools.func
index 64669fad1..883c98da0 100644
--- a/misc/tools.func
+++ b/misc/tools.func
@@ -36,10 +36,6 @@
#
# ==============================================================================
-# Guard against double-sourcing (core.func uses the same pattern)
-[[ -n "${_TOOLS_FUNC_LOADED:-}" ]] && return 0
-_TOOLS_FUNC_LOADED=1
-
# ------------------------------------------------------------------------------
# Debug helper - outputs to stderr when TOOLS_DEBUG is enabled
# Usage: debug_log "message"
@@ -95,17 +91,16 @@ curl_with_retry() {
while [[ $attempt -le $retries ]]; do
debug_log "curl attempt $attempt/$retries: $url"
- # Build curl command as array to avoid command injection via extra_opts
- local -a curl_args=(curl -fsSL --connect-timeout "$connect_timeout" --max-time "$timeout")
- [[ -n "$extra_opts" ]] && read -ra _extra <<<"$extra_opts" && curl_args+=("${_extra[@]}")
+ local curl_cmd="curl -fsSL --connect-timeout $connect_timeout --max-time $timeout"
+ [[ -n "$extra_opts" ]] && curl_cmd="$curl_cmd $extra_opts"
if [[ "$output" == "-" ]]; then
- if "${curl_args[@]}" "$url"; then
+ if $curl_cmd "$url"; then
success=true
break
fi
else
- if "${curl_args[@]}" -o "$output" "$url"; then
+ if $curl_cmd -o "$output" "$url"; then
success=true
break
fi
@@ -158,16 +153,15 @@ curl_api_with_retry() {
while [[ $attempt -le $retries ]]; do
debug_log "curl API attempt $attempt/$retries: $url"
- # Build curl command as array to avoid command injection via extra_opts
- local -a curl_args=(curl -fsSL --connect-timeout "$connect_timeout" --max-time "$timeout" -w '%{http_code}')
- [[ -n "$extra_opts" ]] && read -ra _extra <<<"$extra_opts" && curl_args+=("${_extra[@]}")
+ local curl_cmd="curl -fsSL --connect-timeout $connect_timeout --max-time $timeout -w '%{http_code}'"
+ [[ -n "$extra_opts" ]] && curl_cmd="$curl_cmd $extra_opts"
if [[ -n "$body_file" ]]; then
- http_code=$("${curl_args[@]}" -o "$body_file" "$url" 2>/dev/null) || true
+ http_code=$($curl_cmd -o "$body_file" "$url" 2>/dev/null) || true
else
# Capture body and http_code separately
local tmp_body="/tmp/curl_api_body_$$"
- http_code=$("${curl_args[@]}" -o "$tmp_body" "$url" 2>/dev/null) || true
+ http_code=$($curl_cmd -o "$tmp_body" "$url" 2>/dev/null) || true
if [[ -f "$tmp_body" ]]; then
cat "$tmp_body"
rm -f "$tmp_body"
@@ -310,10 +304,7 @@ edit_yaml_config() {
return 1
fi
- # Escape sed metacharacters in value (| and &) to prevent injection
- local escaped_value="${value//|/\\|}"
- escaped_value="${escaped_value//&/\\&}"
- sed -i "s|^\([[:space:]]*${key}[[:space:]]*:\).*|\1 ${escaped_value}|" "$file"
+ sed -i "s|^\([[:space:]]*${key}[[:space:]]*:\).*|\1 ${value}|" "$file"
}
# ------------------------------------------------------------------------------
@@ -1696,6 +1687,10 @@ is_ubuntu() {
[[ "$(get_os_info id)" == "ubuntu" ]]
}
+is_alpine() {
+ [[ "$(get_os_info id)" == "alpine" ]]
+}
+
# ------------------------------------------------------------------------------
# Get Debian/Ubuntu major version
# ------------------------------------------------------------------------------
@@ -2459,10 +2454,8 @@ start_timer() {
end_timer() {
local start_time="$1"
local label="${2:-Operation}"
- local end_time
- end_time=$(date +%s)
+ local end_time=$(date +%s)
local duration=$((end_time - start_time))
- echo "${label} took ${duration}s"
}
# ------------------------------------------------------------------------------
@@ -2544,7 +2537,7 @@ fetch_and_deploy_gh_tag() {
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
@@ -2566,199 +2559,6 @@ fetch_and_deploy_gh_tag() {
return 0
}
-# ------------------------------------------------------------------------------
-# Get the latest GitLab repository tag matching a glob pattern.
-#
-# Description:
-# - Queries the GitLab repository tags API (up to 100 tags per page)
-# - Filters tag names against a shell glob pattern (e.g. "web-v*" or "mobile-v*")
-# - Always excludes pre-release tags (those containing alpha, beta, or rc)
-# - Sorts matching tags with `sort -V` and returns the highest one
-# - Supports GITLAB_TOKEN for private/rate-limited projects
-#
-# Usage:
-# get_latest_gl_tag "owner/repo" "web-v*"
-# get_latest_gl_tag "owner/repo" "mobile-v*"
-# get_latest_gl_tag "owner/repo" # returns newest tag (no filter)
-#
-# Arguments:
-# $1 - GitLab repo path (namespace/project, e.g. "mygroup/myapp")
-# $2 - Optional glob pattern to filter tag names (e.g. "web-v*")
-#
-# Returns:
-# Latest matching tag name on stdout, or non-zero on failure
-# ------------------------------------------------------------------------------
-get_latest_gl_tag() {
- local repo="$1"
- local pattern="${2:-}"
-
- local repo_encoded
- repo_encoded=$(printf '%s' "$repo" | sed 's|/|%2F|g')
-
- local api_base="https://gitlab.com/api/v4/projects/${repo_encoded}/repository/tags"
- local api_timeout="--connect-timeout 10 --max-time 60"
-
- local header=()
- [[ -n "${GITLAB_TOKEN:-}" ]] && header=(-H "PRIVATE-TOKEN: $GITLAB_TOKEN")
-
- # If a pattern is given, pass it as a regex search to reduce server-side results.
- # GitLab ?search= supports anchored regex; convert leading glob prefix to regex anchor.
- local search_param=""
- if [[ -n "$pattern" ]]; then
- # Strip trailing wildcard for the search hint (server-side prefix filter).
- local prefix="${pattern%%\**}"
- [[ -n "$prefix" ]] && search_param="?search=^${prefix}&per_page=100" || search_param="?per_page=100"
- else
- search_param="?per_page=100"
- fi
-
- local temp_file
- temp_file=$(mktemp) || return 1
-
- local http_code
- http_code=$(curl $api_timeout -sSL -w "%{http_code}" -o "$temp_file" \
- "${header[@]}" "${api_base}${search_param}" 2>/dev/null) || true
-
- if [[ "$http_code" != "200" ]]; then
- rm -f "$temp_file"
- msg_error "GitLab tags API returned HTTP $http_code for $repo"
- return 22
- fi
-
- local tag=""
- if [[ -n "$pattern" ]]; then
- # Client-side glob filter + pre-release exclusion, then version-sort to pick the highest match.
- tag=$(jq -r '.[].name' "$temp_file" 2>/dev/null | while IFS= read -r t; do
- case "$t" in
- *alpha* | *beta* | *rc*) continue ;;
- $pattern) echo "$t" ;;
- esac
- done | sort -V | tail -n1)
- else
- # No pattern: skip pre-release tags, take the first remaining (newest) one.
- tag=$(jq -r '.[].name' "$temp_file" 2>/dev/null |
- grep -Eiv '(alpha|beta|rc)' |
- head -n1)
- fi
-
- rm -f "$temp_file"
-
- if [[ -z "$tag" ]]; then
- msg_error "No tags matching '${pattern:-*}' found for ${repo}"
- return 250
- fi
-
- echo "$tag"
-}
-
-# ------------------------------------------------------------------------------
-# Fetches and deploys a GitLab tag-based source tarball.
-#
-# Description:
-# - Resolves the latest tag matching the given glob pattern via get_latest_gl_tag
-# (or uses the exact tag if one is provided instead of "latest")
-# - Downloads the GitLab source tarball for that tag
-# - Extracts it to the target directory
-# - Writes the resolved tag to ~/. for update-checking
-#
-# Usage:
-# fetch_and_deploy_gl_tag "myapp" "mygroup/myrepo" "web-v*"
-# fetch_and_deploy_gl_tag "myapp" "mygroup/myrepo" "mobile-v*" "/opt/myapp"
-# fetch_and_deploy_gl_tag "myapp" "mygroup/myrepo" "v*" # any v-tag
-# fetch_and_deploy_gl_tag "myapp" "mygroup/myrepo" "web-v3.0*" # narrow version range
-#
-# Arguments:
-# $1 - App name (used for version file ~/. and lowercase tarball name)
-# $2 - GitLab repo path (namespace/project, e.g. "mygroup/myapp")
-# $3 - Tag pattern: glob (e.g. "web-v*") or exact tag (e.g. "web-v3.0.0").
-# Use "latest" to fetch the single newest tag with no pattern filter.
-# $4 - Target directory (default: /opt/$app)
-#
-# Notes:
-# - Supports CLEAN_INSTALL=1 to wipe target before extracting
-# - Supports GITLAB_TOKEN for private/rate-limited projects
-# - For repos that only publish tags, not formal GitLab Releases
-# (use fetch_and_deploy_gl_release for proper Releases with assets)
-# ------------------------------------------------------------------------------
-fetch_and_deploy_gl_tag() {
- local app="$1"
- local repo="$2"
- local tag_pattern="${3:-latest}"
- local target="${4:-/opt/$app}"
-
- local app_lc=""
- app_lc="$(echo "${app,,}" | tr -d ' ')"
- local version_file="$HOME/.${app_lc}"
-
- local api_timeout="--connect-timeout 10 --max-time 60"
- local download_timeout="--connect-timeout 15 --max-time 900"
-
- local header=()
- [[ -n "${GITLAB_TOKEN:-}" ]] && header=(-H "PRIVATE-TOKEN: $GITLAB_TOKEN")
-
- # Resolve the tag: if caller passed a glob/latest, query the API.
- # If caller passed an exact tag (no wildcards), use it directly.
- local resolved_tag="$tag_pattern"
- if [[ "$tag_pattern" == "latest" || "$tag_pattern" == *"*"* || "$tag_pattern" == *"?"* ]]; then
- local glob_arg=""
- [[ "$tag_pattern" != "latest" ]] && glob_arg="$tag_pattern"
- resolved_tag=$(get_latest_gl_tag "$repo" "$glob_arg") || {
- msg_error "Failed to determine latest tag matching '${tag_pattern}' for ${repo}"
- return 250
- }
- fi
-
- local current_version=""
- [[ -f "$version_file" ]] && current_version=$(<"$version_file")
-
- if [[ "$current_version" == "$resolved_tag" ]]; then
- msg_ok "$app is already up-to-date ($resolved_tag)"
- return 0
- fi
-
- local repo_encoded
- repo_encoded=$(printf '%s' "$repo" | sed 's|/|%2F|g')
-
- # GitLab source tarball URL (no release needed, works for any tag).
- local version_safe="${resolved_tag//\//-}"
- local tarball_url="https://gitlab.com/${repo}/-/archive/${resolved_tag}/${app_lc}-${version_safe}.tar.gz"
-
- local tmpdir
- tmpdir=$(mktemp -d) || return 1
- local filename="${app_lc}-${version_safe}.tar.gz"
-
- msg_info "Fetching GitLab tag: ${app} (${resolved_tag})"
-
- curl $download_timeout -fsSL "${header[@]}" -o "$tmpdir/$filename" "$tarball_url" || {
- msg_error "Download failed: $tarball_url"
- rm -rf "$tmpdir"
- return 7
- }
-
- mkdir -p "$target"
- if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
- fi
-
- tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
- msg_error "Failed to extract tarball"
- rm -rf "$tmpdir"
- return 251
- }
-
- local unpack_dir
- unpack_dir=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d | head -n1)
-
- shopt -s dotglob nullglob
- cp -r "$unpack_dir"/* "$target/"
- shopt -u dotglob nullglob
-
- rm -rf "$tmpdir"
- echo "$resolved_tag" >"$version_file"
- msg_ok "Deployed ${app} ${resolved_tag} to ${target}"
- return 0
-}
-
# ------------------------------------------------------------------------------
# Checks for new GitHub tag (for repos without releases).
#
@@ -2833,7 +2633,6 @@ check_for_gh_release() {
local source="$2"
local pinned_version_in="${3:-}" # optional
local pin_reason="${4:-}" # optional reason shown to user
- local tag_prefix="${5:-}" # optional tag prefix filter (e.g. web-v2)
local app_lc=""
app_lc="$(echo "${app,,}" | tr -d ' ')"
local current_file="$HOME/.${app_lc}"
@@ -2889,7 +2688,7 @@ check_for_gh_release() {
rm -f "$gh_check_json"
fi
- if [[ -z "$pinned_version_in" && -z "$tag_prefix" ]]; then
+ if [[ -z "$pinned_version_in" ]]; then
http_code=$(curl -sSL --max-time 20 -w "%{http_code}" -o "$gh_check_json" \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2022-11-28' \
@@ -2917,7 +2716,7 @@ check_for_gh_release() {
rm -f "$gh_check_json"
fi
- # If no releases yet (pinned version, tag prefix, OR /latest failed), fetch up to 100
+ # If no releases yet (pinned version OR /latest failed), fetch up to 100
if [[ -z "$releases_json" ]]; then
http_code=$(curl -sSL --max-time 20 -w "%{http_code}" -o "$gh_check_json" \
-H 'Accept: application/vnd.github+json' \
@@ -2955,18 +2754,9 @@ check_for_gh_release() {
rm -f "$gh_check_json"
fi
- if [[ -n "$tag_prefix" ]]; then
- mapfile -t raw_tags < <(jq -r --arg p "$tag_prefix" \
- '.[] | select(.draft==false and .prerelease==false) | select(.tag_name | startswith($p)) | .tag_name' <<<"$releases_json")
- else
- mapfile -t raw_tags < <(jq -r '.[] | select(.draft==false and .prerelease==false) | .tag_name' <<<"$releases_json")
- fi
+ mapfile -t raw_tags < <(jq -r '.[] | select(.draft==false and .prerelease==false) | .tag_name' <<<"$releases_json")
if ((${#raw_tags[@]} == 0)); then
- if [[ -n "$tag_prefix" ]]; then
- msg_error "No stable releases matching prefix '${tag_prefix}' found for ${app}"
- else
- msg_error "No stable releases found for ${app}"
- fi
+ msg_error "No stable releases found for ${app}"
return 250
fi
@@ -3472,7 +3262,7 @@ fetch_and_deploy_codeberg_release() {
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
@@ -3575,7 +3365,7 @@ fetch_and_deploy_codeberg_release() {
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
@@ -3694,7 +3484,7 @@ fetch_and_deploy_codeberg_release() {
unpack_tmp=$(mktemp -d)
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
if [[ "$filename" == *.zip ]]; then
@@ -3970,7 +3760,6 @@ fetch_and_deploy_gh_release() {
local version="${var_appversion:-${4:-latest}}"
local target="${5:-/opt/$app}"
local asset_pattern="${6:-}"
- local tag_prefix="${7:-}"
# Validate app name to prevent /root/. directory issues
if [[ -z "$app" ]]; then
@@ -4000,13 +3789,7 @@ fetch_and_deploy_gh_release() {
TOOLS_GH_REL_JSON="$gh_rel_json"
local api_url="https://api.github.com/repos/$repo/releases"
- if [[ "$version" != "latest" ]]; then
- api_url="$api_url/tags/$version"
- elif [[ -n "$tag_prefix" ]]; then
- api_url="$api_url?per_page=100"
- else
- api_url="$api_url/latest"
- fi
+ [[ "$version" != "latest" ]] && api_url="$api_url/tags/$version" || api_url="$api_url/latest"
local header=()
[[ -n "${GITHUB_TOKEN:-}" ]] && header=(-H "Authorization: token $GITHUB_TOKEN")
@@ -4069,14 +3852,6 @@ fetch_and_deploy_gh_release() {
local json tag_name
json=$(<"$gh_rel_json")
- if [[ "$version" == "latest" && -n "$tag_prefix" ]]; then
- json=$(echo "$json" | jq --arg p "$tag_prefix" \
- '[.[] | select(.draft==false and .prerelease==false) | select(.tag_name | startswith($p))][0] // empty')
- if [[ -z "$json" || "$json" == "null" ]]; then
- msg_error "No stable release matching prefix '${tag_prefix}' found for $repo on GitHub"
- return 1
- fi
- fi
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
# Only strip leading 'v' when followed by a digit (e.g. v1.2.3), not words like "version/..."
[[ "$tag_name" =~ ^v[0-9] ]] && version="${tag_name:1}" || version="$tag_name"
@@ -4112,7 +3887,7 @@ fetch_and_deploy_gh_release() {
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
@@ -4292,7 +4067,7 @@ fetch_and_deploy_gh_release() {
unpack_tmp=$(mktemp -d)
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
if [[ "$filename" == *.zip ]]; then
@@ -4663,25 +4438,23 @@ setup_composer() {
# - Cleans up legacy repository files
#
# Usage:
-# setup_docker # Uses official Docker repo (recommended)
-# USE_DOCKER_REPO=false setup_docker # Uses distro docker.io package
+# setup_docker # Uses distro package (recommended)
+# USE_DOCKER_REPO=true setup_docker # Uses official Docker repo
# DOCKER_PORTAINER="true" setup_docker
# DOCKER_LOG_DRIVER="json-file" setup_docker
#
# Variables:
-# USE_DOCKER_REPO - Set to "false" to use distro docker.io package
-# (default: true, uses official Docker repository)
+# USE_DOCKER_REPO - Set to "true" to use official Docker repository
+# (default: false, uses distro docker.io package)
# DOCKER_PORTAINER - Install Portainer CE (optional, "true" to enable)
# DOCKER_LOG_DRIVER - Log driver (optional, default: "journald")
# DOCKER_SKIP_UPDATES - Skip container update check (optional, "true" to skip)
#
# Features:
-# - Uses official Docker repository by default
+# - Uses stable distro packages by default
# - Migrates from get.docker.com to repository-based installation
# - Updates Docker Engine if newer version available
-# - Interactive per-container update prompt (Y/N, 60 s auto-no)
-# - Compose-managed containers: full restart via docker compose
-# - Standalone containers: image pull only, no destructive stop/rm
+# - Interactive container update with multi-select
# - Portainer installation and update support
# - Set DOCKER_NONINTERACTIVE=1 to skip interactive prompts (CI/unattended)
# ------------------------------------------------------------------------------
@@ -4692,7 +4465,7 @@ _docker_is_noninteractive() {
setup_docker() {
local docker_installed=false
local portainer_installed=false
- local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
+ local USE_DOCKER_REPO="${USE_DOCKER_REPO:-false}"
# Check if Docker is already installed
if command -v docker &>/dev/null; then
@@ -4707,7 +4480,7 @@ setup_docker() {
msg_info "Portainer container detected"
fi
- # Scenario 1: Use distro repository (opt-out via USE_DOCKER_REPO=false)
+ # Scenario 1: Use distro repository (default, most stable)
if [[ "$USE_DOCKER_REPO" != "true" && "$USE_DOCKER_REPO" != "TRUE" && "$USE_DOCKER_REPO" != "1" ]]; then
# Install or upgrade Docker from distro repo
@@ -4868,83 +4641,63 @@ EOF
fi
fi
- # Container Update Check
- # - Skipped entirely when running unattended / non-interactive
- # - Compose-managed containers: offered via Y/N → docker compose pull + up -d
- # - Standalone containers: offered via Y/N → image pull only (no stop/rm)
- if [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then
+ # Interactive Container Update Check
+ if [[ "${DOCKER_SKIP_UPDATES:-}" != "true" ]] && [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then
msg_info "Checking for container updates"
- local name image compose_workdir compose_service current_digest latest_digest
- local compose_updates=()
- local standalone_updates=()
+ # Get list of running containers with update status
+ local containers_with_updates=()
+ local container_info=()
+ local index=1
- while IFS= read -r line; do
- name=$(echo "$line" | awk '{print $1}')
- image=$(echo "$line" | awk '{print $2}')
+ while IFS= read -r container; do
+ local name=$(echo "$container" | awk '{print $1}')
+ local image=$(echo "$container" | awk '{print $2}')
+ local current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
- # Portainer containers are handled by the dedicated block above
- [[ "$name" == "portainer" || "$name" == "portainer_agent" ]] && continue
+ # Pull latest image digest (ignore failures, e.g. local-only images or registry/permission issues)
+ docker pull "$image" >/dev/null 2>&1 || true
+ local latest_digest=$(docker inspect "$image" --format='{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
- current_digest=$(docker inspect "$name" --format='{{.Image}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
- docker pull "$image" >/dev/null 2>&1 || continue
- latest_digest=$(docker inspect "$image" --format='{{.Id}}' 2>/dev/null | cut -d':' -f2 | cut -c1-12)
- [[ -z "$latest_digest" || "$current_digest" == "$latest_digest" ]] && continue
-
- compose_workdir=$(docker inspect "$name" \
- --format='{{index .Config.Labels "com.docker.compose.project.working_dir"}}' 2>/dev/null || true)
- compose_service=$(docker inspect "$name" \
- --format='{{index .Config.Labels "com.docker.compose.service"}}' 2>/dev/null || true)
-
- if [[ -n "$compose_workdir" && -n "$compose_service" && -d "$compose_workdir" ]]; then
- compose_updates+=("${name}|${image}|${compose_workdir}|${compose_service}")
- else
- standalone_updates+=("${name}|${image}")
+ if [ -n "$latest_digest" ] && [ "$current_digest" != "$latest_digest" ]; then
+ containers_with_updates+=("$name")
+ container_info+=("${index}) ${name} (${image})")
+ ((index++))
fi
done < <(docker ps --format '{{.Names}} {{.Image}}')
- # Stop spinner before any interactive prompt
- stop_spinner
+ if [ ${#containers_with_updates[@]} -gt 0 ]; then
+ echo ""
+ echo "${TAB3}Container updates available:"
+ for info in "${container_info[@]}"; do
+ echo "${TAB3} $info"
+ done
+ echo ""
+ read -r -p "${TAB3}Select containers to update (e.g., 1,3,5 or 'all' or 'none'): " selection
- if [[ ${#compose_updates[@]} -eq 0 && ${#standalone_updates[@]} -eq 0 ]]; then
- msg_ok "All containers are up-to-date"
+ if [[ ${selection,,} == "all" ]]; then
+ for container in "${containers_with_updates[@]}"; do
+ msg_info "Updating container: $container"
+ docker stop "$container"
+ docker rm "$container"
+ # Note: This requires the original docker run command - best to recreate via compose
+ msg_ok "Stopped and removed $container (please recreate with updated image)"
+ done
+ elif [[ ${selection,,} != "none" ]]; then
+ IFS=',' read -ra SELECTED <<<"$selection"
+ for num in "${SELECTED[@]}"; do
+ num=$(echo "$num" | xargs) # trim whitespace
+ if [[ "$num" =~ ^[0-9]+$ ]] && [ "$num" -ge 1 ] && [ "$num" -le "${#containers_with_updates[@]}" ]; then
+ container="${containers_with_updates[$((num - 1))]}"
+ msg_info "Updating container: $container"
+ docker stop "$container"
+ docker rm "$container"
+ msg_ok "Stopped and removed $container (please recreate with updated image)"
+ fi
+ done
+ fi
else
- local reply
- for entry in "${compose_updates[@]}"; do
- IFS='|' read -r name image compose_workdir compose_service <<<"$entry"
- reply=""
- if read -r -t 60 -p "${TAB3}Update ${name} (${image}) via Compose? (auto-no in 60s): " reply; then
- echo ""
- else
- echo ""
- fi
- if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
- msg_info "Updating $name"
- if (cd "$compose_workdir" && $STD docker compose pull "$compose_service" && $STD docker compose up -d "$compose_service"); then
- msg_ok "Updated $name"
- else
- msg_warn "Could not update $name — try manually in $compose_workdir"
- fi
- fi
- done
-
- for entry in "${standalone_updates[@]}"; do
- IFS='|' read -r name image <<<"$entry"
- reply=""
- if read -r -t 60 -p "${TAB3}Pull new image for ${name} (${image})? (auto-no in 60s): " reply; then
- echo ""
- else
- echo ""
- fi
- if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
- msg_info "Pulling new image for $name"
- if $STD docker pull "$image"; then
- msg_ok "New image available for $name — recreate the container to apply the update"
- else
- msg_warn "Failed to pull image for $name"
- fi
- fi
- done
+ msg_ok "All containers are up-to-date"
fi
fi
@@ -6971,11 +6724,9 @@ setup_mariadb_db() {
msg_info "Setting up MariaDB Database"
- # Use --defaults-extra-file to pass credentials safely and escape identifiers
- # to prevent SQL injection via DB name / user / password
- $STD mariadb -u root -e "CREATE DATABASE \`${MARIADB_DB_NAME//\`/\`\`}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
- $STD mariadb -u root -e "CREATE USER '${MARIADB_DB_USER//\'/\'\'}'@'localhost' IDENTIFIED BY '${MARIADB_DB_PASS//\'/\'\'}';"
- $STD mariadb -u root -e "GRANT ALL ON \`${MARIADB_DB_NAME//\`/\`\`}\`.* TO '${MARIADB_DB_USER//\'/\'\'}'@'localhost';"
+ $STD mariadb -u root -e "CREATE DATABASE \`$MARIADB_DB_NAME\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
+ $STD mariadb -u root -e "CREATE USER '$MARIADB_DB_USER'@'localhost' IDENTIFIED BY '$MARIADB_DB_PASS';"
+ $STD mariadb -u root -e "GRANT ALL ON \`$MARIADB_DB_NAME\`.* TO '$MARIADB_DB_USER'@'localhost';"
# Optional extra grants
if [[ -n "${MARIADB_DB_EXTRA_GRANTS:-}" ]]; then
@@ -7157,7 +6908,7 @@ setup_meilisearch() {
MEILI_DB_PATH="${MEILI_DB_PATH:-/var/lib/meilisearch/data}"
msg_info "Removing old MeiliSearch database for migration"
- find "${MEILI_DB_PATH:?}" -mindepth 1 -delete
+ rm -rf "${MEILI_DB_PATH:?}"/*
# Import dump using CLI flag (this is the supported method)
local DUMP_FILE="${MEILI_DUMP_DIR}/${DUMP_UID}.dump"
@@ -7431,18 +7182,6 @@ setup_mongodb() {
mkdir -p /var/lib/mongodb
chown -R mongodb:mongodb /var/lib/mongodb
- local KERNEL_VERSION MONGO_MAJOR
- KERNEL_VERSION=$(uname -r | cut -d- -f1)
- MONGO_MAJOR="${MONGO_VERSION%%.*}"
- if ((MONGO_MAJOR >= 8)) && [[ "$(printf '%s\n' "6.19" "$KERNEL_VERSION" | sort -V | head -n1)" == "6.19" ]]; then
- mkdir -p /etc/systemd/system/mongod.service.d
- cat </etc/systemd/system/mongod.service.d/rseq.conf
-[Service]
-Environment=GLIBC_TUNABLES=glibc.pthread.rseq=1
-EOF
- systemctl daemon-reload
- fi
-
$STD systemctl enable mongod || {
msg_warn "Failed to enable mongod service"
}
@@ -8617,14 +8356,8 @@ setup_postgresql_db() {
fi
msg_info "Setting up PostgreSQL Database"
- # Escape single quotes in identifiers to prevent SQL injection
- local _pg_user_escaped _pg_pass_escaped _pg_db_escaped
- _pg_user_escaped="${PG_DB_USER//\'/\'\'}"
- _pg_pass_escaped="${PG_DB_PASS//\'/\'\'}"
- _pg_db_escaped="${PG_DB_NAME//\'/\'\'}"
-
- $STD sudo -u postgres psql -c "CREATE ROLE $_pg_user_escaped WITH LOGIN PASSWORD '$_pg_pass_escaped';"
- $STD sudo -u postgres psql -c "CREATE DATABASE $_pg_db_escaped WITH OWNER $_pg_user_escaped ENCODING 'UTF8' TEMPLATE template0;"
+ $STD sudo -u postgres psql -c "CREATE ROLE $PG_DB_USER WITH LOGIN PASSWORD '$PG_DB_PASS';"
+ $STD sudo -u postgres psql -c "CREATE DATABASE $PG_DB_NAME WITH OWNER $PG_DB_USER ENCODING 'UTF8' TEMPLATE template0;"
# Configure pg_cron database BEFORE creating the extension (must be set before pg_cron loads)
if [[ -n "${PG_DB_EXTENSIONS:-}" ]] && [[ ",${PG_DB_EXTENSIONS//[[:space:]]/}," == *",pg_cron,"* ]]; then
@@ -8689,7 +8422,6 @@ setup_postgresql_db() {
export PG_DB_USER
export PG_DB_PASS
}
-
# ------------------------------------------------------------------------------
# Installs rbenv and ruby-build, installs Ruby and optionally Rails.
#
@@ -8709,26 +8441,8 @@ setup_ruby() {
local RBENV_DIR="$HOME/.rbenv"
local RBENV_BIN="$RBENV_DIR/bin/rbenv"
local PROFILE_FILE="$HOME/.profile"
- local BASH_PROFILE_FILE="$HOME/.bash_profile"
- local BASHRC_FILE="$HOME/.bashrc"
local TMP_DIR=$(mktemp -d)
- if ! grep -q 'rbenv init' "$PROFILE_FILE" 2>/dev/null; then
- cat <<'EOF' >>"$PROFILE_FILE"
-export PATH="$HOME/.rbenv/bin:$PATH"
-eval "$(rbenv init -)"
-EOF
- fi
- if ! grep -q '.rbenv/shims' "$PROFILE_FILE" 2>/dev/null; then
- echo 'export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"' >>"$PROFILE_FILE"
- fi
- if [[ -f "$BASH_PROFILE_FILE" ]] && ! grep -q '.rbenv/shims' "$BASH_PROFILE_FILE"; then
- echo 'export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"' >>"$BASH_PROFILE_FILE"
- fi
- if [[ -f "$BASHRC_FILE" ]] && ! grep -q '.rbenv/shims' "$BASHRC_FILE"; then
- echo 'export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"' >>"$BASHRC_FILE"
- fi
-
# Get currently installed Ruby version
local CURRENT_RUBY_VERSION=""
if [[ -x "$RBENV_BIN" ]]; then
@@ -9131,16 +8845,6 @@ setup_uv() {
msg_ok "uvx wrapper installed"
fi
- # Install specific Python version if requested (even when uv is already up to date)
- if [[ -n "${PYTHON_VERSION:-}" ]]; then
- msg_info "Installing Python $PYTHON_VERSION via uv"
- $STD uv python install "$PYTHON_VERSION" || {
- msg_error "Failed to install Python $PYTHON_VERSION"
- return 150
- }
- msg_ok "Python $PYTHON_VERSION installed"
- fi
-
return 0
fi
@@ -9400,7 +9104,7 @@ fetch_and_deploy_from_url() {
mkdir -p "$directory"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${directory:?}" -mindepth 1 -delete
+ rm -rf "${directory:?}/"*
fi
local unpack_tmp
@@ -9550,7 +9254,6 @@ check_for_gl_release() {
local source="$2"
local pinned_version_in="${3:-}" # optional
local pin_reason="${4:-}" # optional reason shown to user
- local tag_prefix="${5:-}" # optional tag prefix filter (e.g. web-v2)
local app_lc="${app,,}"
local current_file="$HOME/.${app_lc}"
@@ -9627,18 +9330,9 @@ check_for_gl_release() {
rm -f "$gl_check_json"
fi
- if [[ -n "$tag_prefix" ]]; then
- mapfile -t raw_tags < <(jq -r --arg p "$tag_prefix" \
- '.[] | select(.tag_name | startswith($p)) | .tag_name' <<<"$releases_json")
- else
- mapfile -t raw_tags < <(jq -r '.[] | .tag_name' <<<"$releases_json")
- fi
+ mapfile -t raw_tags < <(jq -r '.[] | .tag_name' <<<"$releases_json")
if ((${#raw_tags[@]} == 0)); then
- if [[ -n "$tag_prefix" ]]; then
- msg_error "No releases matching prefix '${tag_prefix}' found for ${app} on GitLab"
- else
- msg_error "No releases found for ${app} on GitLab"
- fi
+ msg_error "No releases found for ${app} on GitLab"
return 250
fi
@@ -9833,7 +9527,6 @@ fetch_and_deploy_gl_release() {
local version="${var_appversion:-${4:-latest}}"
local target="${5:-/opt/$app}"
local asset_pattern="${6:-}"
- local tag_prefix="${7:-}"
if [[ -z "$app" ]]; then
app="${repo##*/}"
@@ -9865,8 +9558,6 @@ fetch_and_deploy_gl_release() {
local api_url
if [[ "$version" != "latest" ]]; then
api_url="$api_base/$version"
- elif [[ -n "$tag_prefix" ]]; then
- api_url="$api_base?per_page=100&order_by=released_at&sort=desc"
else
api_url="$api_base?per_page=1&order_by=released_at&sort=desc"
fi
@@ -9921,18 +9612,9 @@ fetch_and_deploy_gl_release() {
json=$(<"$gl_rel_json")
if [[ "$version" == "latest" ]]; then
- if [[ -n "$tag_prefix" ]]; then
- json=$(echo "$json" | jq --arg p "$tag_prefix" \
- '[.[] | select(.tag_name | startswith($p))][0] // empty')
- else
- json=$(echo "$json" | jq '.[0] // empty')
- fi
+ json=$(echo "$json" | jq '.[0] // empty')
if [[ -z "$json" || "$json" == "null" ]]; then
- if [[ -n "$tag_prefix" ]]; then
- msg_error "No release matching prefix '${tag_prefix}' found for $repo on GitLab"
- else
- msg_error "No releases found for $repo on GitLab"
- fi
+ msg_error "No releases found for $repo on GitLab"
return 1
fi
fi
@@ -9976,7 +9658,7 @@ fetch_and_deploy_gl_release() {
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
tar --no-same-owner -xzf "$tmpdir/$filename" -C "$tmpdir" || {
@@ -10138,7 +9820,7 @@ fetch_and_deploy_gl_release() {
unpack_tmp=$(mktemp -d)
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
- find "${target:?}" -mindepth 1 -delete
+ rm -rf "${target:?}/"*
fi
if [[ "$filename" == *.zip ]]; then
diff --git a/misc/vm-core.func b/misc/vm-core.func
index da9ee5584..8ad2dfc37 100644
--- a/misc/vm-core.func
+++ b/misc/vm-core.func
@@ -620,19 +620,12 @@ pve_check() {
}
arch_check() {
- local arch
- arch="$(dpkg --print-architecture)"
- if [[ "$arch" != "amd64" && "$arch" != "arm64" ]]; then
- msg_error "This script requires amd64 or arm64."
+ if [ "$(dpkg --print-architecture)" != "amd64" ]; then
+ echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
+ echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
echo -e "Exiting..."
sleep 2
- exit 106
- fi
- if [[ "$arch" == "arm64" && "${var_arm64:-}" != "yes" ]]; then
- echo -e "\n ${INFO}${YWB}This script does not yet support ARM64! \n"
- echo -e "Exiting..."
- sleep 2
- exit 106
+ exit
fi
}
diff --git a/tools/pve/cron-update-lxcs.sh b/tools/pve/cron-update-lxcs.sh
index 437c7e472..c97975c44 100644
--- a/tools/pve/cron-update-lxcs.sh
+++ b/tools/pve/cron-update-lxcs.sh
@@ -116,9 +116,6 @@ add() {
# Add container IDs to exclude from updates (comma-separated):
# EXCLUDE=100,101,102
EXCLUDE=
-
-# Healthchecks.io Ping URL (optional)
-# PING_URL=
CONF
ok "Created config ${CONF_FILE}"
fi
@@ -238,11 +235,9 @@ view_cron_config() {
fi
if [[ -f "$CONF_FILE" ]]; then
echo -e " \e[36mConfig file:\e[0m ${CONF_FILE}"
- local excludes ping_url
+ local excludes
excludes=$(grep -oP '^\s*EXCLUDE\s*=\s*\K.*' "$CONF_FILE" 2>/dev/null || true)
- ping_url=$(grep -oP '^\s*PING_URL\s*=\s*\K.*' "$CONF_FILE" 2>/dev/null | tr -d '"' | tr -d "'" || true)
echo -e " \e[36mExcluded:\e[0m ${excludes:-(none)}"
- echo -e " \e[36mPing URL:\e[0m ${ping_url:-(none)}"
echo ""
echo -e " \e[90m--- ${CONF_FILE} ---\e[0m"
cat "$CONF_FILE"
@@ -289,11 +284,9 @@ show_status() {
fi
if [[ -f "$CONF_FILE" ]]; then
- local excludes ping_url
+ local excludes
excludes=$(grep -oP '^\s*EXCLUDE\s*=\s*\K.*' "$CONF_FILE" 2>/dev/null || echo "(none)")
- ping_url=$(grep -oP '^\s*PING_URL\s*=\s*\K.*' "$CONF_FILE" 2>/dev/null | tr -d '"' | tr -d "'" || echo "(none)")
echo -e " \e[36mExcluded:\e[0m ${excludes:-"(none)"}"
- echo -e " \e[36mPing URL:\e[0m ${ping_url:-"(none)"}"
fi
if [[ -f "$LOG_FILE" ]]; then
diff --git a/tools/pve/update-lxcs-cron.sh b/tools/pve/update-lxcs-cron.sh
index 0e021944a..d7abc4cae 100644
--- a/tools/pve/update-lxcs-cron.sh
+++ b/tools/pve/update-lxcs-cron.sh
@@ -11,15 +11,14 @@
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
CONF_FILE="/etc/update-lxcs.conf"
-LOG_FILE="/var/log/update-lxcs-cron.log"
-PING_URL=""
+
+echo -e "\n $(date)"
# Collect excluded containers from arguments
excluded_containers=("$@")
-# Merge exclusions and healthchecks URL from config file if it exists
+# Merge exclusions from config file if it exists
if [[ -f "$CONF_FILE" ]]; then
- PING_URL=$(grep -oP '^\s*PING_URL\s*=\s*\K.+' "$CONF_FILE" 2>/dev/null | tr -d '"' | tr -d "'" || true)
conf_exclude=$(grep -oP '^\s*EXCLUDE\s*=\s*\K[0-9,]+' "$CONF_FILE" 2>/dev/null || true)
IFS=',' read -ra conf_ids <<<"$conf_exclude"
for id in "${conf_ids[@]}"; do
@@ -28,17 +27,6 @@ if [[ -f "$CONF_FILE" ]]; then
done
fi
-# Overwrite logfile on each run when healthchecks is used
-if [[ -n "$PING_URL" ]]; then
- true > "$LOG_FILE"
-fi
-
-if [[ -n "$PING_URL" ]]; then
- curl -fsS -m 10 --retry 5 "${PING_URL}/start" -o /dev/null 2>/dev/null || true
-fi
-
-echo -e "\n $(date)"
-
function update_container() {
local container=$1
local name
@@ -50,36 +38,12 @@ function update_container() {
alpine) pct exec "$container" -- ash -c "apk -U upgrade" ;;
archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;;
fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;;
- ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update; DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-confold' dist-upgrade -y; status=\$?; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED || true; exit \$status" ;;
+ ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-confold' dist-upgrade -y; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED" ;;
opensuse) pct exec "$container" -- bash -c "zypper ref && zypper --non-interactive dup" ;;
*) echo " [Warn] Unknown OS type '$os' for container $container, skipping" ;;
esac
}
-update_status=0
-
-# Define exit handler to send healthchecks.io status (with logfile on failure/success)
-function exit_handler() {
- local exit_code=$?
- if [[ -n "$PING_URL" ]]; then
- sync
- if [[ $exit_code -ne 0 || $update_status -ne 0 ]]; then
- if [[ -f "$LOG_FILE" ]]; then
- curl -fsS -m 10 --retry 5 --data-binary @"$LOG_FILE" "${PING_URL}/fail" -o /dev/null 2>/dev/null || true
- else
- curl -fsS -m 10 --retry 5 "${PING_URL}/fail" -o /dev/null 2>/dev/null || true
- fi
- else
- if [[ -f "$LOG_FILE" ]]; then
- curl -fsS -m 10 --retry 5 --data-binary @"$LOG_FILE" "$PING_URL" -o /dev/null 2>/dev/null || true
- else
- curl -fsS -m 10 --retry 5 "$PING_URL" -o /dev/null 2>/dev/null || true
- fi
- fi
- fi
-}
-trap exit_handler EXIT
-
for container in $(pct list | awk '{if(NR>1) print $1}'); do
excluded=false
for excluded_container in "${excluded_containers[@]}"; do
@@ -101,7 +65,7 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do
echo -e "[Info] Starting $container"
pct start "$container"
sleep 5
- update_container "$container" || { echo " [Error] Update failed for $container"; update_status=1; }
+ update_container "$container" || echo " [Error] Update failed for $container"
# check if patchmon agent is present in container and run a report if found
if pct exec "$container" -- [ -e "/usr/local/bin/patchmon-agent" ]; then
echo -e "${BL}[Info]${GN} patchmon-agent found in ${BL} $container ${CL}, triggering report. \n"
@@ -110,7 +74,7 @@ for container in $(pct list | awk '{if(NR>1) print $1}'); do
echo -e "[Info] Shutting down $container"
pct shutdown "$container" --timeout 60 &
elif [ "$status" == "status: running" ]; then
- update_container "$container" || { echo " [Error] Update failed for $container"; update_status=1; }
+ update_container "$container" || echo " [Error] Update failed for $container"
# check if patchmon agent is present in container and run a report if found
if pct exec "$container" -- [ -e "/usr/local/bin/patchmon-agent" ]; then
echo -e "${BL}[Info]${GN} patchmon-agent found in ${BL} $container ${CL}, triggering report. \n"
diff --git a/tools/pve/update-lxcs.sh b/tools/pve/update-lxcs.sh
index e083a4fc2..52e9d2528 100644
--- a/tools/pve/update-lxcs.sh
+++ b/tools/pve/update-lxcs.sh
@@ -78,7 +78,7 @@ function update_container() {
alpine) pct exec "$container" -- ash -c "apk -U upgrade" ;;
archlinux) pct exec "$container" -- bash -c "pacman -Syyu --noconfirm" ;;
fedora | rocky | centos | alma) pct exec "$container" -- bash -c "dnf -y update && dnf -y upgrade" ;;
- ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable 2>/dev/null | cat && apt-get -yq dist-upgrade 2>&1; apt-get -yq autoremove 2>&1; apt-get -yq autoclean 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED || true" ;;
+ ubuntu | debian | devuan) pct exec "$container" -- bash -c "apt-get update 2>/dev/null | grep 'packages.*upgraded'; apt list --upgradable 2>/dev/null | cat && apt-get -yq dist-upgrade 2>&1; rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED || true" ;;
opensuse) pct exec "$container" -- bash -c "zypper ref && zypper --non-interactive dup" ;;
esac
}
diff --git a/vm/docker-vm.sh b/vm/docker-vm.sh
index 35d247333..194470a40 100644
--- a/vm/docker-vm.sh
+++ b/vm/docker-vm.sh
@@ -11,6 +11,7 @@
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/api.func) 2>/dev/null
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/vm-core.func) 2>/dev/null
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/cloud-init.func) 2>/dev/null || true
+load_functions
# ==============================================================================
# SCRIPT VARIABLES
@@ -20,7 +21,6 @@ APP_TYPE="vm"
NSAPP="docker-vm"
var_os="debian"
var_version="13"
-ARCH=$(dpkg --print-architecture)
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
@@ -30,9 +30,6 @@ USE_CLOUD_INIT="no"
OS_TYPE=""
OS_VERSION=""
THIN="discard=on,ssd=1,"
-var_arm64="yes"
-
-load_functions
# ==============================================================================
# ERROR HANDLING & CLEANUP
@@ -139,16 +136,11 @@ function default_settings() {
VMID=$(get_valid_nextid)
FORMAT=""
- if [ "$ARCH" = "arm64" ]; then
- MACHINE=""
- CPU_TYPE=""
- else
- MACHINE=" -machine q35"
- CPU_TYPE=" -cpu host"
- fi
+ MACHINE=" -machine q35"
DISK_CACHE=""
DISK_SIZE="10G"
HN="docker"
+ CPU_TYPE=" -cpu host"
CORE_COUNT="2"
RAM_SIZE="4096"
BRG="vmbr0"
@@ -159,15 +151,11 @@ function default_settings() {
METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
- if [ "$ARCH" = "arm64" ]; then
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}virt (ARM64)${CL}"
- else
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
- fi
+ echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}$([ "$ARCH" = "arm64" ] && echo "Default" || echo "Host")${CL}"
+ echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
@@ -209,11 +197,7 @@ function advanced_settings() {
done
# Machine Type
- if [ "$ARCH" = "arm64" ]; then
- FORMAT=""
- MACHINE=""
- echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}virt${CL}"
- elif MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
+ if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
"q35" "Q35 (Modern, PCIe)" ON \
"i440fx" "i440fx (Legacy, PCI)" OFF \
3>&1 1>&2 2>&3); then
@@ -278,10 +262,7 @@ function advanced_settings() {
fi
# CPU Model
- if [ "$ARCH" = "arm64" ]; then
- CPU_TYPE=""
- echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Default${CL}"
- elif CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
+ if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"1" "Host (Recommended)" ON \
"0" "KVM64" OFF \
3>&1 1>&2 2>&3); then
diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh
index df5189614..85d582170 100644
--- a/vm/haos-vm.sh
+++ b/vm/haos-vm.sh
@@ -475,7 +475,7 @@ function advanced_settings() {
done
while true; do
- if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan (leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
+ if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VLAN1" ]; then
VLAN1="Default"
VLAN=""