Compare commits

..

49 Commits

Author SHA1 Message Date
Tobias 99e19c8ef6 rm: comments 2026-07-28 15:09:18 +02:00
Tobias 920bab7068 fix: compatibility in paperless v3 (https://github.com/hansmi/prometheus-paperless-exporter/issues/134) 2026-07-28 15:07:45 +02:00
community-scripts-pr-app[bot] 57e02eee1b Update .app files (#16114)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-07-28 13:38:55 +02:00
community-scripts-pr-app[bot] 45053ea4c3 Update CHANGELOG.md (#16115)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 11:37:14 +00:00
Sam Heinz 1fa4c1fbf7 fix Node.js version drift (#16111)
* fix Node.js version drift

* add upgrade node for oxicloud,ps5,syncin
2026-07-28 13:36:40 +02:00
community-scripts-pr-app[bot] 0299e420e8 Update CHANGELOG.md (#16113)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 10:30:10 +00:00
push-app-to-main[bot] db18c72bd8 Add actual-budget-prometheus-exporter (addon) (#16109)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-07-28 12:29:40 +02:00
community-scripts-pr-app[bot] 4bf8a972bf Update CHANGELOG.md (#16112)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 09:44:49 +00:00
Sam Heinz 47b8fbf2fb fix keep-open for close invalid pr (#16105) 2026-07-28 11:44:26 +02:00
community-scripts-pr-app[bot] 9cc1a739a5 Update CHANGELOG.md (#16108)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 08:12:01 +00:00
Tim Moore 0ce1cea6cd UmlautAdaptarr: use the Debian 13 Microsoft repo with its 2025 signing key (#16077)
* UmlautAdaptarr: use the Debian 13 Microsoft repo with its 2025 signing key

The container is Debian 13 (var_version 13) but the script configures the
Microsoft debian/12 prod repo with suite bookworm.

The move to debian/13 was reverted in #8392 because apt reported "OpenPGP
signature verification failed" (#8385), diagnosed at the time as Microsoft
not having populated the trixie repo. The actual cause was the signing key:
debian/13/prod is signed by EE4D7792F748182B (microsoft-2025.asc), while the
script kept microsoft.asc (EB3E94ADBE1229CF). The suite and URL were changed
but the key was not.

The trixie repo carries the required packages at current patch level
(dotnet-sdk-8.0 8.0.423-1, aspnetcore-runtime-8.0 8.0.29-1).

This makes the call identical to the six other scripts already on the
Debian 13 Microsoft repo (technitiumdns, igotify, mail-archiver, rdtclient,
fileflows, immichframe).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* UmlautAdaptarr: migrate existing containers to the Debian 13 repo on update

Per review feedback: the install-side fix only helps new containers.
Existing ones keep the Debian 12 repo indefinitely, because update_script
only fetches a GitHub release and never touches apt.

Repoints them when the stale Debian 12 repo is detected, mirroring the
conditional setup_deb822_repo calls in ct/technitiumdns.sh and
ct/fileflows.sh. The guard makes this a no-op once migrated.

setup_deb822_repo's microsoft* globs also clear the pre-#9839
microsoft-prod.sources layout; its key lived in /usr/share/keyrings,
which cleanup_old_repo_files does not cover, so it is removed explicitly
as ct/technitiumdns.sh does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Tim Moore <tim.moore@ingenuity.com.au>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 18:11:29 +10:00
community-scripts-pr-app[bot] e7eff1cf81 Update CHANGELOG.md (#16107)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 08:10:45 +00:00
Tim Moore 03edfcef85 fix(bazarr): store data in /var/lib/bazarr instead of inside /opt/bazarr (#16098)
* fix(bazarr): store data in /var/lib/bazarr instead of inside /opt/bazarr

The installer creates /var/lib/bazarr and update_script() uses it as the
"is Bazarr installed" guard, but nothing pointed Bazarr at it. Bazarr
defaults its data directory to <install dir>/data, resolved from its own
source file rather than WorkingDirectory, so a stock container kept
config/ db/ backup/ cache/ log/ restore/ in /opt/bazarr/data - the
directory fetch_and_deploy_gh_release redeploys over - while
/var/lib/bazarr stayed empty.

Pass -c /var/lib/bazarr in the unit, matching the -data= flag the other
*arr scripts use. bazarr.py re-execs its child with sys.argv[1:], so the
flag survives the restart Bazarr performs while loading its config.

update_script() gains a one-time migration for existing installs. It runs
outside the release check so containers already on the latest version are
migrated too, is skipped when the unit already names a data directory,
refuses (before stopping the service) when both locations hold data, and
copies before removing so a failed migration leaves the original database
in place.

Fixes #16097

* fix(bazarr): drop explanatory comments per review
2026-07-28 18:10:12 +10:00
community-scripts-pr-app[bot] bc488e467c Update CHANGELOG.md (#16106)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 08:09:09 +00:00
CanbiZ (MickLesk) 303bb672e6 Bump GitHub Actions across workflows (#16091)
* Bump GitHub Actions across workflows

Update workflow dependencies to newer major versions in repository automation files. This upgrades `actions/checkout` to v7, `actions/github-script` to v9, `actions/create-github-app-token` to v3, and GitHub Pages actions (`upload-pages-artifact` and `deploy-pages`) to v5 to keep CI/CD and maintenance workflows current.

* add dependabot for gh actions
2026-07-28 10:08:38 +02:00
community-scripts-pr-app[bot] 69854a4f74 Update CHANGELOG.md (#16103)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-28 07:40:00 +00:00
Tim Moore dd74eef5f6 Cloudflare-DDNS: store API token in a 600 env file and build the binary at install time (#16100) 2026-07-28 09:39:30 +02:00
community-scripts-pr-app[bot] bf0c6c4503 Update CHANGELOG.md (#16089)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 17:32:42 +00:00
CanbiZ (MickLesk) 895cc7fdcf core: fix OS version fallback when the host catalog lacks the requested version & harden template validation (#16068) 2026-07-27 19:32:09 +02:00
MickLesk 7cee1cb96a Update Meilisearch migration command to use --upgrade-db instead of --experimental-dumpless-upgrade 2026-07-27 19:12:31 +02:00
community-scripts-pr-app[bot] b3739cebde Update CHANGELOG.md (#16087)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 16:25:38 +00:00
Louis GAMBART af497cdd38 Update MeiliSearch command for database upgrade (#16081) 2026-07-27 18:25:02 +02:00
community-scripts-pr-app[bot] ba8375f4d8 Update CHANGELOG.md (#16075)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 10:52:38 +00:00
Tim Moore cfaed33534 Mylar3 & Medusa: use trixie non-free for unrar, not bookworm (#16072)
Both scripts provision Debian 13 containers (var_version 13) but add a
Debian 12 (bookworm) non-free apt source to obtain unrar.

Because the base image only enables the `main` component, trixie's
non-free is never enabled, so bookworm is the only source offering
unrar and the containers deterministically install the Debian 12 build
(1:6.2.6-1+deb12u1) instead of trixie's 1:7.1.8-1.

Mylar3 additionally never removes the source, leaving bookworm
non-free and non-free-firmware permanently enabled at priority 500 on
a Debian 13 system.

Aligns both with install/sabnzbd-install.sh, which already sets up the
same unrar dependency correctly against trixie.

Co-authored-by: Tim Moore <tim.moore@ingenuity.com.au>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 12:52:07 +02:00
community-scripts-pr-app[bot] fccd4d568f Update CHANGELOG.md (#16074)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 10:51:09 +00:00
push-app-to-main[bot] 4804aaedf7 Unpackerr (#16034)
* Add unpackerr (ct)

* Modify source line for build.func in unpackerr.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 12:50:46 +02:00
community-scripts-pr-app[bot] e7e6456cfa Update CHANGELOG.md (#16073)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 10:41:35 +00:00
push-app-to-main[bot] 631f56b29e CookCLI (#16028)
* Add cookcli (ct)

* Update source command for build functions

* Update ct/cookcli.sh

* Update install/cookcli-install.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-07-27 20:41:01 +10:00
community-scripts-pr-app[bot] a5a77dcd99 Update CHANGELOG.md (#16071)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:58:09 +00:00
Tom Frenzel 2b2e026928 OpenThread-BR: Add runtime configuration options (#16038)
* feat(openthread-br): add nat64 support

* feat(openthread-br): add runtime config service

* chore(openthread-br): rename post-start script
2026-07-27 10:57:45 +02:00
community-scripts-pr-app[bot] 8bb779ea58 Update CHANGELOG.md (#16070)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:54:40 +00:00
CanbiZ (MickLesk) 88ff91e9f2 Vikunja: pin install/update to v2.3.0 due upstream issues (#16059)
* Pin Vikunja install/update to v2.3.0

Set both install and update scripts to deploy Vikunja v2.3.0 instead of latest. The update flow now checks against this pinned release and includes context that v2.4.0 is temporarily avoided due to an upstream startup failure caused by the packaged systemd SystemCallFilter.

* minor fix
2026-07-27 10:54:07 +02:00
community-scripts-pr-app[bot] e9e59f6880 Update CHANGELOG.md (#16069)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:53:11 +00:00
push-app-to-main[bot] 4ad0fed0bd Discourse (#16024)
* Add discourse (ct)

* Change sourcing method for build.func in discourse.sh

* Apply suggestion from @CrazyWolf13

* Refactor credentials output to use heredoc syntax

* Apply suggestion from @tremor021

* Apply suggestion from @tremor021

* Apply suggestion from @tremor021

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2026-07-27 10:52:43 +02:00
community-scripts-pr-app[bot] 07f30c6b75 Update CHANGELOG.md (#16067)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:51:50 +00:00
push-app-to-main[bot] fc110f19bc Mastodon (#16029)
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 10:51:17 +02:00
community-scripts-pr-app[bot] 1a5f25297b Update CHANGELOG.md (#16066)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:48:37 +00:00
CanbiZ (MickLesk) da79270870 core: Handle LXC upgrade prompt cancellation (#16058)
Clarify the upgrade prompt options in `create_lxc_container`, treat empty or unrecognized input as ignore instead of implicit cancel, and explicitly abort container creation when the user chooses Cancel.
2026-07-27 10:48:05 +02:00
community-scripts-pr-app[bot] 5e8c9d85df Update CHANGELOG.md (#16065)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:32:45 +00:00
push-app-to-main[bot] 92ca3bbaaf Docspell (#16033)
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 10:32:20 +02:00
community-scripts-pr-app[bot] 84446c7dd2 Update CHANGELOG.md (#16064)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:31:33 +00:00
push-app-to-main[bot] 2044968562 Poznote (#16030)
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 10:31:10 +02:00
community-scripts-pr-app[bot] 6acf4ad3b9 Update CHANGELOG.md (#16062)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 08:03:39 +00:00
push-app-to-main[bot] 41af8bf1c9 Shiori (#16026)
* Add shiori (ct)

* Change author from GitHub Copilot to MickLesk

* Update author information in shiori-install.sh

* Update install/shiori-install.sh

* Update ct/shiori.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-07-27 10:03:11 +02:00
MickLesk 46a1e13981 Harden close_issue_in_dev workflow
Refactor the workflow to prefer back-references stamped in PR bodies over fuzzy title/slug matching. Add safety guard refusing to close more than 3 issues per PR. Restrict issue search to migration-labelled issues only. Use exact slug matching instead of substring matching. Add permissions block, env var for DEV_REPO, and skip already-closed issues.
2026-07-27 10:02:28 +02:00
community-scripts-pr-app[bot] f9afc80f81 Update CHANGELOG.md (#16061)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 07:53:52 +00:00
push-app-to-main[bot] d688c759d7 Nezha (#16025)
* Add nezha (ct)

* Update author in nezha.sh script

* Fix dashboard file handling in nezha.sh

* Update author information in nezha-install.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 09:53:27 +02:00
community-scripts-pr-app[bot] 7715c37553 Update CHANGELOG.md (#16057)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-27 06:41:38 +00:00
push-app-to-main[bot] 5be03046e4 PasswordPusher (#16031)
* Add passwordpusher (ct)

* Update install/passwordpusher-install.sh

* Update ct/passwordpusher.sh

* Refactor passwordpusher.sh to streamline sourcing

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-07-27 08:41:11 +02:00
80 changed files with 2403 additions and 316 deletions
+17
View File
@@ -0,0 +1,17 @@
# Keeps the GitHub Actions referenced in .github/workflows up to date.
# https://docs.github.com/code-security/dependabot/working-with-dependabot/dependabot-options-reference
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
# One PR per week for all action bumps instead of one PR per action.
groups:
github-actions:
patterns:
- "*"
+3 -3
View File
@@ -20,21 +20,21 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
# Step 1: Checkout repository
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v7
# Step 2: Disable file mode changes detection
- name: Disable file mode changes
+2 -2
View File
@@ -16,13 +16,13 @@ jobs:
CONFIG_PATH: .github/autolabeler-config.json
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Install dependencies
run: npm install minimatch
- name: Label PR based on file changes, title, and PR template
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const fs = require('fs').promises;
+4 -4
View File
@@ -19,25 +19,25 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Archive old changelog entries
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const fs = require('fs').promises;
+5 -5
View File
@@ -19,20 +19,20 @@ jobs:
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate a token for PR approval and merge
id: generate-token-merge
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.APP_ID_APPROVE_AND_MERGE }}
private-key: ${{ secrets.APP_KEY_APPROVE_AND_MERGE }}
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
@@ -53,7 +53,7 @@ jobs:
- name: Get categorized pull requests
id: get-categorized-prs
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
async function main() {
@@ -213,7 +213,7 @@ jobs:
return await main();
- name: Update CHANGELOG.md
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const fs = require('fs').promises;
+2 -2
View File
@@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
ref: main
@@ -242,7 +242,7 @@ jobs:
checked=$((checked + 1))
# Extract our NODE_VERSION
our_version=$(grep -oP 'NODE_VERSION="(\d+)"' "$script" | head -1 | grep -oP '\d+' || echo "")
our_version=$(grep -oP 'NODE_VERSION=\K"?\d+' "$script" | head -1 | grep -oP '\d+' || echo "")
if [[ -z "$our_version" ]]; then
if grep -q 'NODE_VERSION=\$(' "$script"; then
our_version="dynamic"
+3 -3
View File
@@ -15,7 +15,7 @@ jobs:
contents: read
steps:
- name: Close PR if it does not follow the PR template
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const pr = context.payload.pull_request;
@@ -45,7 +45,7 @@ jobs:
}
const labels = pr.labels.map((label) => label.name);
const skipLabels = ["automated pr", "keep open"];
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.`);
@@ -136,7 +136,7 @@ jobs:
``,
`> 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.`,
`Maintainers can add the \`keep-open\` label to exempt a PR from this check.`,
``,
`Thank you for contributing! 🙏`,
].join("\n");
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
contents: read
steps:
- name: Close PR if unauthorized new script submission
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const pr = context.payload.pull_request;
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Auto-close if tteck script detected
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const issue = context.payload.issue;
+106 -70
View File
@@ -3,109 +3,145 @@ on:
pull_request:
types:
- closed
permissions:
contents: read
jobs:
close_issue:
if: github.event.pull_request.merged == true && github.repository == 'community-scripts/ProxmoxVE'
runs-on: self-hosted
env:
DEV_REPO: community-scripts/ProxmoxVED
steps:
- name: Checkout target repo (merge commit)
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: community-scripts/ProxmoxVE
ref: ${{ github.event.pull_request.merge_commit_sha }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract and Process PR Title
id: extract_title
run: |
title=$(echo "${{ github.event.pull_request.title }}" | sed 's/^New Script://g' | tr '[:upper:]' '[:lower:]' | sed 's/ //g' | sed 's/-//g')
echo "Processed Title: $title"
echo "title=$title" >> $GITHUB_ENV
- name: Get slugs from merged PR
- name: Collect script slugs from the merged PR
id: get_slugs
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
pr_files=$(gh pr view ${{ github.event.pull_request.number }} --repo community-scripts/ProxmoxVE --json files -q '.files[].path' 2>/dev/null || true)
slugs=""
for path in $pr_files; do
[[ -f "$path" ]] || continue
if [[ "$path" == frontend/public/json/*.json ]]; then
s=$(jq -r '.slug // empty' "$path" 2>/dev/null)
[[ -n "$s" ]] && slugs="$slugs $s"
elif [[ "$path" == ct/*.sh ]] || [[ "$path" == install/*.sh ]] || [[ "$path" == tools/*.sh ]] || [[ "$path" == turnkey/*.sh ]] || [[ "$path" == vm/*.sh ]]; then
base=$(basename "$path" .sh)
if [[ "$path" == install/* && "$base" == *-install ]]; then
s="${base%-install}"
else
s="$base"
fi
[[ -n "$s" ]] && slugs="$slugs $s"
fi
done
slugs=$(echo $slugs | xargs -n1 | sort -u | tr '\n' ' ')
if [[ -z "$slugs" && -n "$title" ]]; then
slugs="$title"
fi
if [[ -z "$slugs" ]]; then
echo "count=0" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "$slugs" > pocketbase_slugs.txt
echo "count=$(echo $slugs | wc -w)" >> "$GITHUB_OUTPUT"
while IFS= read -r path; do
[ -n "$path" ] || continue
[ -f "$path" ] || continue
- name: Find matching issues in ProxmoxVED by slug
case "$path" in
frontend/public/json/*.json)
s=$(jq -r '.slug // empty' "$path" 2>/dev/null || true)
;;
install/*.sh)
s=$(basename "$path" .sh)
s="${s%-install}"
;;
ct/*.sh|tools/*.sh|turnkey/*.sh|vm/*.sh)
s=$(basename "$path" .sh)
;;
*)
s=""
;;
esac
if [ -n "$s" ]; then
slugs="$slugs $s"
fi
done < <(gh pr view "$PR_NUMBER" --repo community-scripts/ProxmoxVE --json files --jq '.files[].path')
slugs=$(printf '%s\n' $slugs | sed '/^$/d' | sort -u | tr '\n' ' ' | xargs || true)
printf '%s' "$slugs" > pocketbase_slugs.txt
echo "count=$(printf '%s' "$slugs" | wc -w | tr -d '[:space:]')" >> "$GITHUB_OUTPUT"
echo "Slugs in this PR: ${slugs:-<none>}"
- name: Resolve the matching ProxmoxVED issue
id: find_issue
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
if [[ ! -s pocketbase_slugs.txt ]]; then
echo "No slugs derived from PR — nothing to match."
echo "issue_numbers=" >> "$GITHUB_OUTPUT"
exit 0
# move-to-main-repo.yaml stamps the source issue into the PR body it
# creates, so migration PRs carry an exact back-reference. Guessing from
# titles or file names is never needed for them.
matched=$(printf '%s' "$PR_BODY" \
| grep -oE 'community-scripts/ProxmoxVED#[0-9]+' \
| sed 's/.*#//' || true)
if [ -n "$matched" ]; then
echo "Back-reference in PR body -> issue(s): $(printf '%s' "$matched" | tr '\n' ' ')"
else
slugs=$(cat pocketbase_slugs.txt)
if [ -z "$slugs" ]; then
echo "No back-reference and no script slugs — nothing to close."
else
# Hand-made PR: fall back to an exact slug match, and only against
# issues a maintainer already put into migration. A substring match
# here would close unrelated issues that merely mention the app.
issues=$(gh issue list --repo "$DEV_REPO" --state open --limit 500 \
--json number,title,body,labels \
| jq -c '[.[] | select([.labels[].name]
| any(. == "Started Migration To ProxmoxVE" or . == "Migration To ProxmoxVE"))]')
echo "Migration candidates in $DEV_REPO: $(printf '%s' "$issues" | jq 'length')"
for slug in $slugs; do
while IFS= read -r row; do
[ -n "$row" ] || continue
num=$(printf '%s' "$row" | jq -r '.number')
# Same slug derivation the ProxmoxVED workflows use, so both
# sides agree on what "alpine-cinny" means.
name=$(printf '%s' "$row" | jq -r '.body // ""' \
| sed -n '/^###[[:space:]]*Name of the Script/,/^###/p' \
| sed '1d;/^###/d;/^[[:space:]]*$/d' | head -n1)
[ -n "$name" ] || name=$(printf '%s' "$row" | jq -r '.title')
issue_slug=$(printf '%s' "$name" | tr -d '\r' | tr '[:upper:]' '[:lower:]' | sed 's/[[:space:]]\+/-/g')
if [ "$issue_slug" = "$slug" ]; then
echo "Exact slug match: $slug -> #$num"
matched="$matched $num"
fi
done < <(printf '%s' "$issues" | jq -c '.[]')
done
fi
fi
slugs=$(cat pocketbase_slugs.txt)
# Normalize: lowercase, strip spaces and hyphens (same shape as the slug derivation)
norm() { echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[[:space:]]//g; s/-//g'; }
matched=$(printf '%s\n' $matched | sed '/^$/d' | sort -un | tr '\n' ' ' | xargs || true)
count=$(printf '%s' "$matched" | wc -w | tr -d '[:space:]')
issues=$(gh issue list --repo community-scripts/ProxmoxVED --state open --limit 1000 --json number,title,body)
matched=""
for slug in $slugs; do
nslug=$(norm "$slug")
[[ -z "$nslug" ]] && continue
while IFS= read -r row; do
num=$(echo "$row" | jq -r '.number')
ntitle=$(norm "$(echo "$row" | jq -r '.title')")
body=$(echo "$row" | jq -r '.body // ""' | tr '[:upper:]' '[:lower:]')
# Match when the issue title contains the slug, or the body mentions it verbatim
if [[ "$ntitle" == *"$nslug"* ]] || [[ "$body" == *"$slug"* ]]; then
matched="$matched $num"
fi
done < <(echo "$issues" | jq -c '.[]')
done
matched=$(echo $matched | xargs -n1 2>/dev/null | sort -un | tr '\n' ' ')
if [[ -z "$matched" ]]; then
echo "No matching ProxmoxVED issues found for slugs: $slugs"
echo "issue_numbers=" >> "$GITHUB_OUTPUT"
exit 0
if [ "$count" -gt 3 ]; then
echo "::error::Refusing to close $count issues for a single PR ($matched) — matching is wrong."
exit 1
fi
echo "Matched ProxmoxVED issues: $matched"
echo "issue_numbers=$matched" >> "$GITHUB_OUTPUT"
echo "Closing: ${matched:-<none>}"
- name: Comment on and close matching ProxmoxVED issues
if: steps.find_issue.outputs.issue_numbers != ''
shell: bash
env:
GH_TOKEN: ${{ secrets.PAT_MICHEL }}
PR_NUMBER: ${{ github.event.pull_request.number }}
ISSUE_NUMBERS: ${{ steps.find_issue.outputs.issue_numbers }}
run: |
for issue_number in ${{ steps.find_issue.outputs.issue_numbers }}; do
echo "Closing ProxmoxVED issue #$issue_number"
gh issue comment "$issue_number" --repo community-scripts/ProxmoxVED --body "Merged with #${{ github.event.pull_request.number }} in ProxmoxVE"
gh issue close "$issue_number" --repo community-scripts/ProxmoxVED
for issue_number in $ISSUE_NUMBERS; do
state=$(gh issue view "$issue_number" --repo "$DEV_REPO" --json state --jq '.state' 2>/dev/null || echo "MISSING")
if [ "$state" != "OPEN" ]; then
echo "Skipping #$issue_number (state: $state)"
continue
fi
echo "Closing $DEV_REPO#$issue_number"
gh issue comment "$issue_number" --repo "$DEV_REPO" \
--body "Merged with #${PR_NUMBER} in ProxmoxVE"
gh issue close "$issue_number" --repo "$DEV_REPO"
done
- name: Set is_dev to false in PocketBase
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Delete branches of merged PRs
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const owner = context.repo.owner;
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
runs-on: self-hosted
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Clean CHANGELOG (remove HTML header)
run: sed -n '/^## /,$p' CHANGELOG.md > changelog_cleaned.md
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Lock old issues and PRs
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const daysBeforeLock = 7;
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
steps:
- name: Mint GitHub App token (bot identity)
id: app-token
uses: actions/create-github-app-token@v1
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.PB_BOT_APP_ID }}
private-key: ${{ secrets.PB_BOT_APP_PRIVATE_KEY }}
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: self-hosted
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
contents: read
steps:
- name: Handle stale PRs
uses: actions/github-script@v7
uses: actions/github-script@v9
with:
script: |
const now = new Date();
+3 -3
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Create redirect page
run: |
@@ -33,9 +33,9 @@ jobs:
</html>
EOF
- uses: actions/upload-pages-artifact@v3
- uses: actions/upload-pages-artifact@v5
with:
path: site
- name: Deploy
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
runs-on: self-hosted
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0
+56
View File
@@ -508,6 +508,62 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-07-28
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix Node.js version drift [@asylumexp](https://github.com/asylumexp) ([#16111](https://github.com/community-scripts/ProxmoxVE/pull/16111))
- UmlautAdaptarr: use the Debian 13 Microsoft repo with its 2025 signing key [@angusmaul](https://github.com/angusmaul) ([#16077](https://github.com/community-scripts/ProxmoxVE/pull/16077))
- fix(bazarr): store data in /var/lib/bazarr instead of inside /opt/bazarr [@angusmaul](https://github.com/angusmaul) ([#16098](https://github.com/community-scripts/ProxmoxVE/pull/16098))
- Cloudflare-DDNS: store API token in a 600 env file and build the binary at install time [@angusmaul](https://github.com/angusmaul) ([#16100](https://github.com/community-scripts/ProxmoxVE/pull/16100))
### 🧰 Tools
- actual-budget-prometheus-exporter ([#16109](https://github.com/community-scripts/ProxmoxVE/pull/16109))
### 📂 Github
- fix keep-open for close invalid pr [@asylumexp](https://github.com/asylumexp) ([#16105](https://github.com/community-scripts/ProxmoxVE/pull/16105))
- Bump GitHub Actions across workflows [@MickLesk](https://github.com/MickLesk) ([#16091](https://github.com/community-scripts/ProxmoxVE/pull/16091))
## 2026-07-27
### 🆕 New Scripts
- Unpackerr ([#16034](https://github.com/community-scripts/ProxmoxVE/pull/16034))
- CookCLI ([#16028](https://github.com/community-scripts/ProxmoxVE/pull/16028))
- Discourse ([#16024](https://github.com/community-scripts/ProxmoxVE/pull/16024))
- Mastodon ([#16029](https://github.com/community-scripts/ProxmoxVE/pull/16029))
- Docspell ([#16033](https://github.com/community-scripts/ProxmoxVE/pull/16033))
- Poznote ([#16030](https://github.com/community-scripts/ProxmoxVE/pull/16030))
- Shiori ([#16026](https://github.com/community-scripts/ProxmoxVE/pull/16026))
- Nezha ([#16025](https://github.com/community-scripts/ProxmoxVE/pull/16025))
- PasswordPusher ([#16031](https://github.com/community-scripts/ProxmoxVE/pull/16031))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Update MeiliSearch command for database upgrade [@Isnubi](https://github.com/Isnubi) ([#16081](https://github.com/community-scripts/ProxmoxVE/pull/16081))
- Mylar3 & Medusa: use trixie non-free for unrar, not bookworm [@angusmaul](https://github.com/angusmaul) ([#16072](https://github.com/community-scripts/ProxmoxVE/pull/16072))
- Vikunja: pin install/update to v2.3.0 due upstream issues [@MickLesk](https://github.com/MickLesk) ([#16059](https://github.com/community-scripts/ProxmoxVE/pull/16059))
- #### ✨ New Features
- OpenThread-BR: Add runtime configuration options [@tomfrenzel](https://github.com/tomfrenzel) ([#16038](https://github.com/community-scripts/ProxmoxVE/pull/16038))
### 💾 Core
- #### 🐞 Bug Fixes
- core: Handle LXC upgrade prompt cancellation [@MickLesk](https://github.com/MickLesk) ([#16058](https://github.com/community-scripts/ProxmoxVE/pull/16058))
- #### ✨ New Features
- core: fix OS version fallback when the host catalog lacks the requested version & harden template validation [@MickLesk](https://github.com/MickLesk) ([#16068](https://github.com/community-scripts/ProxmoxVE/pull/16068))
## 2026-07-26
### 🆕 New Scripts
+25
View File
@@ -28,6 +28,31 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if ! grep -qE -- "bazarr\.py.*[[:space:]](-c|--config)([[:space:]]|=)" /etc/systemd/system/bazarr.service 2>/dev/null; then
if [[ -d /opt/bazarr/data && ! -L /opt/bazarr/data && -n "$(ls -A /var/lib/bazarr/ 2>/dev/null)" ]]; then
msg_error "/opt/bazarr/data and /var/lib/bazarr both contain data - refusing to merge them. Keep the copy you want in /var/lib/bazarr, remove /opt/bazarr/data, then run the update again."
exit 1
fi
msg_info "Moving Bazarr data to /var/lib/bazarr"
systemctl stop bazarr
if [[ -L /opt/bazarr/data ]]; then
rm -f /opt/bazarr/data
elif [[ -d /opt/bazarr/data ]]; then
if ! cp -a /opt/bazarr/data/. /var/lib/bazarr/; then
systemctl start bazarr
msg_error "Could not copy /opt/bazarr/data to /var/lib/bazarr - nothing was removed."
exit 1
fi
rm -rf /opt/bazarr/data
fi
sed -i -E "s|^(ExecStart=.*bazarr\.py.*)$|\1 -c /var/lib/bazarr|" /etc/systemd/system/bazarr.service
systemctl daemon-reload
systemctl start bazarr
msg_ok "Moved Bazarr data to /var/lib/bazarr"
fi
if check_for_gh_release "bazarr" "morpheus65535/bazarr"; then
msg_info "Stopping Service"
systemctl stop bazarr
+27 -3
View File
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-3}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
@@ -24,11 +24,35 @@ function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/cloudflare-ddns.service ]]; then
if [[ ! -f /usr/local/bin/ddns ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_error "There is no update function for ${APP}."
if check_for_gh_release "cloudflare-ddns" "favonia/cloudflare-ddns"; then
msg_info "Stopping Service"
systemctl stop cloudflare-ddns
msg_ok "Stopped Service"
setup_go
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cloudflare-ddns" "favonia/cloudflare-ddns" "tarball"
msg_info "Updating ${APP}"
cd /opt/cloudflare-ddns
export CGO_ENABLED=0 GOOS=linux
$STD go build -trimpath -ldflags="-s -w" -o /usr/local/bin/ddns ./cmd/ddns
msg_ok "Updated ${APP}"
msg_info "Removing Build Dependencies"
rm -rf /usr/local/go /usr/local/bin/go /usr/local/bin/gofmt /root/go /root/.cache/go-build /opt/cloudflare-ddns
msg_ok "Removed Build Dependencies"
msg_info "Starting Service"
systemctl start cloudflare-ddns
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
+60
View File
@@ -0,0 +1,60 @@
#!/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/cooklang/cookcli
APP="CookCLI"
var_tags="${var_tags:-recipes;cooking;food}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
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 [[ ! -f /opt/cookcli/cook ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "cook" "cooklang/cookcli"; then
msg_info "Stopping Service"
systemctl stop cookcli
msg_ok "Stopped Service"
create_backup /opt/cookcli/recipes
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cook" "cooklang/cookcli" "prebuild" "latest" "/opt/cookcli" "cook-$(arch_resolve "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-musl").tar.gz"
chmod +x /opt/cookcli/cook
restore_backup
msg_info "Starting Service"
systemctl start cookcli
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}:9080${CL}"
+1 -1
View File
@@ -25,7 +25,7 @@ function update_script() {
check_container_storage
check_container_resources
NODE_VERSION="24" setup_nodejs
NODE_VERSION="26" setup_nodejs
ensure_dependencies build-essential
if command -v cross-seed &>/dev/null; then
+71
View File
@@ -0,0 +1,71 @@
#!/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://www.discourse.org/
APP="Discourse"
var_tags="${var_tags:-forum;community;discussion}"
var_cpu="${var_cpu:-4}"
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}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/discourse ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if [[ ! -f /opt/discourse/.env ]]; then
msg_error "No Discourse Configuration Found!"
exit
fi
msg_info "Stopping Service"
systemctl stop discourse
msg_ok "Stopped Service"
create_backup /opt/discourse/.env
msg_info "Updating Discourse"
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
cd /opt/discourse
git pull origin main
$STD bundle install --deployment --without test development
$STD yarn install
$STD runuser -u postgres -- psql -d discourse -c "CREATE EXTENSION IF NOT EXISTS vector;"
$STD bundle exec rails assets:precompile
$STD bundle exec rails db:migrate
msg_ok "Updated Discourse"
restore_backup
msg_info "Starting Service"
systemctl start discourse
msg_ok "Started Service"
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}${CL}"
+2 -2
View File
@@ -27,8 +27,8 @@ function update_script() {
msg_error "No ${APP} Installation Found!"
exit
fi
if ! command -v node >/dev/null || [[ "$(/usr/bin/env node -v | grep -oP '^v\K[0-9]+')" != "22" ]]; then
NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
if ! command -v node >/dev/null || [[ "$(/usr/bin/env node -v | grep -oP '^v\K[0-9]+')" != "26" ]]; then
NODE_VERSION="26" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
fi
export NODE_OPTIONS="--max_old_space_size=4096"
+61
View File
@@ -0,0 +1,61 @@
#!/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://docspell.org/
APP="Docspell"
var_tags="${var_tags:-documents;ocr;paperless;productivity}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-16}"
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/docspell-restserver/docspell-server.conf ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "docspell-joex" "eikek/docspell"; then
msg_info "Stopping Services"
systemctl stop docspell-joex docspell-restserver
msg_ok "Stopped Services"
create_backup /etc/docspell-joex/docspell-joex.conf \
/etc/docspell-restserver/docspell-server.conf
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "docspell-joex" "eikek/docspell" "binary" "latest" "/opt/docspell" "docspell-joex_*_all.deb"
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "docspell-restserver" "eikek/docspell" "binary" "latest" "/opt/docspell" "docspell-restserver_*_all.deb"
restore_backup
msg_info "Starting Services"
systemctl start docspell-restserver docspell-joex
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}:7880${CL}"
+6
View File
@@ -0,0 +1,6 @@
______ __ ________ ____
/ ____/___ ____ / /__/ ____/ / / _/
/ / / __ \/ __ \/ //_/ / / / / /
/ /___/ /_/ / /_/ / ,< / /___/ /____/ /
\____/\____/\____/_/|_|\____/_____/___/
+6
View File
@@ -0,0 +1,6 @@
____ _
/ __ \(_)_____________ __ _______________
/ / / / / ___/ ___/ __ \/ / / / ___/ ___/ _ \
/ /_/ / (__ ) /__/ /_/ / /_/ / / (__ ) __/
/_____/_/____/\___/\____/\__,_/_/ /____/\___/
+6
View File
@@ -0,0 +1,6 @@
____ ____
/ __ \____ ______________ ___ / / /
/ / / / __ \/ ___/ ___/ __ \/ _ \/ / /
/ /_/ / /_/ / /__(__ ) /_/ / __/ / /
/_____/\____/\___/____/ .___/\___/_/_/
/_/
+6
View File
@@ -0,0 +1,6 @@
__ ___ __ __
/ |/ /___ ______/ /_____ ____/ /___ ____
/ /|_/ / __ `/ ___/ __/ __ \/ __ / __ \/ __ \
/ / / / /_/ (__ ) /_/ /_/ / /_/ / /_/ / / / /
/_/ /_/\__,_/____/\__/\____/\__,_/\____/_/ /_/
+6
View File
@@ -0,0 +1,6 @@
_ __ __
/ | / /__ ____ / /_ ____ _
/ |/ / _ \/_ / / __ \/ __ `/
/ /| / __/ / /_/ / / / /_/ /
/_/ |_/\___/ /___/_/ /_/\__,_/
+6
View File
@@ -0,0 +1,6 @@
____ ______ __
/ __ \____ ____________ ______ _________/ / __ \__ _______/ /_ ___ _____
/ /_/ / __ `/ ___/ ___/ | /| / / __ \/ ___/ __ / /_/ / / / / ___/ __ \/ _ \/ ___/
/ ____/ /_/ (__ |__ )| |/ |/ / /_/ / / / /_/ / ____/ /_/ (__ ) / / / __/ /
/_/ \__,_/____/____/ |__/|__/\____/_/ \__,_/_/ \__,_/____/_/ /_/\___/_/
+6
View File
@@ -0,0 +1,6 @@
____ __
/ __ \____ ____ ____ ____ / /____
/ /_/ / __ \/_ / / __ \/ __ \/ __/ _ \
/ ____/ /_/ / / /_/ / / / /_/ / /_/ __/
/_/ \____/ /___/_/ /_/\____/\__/\___/
+6
View File
@@ -0,0 +1,6 @@
_____ __ _ _
/ ___// /_ (_)___ _____(_)
\__ \/ __ \/ / __ \/ ___/ /
___/ / / / / / /_/ / / / /
/____/_/ /_/_/\____/_/ /_/
+6
View File
@@ -0,0 +1,6 @@
__ __ __
/ / / /___ ____ ____ ______/ /_____ __________
/ / / / __ \/ __ \/ __ `/ ___/ //_/ _ \/ ___/ ___/
/ /_/ / / / / /_/ / /_/ / /__/ ,< / __/ / / /
\____/_/ /_/ .___/\__,_/\___/_/|_|\___/_/ /_/
/_/
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mastodon/mastodon
APP="Mastodon"
var_tags="${var_tags:-social;fediverse;activitypub}"
var_cpu="${var_cpu:-4}"
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/mastodon ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "mastodon" "mastodon/mastodon"; then
msg_info "Stopping Services"
systemctl stop mastodon-web mastodon-sidekiq mastodon-streaming
msg_ok "Stopped Services"
create_backup /opt/mastodon/public/system /opt/mastodon/.env.production
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mastodon" "mastodon/mastodon" "tarball"
sed -i "s/config.force_ssl = true/config.force_ssl = ENV.fetch('LOCAL_HTTPS', 'false') == 'true'/" /opt/mastodon/config/environments/production.rb
sed -i "s/https = Rails.env.production? || ENV\['LOCAL_HTTPS'\] == 'true'/https = ENV.fetch('LOCAL_HTTPS', 'false') == 'true'/" /opt/mastodon/config/initializers/1_hosts.rb
msg_info "Installing Ruby Dependencies"
cd /opt/mastodon
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
$STD bundle config set --local without 'development test'
$STD bundle config set --local deployment 'true'
$STD bundle install -j"$(nproc)"
msg_ok "Installed Ruby Dependencies"
msg_info "Installing Node.js Dependencies"
$STD yarn install
msg_ok "Installed Node.js Dependencies"
restore_backup
msg_info "Running Database Migrations"
RAILS_ENV=production $STD bundle exec rails db:migrate
msg_ok "Ran Database Migrations"
msg_info "Precompiling Assets"
RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 $STD bundle exec rails assets:precompile
msg_ok "Precompiled Assets"
msg_info "Starting Services"
systemctl start mastodon-web mastodon-sidekiq mastodon-streaming
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}${CL}"
+64
View File
@@ -0,0 +1,64 @@
#!/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/nezhahq/nezha
APP="Nezha"
var_tags="${var_tags:-monitoring;infrastructure;analytics}"
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:-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/nezha ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "nezha" "nezhahq/nezha"; then
msg_info "Stopping Service"
systemctl stop nezha
msg_ok "Stopped Service"
create_backup /opt/nezha/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nezha" "nezhahq/nezha" "prebuild" "latest" "/opt/nezha" "dashboard-linux-amd64.zip"
if [[ -f /opt/nezha/dashboard-linux-amd64 ]]; then
mv /opt/nezha/dashboard-linux-amd64 /opt/nezha/dashboard
chmod +x /opt/nezha/dashboard
fi
restore_backup
msg_info "Starting Service"
systemctl start nezha
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}:8008${CL}"
+27
View File
@@ -70,7 +70,9 @@ function update_script() {
-DOTBR_BACKBONE_ROUTER=ON \
-DOTBR_SYSTEMD_UNIT_DIR=/etc/systemd/system \
-DOT_FIREWALL=ON \
-DOTBR_NAT64=ON \
-DOT_POSIX_NAT64_CIDR="192.168.255.0/24" \
-DOTBR_DNS_UPSTREAM_QUERY=ON \
..
$STD ninja
$STD ninja install
@@ -101,6 +103,31 @@ EOF
mv /etc/default/otbr-agent.bak /etc/default/otbr-agent
msg_ok "Restored Configuration"
if [[ ! -f /etc/systemd/system/otbr-agent.service.d/10-otbr-post-start.conf ]]; then
msg_info "Configuring OpenThread Border Router post-start service"
cat <<'EOF' >/usr/local/bin/otbr-post-start.sh
#!/bin/sh
# OpenThread Border Router post-start script
# Run custom commands for runtime configuration options
# Wait for the otbr-agent service to be initialized
#sleep 3
# Configure routing and translation features
#ot-ctl nat64 enable
#ot-ctl dns server upstream enable
EOF
chmod +x /usr/local/bin/otbr-post-start.sh
mkdir -p /etc/systemd/system/otbr-agent.service.d
cat <<'EOF' >/etc/systemd/system/otbr-agent.service.d/10-otbr-post-start.conf
[Service]
ExecStartPost=/usr/local/bin/otbr-post-start.sh
EOF
systemctl daemon-reload
msg_ok "Configured OpenThread Border Router post-start service"
fi
msg_info "Starting Services"
systemctl start otbr-agent
systemctl start otbr-web
+1 -1
View File
@@ -29,7 +29,7 @@ function update_script() {
exit
fi
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
NODE_VERSION="26" NODE_MODULE="corepack" setup_nodejs
if check_for_gh_release "outline" "outline/outline"; then
msg_info "Stopping Services"
+2
View File
@@ -31,6 +31,8 @@ function update_script() {
exit
fi
NODE_VERSION="26" setup_nodejs
if check_for_gh_release "OxiCloud" "DioCrafts/OxiCloud"; then
msg_info "Stopping OxiCloud"
systemctl stop oxicloud
+79
View File
@@ -0,0 +1,79 @@
#!/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/pglombardo/PasswordPusher
APP="PasswordPusher"
var_tags="${var_tags:-security;sharing;password}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
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/passwordpusher ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "passwordpusher" "pglombardo/PasswordPusher"; then
msg_info "Stopping Service"
systemctl stop passwordpusher
msg_ok "Stopped Service"
create_backup /opt/passwordpusher/storage /opt/passwordpusher/.env.production
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
msg_info "Installing Gem Dependencies"
cd /opt/passwordpusher
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
$STD bundle config set --local without 'development test'
$STD bundle config set --local deployment 'true'
$STD bundle install
msg_ok "Installed Gem Dependencies"
msg_info "Installing JS Dependencies"
$STD yarn install --frozen-lockfile
msg_ok "Installed JS Dependencies"
msg_info "Running Database Migrations"
RAILS_ENV=production $STD bundle exec rails db:migrate
msg_ok "Ran Database Migrations"
msg_info "Precompiling Assets"
RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 $STD bundle exec rails assets:precompile
msg_ok "Precompiled Assets"
restore_backup
msg_info "Starting Service"
systemctl start passwordpusher
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}:5100${CL}"
+64
View File
@@ -0,0 +1,64 @@
#!/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/timothepoznanski/poznote
APP="Poznote"
var_tags="${var_tags:-notes;documentation;php}"
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 /var/www/html/data ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "poznote" "timothepoznanski/poznote"; then
msg_info "Stopping Service"
systemctl stop nginx
msg_ok "Stopped Service"
create_backup /var/www/html/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "poznote" "timothepoznanski/poznote" "tarball"
msg_info "Deploying New Version"
cp -r /opt/poznote/src/. /var/www/html/
chown -R www-data:www-data /var/www/html
msg_ok "Deployed New Version"
restore_backup
msg_info "Starting Service"
systemctl start nginx
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}:8040${CL}"
+3
View File
@@ -28,6 +28,9 @@ function update_script() {
msg_error "No ${APP} installation found!"
exit
fi
NODE_VERSION="24" NODE_MODULE="playactor" setup_nodejs
if check_for_gh_release "ps5-mqtt" "FunkeyFlo/ps5-mqtt"; then
msg_info "Stopping service"
systemctl stop ps5-mqtt
+58
View File
@@ -0,0 +1,58 @@
#!/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/go-shiori/shiori
APP="Shiori"
var_tags="${var_tags:-bookmarks;read-it-later;notes}"
var_cpu="${var_cpu:-1}"
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/shiori ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "shiori" "go-shiori/shiori"; then
msg_info "Stopping Service"
systemctl stop shiori
msg_ok "Stopped Service"
create_backup /opt/shiori/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "shiori" "go-shiori/shiori" "prebuild" "latest" "/opt/shiori" "shiori_Linux_$(arch_resolve "x86_64" "aarch64")_*.tar.gz"
chmod +x /opt/shiori/shiori
restore_backup
msg_info "Starting Service"
systemctl start shiori
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}"
+2
View File
@@ -30,6 +30,8 @@ function update_script() {
exit
fi
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "sync-in" "Sync-in/server"; then
msg_info "Stopping Service"
systemctl stop sync-in
+1 -1
View File
@@ -30,7 +30,7 @@ function update_script() {
exit
fi
NODE_VERSION="24" setup_nodejs
NODE_VERSION="26" setup_nodejs
if check_for_gh_tag "guacd" "apache/guacamole-server"; then
msg_info "Stopping guacd"
+12
View File
@@ -29,6 +29,18 @@ function update_script() {
exit
fi
if grep -qs "packages.microsoft.com/debian/12" /etc/apt/sources.list.d/microsoft*.sources; then
msg_info "Migrating Microsoft Repository to Debian 13"
setup_deb822_repo \
"microsoft" \
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie" \
"main"
rm -f /usr/share/keyrings/microsoft-prod.gpg
msg_ok "Migrated Microsoft Repository to Debian 13"
fi
if check_for_gh_release "UmlautAdaptarr" "PCJones/Umlautadaptarr"; then
msg_info "Stopping Service"
systemctl stop umlautadaptarr
+59
View File
@@ -0,0 +1,59 @@
#!/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://unpackerr.zip/
APP="Unpackerr"
var_tags="${var_tags:-downloads;arr;automation;extraction}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-2}"
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/unpackerr/unpackerr.conf ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "unpackerr" "Unpackerr/unpackerr"; then
msg_info "Stopping Service"
systemctl stop unpackerr
msg_ok "Stopped Service"
create_backup /etc/unpackerr/unpackerr.conf
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "unpackerr" "Unpackerr/unpackerr" "binary" "latest" "/opt/unpackerr" "unpackerr_*_$(arch_resolve).deb"
restore_backup
msg_info "Starting Service"
systemctl start unpackerr
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}Configure integrations in:${CL}"
echo -e "${GATEWAY}${BGN}/etc/unpackerr/unpackerr.conf${CL}"
+6 -5
View File
@@ -29,9 +29,9 @@ function update_script() {
exit
fi
RELEASE="$( [[ -f "$HOME/.vikunja" ]] && cat "$HOME/.vikunja" 2>/dev/null || [[ -f /opt/Vikunja_version ]] && cat /opt/Vikunja_version 2>/dev/null || true)"
if [[ -z "$RELEASE" ]] || [[ "$RELEASE" == "unstable" ]] || dpkg --compare-versions "${RELEASE:-0.0.0}" lt "1.0.0"; then
msg_warn "You are upgrading from Vikunja '$RELEASE'."
INSTALLED_VERSION="$( [[ -f "$HOME/.vikunja" ]] && cat "$HOME/.vikunja" 2>/dev/null || [[ -f /opt/Vikunja_version ]] && cat /opt/Vikunja_version 2>/dev/null || true)"
if [[ -z "$INSTALLED_VERSION" ]] || [[ "$INSTALLED_VERSION" == "unstable" ]] || dpkg --compare-versions "${INSTALLED_VERSION:-0.0.0}" lt "1.0.0"; then
msg_warn "You are upgrading from Vikunja '$INSTALLED_VERSION'."
msg_warn "This requires MANUAL config changes in /etc/vikunja/config.yml."
msg_warn "See: https://vikunja.io/changelog/whats-new-in-vikunja-1.0.0/#config-changes"
@@ -46,7 +46,8 @@ function update_script() {
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
fi
if check_for_gh_release "vikunja" "go-vikunja/vikunja"; then
RELEASE="v2.3.0"
if check_for_gh_release "vikunja" "go-vikunja/vikunja" "${RELEASE}" "v2.4.0 is killed at startup by the systemd SystemCallFilter shipped in the .deb (upstream go-vikunja/vikunja#3252); pinned until a fixed release is out"; then
echo
msg_warn "The package update may include config file changes."
echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}"
@@ -65,7 +66,7 @@ function update_script() {
systemctl stop vikunja
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
$STD systemctl daemon-reload
msg_info "Starting Service"
+1 -1
View File
@@ -36,7 +36,7 @@ UMask=0002
Restart=on-failure
RestartSec=5
Type=simple
ExecStart=/opt/bazarr/venv/bin/python3 /opt/bazarr/bazarr.py
ExecStart=/opt/bazarr/venv/bin/python3 /opt/bazarr/bazarr.py -c /var/lib/bazarr
KillSignal=SIGINT
TimeoutStopSec=20
SyslogIdentifier=bazarr
+37 -12
View File
@@ -13,8 +13,6 @@ setting_up_container
network_check
update_os
setup_go
var_cf_api_token="default"
read -rp "${TAB3}Enter the Cloudflare API token: " var_cf_api_token
@@ -53,23 +51,50 @@ while true; do
done
msg_ok "Configured Application"
setup_go
fetch_and_deploy_gh_release "cloudflare-ddns" "favonia/cloudflare-ddns" "tarball"
msg_info "Building ${APPLICATION}"
cd /opt/cloudflare-ddns
export CGO_ENABLED=0 GOOS=linux
$STD go build -trimpath -ldflags="-s -w" -o /usr/local/bin/ddns ./cmd/ddns
msg_ok "Built ${APPLICATION}"
# The binary is statically linked (CGO_ENABLED=0), so Go is only a build-time
# dependency. Removing it keeps the container small; update_script reinstalls it
# via setup_go when a rebuild is needed.
msg_info "Removing Build Dependencies"
rm -rf /usr/local/go /usr/local/bin/go /usr/local/bin/gofmt /root/go /root/.cache/go-build /opt/cloudflare-ddns
msg_ok "Removed Build Dependencies"
msg_info "Setting up service"
mkdir -p /root/go
useradd --system --no-create-home --shell /usr/sbin/nologin cloudflare-ddns 2>/dev/null || true
cat <<EOF >/etc/cloudflare-ddns.env
CLOUDFLARE_API_TOKEN=${var_cf_api_token}
DOMAINS=${var_cf_domains}
PROXIED=${var_cf_proxied}
IP6_PROVIDER=${var_cf_ip6_provider}
EOF
chown root:root /etc/cloudflare-ddns.env
chmod 600 /etc/cloudflare-ddns.env
cat <<EOF >/etc/systemd/system/cloudflare-ddns.service
[Unit]
Description=Cloudflare DDNS Service (Go run)
After=network.target
Description=Cloudflare DDNS Service
After=network-online.target
Wants=network-online.target
[Service]
Environment="CLOUDFLARE_API_TOKEN=${var_cf_api_token}"
Environment="DOMAINS=${var_cf_domains}"
Environment="PROXIED=${var_cf_proxied}"
Environment="IP6_PROVIDER=${var_cf_ip6_provider}"
Environment="GOPATH=/root/go"
Environment="GOCACHE=/tmp/go-build"
ExecStart=/usr/local/bin/go run github.com/favonia/cloudflare-ddns/cmd/ddns@latest
Type=simple
User=cloudflare-ddns
Group=cloudflare-ddns
EnvironmentFile=/etc/cloudflare-ddns.env
ExecStart=/usr/local/bin/ddns
Restart=always
RestartSec=300
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
+47
View File
@@ -0,0 +1,47 @@
#!/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/cooklang/cookcli
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "cook" "cooklang/cookcli" "prebuild" "latest" "/opt/cookcli" "cook-$(arch_resolve "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-musl").tar.gz"
msg_info "Configuring CookCLI"
chmod +x /opt/cookcli/cook
mkdir -p /opt/cookcli/recipes
cd /opt/cookcli/recipes
$STD /opt/cookcli/cook seed
msg_ok "Configured CookCLI"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/cookcli.service
[Unit]
Description=CookCLI Recipe Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/cookcli/recipes
ExecStart=/opt/cookcli/cook server --host 0.0.0.0 --port 9080
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now cookcli
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y build-essential
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
NODE_VERSION="26" setup_nodejs
msg_info "Setup Cross-Seed"
$STD npm install cross-seed@latest -g
+218
View File
@@ -0,0 +1,218 @@
#!/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://www.discourse.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 \
build-essential \
git \
libssl-dev \
libreadline-dev \
zlib1g-dev \
libyaml-dev \
imagemagick \
gsfonts \
brotli \
nginx \
redis-server
msg_ok "Installed Dependencies"
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
NODE_VERSION="24" setup_nodejs
RUBY_VERSION="3.4.4" setup_ruby
msg_info "Configuring PostgreSQL for Discourse"
DISCOURSE_DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
PG_HBA=$(find /etc/postgresql -name pg_hba.conf 2>/dev/null | head -n1)
sed -i 's/^local\s\+all\s\+all\s\+peer$/local all all md5/' "$PG_HBA"
$STD systemctl restart postgresql
PG_DB_NAME="discourse" PG_DB_USER="discourse" PG_DB_PASS="$DISCOURSE_DB_PASS" PG_DB_EXTENSIONS="vector" setup_postgresql_db
msg_ok "Configured PostgreSQL for Discourse"
msg_info "Configuring Discourse"
DISCOURSE_SECRET_KEY=$(openssl rand -hex 64)
$STD git clone --depth 1 https://github.com/discourse/discourse.git /opt/discourse
cd /opt/discourse
cat <<EOF >/opt/discourse/.env
RAILS_ENV=production
RAILS_LOG_TO_STDOUT=true
RAILS_SERVE_STATIC_FILES=true
SECRET_KEY_BASE=${DISCOURSE_SECRET_KEY}
DISCOURSE_DB_HOST=/var/run/postgresql
DISCOURSE_DB_PORT=5432
DISCOURSE_DB_NAME=discourse
DISCOURSE_DB_USERNAME=discourse
DISCOURSE_DB_PASSWORD=${DISCOURSE_DB_PASS}
DISCOURSE_REDIS_URL=redis://localhost:6379
DISCOURSE_DEVELOPER_EMAILS=admin@discourse.local
DISCOURSE_HOSTNAME=${LOCAL_IP}
DISCOURSE_SMTP_ADDRESS=localhost
DISCOURSE_SMTP_PORT=25
DISCOURSE_SMTP_AUTHENTICATION=none
DISCOURSE_NOTIFICATION_EMAIL=noreply@${LOCAL_IP}
DISCOURSE_SKIP_NEW_ACCOUNT_EMAIL=true
APP_ROOT=/opt/discourse
EOF
mkdir -p /opt/discourse/tmp/sockets /opt/discourse/tmp/pids /opt/discourse/log
chown -R root:root /opt/discourse
chmod 755 /opt/discourse
msg_ok "Configured Discourse"
msg_info "Installing Discourse Dependencies"
$STD systemctl enable --now redis-server
cd /opt/discourse
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
eval "$(rbenv init - bash)" 2>/dev/null || true
export RAILS_ENV=production
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
$STD corepack enable
$STD bundle config set --local deployment true
$STD bundle config set --local without 'test development'
$STD bundle install
$STD pnpm install
msg_ok "Installed Discourse Dependencies"
msg_info "Setting Up Database"
cd /opt/discourse
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
eval "$(rbenv init - bash)" 2>/dev/null || true
export RAILS_ENV=production
set -a
source /opt/discourse/.env
set +a
$STD bundle exec rails db:migrate
$STD bundle exec rails db:seed
msg_ok "Set Up Database"
msg_info "Creating Admin Account"
ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
$STD bundle exec rails runner "
user = User.new(email: 'admin@discourse.local', username: 'admin', password: '${ADMIN_PASS}')
user.active = true
user.admin = true
user.approved = true
user.save!(validate: false)
user.activate
user.grant_admin!
user.change_trust_level!(TrustLevel[4])
SiteSetting.has_login_hint = false
SiteSetting.wizard_enabled = false
"
cat <<EOF >~/discourse.creds
Discourse Credentials
Admin Username: admin
Admin Email: admin@discourse.local
Admin Password: ${ADMIN_PASS}
Database Password: ${DISCOURSE_DB_PASS}
EOF
msg_ok "Created Admin Account"
msg_info "Building Discourse Assets"
cd /opt/discourse
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
eval "$(rbenv init - bash)" 2>/dev/null || true
export RAILS_ENV=production
set -a && source /opt/discourse/.env && set +a
$STD bundle exec rails assets:precompile
msg_ok "Built Discourse Assets"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/discourse.service
[Unit]
Description=Discourse Forum
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/discourse
EnvironmentFile=/opt/discourse/.env
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/root/.rbenv/shims/bundle exec pitchfork -c config/pitchfork.conf.rb
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/discourse-sidekiq.service
[Unit]
Description=Discourse Sidekiq
After=network.target postgresql.service redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/discourse
EnvironmentFile=/opt/discourse/.env
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/root/.rbenv/shims/bundle exec sidekiq -q critical -q default -q low -q ultra_low
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now discourse discourse-sidekiq
msg_ok "Created Services"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/discourse
server {
listen 80 default_server;
server_name _;
root /opt/discourse/public;
client_max_body_size 100M;
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
location /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public,immutable;
}
location /uploads/ {
expires 1h;
}
location / {
try_files \$uri @discourse;
}
location @discourse {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
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 X-Accel-Mapping /opt/discourse/public/=/downloads/;
}
}
EOF
ln -sf /etc/nginx/sites-available/discourse /etc/nginx/sites-enabled/discourse
rm -f /etc/nginx/sites-enabled/default
$STD systemctl enable --now nginx
$STD systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -19,7 +19,7 @@ $STD apt install -y \
make
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
NODE_VERSION="26" NODE_MODULE="pnpm@$(curl -s https://raw.githubusercontent.com/docmost/docmost/main/package.json | jq -r '.packageManager | split("@")[1]')" setup_nodejs
PG_VERSION="16" setup_postgresql
PG_DB_NAME="docmost_db" PG_DB_USER="docmost_user" setup_postgresql_db
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
+108
View File
@@ -0,0 +1,108 @@
#!/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://docspell.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 \
ocrmypdf \
tesseract-ocr \
tesseract-ocr-deu \
tesseract-ocr-eng \
unpaper \
weasyprint \
libreoffice-core \
ghostscript \
libreoffice-writer \
libreoffice-calc \
python3-pip \
python3-uno \
python3-venv
python3 -m venv \
--system-site-packages \
/opt/unoserver
$STD /opt/unoserver/bin/pip install --upgrade pip
$STD /opt/unoserver/bin/pip install unoserver
msg_ok "Installed Dependencies"
JAVA_VERSION="21" setup_java
PG_VERSION="17" setup_postgresql
PG_DB_NAME="docspell" PG_DB_USER="docspell" setup_postgresql_db
fetch_and_deploy_gh_release "docspell-joex" "eikek/docspell" "binary" "latest" "/opt/docspell" "docspell-joex_*_all.deb"
fetch_and_deploy_gh_release "docspell-restserver" "eikek/docspell" "binary" "latest" "/opt/docspell" "docspell-restserver_*_all.deb"
msg_info "Configuring Docspell"
DOCSPELL_SECRET=$(openssl rand -hex 32)
DOCSPELL_ADMIN_SECRET=$(openssl rand -hex 32)
cat <<EOF >/etc/docspell-restserver/docspell-server.conf
docspell.server {
app-id = "rest1"
base-url = "http://${LOCAL_IP}:7880"
internal-url = "http://127.0.0.1:7880"
bind {
address = "0.0.0.0"
port = 7880
}
auth.server-secret = "hex:${DOCSPELL_SECRET}"
admin-endpoint.secret = "${DOCSPELL_ADMIN_SECRET}"
full-text-search {
enabled = true
backend = "postgresql"
postgresql.use-default-connection = true
}
backend {
jdbc {
url = "jdbc:postgresql://127.0.0.1:5432/${PG_DB_NAME}"
user = "${PG_DB_USER}"
password = "${PG_DB_PASS}"
}
signup.mode = "open"
}
}
EOF
cat <<EOF >/etc/docspell-joex/docspell-joex.conf
docspell.joex {
app-id = "joex1"
base-url = "http://127.0.0.1:7878"
bind {
address = "127.0.0.1"
port = 7878
}
jdbc {
url = "jdbc:postgresql://127.0.0.1:5432/${PG_DB_NAME}"
user = "${PG_DB_USER}"
password = "${PG_DB_PASS}"
}
full-text-search {
enabled = true
backend = "postgresql"
postgresql.use-default-connection = true
}
scheduler.pool-size = 1
text-analysis.nlp.mode = "basic"
}
EOF
chown root:docspell /etc/docspell-joex/docspell-joex.conf /etc/docspell-restserver/docspell-server.conf
chmod 640 /etc/docspell-joex/docspell-joex.conf /etc/docspell-restserver/docspell-server.conf
msg_ok "Configured Docspell"
msg_info "Creating Services"
systemctl enable -q --now docspell-restserver docspell-joex
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc
+275
View File
@@ -0,0 +1,275 @@
#!/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/mastodon/mastodon
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 \
git \
imagemagick \
libvips-tools \
libpq-dev \
libxslt1-dev \
file \
protobuf-compiler \
pkg-config \
autoconf \
bison \
build-essential \
libssl-dev \
libyaml-dev \
libreadline-dev \
zlib1g-dev \
libffi-dev \
libgdbm-dev \
libidn-dev \
libicu-dev \
libjemalloc-dev \
libjemalloc2 \
redis-server \
nginx
msg_ok "Installed Dependencies"
setup_ffmpeg
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
$STD corepack enable
PG_VERSION="17" setup_postgresql
PG_DB_NAME="mastodon_production" PG_DB_USER="mastodon" PG_DB_SKIP_ALTER_ROLE="true" setup_postgresql_db
$STD sudo -u postgres psql -c "ALTER USER mastodon CREATEDB;"
RUBY_VERSION="4.0.5" RUBY_INSTALL_RAILS="false" setup_ruby
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
fetch_and_deploy_gh_release "mastodon" "mastodon/mastodon" "tarball"
sed -i "s/config.force_ssl = true/config.force_ssl = ENV.fetch('LOCAL_HTTPS', 'false') == 'true'/" /opt/mastodon/config/environments/production.rb
sed -i "s/https = Rails.env.production? || ENV\['LOCAL_HTTPS'\] == 'true'/https = ENV.fetch('LOCAL_HTTPS', 'false') == 'true'/" /opt/mastodon/config/initializers/1_hosts.rb
msg_info "Installing Ruby Dependencies"
cd /opt/mastodon
$STD bundle config set --local without 'development test'
$STD bundle config set --local deployment 'true'
$STD bundle install -j"$(nproc)"
msg_ok "Installed Ruby Dependencies"
msg_info "Installing Node.js Dependencies"
$STD yarn install
msg_ok "Installed Node.js Dependencies"
msg_info "Configuring Mastodon"
SECRET_KEY_BASE=$(RAILS_ENV=production bundle exec rails secret)
OTP_SECRET=$(RAILS_ENV=production bundle exec rails secret)
VAPID_OUTPUT=$(RAILS_ENV=production bundle exec rails mastodon:webpush:generate_vapid_key 2>/dev/null)
VAPID_PRIVATE_KEY=$(echo "$VAPID_OUTPUT" | grep "^VAPID_PRIVATE_KEY=" | cut -d= -f2-)
VAPID_PUBLIC_KEY=$(echo "$VAPID_OUTPUT" | grep "^VAPID_PUBLIC_KEY=" | cut -d= -f2-)
ENCRYPT_OUTPUT=$(RAILS_ENV=production bundle exec rails db:encryption:init 2>/dev/null)
AR_DET_KEY=$(echo "$ENCRYPT_OUTPUT" | grep "^ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=" | cut -d= -f2-)
AR_SALT=$(echo "$ENCRYPT_OUTPUT" | grep "^ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=" | cut -d= -f2-)
AR_PRIMARY=$(echo "$ENCRYPT_OUTPUT" | grep "^ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=" | cut -d= -f2-)
mkdir -p /opt/mastodon/public/system
cat <<EOF >/opt/mastodon/.env.production
LOCAL_DOMAIN=${LOCAL_IP}
LOCAL_HTTPS=false
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
DB_HOST=127.0.0.1
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=${PG_DB_PASS}
DB_PORT=5432
RAILS_ENV=production
NODE_ENV=production
RAILS_SERVE_STATIC_FILES=true
BIND=0.0.0.0
SECRET_KEY_BASE=${SECRET_KEY_BASE}
OTP_SECRET=${OTP_SECRET}
VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}
VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=${AR_DET_KEY}
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=${AR_SALT}
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=${AR_PRIMARY}
SMTP_SERVER=
SMTP_PORT=587
SMTP_FROM_ADDRESS=notifications@${LOCAL_IP}
EOF
msg_ok "Configured Mastodon"
msg_info "Setting up Database"
RAILS_ENV=production $STD bundle exec rails db:setup
msg_ok "Set up Database"
msg_info "Precompiling Assets (Patience)"
RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 $STD bundle exec rails assets:precompile
msg_ok "Precompiled Assets"
msg_info "Creating Admin Account"
if ! ADMIN_OUTPUT=$(EMAIL_DOMAIN_ALLOWLIST="${LOCAL_IP}" RAILS_ENV=production bundle exec bin/tootctl accounts create admin \
--email "admin@${LOCAL_IP}" \
--confirmed \
--approve \
--role Owner); then
msg_error "Failed to create Mastodon admin account"
exit 1
fi
ADMIN_PASS=$(echo "$ADMIN_OUTPUT" | sed -n 's/^New password: //p')
if [[ -z "$ADMIN_PASS" ]]; then
msg_error "Failed to retrieve Mastodon admin password"
exit 1
fi
RAILS_ENV=production $STD bundle exec bin/tootctl settings registrations approved
cat <<EOF > ~/mastodon.creds
Mastodon Admin Credentials
URL: http://${LOCAL_IP}
Email: admin@${LOCAL_IP}
Password: ${ADMIN_PASS}
EOF
msg_ok "Created Admin Account"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/mastodon-web.service
[Unit]
Description=mastodon-web
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mastodon
Environment=RAILS_ENV=production
Environment=PORT=3000
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/root/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 \$MAINPID
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/mastodon-sidekiq.service
[Unit]
Description=mastodon-sidekiq
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mastodon
Environment=RAILS_ENV=production
Environment=DB_POOL=25
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/root/.rbenv/shims/bundle exec sidekiq -c 25
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/mastodon-streaming.service
[Unit]
Description=mastodon-streaming
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/mastodon
Environment=NODE_ENV=production
Environment=PORT=4000
ExecStart=/usr/bin/node ./streaming
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now mastodon-web mastodon-sidekiq mastodon-streaming
msg_ok "Created Services"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/mastodon
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream mastodon_web {
server 127.0.0.1:3000 fail_timeout=0;
}
upstream mastodon_streaming {
server 127.0.0.1:4000 fail_timeout=0;
}
server {
listen 80;
server_name _;
client_max_body_size 99m;
root /opt/mastodon/public;
gzip on;
gzip_types text/plain application/json application/javascript text/css image/svg+xml;
location / {
try_files $uri @proxy;
}
location ~ ^/assets/ {
add_header Cache-Control "public, max-age=2419200, must-revalidate";
try_files $uri =404;
}
location ^~ /api/v1/streaming {
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_pass http://mastodon_streaming;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
location @proxy {
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_pass http://mastodon_web;
proxy_buffering on;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
EOF
ln -sf /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
rm -f /etc/nginx/sites-enabled/default
$STD nginx -t
systemctl enable -q --now redis-server
systemctl enable -q --now nginx
systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -20,7 +20,7 @@ $STD apt install -y \
mediainfo
cat <<EOF >/etc/apt/sources.list.d/non-free.list
deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb https://deb.debian.org/debian trixie main contrib non-free non-free-firmware
EOF
$STD apt update
$STD apt install -y unrar
+2 -1
View File
@@ -17,8 +17,9 @@ msg_info "Installing Dependencies"
cat <<EOF >/etc/apt/sources.list.d/non-free.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: bookworm
Suites: trixie
Components: non-free non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
$STD apt update
$STD apt install -y unrar
+48
View File
@@ -0,0 +1,48 @@
#!/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/nezhahq/nezha
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "nezha" "nezhahq/nezha" "prebuild" "latest" "/opt/nezha" "dashboard-linux-amd64.zip"
msg_info "Preparing Application Files"
if [[ -f /opt/nezha/dashboard-linux-amd64 ]]; then
mv /opt/nezha/dashboard-linux-amd64 /opt/nezha/dashboard
fi
chmod +x /opt/nezha/dashboard
mkdir -p /opt/nezha/data
msg_ok "Prepared Application Files"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/nezha.service
[Unit]
Description=Nezha Monitoring Dashboard
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/nezha
ExecStart=/opt/nezha/dashboard
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nezha
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+21
View File
@@ -66,7 +66,9 @@ $STD cmake -GNinja \
-DOTBR_BACKBONE_ROUTER=ON \
-DOTBR_SYSTEMD_UNIT_DIR=/etc/systemd/system \
-DOT_FIREWALL=ON \
-DOTBR_NAT64=ON \
-DOT_POSIX_NAT64_CIDR="192.168.255.0/24" \
-DOTBR_DNS_UPSTREAM_QUERY=ON \
..
$STD ninja
$STD ninja install
@@ -103,6 +105,25 @@ EOF
cat <<'EOF' >/etc/default/otbr-web
OTBR_WEB_OPTS="-I wpan0 -a 0.0.0.0 -p 80"
EOF
cat <<'EOF' >/usr/local/bin/otbr-post-start.sh
#!/bin/sh
# OpenThread Border Router post-start script
# Run custom commands for runtime configuration options
# Wait for the otbr-agent service to be initialized
#sleep 3
# Configure routing and translation features
#ot-ctl nat64 enable
#ot-ctl dns server upstream enable
EOF
chmod +x /usr/local/bin/otbr-post-start.sh
mkdir -p /etc/systemd/system/otbr-agent.service.d
cat <<'EOF' >/etc/systemd/system/otbr-agent.service.d/10-otbr-post-start.conf
[Service]
ExecStartPost=/usr/local/bin/otbr-post-start.sh
EOF
systemctl enable -q dbus rsyslog otbr-agent otbr-web
systemctl enable -q bind9 2>/dev/null || systemctl enable -q named 2>/dev/null || true
systemctl start -q dbus rsyslog bind9
+1 -1
View File
@@ -20,7 +20,7 @@ $STD apt install -y \
redis
msg_ok "Installed Dependencies"
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
NODE_VERSION="26" NODE_MODULE="corepack" setup_nodejs
PG_VERSION="16" setup_postgresql
PG_DB_NAME="outline" PG_DB_USER="outline" setup_postgresql_db
+1 -1
View File
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y build-essential
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
NODE_VERSION="26" 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"
+88
View File
@@ -0,0 +1,88 @@
#!/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/pglombardo/PasswordPusher
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 \
default-libmysqlclient-dev \
git \
libpq-dev \
libsqlite3-dev \
pkg-config
msg_ok "Installed Dependencies"
RUBY_VERSION="4.0.5" RUBY_INSTALL_RAILS="false" setup_ruby
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
msg_info "Installing Gem Dependencies"
cd /opt/passwordpusher
$STD bundle config set --local without 'development test'
$STD bundle config set --local deployment 'true'
$STD bundle install
msg_ok "Installed Gem Dependencies"
msg_info "Installing JS Dependencies"
$STD yarn install --frozen-lockfile
msg_ok "Installed JS Dependencies"
msg_info "Configuring PasswordPusher"
mkdir -p /opt/passwordpusher/storage/db
SECRET_KEY_BASE=$(bundle exec rails secret)
MASTER_KEY=$(openssl rand -hex 32)
cat <<EOF >/opt/passwordpusher/.env.production
SECRET_KEY_BASE=${SECRET_KEY_BASE}
PWPUSH_MASTER_KEY=${MASTER_KEY}
PWP__FILES__STORAGE=local
RAILS_LOG_TO_STDOUT=true
PORT=5100
EOF
msg_ok "Configured PasswordPusher"
msg_info "Setting up Database"
RAILS_ENV=production $STD bundle exec rails db:setup
msg_ok "Set up Database"
msg_info "Precompiling Assets"
RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1 $STD bundle exec rails assets:precompile
msg_ok "Precompiled Assets"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/passwordpusher.service
[Unit]
Description=Password Pusher
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/passwordpusher
Environment=RAILS_ENV=production
Environment=PATH=/root/.rbenv/shims:/root/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
EnvironmentFile=/opt/passwordpusher/.env.production
ExecStart=/root/.rbenv/shims/bundle exec puma -C config/puma.rb -e production
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now passwordpusher
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+63
View File
@@ -0,0 +1,63 @@
#!/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/timothepoznanski/poznote
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_FPM="YES" setup_php
fetch_and_deploy_gh_release "poznote" "timothepoznanski/poznote" "tarball"
msg_info "Deploying Poznote"
mkdir -p /var/www/html/data/database
cp -r /opt/poznote/src/. /var/www/html/
touch /var/www/html/data/database/poznote.db
chown -R www-data:www-data /var/www/html
msg_ok "Deployed Poznote"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/poznote
server {
listen 8040;
root /var/www/html;
index index.php index.html;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT \$document_root;
}
location ~ /\.ht {
deny all;
}
}
EOF
ln -sf /etc/nginx/sites-available/poznote /etc/nginx/sites-enabled/poznote
rm -f /etc/nginx/sites-enabled/default
$STD nginx -t
systemctl enable -q --now nginx
systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -19,7 +19,7 @@ $STD apt install -y \
ca-certificates
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="playactor" setup_nodejs
NODE_VERSION="24" NODE_MODULE="playactor" setup_nodejs
fetch_and_deploy_gh_release "ps5-mqtt" "FunkeyFlo/ps5-mqtt" "tarball"
msg_info "Configuring PS5-MQTT"
+52
View File
@@ -0,0 +1,52 @@
#!/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/go-shiori/shiori
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "shiori" "go-shiori/shiori" "prebuild" "latest" "/opt/shiori" "shiori_Linux_$(arch_resolve "x86_64" "aarch64")_*.tar.gz"
msg_info "Configuring Shiori"
mkdir -p /opt/shiori/data
SECRET_KEY=$(tr -d '-' </proc/sys/kernel/random/uuid)
cat <<EOF >/opt/shiori/.env
SHIORI_DIR=/opt/shiori/data
SHIORI_HTTP_PORT=8080
SHIORI_HTTP_ADDRESS=0.0.0.0:
SHIORI_HTTP_SECRET_KEY=${SECRET_KEY}
EOF
msg_ok "Configured Shiori"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/shiori.service
[Unit]
Description=Shiori Bookmark Manager
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/shiori
EnvironmentFile=/opt/shiori/.env
ExecStart=/opt/shiori/shiori server
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now shiori
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
NODE_VERSION="22" setup_nodejs
NODE_VERSION="24" setup_nodejs
setup_mariadb
MARIADB_DB_NAME="sync_in" MARIADB_DB_USER="sync_in" setup_mariadb_db
+1 -1
View File
@@ -54,7 +54,7 @@ cd /opt
rm -rf /opt/guacamole-server
msg_ok "Built Guacamole Server (guacd)"
NODE_VERSION="24" setup_nodejs
NODE_VERSION="26" setup_nodejs
fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix" "tarball"
msg_info "Building Frontend"
+3 -3
View File
@@ -16,9 +16,9 @@ update_os
msg_info "Installing Dependencies"
setup_deb822_repo \
"microsoft" \
"https://packages.microsoft.com/keys/microsoft.asc" \
"https://packages.microsoft.com/debian/12/prod/" \
"bookworm" \
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie" \
"main"
$STD apt install -y \
dotnet-sdk-8.0 \
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://unpackerr.zip/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "unpackerr" "Unpackerr/unpackerr" "binary" "latest" "/opt/unpackerr" "unpackerr_*_$(arch_resolve).deb"
msg_info "Configuring Unpackerr"
mkdir -p /etc/unpackerr
cat <<EOF >/etc/unpackerr/unpackerr.conf
debug = false
quiet = false
activity = false
interval = "2m"
parallel = 1
file_mode = "0644"
dir_mode = "0755"
[webserver]
metrics = false
listen_addr = "0.0.0.0:5656"
[folders]
interval = "0s"
EOF
chmod 640 /etc/unpackerr/unpackerr.conf
msg_ok "Configured Unpackerr"
msg_info "Creating Service"
systemctl enable -q --now unpackerr
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+2 -1
View File
@@ -13,7 +13,8 @@ setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
RELEASE="v2.3.0"
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
msg_info "Setting up Vikunja"
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
+1 -1
View File
@@ -62,7 +62,7 @@ cat <<EOF >/opt/wanderer/start.sh
trap "kill 0" EXIT
cd /opt/wanderer/source/search && meilisearch --experimental-dumpless-upgrade --master-key \$MEILI_MASTER_KEY &
cd /opt/wanderer/source/search && meilisearch --upgrade-db --master-key \$MEILI_MASTER_KEY &
sleep 1
cd /opt/wanderer/source/db && ./pocketbase serve --http=\$PB_URL --dir=\$PB_DB_LOCATION &
cd /opt/wanderer/source/web && node build &
+132 -145
View File
@@ -895,6 +895,108 @@ choose_and_set_storage_for_file() {
# SECTION 5: CONFIGURATION & DEFAULTS MANAGEMENT
# ==============================================================================
# ------------------------------------------------------------------------------
# Distinct versions of OS type $1 in the cached pveam catalog (no network).
# `pveam available` prints "<section>\t<template>" - the name is field 2.
# Must never fail: callers capture this via mapfile < <(...).
# ------------------------------------------------------------------------------
_list_os_versions() {
local ostype="${1:-}"
[[ -n "$ostype" ]] || return 0
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' |
sed -nE "s/^${ostype}-([0-9]+(\.[0-9]+)?).*/\1/p" |
sort -u -V || true
}
# ------------------------------------------------------------------------------
# Catalog templates matching prefix $1 and variant $2 ("debian-13" +
# "-standard_"), oldest first. Same no-fail contract as _list_os_versions.
# ------------------------------------------------------------------------------
_list_templates() {
local search="${1:-}" pattern="${2:-}"
[[ -n "$search" ]] || return 0
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' |
grep -E "^${search}.*${pattern}" |
sort -t - -k 2 -V || true
}
# ------------------------------------------------------------------------------
# Maps var_version onto a version this host's catalog actually has, before the
# settings summary is printed. Availability comes from `pveam available` only -
# never inferred from the PVE release (an updated 8.4 may carry templates an
# older 8.x never saw, and entries drop out again at EOL).
# Picks the nearest version, newer wins on a tie. Interactive: menu with that
# candidate preselected; unattended: takes it with a warning.
# ------------------------------------------------------------------------------
resolve_os_version() {
local ostype="${var_os:-}" want="${var_version:-}"
[[ -n "$ostype" && -n "$want" ]] || return 0
# ARM64 pulls from linuxcontainers.org, the pveam catalog says nothing there
[[ "$(dpkg --print-architecture 2>/dev/null)" == "arm64" ]] && return 0
local -a versions=()
mapfile -t versions < <(_list_os_versions "$ostype")
[[ ${#versions[@]} -gt 0 ]] || return 0
local v
for v in "${versions[@]}"; do
[[ "$v" == "$want" ]] && return 0
done
# Already downloaded counts as available even if the catalog dropped it
if [[ -n "${TEMPLATE_STORAGE:-}" ]] &&
pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "/${ostype}-${want}-"; then
return 0
fi
local candidate
candidate=$(printf '%s\n' "${versions[@]}" | awk -v want="$want" '
function num(v, a) { split(v, a, "."); return a[1] * 10000 + (a[2] + 0) }
BEGIN { w = num(want); best = ""; bestd = -1 }
{
d = num($0) - w
ad = (d < 0) ? -d : d
if (bestd < 0 || ad < bestd || (ad == bestd && d > 0)) { bestd = ad; best = $0 }
}
END { print best }
')
[[ -n "$candidate" ]] || return 0
msg_warn "${ostype^} ${want} is not in this host's template catalog (PVE ${PVEVERSION:-unknown})"
if [[ "${PHS_SILENT:-0}" != "1" ]] && command -v whiptail &>/dev/null && [ -t 0 ] && [[ "$TERM" != "dumb" ]]; then
local -a menu=()
while read -r v; do
if [[ "$v" == "$candidate" ]]; then
menu+=("$v" "closest to ${want} (recommended)")
else
menu+=("$v" " ")
fi
done < <(printf '%s\n' "${versions[@]}" | sort -rV)
local choice
choice=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
--title "OS VERSION NOT AVAILABLE" \
--ok-button "Use" --cancel-button "Exit" \
--menu "\n${ostype^} ${want} is not available on this Proxmox host.\n\nSelect the version to use instead:" \
20 70 8 "${menu[@]}" --default-item "$candidate" \
3>&1 1>&2 2>&3) || exit_script
candidate="$choice"
else
msg_warn "Unattended run - continuing with ${ostype} ${candidate}"
fi
var_version="$candidate"
export var_version
msg_ok "Using ${ostype} ${var_version} instead of ${want}"
return 0 # last call in base_settings(), which runs under errexit
}
# ------------------------------------------------------------------------------
# base_settings()
#
@@ -1068,8 +1170,11 @@ base_settings() {
var_os="debian"
fi
if [ -z "$var_version" ]; then
var_version="12"
var_version="13"
fi
# every install path passes here, and still before any summary is printed
resolve_os_version
}
# ------------------------------------------------------------------------------
@@ -6070,14 +6175,14 @@ create_lxc_container() {
_has_fallback_option=true
echo " [1] Run host upgrade now (recommended). WARNING: this runs apt upgrade and updates all Packages on your host!"
echo " [2] Use an older ${PCT_OSTYPE} template instead (may not work with all scripts)"
echo " [3] Ignore"
echo " [4] Cancel"
echo " [3] Ignore (continue without upgrading)"
echo " [4] Cancel (abort the script)"
echo
read -rp "Select option [1/2/3/4]: " _ans </dev/tty
else
echo " [1] Run host upgrade now (recommended). WARNING: this runs apt upgrade and updates all Packages on your host!"
echo " [2] Ignore"
echo " [3] Cancel"
echo " [2] Ignore (continue without upgrading)"
echo " [3] Cancel (abort the script)"
echo
read -rp "Select option [1/2/3]: " _ans </dev/tty
fi
@@ -6101,7 +6206,8 @@ create_lxc_container() {
return 4
;;
*)
return 4
# Unrecognized/empty input: treat as ignore, never as an implicit cancel
return 2
;;
esac
else
@@ -6112,9 +6218,13 @@ create_lxc_container() {
2)
return 2
;;
*)
3)
return 4
;;
*)
# Unrecognized/empty input: treat as ignore, never as an implicit cancel
return 2
;;
esac
fi
@@ -6474,7 +6584,7 @@ create_lxc_container() {
fi
ONLINE_TEMPLATES=()
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
mapfile -t ONLINE_TEMPLATES < <(_list_templates "$TEMPLATE_SEARCH" "$TEMPLATE_PATTERN")
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
TEMPLATE="$ONLINE_TEMPLATE"
@@ -6482,58 +6592,13 @@ create_lxc_container() {
msg_ok "Template search completed"
fi
# If still no template, try to find alternatives
# resolve_os_version() already validated the version, so this means the
# variant (TEMPLATE_PATTERN) is missing - a catalog issue, don't auto-repair
if [[ -z "$TEMPLATE" ]]; then
msg_warn "No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}, searching for alternatives..."
# Get all available versions for this OS type
AVAILABLE_VERSIONS=()
mapfile -t AVAILABLE_VERSIONS < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk -F'\t' '{print $1}' |
grep "^${PCT_OSTYPE}-" |
sed -E "s/.*${PCT_OSTYPE}-([0-9]+(\.[0-9]+)?).*/\1/" |
sort -u -V 2>/dev/null
)
if [[ ${#AVAILABLE_VERSIONS[@]} -gt 0 ]]; then
echo ""
echo "${BL}Available ${PCT_OSTYPE} versions:${CL}"
for i in "${!AVAILABLE_VERSIONS[@]}"; do
echo " [$((i + 1))] ${AVAILABLE_VERSIONS[$i]}"
done
echo ""
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or press Enter to cancel: " choice </dev/tty
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then
PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}"
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION}"
ONLINE_TEMPLATES=()
mapfile -t ONLINE_TEMPLATES < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' |
grep -E "^${TEMPLATE_SEARCH}-.*${TEMPLATE_PATTERN}" |
sort -t - -k 2 -V 2>/dev/null || true
)
if [[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]]; then
TEMPLATE="${ONLINE_TEMPLATES[-1]}"
TEMPLATE_SOURCE="online"
else
msg_error "No templates available for ${PCT_OSTYPE} ${PCT_OSVERSION}"
exit 225
fi
else
msg_custom "🚫" "${YW}" "Installation cancelled"
exit 0
fi
else
msg_error "No ${PCT_OSTYPE} templates available"
exit 225
fi
msg_error "No ${TEMPLATE_PATTERN#-} template found for ${PCT_OSTYPE} ${PCT_OSVERSION}"
msg_custom "️" "${YW}" "Refresh the catalog and check what this host offers:"
echo -e "${TAB} pveam update && pveam available -section system | grep '${PCT_OSTYPE}-'"
exit 225
fi
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || true)"
@@ -6548,93 +6613,10 @@ create_lxc_container() {
fi
[[ -n "$TEMPLATE_PATH" ]] || {
if [[ -z "$TEMPLATE" ]]; then
msg_error "Template ${PCT_OSTYPE} ${PCT_OSVERSION} not available"
# Get available versions
mapfile -t AVAILABLE_VERSIONS < <(
pveam available -section system 2>/dev/null |
grep "^${PCT_OSTYPE}-" |
sed -E 's/.*'"${PCT_OSTYPE}"'-([0-9]+\.[0-9]+).*/\1/' |
grep -E '^[0-9]+\.[0-9]+$' |
sort -u -V 2>/dev/null || sort -u
)
if [[ ${#AVAILABLE_VERSIONS[@]} -gt 0 ]]; then
echo -e "\n${BL}Available versions:${CL}"
for i in "${!AVAILABLE_VERSIONS[@]}"; do
echo " [$((i + 1))] ${AVAILABLE_VERSIONS[$i]}"
done
echo ""
read -p "Select version [1-${#AVAILABLE_VERSIONS[@]}] or press Enter to exit: " choice </dev/tty
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then
export var_version="${AVAILABLE_VERSIONS[$((choice - 1))]}"
export PCT_OSVERSION="$var_version"
msg_ok "Switched to ${PCT_OSTYPE} ${var_version}"
# Retry template search with new version
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
mapfile -t LOCAL_TEMPLATES < <(
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v search="${TEMPLATE_SEARCH}-" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
sed 's|.*/||' | sort -t - -k 2 -V
)
mapfile -t ONLINE_TEMPLATES < <(
pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' |
grep -E "^${TEMPLATE_SEARCH}-.*${TEMPLATE_PATTERN}" |
sort -t - -k 2 -V 2>/dev/null || true
)
ONLINE_TEMPLATE=""
[[ ${#ONLINE_TEMPLATES[@]} -gt 0 ]] && ONLINE_TEMPLATE="${ONLINE_TEMPLATES[-1]}"
if [[ ${#LOCAL_TEMPLATES[@]} -gt 0 ]]; then
TEMPLATE="${LOCAL_TEMPLATES[-1]}"
TEMPLATE_SOURCE="local"
else
TEMPLATE="$ONLINE_TEMPLATE"
TEMPLATE_SOURCE="online"
fi
TEMPLATE_PATH="$(pvesm path $TEMPLATE_STORAGE:vztmpl/$TEMPLATE 2>/dev/null || true)"
if [[ -z "$TEMPLATE_PATH" ]]; then
TEMPLATE_BASE=$(awk -v s="$TEMPLATE_STORAGE" '$1==s {f=1} f && /path/ {print $2; exit}' /etc/pve/storage.cfg)
[[ -n "$TEMPLATE_BASE" ]] && TEMPLATE_PATH="$TEMPLATE_BASE/template/cache/$TEMPLATE"
fi
# If we still don't have a path but have a valid template name, construct it
if [[ -z "$TEMPLATE_PATH" && -n "$TEMPLATE" ]]; then
TEMPLATE_PATH="/var/lib/vz/template/cache/$TEMPLATE"
fi
[[ -n "$TEMPLATE_PATH" ]] || {
msg_error "Template still not found after version change"
exit 220
}
else
msg_custom "🚫" "${YW}" "Installation cancelled"
exit 0
fi
else
msg_error "No ${PCT_OSTYPE} templates available"
exit 220
fi
fi
msg_error "Could not resolve a storage path for template ${TEMPLATE}"
exit 220
}
# Validate that we found a template
if [[ -z "$TEMPLATE" ]]; then
msg_error "No template found for ${PCT_OSTYPE} ${PCT_OSVERSION}"
msg_custom "️" "${YW}" "Please check:"
msg_custom " •" "${YW}" "Is pveam catalog available? (run: pveam available -section system)"
msg_custom " •" "${YW}" "Does the template exist for your OS version?"
exit 225
fi
msg_ok "Template ${BL}$TEMPLATE${CL} [$TEMPLATE_SOURCE]"
msg_debug "Resolved TEMPLATE_PATH=$TEMPLATE_PATH"
@@ -6701,7 +6683,12 @@ create_lxc_container() {
if [[ "$PCT_OSTYPE" == "debian" ]]; then
OSVER="$(parse_template_osver "$TEMPLATE")"
if [[ -n "$OSVER" ]]; then
offer_lxc_stack_upgrade_and_maybe_retry "no" || true
local _lxc_stack_rc=0
offer_lxc_stack_upgrade_and_maybe_retry "no" || _lxc_stack_rc=$?
# 4 = user chose "Cancel" -> honor it and abort before creating the container
if [[ $_lxc_stack_rc -eq 4 ]]; then
exit_script
fi
fi
fi
+4 -3
View File
@@ -376,10 +376,11 @@ error_handler() {
active_log="$BUILD_LOG"
fi
# stderr: the trap can fire inside a $(...) capture that would eat this as data
if [[ -n "$active_log" && -s "$active_log" ]]; then
echo -e "\n${TAB}--- Last 20 lines of log ---"
tail -n 20 "$active_log"
echo -e "${TAB}-----------------------------------\n"
echo -e "\n${TAB}--- Last 20 lines of log ---" >&2
tail -n 20 "$active_log" >&2
echo -e "${TAB}-----------------------------------\n" >&2
fi
# ── Node.js heap OOM detection with actionable guidance ──
+2 -2
View File
@@ -7039,11 +7039,11 @@ setup_meilisearch() {
fi
if [[ "$NEEDS_MIGRATION" == "true" ]]; then
# One-time in-place migration via --experimental-dumpless-upgrade.
# One-time in-place migration via --experimental-dumpless-upgrade (replaced with --upgrade-db)
# Meilisearch migrates the on-disk DB during this startup; subsequent
# normal (systemd) starts run without the flag.
msg_info "Migrating data in place (dumpless upgrade ${CURRENT_VERSION}${NEW_VERSION})"
/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml --experimental-dumpless-upgrade >/dev/null 2>&1 &
/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml --upgrade-db >/dev/null 2>&1 &
local MEILI_PID=$!
local MAX_WAIT=300
@@ -0,0 +1,224 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/sakowicz/actual-budget-prometheus-exporter
if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "actual-budget-prometheus-exporter" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
load_functions
# ==============================================================================
# CONFIGURATION
# ==============================================================================
VERBOSE=${var_verbose:-no}
APP="actual-budget-prometheus-exporter"
APP_TYPE="tools"
INSTALL_PATH="/opt/actual-budget-prometheus-exporter"
CONFIG_PATH="/opt/actual-budget-prometheus-exporter.env"
SERVICE_PATH="/etc/systemd/system/actual-budget-prometheus-exporter.service"
# ==============================================================================
# OS DETECTION
# ==============================================================================
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
exit 238
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling Actual-Budget-Prometheus-Exporter"
systemctl disable -q --now actual-budget-prometheus-exporter
rm -f "$SERVICE_PATH"
rm -rf "$INSTALL_PATH"
rm -f "$CONFIG_PATH"
rm -f "/usr/local/bin/update_actual-budget-prometheus-exporter"
rm -f "$HOME/.actual-budget-prometheus-exporter"
msg_ok "Actual-Budget-Prometheus-Exporter has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "actual-budget-prometheus-exporter" "sakowicz/actual-budget-prometheus-exporter"; then
msg_info "Stopping service"
systemctl stop actual-budget-prometheus-exporter
msg_ok "Stopped service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "actual-budget-prometheus-exporter" "sakowicz/actual-budget-prometheus-exporter" "tarball" "latest"
NODE_VERSION="22" setup_nodejs
msg_info "Building Actual-Budget-Prometheus-Exporter"
cd "$INSTALL_PATH"
$STD npm ci
$STD npm run build
msg_ok "Built Actual-Budget-Prometheus-Exporter"
msg_info "Starting service"
systemctl start actual-budget-prometheus-exporter
msg_ok "Started service"
msg_ok "Updated successfully!"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
read -erp "Enter URL of Actual Budget server, example: (http://127.0.0.1:5006): " ACTUAL_SERVER_URL
read -rsp "Enter Actual Budget server password: " ACTUAL_PASSWORD
printf "\n"
echo -e "${TAB}${INFO} Find the Sync ID in Actual under Settings > Advanced settings > Sync ID"
read -erp "Enter Budget Sync ID: " ACTUAL_BUDGET_ID_1
read -rsp "Enter E2E encryption password (leave empty if end-to-end encryption is disabled): " ACTUAL_E2E_PASSWORD_1
printf "\n"
read -erp "Enter metrics port (default: 3001): " PORT_INPUT
PORT="${PORT_INPUT:-3001}"
# build-essential and python3 are required to compile better-sqlite3
# (native dependency of @actual-app/api) when no prebuilt binary is available.
msg_info "Installing Dependencies"
$STD apt install -y build-essential python3
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "actual-budget-prometheus-exporter" "sakowicz/actual-budget-prometheus-exporter" "tarball" "latest"
NODE_VERSION="22" setup_nodejs
msg_info "Building Actual-Budget-Prometheus-Exporter"
cd "$INSTALL_PATH"
$STD npm ci
$STD npm run build
msg_ok "Built Actual-Budget-Prometheus-Exporter"
msg_info "Creating configuration"
cat <<EOF >"$CONFIG_PATH"
# https://github.com/sakowicz/actual-budget-prometheus-exporter
ACTUAL_SERVER_URL="${ACTUAL_SERVER_URL}"
ACTUAL_PASSWORD="${ACTUAL_PASSWORD}"
ACTUAL_BUDGET_ID_1="${ACTUAL_BUDGET_ID_1}"
ACTUAL_E2E_PASSWORD_1="${ACTUAL_E2E_PASSWORD_1}"
PORT="${PORT}"
# Optional: friendly label for the budget shown in the exported metrics
# ACTUAL_BUDGET_NAME_1=""
# Optional: monitor additional budgets by incrementing the numeric suffix
# ACTUAL_BUDGET_ID_2=""
# ACTUAL_E2E_PASSWORD_2=""
# ACTUAL_BUDGET_NAME_2=""
# Optional: set to 0 to accept a self-signed TLS certificate on the Actual server
# NODE_TLS_REJECT_UNAUTHORIZED="0"
EOF
msg_ok "Created configuration"
msg_info "Creating service"
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=Actual Budget Prometheus Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=root
WorkingDirectory=$INSTALL_PATH
EnvironmentFile=$CONFIG_PATH
ExecStart=/usr/bin/node $INSTALL_PATH/dist/app.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now actual-budget-prometheus-exporter
msg_ok "Created and started service"
# Create update script
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'UPDATEEOF' >/usr/local/bin/update_actual-budget-prometheus-exporter
#!/usr/bin/env bash
# actual-budget-prometheus-exporter Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/actual-budget-prometheus-exporter.sh)"
UPDATEEOF
chmod +x /usr/local/bin/update_actual-budget-prometheus-exporter
msg_ok "Created update script (/usr/local/bin/update_actual-budget-prometheus-exporter)"
echo ""
msg_ok "Actual-Budget-Prometheus-Exporter installed successfully"
msg_ok "Metrics: ${BL}http://${LOCAL_IP}:${PORT}/metrics${CL}"
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
}
# ==============================================================================
# MAIN
# ==============================================================================
header_info
ensure_usr_local_bin_persist
get_lxc_ip
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/dist/app.js" ]]; then
update
else
msg_error "Actual-Budget-Prometheus-Exporter is not installed. Nothing to update."
exit 233
fi
exit 0
fi
# Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/dist/app.js" ]]; then
msg_warn "Actual-Budget-Prometheus-Exporter is already installed."
echo ""
echo -n "${TAB}Uninstall Actual-Budget-Prometheus-Exporter? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update Actual-Budget-Prometheus-Exporter? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
# Fresh installation
msg_warn "Actual-Budget-Prometheus-Exporter is not installed."
echo ""
echo -e "${TAB}${INFO} This will install:"
echo -e "${TAB} - Actual Budget Prometheus Exporter (Node.js source build)"
echo -e "${TAB} - Systemd service"
echo ""
echo -n "${TAB}Install Actual-Budget-Prometheus-Exporter? (y/N): "
read -r install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
install
else
msg_warn "Installation cancelled. Exiting."
exit 0
fi
@@ -35,6 +35,32 @@ if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
exit 238
fi
# ==============================================================================
# SERVICE FILE
# ==============================================================================
function write_service() {
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=Prometheus Paperless NGX Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=root
EnvironmentFile=$CONFIG_PATH
ExecStart=$BINARY_PATH \\
--paperless_url=\${PAPERLESS_URL} \\
--paperless_auth_token_file=$AUTH_TOKEN_FILE \\
--paperless_header 'Accept: application/json; version=9' \\
--collectors=tag,correspondent,document_type,storage_path,task,log,group,user,status,statistics
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
}
# ==============================================================================
# UNINSTALL
# ==============================================================================
@@ -57,19 +83,31 @@ function uninstall() {
# UPDATE
# ==============================================================================
function update() {
local release_found=1
if check_for_gh_release "prom-paperless-exp" "hansmi/prometheus-paperless-exporter"; then
release_found=0
msg_info "Stopping service"
systemctl stop prometheus-paperless-ngx-exporter
msg_ok "Stopped service"
fetch_and_deploy_gh_release "prom-paperless-exp" "hansmi/prometheus-paperless-exporter" "binary" "latest"
msg_info "Starting service"
systemctl start prometheus-paperless-ngx-exporter
msg_ok "Started service"
msg_ok "Updated successfully!"
exit
fi
msg_info "Refreshing service configuration"
write_service
msg_ok "Refreshed service configuration"
msg_info "Starting service"
systemctl restart prometheus-paperless-ngx-exporter
msg_ok "Started service"
if [[ $release_found -eq 0 ]]; then
msg_ok "Updated successfully!"
else
msg_ok "No new release found, service configuration refreshed"
fi
exit
}
# ==============================================================================
@@ -93,24 +131,7 @@ EOF
msg_ok "Created configuration"
msg_info "Creating service"
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=Prometheus Paperless NGX Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=root
EnvironmentFile=$CONFIG_PATH
ExecStart=$BINARY_PATH \\
--paperless_url=\${PAPERLESS_URL} \\
--paperless_auth_token_file=$AUTH_TOKEN_FILE
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
write_service
systemctl enable -q --now prometheus-paperless-ngx-exporter
msg_ok "Created and started service"
@@ -0,0 +1,6 @@
__ __ __ __ __ __ __ __
____ ______/ /___ ______ _/ / / /_ __ ______/ /___ ____ / /_ ____ _________ ____ ___ ___ / /_/ /_ ___ __ _______ ___ _ ______ ____ _____/ /____ _____
/ __ `/ ___/ __/ / / / __ `/ /_____/ __ \/ / / / __ / __ `/ _ \/ __/_____/ __ \/ ___/ __ \/ __ `__ \/ _ \/ __/ __ \/ _ \/ / / / ___/_____/ _ \| |/_/ __ \/ __ \/ ___/ __/ _ \/ ___/
/ /_/ / /__/ /_/ /_/ / /_/ / /_____/ /_/ / /_/ / /_/ / /_/ / __/ /_/_____/ /_/ / / / /_/ / / / / / / __/ /_/ / / / __/ /_/ (__ )_____/ __/> </ /_/ / /_/ / / / /_/ __/ /
\__,_/\___/\__/\__,_/\__,_/_/ /_.___/\__,_/\__,_/\__, /\___/\__/ / .___/_/ \____/_/ /_/ /_/\___/\__/_/ /_/\___/\__,_/____/ \___/_/|_/ .___/\____/_/ \__/\___/_/
/____/ /_/ /_/