Compare commits

...
66 Commits
Author SHA1 Message Date
community-scripts-pr-app[bot]andgithub-actions[bot] feb2c35a2b Update CHANGELOG.md (#18707)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 14:33:55 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 651a9fb3a3 Update CHANGELOG.md (#18706)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 14:33:32 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 075828b1e9 Update CHANGELOG.md (#18705)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 14:26:28 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] df3ebb4dd1 Update CHANGELOG.md (#18704)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 13:48:25 +00:00
push-app-to-main[bot] 2c2265e44b Add marimo (ct) (#18672)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 14:47:44 +01:00
Rögl-Brunner Michel 38cccdd417 pr-script-test: run external installers, and catch failed installs on Incus
CloudPanel (DevScripts PR 2614) installs through upstream's install.sh,
which core runs only after asking; CI cannot answer, so set
var_external_installer=yes for the build and the update.

A failed install on Incus also showed as passed: with dev_mode=keep the
engine still prints "Completed Successfully", and the line that gives the
failure away names the container ci-9000 there, not 9000, so the check
for it never matched.
2026-11-13 14:45:05 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 09a1164445 Update CHANGELOG.md (#18703)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 13:26:56 +00:00
Rögl-Brunner Michel 32bd1440d2 pr-script-test: remove the temporary token probes
They found the cause: marimo-team has an IP allow list, so GitHub
refuses the token from the lab with a 403 that core read as a rate
limit. Fixed in core. The quota line stays.
2026-11-13 13:32:06 +01:00
Rögl-Brunner Michel f9693f2fd3 pr-script-test: probe what GitHub answers the token in the guest (temporary) 2026-11-13 13:25:23 +01:00
Rögl-Brunner Michel c8799b0bcb pr-script-test: log the token length each shell of the update sees (temporary) 2026-11-13 13:20:01 +01:00
Rögl-Brunner Michel 0033568ca5 pr-script-test: log which GitHub calls in the guest carry the token (temporary) 2026-11-13 13:14:04 +01:00
Rögl-Brunner Michel d887fb8e95 pr-script-test: probe whether the guest profile clears the token 2026-11-13 13:08:55 +01:00
Rögl-Brunner Michel fe4e449b2f pr-script-test: probe the token inside the guest, not on the host
On the host the job token reads another repo's release fine (200), yet
installs and updates in the guest hit the anonymous limit. Probe there,
just before the update. Also drops the /tmp file named after $$.
2026-11-13 13:02:11 +01:00
Rögl-Brunner Michel cd4b7aa63d pr-script-test: probe whether the job token can read another repo's release 2026-11-13 12:56:10 +01:00
Rögl-Brunner Michel b80d038846 pr-script-test: log the GitHub API quota, with and without the token
marimo (ProxmoxVE PR 18672) hit the rate limit in its update although the
job token is passed as GITHUB_TOKEN there. Log what both the token and the
lab address have left at the start and when an update hits the limit.
2026-11-13 12:49:35 +01:00
Rögl-Brunner Michel 9368f43aa9 pr-script-test: the label builds only for write access or a bot
Triage can set labels too; /test needs write, so the label does as well.
The merge workflow sets "Ready For Testing" through an app, which passes.
2026-11-13 12:44:20 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] d03f124259 Update CHANGELOG.md (#18701)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 11:41:57 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] cd685377dc Update CHANGELOG.md (#18700)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 11:41:28 +00:00
push-app-to-main[bot] 58310699e7 Add goatcounter (ct) (#18662)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 12:41:15 +01:00
push-app-to-main[bot] f71c4c2ee1 Add unsloth (ct) (#18697)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 12:40:55 +01:00
Rögl-Brunner Michel c8661ac328 pr-script-test: build the app when an issue gets "Ready For Testing"
The label on a script issue now starts the same build as `/test <app>`
in that issue: the app from the default branch. The app is the issue
form's "Script path", else "Name of the Script" as a slug (the rule of
pr-merged-ready-for-testing.yml). tools/ issues are skipped. Any other
label gets a group of its own, like a comment that is not a /test.
2026-11-13 12:40:49 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 373b564c29 Update CHANGELOG.md (#18698)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 11:30:41 +00:00
push-app-to-main[bot] e5b615e27d Add colanode (ct) (#18685)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 12:30:02 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 6bd95a405b Update CHANGELOG.md (#18696)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 11:29:16 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 462a72a40f Update CHANGELOG.md (#18695)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 11:28:45 +00:00
push-app-to-main[bot] 89032c7630 Add simplelogin (ct) (#18680)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 12:28:35 +01:00
push-app-to-main[bot] bd8ef8f543 Add nightingale (ct) (#18674)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 12:28:15 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 8e9a731afe Update CHANGELOG.md (#18694)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:58:32 +00:00
push-app-to-main[bot] e406c773ba Add temporal (ct) (#18670)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:57:58 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] ce75d40091 Update CHANGELOG.md (#18693)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:51:53 +00:00
push-app-to-main[bot] 3a823384e9 Add trailbase (ct) (#18669)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:51:23 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 36c37028af Update CHANGELOG.md (#18692)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:47:33 +00:00
push-app-to-main[bot] b261ecf63a Add weaviate (ct) (#18671)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:46:58 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 08a66f4b26 Update CHANGELOG.md (#18691)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:41:48 +00:00
push-app-to-main[bot] 4c813f3ae7 Add spacebot (ct) (#18668)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:41:19 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 90ee3cef62 Update CHANGELOG.md (#18690)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:28:35 +00:00
push-app-to-main[bot] 6d95e87a75 Add new-api (ct) (#18667)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:28:06 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 6520393d42 Update CHANGELOG.md (#18689)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:27:51 +00:00
push-app-to-main[bot] 269bd77d74 Add martin (ct) (#18666)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:27:25 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] d3dadaf04c Update CHANGELOG.md (#18688)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:27:21 +00:00
push-app-to-main[bot] db323df14f Add langflow (ct) (#18665)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:26:49 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] d0f7277ad9 Update CHANGELOG.md (#18687)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:24:18 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 5782a6c273 Update CHANGELOG.md (#18686)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:23:52 +00:00
push-app-to-main[bot] f7c630962a Add inngest (ct) (#18664)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:23:50 +01:00
push-app-to-main[bot] 3e12b796b7 Add hatchet (ct) (#18663)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:23:20 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 4d00f20118 Update CHANGELOG.md (#18684)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 09:22:59 +00:00
push-app-to-main[bot] 96c8094109 Add engram (ct) (#18661)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 10:22:30 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 97eb111801 Update CHANGELOG.md (#18683)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:32:21 +00:00
push-app-to-main[bot] d13b503426 Add euro-office (ct) (#18660)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:31:52 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 8f8a1393e0 Update CHANGELOG.md (#18682)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:22:06 +00:00
push-app-to-main[bot] dd75297935 Add cypht (ct) (#18659)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:21:35 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] a57e899058 Update CHANGELOG.md (#18681)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:19:41 +00:00
push-app-to-main[bot] d7bda2e9b8 Add airconnect (ct) (#18653)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:19:12 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 0ff308a706 Update CHANGELOG.md (#18679)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:16:02 +00:00
push-app-to-main[bot] fc4f8e2ac5 Add bulwark (ct) (#18656)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:15:32 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] b107350c78 Update CHANGELOG.md (#18678)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:12:07 +00:00
push-app-to-main[bot] dd5be08eb4 Add convex (ct) (#18658)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:11:37 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] d64c231777 Update CHANGELOG.md (#18677)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:07:59 +00:00
push-app-to-main[bot] e3bfc6e0c3 Add chroma (ct) (#18657)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 09:07:26 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 38be7c108b Update CHANGELOG.md (#18676)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 08:00:01 +00:00
push-app-to-main[bot] 61c8c48915 Add bugsink (ct) (#18655)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 08:59:30 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 0b345a0cda Update CHANGELOG.md (#18675)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 07:56:22 +00:00
push-app-to-main[bot] 2fbbc9c185 Add 9router (ct) (#18654)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-11-13 08:55:56 +01:00
Rögl-Brunner Michel c9ba40bfdb pr-script-test: fail the URL check on bad answers, not on non-200
Warpgate answers 401 on its root, a login wall, and the check failed it
(DevScripts issue 2537). Any answer now counts as the app being up,
except no answer, 404/410, a 5xx or a redirect loop. Same rule for VMs.
2026-11-13 08:32:29 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] b839ff1862 Update CHANGELOG.md (#18652)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 07:00:52 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] cb8a6fc098 Update CHANGELOG.md (#18651)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-11-13 07:00:28 +00:00
52 changed files with 3855 additions and 14 deletions

No files matched your search

+40 -4
View File
@@ -34,6 +34,10 @@ name: PR script test
on:
issue_comment:
types: [created]
# The "Ready For Testing" label on a script issue builds that app from the
# default branch, as `/test <app>` in the issue would.
issues:
types: [labeled]
# Every PR, see above. pull_request_target runs this file from main, never
# the PR's copy of it, and does not wait for "approve and run" on forks.
pull_request_target:
@@ -62,11 +66,13 @@ permissions: {}
# One queue per PR. A newer push replaces a run that is still waiting (its
# gate would skip anyway: the head moved), but never kills one that is
# building: a cancelled job leaves its guest behind until the sweeper. Any
# comment starts this workflow; one that is not a /test gets a group of its
# own, so it cannot push a waiting test out of the queue.
# comment and any label starts this workflow; one that is not a /test (or
# not the "Ready For Testing" label) gets a group of its own, so it cannot
# push a waiting test out of the queue.
concurrency:
group: >-
pr-script-test-${{ github.event_name == 'issue_comment' && !startsWith(github.event.comment.body, '/test')
pr-script-test-${{ ((github.event_name == 'issue_comment' && !startsWith(github.event.comment.body, '/test'))
|| (github.event_name == 'issues' && github.event.label.name != 'Ready For Testing'))
&& format('noop-{0}', github.run_id)
|| github.event.pull_request.number || github.event.issue.number || inputs.pr }}
cancel-in-progress: false
@@ -76,6 +82,7 @@ jobs:
if: >-
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/test')) ||
(github.event_name == 'issues' && github.event.label.name == 'Ready For Testing' && !github.event.issue.pull_request) ||
(github.event_name == 'pull_request_target' && !github.event.pull_request.draft)
runs-on: ubuntu-latest
permissions:
@@ -120,6 +127,35 @@ jobs:
} else if (context.eventName === 'workflow_dispatch') {
prNumber = Number(context.payload.inputs.pr);
requested = `${context.payload.inputs.sha || ''} ${context.payload.inputs.scripts || ''}`;
} else if (context.eventName === 'issues') {
// "Ready For Testing" on a script issue: the app the issue form
// names, as `/test <app>` would. Only people who can triage set a
// label, and the default branch is what gets built.
const issue = context.payload.issue;
prNumber = issue.number;
// Triage can label too; building needs write, as for /test. The
// merge workflow labels through an app, i.e. a bot.
const sender = context.payload.sender;
if (sender.type !== 'Bot') {
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username: sender.login });
if (!['admin', 'maintain', 'write'].includes(perm.permission)) {
core.notice(`${sender.login} has ${perm.permission} access; a test needs write`);
return;
}
}
const body = (issue.body || '').replace(/\r/g, '');
const field = name => {
const m = body.match(new RegExp(`^###[ \t]*${name}[ \t]*\n+([^\n#][^\n]*)`, 'm'));
return m && m[1].trim() !== '_No response_' ? m[1].trim() : '';
};
const type = field('Script Type');
if (type && !/^(CT|VM)\b/.test(type)) { core.notice(`${type}: only ct/ and vm/ scripts are built`); return; }
const path = field('Script path').replace(/^\/+/, '');
// Same slug rule as pr-merged-ready-for-testing.yml: the "Name of
// the Script" field, else the title, lowercased, spaces -> dashes.
const slug = (field('Name of the Script') || issue.title).trim().toLowerCase().replace(/\s+/g, '-');
requested = /^(ct|vm)\/[A-Za-z0-9._-]+\.sh$/.test(path) ? path : slug;
core.info(`Ready For Testing: building ${requested}`);
} else {
prNumber = context.payload.issue.number;
const body = context.payload.comment.body.trim();
@@ -140,7 +176,7 @@ jobs:
// `/test <app>` in an issue (not a PR) builds that app from the
// default branch as it is right now, e.g. to see whether a reported
// error reproduces. No PR, so no check run, no review, no approval.
const isIssue = context.eventName === 'issue_comment' && !context.payload.issue.pull_request;
const isIssue = ['issue_comment', 'issues'].includes(context.eventName) && !context.payload.issue.pull_request;
let pr = null, head, headSha;
if (isIssue) {
const { data: info } = await github.rest.repos.get({ owner, repo });
+34 -7
View File
@@ -373,6 +373,20 @@ setup_error() {
exit 1
}
# Any answer means the app is up, unless it says it isn't: nothing at all,
# 404/410 (the printed URL leads nowhere), 5xx (server error, proxy without
# backend), or a 3xx left after 5 redirects (a loop). 401/403 are a login
# wall (warpgate answers 401), 400 a quirk of the app: both pass.
url_ok() { [[ "$1" =~ ^[1-4][0-9][0-9]$ && ! "$1" =~ ^(3[0-9][0-9]|404|410)$ ]]; }
url_why() {
case "$1" in
404 | 410) echo "the printed URL leads nowhere" ;;
5??) echo "server error" ;;
3??) echo "still redirecting after 5 hops" ;;
*) echo "the app never answered" ;;
esac
}
# --- Reserve a container ID ---------------------------------------------------
# A lock file per ID, not just "first free one", because the engine only creates
# the container minutes later and two jobs would otherwise pick the same ID.
@@ -454,8 +468,19 @@ fi
touch "$RAW_LOG.start"
[[ -n "$OS" ]] && build_env+=(var_os="$OS")
[[ -n "$VAR_ARM64" ]] && build_env+=(var_arm64=yes)
# A script that hands over to upstream's own installer (run_external_installer)
# asks first; nobody can answer in CI, and testing the script means running it.
build_env+=(var_external_installer=yes)
# Both engines turn var_github_token into GITHUB_TOKEN inside the container.
[[ -n "${GH_API_TOKEN:-}" ]] && build_env+=(var_github_token="$GH_API_TOKEN")
# How much API quota this build starts with, with the token and without (the
# lab's one address). /rate_limit itself costs nothing. A "rate limit" in the
# build is then easy to place.
gh_quota() {
curl -s --max-time 10 ${1:+-H "Authorization: Bearer $1"} https://api.github.com/rate_limit 2>/dev/null |
jq -r '.rate | "\(.remaining) of \(.limit) left, resets in \(((.reset - now) / 60) | floor) min"' 2>/dev/null || echo "unknown"
}
echo "GitHub API quota: token $(gh_quota "${GH_API_TOKEN:-}") · no token $(gh_quota "")"
# --- Answers for the script's questions ------------------------------------------
# Nobody types into CI, so anything the install asks has to be answered up front.
@@ -574,7 +599,8 @@ if ((exit_code != 0)); then
fi
# With dev_mode=keep (needed to read the install log) the engine carries on
# after a failed install and still prints "Completed Successfully", exit 0.
install_exit=$(strip_ansi <"$RAW_LOG" | grep -oE 'Installation failed in container [0-9]+ \(exit code: [0-9]+\)' |
# The container is a number on Proxmox (9000) and a name on Incus (ci-9000).
install_exit=$(strip_ansi <"$RAW_LOG" | grep -oE 'Installation failed in container [A-Za-z0-9._-]+ \(exit code: [0-9]+\)' |
grep -oE '[0-9]+\)$' | tr -d ')' | tail -n 1)
if [[ -n "$install_exit" ]]; then
last=$(failure_line)
@@ -615,8 +641,8 @@ take_screenshot() {
}
# Is the app up? No failed services, and the URL the script tells the user to
# open, e.g. http://${IP}:1337/admin, answers 200 (after redirects, so a jump
# to /login is fine). A script that prints no URL has no web UI to check.
# open, e.g. http://${IP}:1337/admin, answers without an error (see url_ok;
# redirects are followed, so a jump to /login is fine). A script that prints no URL has no web UI to check.
# Run after the install and again after the update. Sets health_problem.
app_url() { # the URL the script at $1 tells the user to open
local pattern
@@ -639,13 +665,13 @@ check_health() {
local waited
for ((waited = 0; waited < URL_WAIT; waited += 5)); do
http_code=$(curl -sk -L --max-redirs 5 -o /dev/null -w '%{http_code}' --max-time 10 "$url" || true)
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] && break
url_ok "$http_code" && break
sleep 5
done
# Also when the check fails: an error page explains more than a status code.
[[ "$http_code" =~ ^[1-5][0-9][0-9]$ ]] && take_screenshot "$1"
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] ||
{ health_problem="${url} answered ${http_code/#000/nothing} instead of 200 within ${URL_WAIT}s"; return 1; }
url_ok "$http_code" ||
{ health_problem="${url} answered ${http_code/#000/nothing} within ${URL_WAIT}s ($(url_why "$http_code"))"; return 1; }
}
check_health screenshot.png || fail "$health_problem"
@@ -721,7 +747,7 @@ run_update() {
# timeout runs a program, not a shell function, so spell out the exec here.
if [[ "$PLATFORM" == "incus" ]]; then guest_cmd=(incus exec "$ctid" --); else guest_cmd=(pct exec "$ctid" --); fi
timeout --kill-after=1m "$UPDATE_TIMEOUT" "${guest_cmd[@]}" env PHS_SILENT=1 mode=default MODE=default \
TERM=dumb DIAGNOSTICS=no var_ignore_breaking_changes=yes ${GH_API_TOKEN:+GITHUB_TOKEN="$GH_API_TOKEN"} update </dev/null \
TERM=dumb DIAGNOSTICS=no var_ignore_breaking_changes=yes var_external_installer=yes ${GH_API_TOKEN:+GITHUB_TOKEN="$GH_API_TOKEN"} update </dev/null \
> >(tee "$raw" | live_filter) 2>&1 &
update_pid=$!
wait "$update_pid"
@@ -747,6 +773,7 @@ fi
update_error=$(strip_ansi <"$UPDATE_RAW" | grep -E '✖|\[ERROR\]' | tail -n 1 | sed -E 's/^\s*(✖️?|\s)*//' | cut -c1-180)
if [[ -n "$update_error" ]]; then
if [[ "${update_error,,}" == *"rate limit"* ]]; then
echo "GitHub API quota now: token $(gh_quota "${GH_API_TOKEN:-}") · no token $(gh_quota "")"
update_status="error"
update_step="could not be tested: ${update_error}"
status="pass"
+3 -3
View File
@@ -121,7 +121,7 @@ vm_build_and_check() {
for ((waited = 0; waited < VM_URL_WAIT; waited += 10)); do
vm_running || fail "VM ${ctid} stopped by itself while its web UI was awaited"
http_code=$(curl -sk -L --max-redirs 5 -o /dev/null -w '%{http_code}' --max-time 10 "$url" || true)
[[ "$http_code" =~ ^2[0-9][0-9]$ ]] && break
url_ok "$http_code" && break
sleep 10
done
[[ "$http_code" =~ ^[1-5][0-9][0-9]$ ]] && take_screenshot screenshot.png
@@ -130,8 +130,8 @@ vm_build_and_check() {
sleep 20
fi
[[ -s "$OUT_DIR/screenshot.png" ]] || vm_console_shot
if [[ -n "$url" && ! "$http_code" =~ ^2[0-9][0-9]$ ]]; then
fail "${url} answered ${http_code/#000/nothing} instead of 200 within ${VM_URL_WAIT}s"
if [[ -n "$url" ]] && ! url_ok "$http_code"; then
fail "${url} answered ${http_code/#000/nothing} within ${VM_URL_WAIT}s"
fi
vm_running || fail "VM ${ctid} stopped by itself"
+40
View File
@@ -581,6 +581,46 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-11-13
### 🆕 New Scripts
- marimo ([#18672](https://github.com/community-scripts/ProxmoxVE/pull/18672))
- GoatCounter ([#18662](https://github.com/community-scripts/ProxmoxVE/pull/18662))
- Unsloth ([#18697](https://github.com/community-scripts/ProxmoxVE/pull/18697))
- colanode ([#18685](https://github.com/community-scripts/ProxmoxVE/pull/18685))
- SimpleLogin ([#18680](https://github.com/community-scripts/ProxmoxVE/pull/18680))
- Nightingale ([#18674](https://github.com/community-scripts/ProxmoxVE/pull/18674))
- Temporal ([#18670](https://github.com/community-scripts/ProxmoxVE/pull/18670))
- TrailBase ([#18669](https://github.com/community-scripts/ProxmoxVE/pull/18669))
- Weaviate ([#18671](https://github.com/community-scripts/ProxmoxVE/pull/18671))
- Spacebot ([#18668](https://github.com/community-scripts/ProxmoxVE/pull/18668))
- New-API ([#18667](https://github.com/community-scripts/ProxmoxVE/pull/18667))
- Martin ([#18666](https://github.com/community-scripts/ProxmoxVE/pull/18666))
- Langflow ([#18665](https://github.com/community-scripts/ProxmoxVE/pull/18665))
- Inngest ([#18664](https://github.com/community-scripts/ProxmoxVE/pull/18664))
- Hatchet ([#18663](https://github.com/community-scripts/ProxmoxVE/pull/18663))
- Engram ([#18661](https://github.com/community-scripts/ProxmoxVE/pull/18661))
- Euro-Office ([#18660](https://github.com/community-scripts/ProxmoxVE/pull/18660))
- Cypht ([#18659](https://github.com/community-scripts/ProxmoxVE/pull/18659))
- AirConnect ([#18653](https://github.com/community-scripts/ProxmoxVE/pull/18653))
- Bulwark ([#18656](https://github.com/community-scripts/ProxmoxVE/pull/18656))
- Convex ([#18658](https://github.com/community-scripts/ProxmoxVE/pull/18658))
- Chroma ([#18657](https://github.com/community-scripts/ProxmoxVE/pull/18657))
- Bugsink ([#18655](https://github.com/community-scripts/ProxmoxVE/pull/18655))
- 9Router ([#18654](https://github.com/community-scripts/ProxmoxVE/pull/18654))
### 💾 Core
- fix: run Meilisearch --upgrade-db on patch updates too [@CrazyWolf13](https://github.com/CrazyWolf13) ([core#259](https://github.com/community-scripts/core/pull/259))
- db: only chmod a database credentials file that is a regular file [@MickLesk](https://github.com/MickLesk) ([core#253](https://github.com/community-scripts/core/pull/253))
- fix: take a Debian cloud image from the newest build that has it [@MickLesk](https://github.com/MickLesk) ([core#261](https://github.com/community-scripts/core/pull/261))
- telemetry: always on for DevScripts, with a one-time notice [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([core#245](https://github.com/community-scripts/core/pull/245))
- Shield pct start and the template check from a closed console [@MickLesk](https://github.com/MickLesk) ([core#239](https://github.com/community-scripts/core/pull/239))
- core: say why a container stopped by itself during its setup [@MickLesk](https://github.com/MickLesk) ([core#234](https://github.com/community-scripts/core/pull/234))
- Download a corrupt local template again instead of keeping it [@MickLesk](https://github.com/MickLesk) ([core#235](https://github.com/community-scripts/core/pull/235))
- fetch the install script before the container is created [@MickLesk](https://github.com/MickLesk) ([core#236](https://github.com/community-scripts/core/pull/236))
## 2026-11-12
### 🆕 New Scripts
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/decolua/9router
APP="9Router"
var_tags="${var_tags:-ai;llm;gateway}"
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 /usr/lib/node_modules/9router ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
CURRENT=$(jq -r '.version' /usr/lib/node_modules/9router/package.json)
RELEASE=$(npm view 9router version)
if [[ "$CURRENT" == "$RELEASE" ]]; then
msg_ok "No update available: 9Router (${CURRENT})"
exit
fi
NODE_VERSION="22" setup_nodejs
msg_info "Stopping 9Router"
systemctl stop 9router
msg_ok "Stopped 9Router"
msg_info "Updating 9Router to ${RELEASE}"
$STD npm install -g --ignore-scripts "9router@${RELEASE}"
msg_ok "Updated 9Router to ${RELEASE}"
msg_info "Starting 9Router"
systemctl start 9router
msg_ok "Started 9Router"
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}:20128/dashboard${CL}"
echo -e "${INFO}${YW}Dashboard password: INITIAL_PASSWORD in /opt/9router_data/.env (inside the container)${CL}"
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Chris Moriarty (cwmoriarty)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/philippe44/AirConnect
APP="AirConnect"
var_tags="${var_tags:-airplay;audio;streaming}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/airconnect ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "airconnect" "philippe44/AirConnect"; then
msg_info "Stopping AirConnect"
systemctl stop airupnp aircast
msg_ok "Stopped AirConnect"
CLEAN_INSTALL=1 CLEAN_INSTALL_KEEP="airupnp.xml aircast.xml" fetch_and_deploy_gh_release "airconnect" "philippe44/AirConnect" "prebuild" "latest" "/opt/airconnect" "AirConnect-*.zip"
msg_info "Configuring AirConnect"
chmod +x /opt/airconnect/airupnp-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/aircast-linux-$(arch_resolve x86_64 aarch64)
ln -sf /opt/airconnect/airupnp-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/airupnp
ln -sf /opt/airconnect/aircast-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/aircast
find /opt/airconnect -maxdepth 1 -type f ! -name "air*linux-$(arch_resolve x86_64 aarch64)*" ! -name "airupnp" ! -name "aircast" ! -name "*.xml" -delete
msg_ok "Configured AirConnect"
msg_info "Starting AirConnect"
systemctl start airupnp aircast
msg_ok "Started AirConnect"
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}AirConnect is running and bridging AirPlay to discovered players:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}airupnp${CL} ${YW}(UPnP / Sonos bridge)${CL}"
echo -e "${TAB}${GATEWAY}${BGN}aircast${CL} ${YW}(Chromecast bridge)${CL}"
echo -e "${INFO}${YW}Ensure your container is on the same LAN subnet as your devices.${CL}"
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/bugsink/bugsink
APP="Bugsink"
var_tags="${var_tags:-monitoring;error-tracking;sentry}"
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}"
export var_admin_email="${var_admin_email:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/bugsink ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "bugsink" "bugsink/bugsink"; then
msg_info "Stopping Bugsink"
systemctl stop bugsink bugsink-snappea
msg_ok "Stopped Bugsink"
PYTHON_VERSION="3.12" setup_uv
msg_info "Updating Bugsink"
$STD uv pip install --upgrade --python /opt/bugsink/.venv/bin/python "bugsink==${CHECK_UPDATE_RELEASE}"
cd /opt/bugsink_data
$STD /opt/bugsink/.venv/bin/bugsink-manage migrate
$STD /opt/bugsink/.venv/bin/bugsink-manage migrate snappea --database=snappea
cat <<EOF >~/.bugsink
${CHECK_UPDATE_RELEASE}
EOF
msg_ok "Updated Bugsink"
msg_info "Starting Bugsink"
systemctl start bugsink bugsink-snappea
msg_ok "Started Bugsink"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}"
echo -e "${INFO}${YW}Admin login: /opt/bugsink_data/.env (inside the container)${CL}"
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/bulwarkmail/webmail
APP="Bulwark"
var_tags="${var_tags:-mail;webmail;jmap}"
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}"
export var_jmap_url="${var_jmap_url:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/bulwark ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "bulwark" "bulwarkmail/webmail"; then
msg_info "Stopping Bulwark"
systemctl stop bulwark
msg_ok "Stopped Bulwark"
NODE_VERSION="24" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bulwark" "bulwarkmail/webmail" "prebuild" "latest" "/opt/bulwark" "bulwark-standalone-*-linux-$(arch_resolve).tar.gz"
msg_info "Starting Bulwark"
systemctl start bulwark
msg_ok "Started Bulwark"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW}Setup wizard token: journalctl -u bulwark (inside the container)${CL}"
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/chroma-core/chroma
APP="Chroma"
var_tags="${var_tags:-database;vector;ai}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/chroma ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
CURRENT=$(cat ~/.chroma)
RELEASE=$(curl -fsSL https://pypi.org/pypi/chromadb/json | jq -r '.info.version')
if [[ "$CURRENT" == "$RELEASE" ]]; then
msg_ok "No update available: Chroma (${CURRENT})"
exit
fi
msg_info "Stopping Chroma"
systemctl stop chroma
msg_ok "Stopped Chroma"
PYTHON_VERSION="3.12" setup_uv
msg_info "Updating Chroma to ${RELEASE}"
$STD uv pip install --upgrade --python /opt/chroma/.venv/bin/python "chromadb==${RELEASE}"
cat <<EOF >~/.chroma
${RELEASE}
EOF
msg_ok "Updated Chroma to ${RELEASE}"
msg_info "Starting Chroma"
systemctl start chroma
msg_ok "Started Chroma"
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}:8000/docs${CL}"
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://colanode.com/
APP="Colanode"
var_tags="${var_tags:-collaboration;notes;chat}"
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:-no}" # unset = ask the user; set yes/no only when verified
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/colanode ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "colanode" "colanode/colanode"; then
msg_info "Stopping Services"
systemctl stop colanode-server
msg_ok "Stopped Services"
create_backup /opt/colanode/.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "colanode" "colanode/colanode" "tarball"
msg_info "Rebuilding Application"
cd /opt/colanode
export NODE_OPTIONS="--max-old-space-size=4096"
$STD npm install
$STD npm run build -w @colanode/core
$STD npm run build -w @colanode/crdt
$STD npm run build -w @colanode/server
$STD npm run build -w @colanode/client
$STD npm run build -w @colanode/ui
$STD npm run build -w @colanode/web
cp -r /opt/colanode/apps/web/dist/. /var/www/colanode/
$STD npm prune --production
unset NODE_OPTIONS
msg_ok "Rebuilt Application"
restore_backup
msg_info "Starting Services"
systemctl start colanode-server
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 URLs:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}:4000${CL} (Web UI)"
echo -e "${INFO}${YW} Before using: import the self-signed cert into your browser:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}:4000/colanode.crt${CL}"
echo -e "${INFO}${YW} Server URL to use inside the app:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}:4000/config${CL}"
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/get-convex/convex-backend
APP="Convex"
var_tags="${var_tags:-backend;database;realtime}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/convex ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "convex" "get-convex/convex-backend"; then
msg_info "Stopping Convex"
systemctl stop convex
msg_ok "Stopped Convex"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "convex" "get-convex/convex-backend" "prebuild" "latest" "/opt/convex" "convex-local-backend-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "convex-dashboard" "get-convex/convex-backend" "prebuild" "$(cat ~/.convex)" "/opt/convex-dashboard" "dashboard.zip"
msg_info "Starting Convex"
systemctl start convex
msg_ok "Started Convex"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access the dashboard using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:6791${CL}"
echo -e "${INFO}${YW}Deployment URL: http://${IP}:3210, admin key in /opt/convex_data/.env${CL}"
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/cypht-org/cypht
APP="Cypht"
var_tags="${var_tags:-email;webmail}"
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}"
export var_admin_user="${var_admin_user:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/cypht ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "cypht" "cypht-org/cypht"; then
msg_info "Stopping Cypht"
systemctl stop nginx php8.4-fpm
msg_ok "Stopped Cypht"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cypht" "cypht-org/cypht" "prebuild" "latest" "/opt/cypht" "cypht.tar.gz"
msg_info "Updating Cypht"
ln -sf /opt/cypht_data/.env /opt/cypht/.env
cd /opt/cypht
$STD php scripts/setup_database.php
$STD php scripts/config_gen.php
chown -R www-data:www-data /opt/cypht_data/users /opt/cypht_data/attachments
msg_ok "Updated Cypht"
msg_info "Starting Cypht"
systemctl start php8.4-fpm nginx
msg_ok "Started Cypht"
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}"
echo -e "${INFO}${YW}Login: /opt/cypht_data/.env (inside the container)${CL}"
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Gentleman-Programming/engram
APP="Engram"
var_tags="${var_tags:-ai;mcp;memory}"
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}"
export var_cloud_token="${var_cloud_token:-}"
export var_admin_token="${var_admin_token:-}"
export var_allowed_projects="${var_allowed_projects:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/engram/engram ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "engram" "Gentleman-Programming/engram"; then
msg_info "Stopping Engram"
systemctl stop engram
msg_ok "Stopped Engram"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "engram" "Gentleman-Programming/engram" "prebuild" "latest" "/opt/engram" "engram_*_linux_$(arch_resolve).tar.gz"
msg_info "Starting Engram"
systemctl start engram
msg_ok "Started Engram"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}/dashboard/${CL}"
echo -e "${INFO}${YW}Sync and admin tokens: /opt/engram_data/.env (inside the container)${CL}"
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Euro-Office/DocumentServer
APP="Euro-Office"
var_tags="${var_tags:-office;documents;collaboration}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
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/euro-office/documentserver ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "euro-office" "Euro-Office/DocumentServer"; then
msg_info "Stopping Euro-Office"
$STD documentserver-prepare4shutdown.sh
systemctl stop ds-docservice ds-converter ds-metrics ds-example
msg_ok "Stopped Euro-Office"
fetch_and_deploy_gh_release "euro-office" "Euro-Office/DocumentServer" "binary" "latest" "" "euro-office-documentserver_*_$(arch_resolve).deb"
msg_info "Starting Euro-Office"
systemctl start ds-metrics ds-converter ds-docservice
if systemctl is-enabled -q ds-example; then
systemctl start ds-example
fi
systemctl reload nginx
msg_ok "Started Euro-Office"
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}"
echo -e "${INFO}${YW}JWT secret: documentserver-jwt-status.sh (inside the container)${CL}"
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/arp242/goatcounter
APP="GoatCounter"
var_tags="${var_tags:-analytics;privacy}"
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}"
export var_admin_email="${var_admin_email:-}"
export var_admin_pass="${var_admin_pass:-}"
export var_goatcounter_domain="${var_goatcounter_domain:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/goatcounter/goatcounter ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "goatcounter" "arp242/goatcounter"; then
msg_info "Stopping GoatCounter"
systemctl stop goatcounter
msg_ok "Stopped GoatCounter"
fetch_and_deploy_gh_release "goatcounter" "arp242/goatcounter" "singlefile" "latest" "/opt/goatcounter" "goatcounter-v*-linux-$(arch_resolve).gz"
mv /opt/goatcounter/goatcounter /opt/goatcounter/goatcounter.gz
gunzip -f /opt/goatcounter/goatcounter.gz
msg_info "Starting GoatCounter"
systemctl start goatcounter
msg_ok "Started GoatCounter"
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}"
echo -e "${INFO}${YW}Admin login: /opt/goatcounter_data/.env (inside the container)${CL}"
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/hatchet-dev/hatchet
APP="Hatchet"
var_tags="${var_tags:-workflow;queue;automation}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
var_unprivileged="${var_unprivileged:-1}"
export var_admin_email="${var_admin_email:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/hatchet ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "hatchet" "hatchet-dev/hatchet"; then
msg_info "Stopping Hatchet"
systemctl stop hatchet
msg_ok "Stopped Hatchet"
setup_go
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hatchet" "hatchet-dev/hatchet" "tarball"
NODE_VERSION="24" NODE_MODULE="$(jq -r '.packageManager' /opt/hatchet/frontend/app/package.json)" setup_nodejs
msg_info "Building Hatchet"
cd /opt/hatchet/frontend/snippets
$STD python3 generate.py
cd /opt/hatchet/frontend/app
$STD pnpm install --frozen-lockfile
$STD pnpm run build
cd /opt/hatchet
for target in lite admin migrate; do
CGO_ENABLED=0 $STD go build -ldflags="-w -s -X main.Version=v$(cat ~/.hatchet)" -o "bin/hatchet-${target}" "./cmd/hatchet-${target}"
done
rm -rf /opt/hatchet/frontend/app/node_modules ~/.local/share/pnpm/store
$STD go clean -cache -modcache
msg_ok "Built Hatchet"
msg_info "Starting Hatchet"
systemctl start hatchet
msg_ok "Started Hatchet"
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}:8888${CL}"
echo -e "${INFO}${YW}Admin login: /opt/hatchet_data/.env (inside the container)${CL}"
+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/inngest/inngest
APP="Inngest"
var_tags="${var_tags:-automation;queue;workflow}"
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/inngest ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "inngest" "inngest/inngest"; then
msg_info "Stopping Inngest"
systemctl stop inngest
msg_ok "Stopped Inngest"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "inngest" "inngest/inngest" "prebuild" "latest" "/opt/inngest" "inngest_*_linux_$(arch_resolve).tar.gz"
msg_info "Starting Inngest"
systemctl start inngest
msg_ok "Started Inngest"
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}:8288${CL}"
echo -e "${INFO}${YW}Event and signing keys: /opt/inngest_data/.env (inside the container)${CL}"
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/langflow-ai/langflow
APP="Langflow"
var_tags="${var_tags:-ai;llm;agents}"
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}" # unset = ask the user; set yes/no only when verified
var_unprivileged="${var_unprivileged:-1}"
export var_admin_user="${var_admin_user:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/langflow ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "langflow" "langflow-ai/langflow"; then
msg_info "Stopping Langflow"
systemctl stop langflow
msg_ok "Stopped Langflow"
PYTHON_VERSION="3.14" USE_UVX="YES" setup_uv
msg_info "Updating Langflow"
$STD uv venv --clear --python 3.14 /opt/langflow/.venv
$STD uv pip install --python /opt/langflow/.venv/bin/python "langflow==${CHECK_UPDATE_RELEASE#v}"
cat <<EOF >~/.langflow
${CHECK_UPDATE_RELEASE#v}
EOF
msg_ok "Updated Langflow"
msg_info "Starting Langflow"
systemctl start langflow
msg_ok "Started Langflow"
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}:7860${CL}"
echo -e "${INFO}${YW}Login: LANGFLOW_SUPERUSER and LANGFLOW_SUPERUSER_PASSWORD in /opt/langflow_data/.env (inside the container)${CL}"
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/marimo-team/marimo
APP="marimo"
var_tags="${var_tags:-notebook;python;data}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_token_password="${var_token_password:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/marimo ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "marimo" "marimo-team/marimo"; then
msg_info "Stopping marimo"
systemctl stop marimo
msg_ok "Stopped marimo"
PYTHON_VERSION="3.13" setup_uv
msg_info "Updating marimo"
$STD uv pip install --upgrade --python /opt/marimo/.venv/bin/python "marimo[recommended]==${CHECK_UPDATE_RELEASE}" pandas
cat <<EOF >~/.marimo
${CHECK_UPDATE_RELEASE}
EOF
msg_ok "Updated marimo"
msg_info "Starting marimo"
systemctl start marimo
msg_ok "Started marimo"
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}:2718${CL}"
echo -e "${INFO}${YW}Password: MARIMO_TOKEN_PASSWORD in /opt/marimo_data/.env (inside the container)${CL}"
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/maplibre/martin
APP="Martin"
var_tags="${var_tags:-maps;gis;tiles}"
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 [[ ! -x /opt/martin/martin ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "martin" "maplibre/martin"; then
msg_info "Stopping Martin"
systemctl stop martin
msg_ok "Stopped Martin"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "martin" "maplibre/martin" "prebuild" "latest" "/opt/martin" "martin-$(arch_resolve "x86_64" "aarch64")-unknown-linux-musl.tar.gz"
msg_info "Starting Martin"
systemctl start martin
msg_ok "Started Martin"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/QuantumNous/new-api
APP="New-API"
var_tags="${var_tags:-ai;llm;gateway}"
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}"
export var_admin_user="${var_admin_user:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/new-api/new-api ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "new-api" "QuantumNous/new-api"; then
msg_info "Stopping New API"
systemctl stop new-api
msg_ok "Stopped New API"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "new-api" "QuantumNous/new-api" "singlefile" "latest" "/opt/new-api" "$(arch_resolve "new-api-v" "new-api-arm64-v")*[0-9]"
msg_info "Starting New API"
systemctl start new-api
msg_ok "Started New API"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
echo -e "${INFO}${YW}Admin login: /opt/new-api_data/.env (inside the container)${CL}"
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/ccfos/nightingale
APP="Nightingale"
var_tags="${var_tags:-monitoring;alerting}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/nightingale ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "nightingale" "ccfos/nightingale"; then
msg_info "Stopping Nightingale"
systemctl stop nightingale
msg_ok "Stopped Nightingale"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nightingale" "ccfos/nightingale" "prebuild" "latest" "/opt/nightingale" "n9e-v*-linux-$(arch_resolve).tar.gz"
msg_info "Starting Nightingale"
systemctl start nightingale
msg_ok "Started Nightingale"
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}:17000${CL}"
+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/simple-login/app
APP="SimpleLogin"
var_tags="${var_tags:-email;privacy;alias}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
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/simplelogin ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "simplelogin" "simple-login/app"; then
msg_info "Stopping Services"
systemctl stop simplelogin-webapp simplelogin-email simplelogin-job
msg_ok "Stopped Services"
create_backup /opt/simplelogin/.env \
/opt/simplelogin/dkim \
/opt/simplelogin/openid-rsa.key \
/opt/simplelogin/openid-rsa.pub \
/opt/simplelogin/uploads \
/opt/simplelogin/.gnupg
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "simplelogin" "simple-login/app"
restore_backup
grep -q '^METRICS_BACKENDS=' /opt/simplelogin/.env || echo "METRICS_BACKENDS=noop" >>/opt/simplelogin/.env
msg_info "Installing Dependencies"
cd /opt/simplelogin
$STD uv venv
$STD uv pip install setuptools hatchling editables
export CMAKE_POLICY_VERSION_MINIMUM=3.5
$STD uv sync --locked --no-dev --no-build-isolation --no-install-package newrelic
if [[ -f /opt/simplelogin/static/package.json ]]; then
cd /opt/simplelogin/static
$STD npm ci
fi
msg_ok "Installed Dependencies"
msg_info "Running Database Migrations"
cd /opt/simplelogin
$STD .venv/bin/alembic upgrade head
msg_ok "Ran Database Migrations"
msg_info "Starting Services"
systemctl start simplelogin-webapp simplelogin-email simplelogin-job
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}"
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/spacedriveapp/spacebot
APP="Spacebot"
var_tags="${var_tags:-ai;agent;chatops}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_llm_base_url="${var_llm_base_url:-}"
export var_llm_api_key="${var_llm_api_key:-}"
export var_llm_model="${var_llm_model:-}"
if [[ -n "$var_llm_base_url" && -z "$var_llm_model" ]]; then
msg_error "var_llm_model is required with var_llm_base_url."
exit 1
fi
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/spacebot ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "spacebot" "spacedriveapp/spacebot"; then
msg_info "Stopping Spacebot"
systemctl stop spacebot
msg_ok "Stopped Spacebot"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "spacebot" "spacedriveapp/spacebot" "prebuild" "latest" "/opt/spacebot" "spacebot-v*-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.tar.gz"
msg_info "Starting Spacebot"
systemctl start spacebot
msg_ok "Started Spacebot"
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}:19898${CL}"
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Renan Bastos (renanbastos93)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/temporalio/temporal
APP="Temporal"
var_tags="${var_tags:-workflow;automation}"
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}" # unset = ask the user; server, UI and CLI all ship linux_arm64 assets, but not yet run on arm64
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/temporal ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "temporal" "temporalio/temporal"; then
msg_info "Stopping Temporal"
systemctl stop temporal-ui temporal
msg_ok "Stopped Temporal"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"
msg_info "Migrating Temporal Database"
set -a && source /etc/temporal/temporal.env && set +a
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
msg_ok "Migrated Temporal Database"
msg_info "Starting Temporal"
systemctl start temporal temporal-ui
msg_ok "Started Temporal"
msg_ok "Updated Temporal successfully!"
fi
if check_for_gh_release "temporal-ui" "temporalio/ui-server"; then
msg_info "Stopping Temporal UI"
systemctl stop temporal-ui
msg_ok "Stopped Temporal UI"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"
msg_info "Starting Temporal UI"
systemctl start temporal-ui
msg_ok "Started Temporal UI"
msg_ok "Updated Temporal UI successfully!"
fi
if check_for_gh_release "temporal-cli" "temporalio/cli"; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"
msg_ok "Updated Temporal CLI 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}"
echo -e "${INFO}${YW}gRPC endpoint for workers and SDKs: ${IP}:7233${CL}"
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/trailbaseio/trailbase
APP="TrailBase"
var_tags="${var_tags:-backend;database;api}"
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}"
export var_admin_email="${var_admin_email:-}"
export var_admin_pass="${var_admin_pass:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/trailbase ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "trailbase" "trailbaseio/trailbase"; then
msg_info "Stopping TrailBase"
systemctl stop trailbase
msg_ok "Stopped TrailBase"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "trailbase" "trailbaseio/trailbase" "prebuild" "latest" "/opt/trailbase" "trailbase_v*_$(arch_resolve "x86_64" "aarch64")_linux.zip"
msg_info "Starting TrailBase"
systemctl start trailbase
msg_ok "Started TrailBase"
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}:4000/_/admin/${CL}"
echo -e "${INFO}${YW}Admin login: /opt/trailbase_data/.env (inside the container)${CL}"
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/unslothai/unsloth
APP="Unsloth"
var_tags="${var_tags:-ai;llm}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-40}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_gpu="${var_gpu:-yes}"
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/unsloth ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Stopping Service"
systemctl stop unsloth
msg_ok "Stopped Service"
if [[ -d /dev/dri || -e /dev/nvidia0 || -e /dev/kfd ]]; then
ENABLE_GPU="yes" setup_hwaccel
fi
msg_info "Updating ${APP} (Patience)"
curl -fsSL https://unsloth.ai/install.sh -o /tmp/unsloth-install.sh
export UNSLOTH_STUDIO_HOME=/opt/unsloth
export UNSLOTH_SKIP_AUTOSTART=1
export UNSLOTH_PYTHON=3.12
$STD sh /tmp/unsloth-install.sh
unset UNSLOTH_SKIP_AUTOSTART UNSLOTH_PYTHON
rm -f /tmp/unsloth-install.sh
msg_ok "Updated ${APP}"
msg_info "Starting Service"
systemctl start unsloth
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}:8888${CL}"
echo -e "${INFO}${YW}Login credentials: ~/unsloth.creds (inside the container)${CL}"
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/weaviate/weaviate
APP="Weaviate"
var_tags="${var_tags:-database;vector;ai}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_api_key="${var_api_key:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/weaviate ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "weaviate" "weaviate/weaviate"; then
msg_info "Stopping Weaviate"
systemctl stop weaviate
msg_ok "Stopped Weaviate"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "weaviate" "weaviate/weaviate" "prebuild" "latest" "/opt/weaviate" "weaviate-v*-linux-$(arch_resolve).tar.gz"
msg_info "Starting Weaviate"
systemctl start weaviate
msg_ok "Started Weaviate"
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}"
echo -e "${INFO}${YW}API key (user admin): /opt/weaviate_data/.env (inside the container)${CL}"
+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/decolua/9router
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="22" setup_nodejs
setup_ffmpeg
msg_info "Installing 9Router"
$STD npm install -g --ignore-scripts "9router@${var_appversion:-latest}"
msg_ok "Installed 9Router"
msg_info "Configuring 9Router"
mkdir -p /opt/9router_data
cat <<EOF >/opt/9router_data/.env
DATA_DIR=/opt/9router_data
PORT=20128
HOSTNAME=0.0.0.0
NODE_ENV=production
NEXT_TELEMETRY_DISABLED=1
BASE_URL=http://localhost:20128
INITIAL_PASSWORD=$(random_password)
JWT_SECRET=$(openssl rand -hex 32)
API_KEY_SECRET=$(openssl rand -hex 32)
MACHINE_ID_SALT=$(openssl rand -hex 16)
EOF
chmod 600 /opt/9router_data/.env
msg_ok "Configured 9Router"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/9router.service
[Unit]
Description=9Router
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/usr/lib/node_modules/9router/app
EnvironmentFile=/opt/9router_data/.env
ExecStart=/usr/bin/node /usr/lib/node_modules/9router/app/custom-server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now 9router
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Chris Moriarty (cwmoriarty)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/philippe44/AirConnect
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "airconnect" "philippe44/AirConnect" "prebuild" "latest" "/opt/airconnect" "AirConnect-*.zip"
msg_info "Configuring AirConnect"
chmod +x /opt/airconnect/airupnp-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/aircast-linux-$(arch_resolve x86_64 aarch64)
ln -sf /opt/airconnect/airupnp-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/airupnp
ln -sf /opt/airconnect/aircast-linux-$(arch_resolve x86_64 aarch64) /opt/airconnect/aircast
find /opt/airconnect -maxdepth 1 -type f ! -name "air*linux-$(arch_resolve x86_64 aarch64)*" ! -name "airupnp" ! -name "aircast" ! -name "*.xml" -delete
msg_ok "Configured AirConnect"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/airupnp.service
[Unit]
Description=AirUPnP bridge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/airconnect
ExecStart=/opt/airconnect/airupnp -l 1000:2000 -Z -x /opt/airconnect/airupnp.xml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now airupnp
cat <<EOF >/etc/systemd/system/aircast.service
[Unit]
Description=AirCast bridge
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/airconnect
ExecStart=/opt/airconnect/aircast -Z -x /opt/airconnect/aircast.xml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now aircast
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc
+86
View File
@@ -0,0 +1,86 @@
#!/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/bugsink/bugsink
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Bugsink"
BUGSINK_VERSION="${var_appversion:-$(get_latest_github_release "bugsink/bugsink")}"
$STD uv venv --python 3.12 /opt/bugsink/.venv
$STD uv pip install --python /opt/bugsink/.venv/bin/python "bugsink==${BUGSINK_VERSION}"
cat <<EOF >~/.bugsink
${BUGSINK_VERSION}
EOF
msg_ok "Installed Bugsink"
msg_info "Configuring Bugsink"
ADMIN_EMAIL="${var_admin_email:-admin@localhost}"
ADMIN_PASS="${var_admin_pass:-$(random_password)}"
mkdir -p /opt/bugsink_data
cd /opt/bugsink_data
$STD /opt/bugsink/.venv/bin/bugsink-create-conf --template=singleserver --host="${LOCAL_IP}" --base-dir=/opt/bugsink_data
sed -i \
-e "s|\"BASE_URL\": \"https://${LOCAL_IP}\"|\"BASE_URL\": \"http://${LOCAL_IP}:8000\"|" \
-e 's|^SESSION_COOKIE_SECURE = True|SESSION_COOKIE_SECURE = False|' \
-e 's|^CSRF_COOKIE_SECURE = True|CSRF_COOKIE_SECURE = False|' \
-e 's|^USE_X_REAL_IP = True|USE_X_REAL_IP = False|' \
/opt/bugsink_data/bugsink_conf.py
$STD /opt/bugsink/.venv/bin/bugsink-manage migrate
$STD /opt/bugsink/.venv/bin/bugsink-manage migrate snappea --database=snappea
DJANGO_SUPERUSER_PASSWORD="$ADMIN_PASS" $STD /opt/bugsink/.venv/bin/bugsink-manage createsuperuser --noinput --username "$ADMIN_EMAIL" --email "$ADMIN_EMAIL"
cat <<EOF >/opt/bugsink_data/.env
BUGSINK_ADMIN_EMAIL=${ADMIN_EMAIL}
BUGSINK_ADMIN_PASSWORD=${ADMIN_PASS}
EOF
chmod 600 /opt/bugsink_data/.env /opt/bugsink_data/bugsink_conf.py
msg_ok "Configured Bugsink"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/bugsink.service
[Unit]
Description=Bugsink
After=network.target
[Service]
Type=notify
WorkingDirectory=/opt/bugsink_data
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/bugsink/.venv/bin/gunicorn --bind=0.0.0.0:8000 --workers=4 --max-requests=1000 --max-requests-jitter=100 --access-logfile - bugsink.wsgi
Restart=always
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/bugsink-snappea.service
[Unit]
Description=Bugsink Snappea
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/bugsink_data
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/bugsink/.venv/bin/bugsink-runsnappea
Restart=always
RuntimeMaxSec=1d
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now bugsink bugsink-snappea
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/bulwarkmail/webmail
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "bulwark" "bulwarkmail/webmail" "prebuild" "latest" "/opt/bulwark" "bulwark-standalone-*-linux-$(arch_resolve).tar.gz"
msg_info "Configuring Bulwark"
mkdir -p /opt/bulwark_data
cat <<EOF >/opt/bulwark_data/.env
NODE_ENV=production
HOSTNAME=0.0.0.0
PORT=3000
JMAP_SERVER_URL=${var_jmap_url:-}
COOKIE_SECURE=false
ADMIN_CONFIG_DIR=/opt/bulwark_data/admin
ADMIN_STATE_DIR=/opt/bulwark_data/admin-state
SETTINGS_DATA_DIR=/opt/bulwark_data/settings
PLUGIN_SECRETS_DIR=/opt/bulwark_data/plugin-secrets
TELEMETRY_DATA_DIR=/opt/bulwark_data/telemetry
VERSION_CHECK_DATA_DIR=/opt/bulwark_data/version-check
EOF
chmod 600 /opt/bulwark_data/.env
msg_ok "Configured Bulwark"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/bulwark.service
[Unit]
Description=Bulwark Webmail
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/bulwark
EnvironmentFile=/opt/bulwark_data/.env
ExecStart=/usr/bin/node /opt/bulwark/server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now bulwark
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+57
View File
@@ -0,0 +1,57 @@
#!/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/chroma-core/chroma
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PYTHON_VERSION="3.12" setup_uv
CHROMA_VERSION="${var_appversion:-$(curl -fsSL https://pypi.org/pypi/chromadb/json | jq -r '.info.version')}"
msg_info "Installing Chroma ${CHROMA_VERSION}"
$STD uv venv --python 3.12 /opt/chroma/.venv
$STD uv pip install --python /opt/chroma/.venv/bin/python "chromadb==${CHROMA_VERSION}"
cat <<EOF >~/.chroma
${CHROMA_VERSION}
EOF
msg_ok "Installed Chroma ${CHROMA_VERSION}"
msg_info "Configuring Chroma"
mkdir -p /opt/chroma_data
cat <<EOF >/opt/chroma_data/config.yaml
persist_path: "/opt/chroma_data"
listen_address: "0.0.0.0"
port: 8000
EOF
msg_ok "Configured Chroma"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/chroma.service
[Unit]
Description=Chroma
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/chroma_data
ExecStart=/opt/chroma/.venv/bin/chroma run /opt/chroma_data/config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now chroma
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+122
View File
@@ -0,0 +1,122 @@
#!/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://colanode.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
redis-server \
nginx
msg_ok "Installed Dependencies"
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
PG_DB_NAME="colanode_db" PG_DB_USER="colanode" PG_DB_EXTENSIONS="vector" setup_postgresql_db
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "colanode" "colanode/colanode" "tarball"
msg_info "Building Application"
cd /opt/colanode
export NODE_OPTIONS="--max-old-space-size=4096"
$STD npm install
$STD npm run build -w @colanode/core
$STD npm run build -w @colanode/crdt
$STD npm run build -w @colanode/server
$STD npm run build -w @colanode/client
$STD npm run build -w @colanode/ui
$STD npm run build -w @colanode/web
$STD npm prune --production
unset NODE_OPTIONS
msg_ok "Built Application"
msg_info "Configuring Application"
mkdir -p /var/lib/colanode/storage /var/www/colanode
cp -r /opt/colanode/apps/web/dist/. /var/www/colanode/
cat <<EOF >/opt/colanode/.env
POSTGRES_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
REDIS_URL=redis://127.0.0.1:6379
NODE_ENV=production
EOF
msg_ok "Configured Application"
msg_info "Configuring Nginx"
create_self_signed_cert "colanode"
# Make cert available for browser import (required for Service Worker to work)
cp /etc/ssl/colanode/colanode.crt /var/www/colanode/colanode.crt
cat <<EOF >/etc/nginx/sites-available/colanode
server {
listen 4000 ssl;
server_name _;
root /var/www/colanode;
index index.html;
ssl_certificate /etc/ssl/colanode/colanode.crt;
ssl_certificate_key /etc/ssl/colanode/colanode.key;
# Required for SharedArrayBuffer / OPFS SQLite (WASM)
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
# Proxy API and WebSocket traffic to the Node.js server
location ~ ^/(config|client)(/.*)?$ {
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;
}
# Serve self-signed cert for browser import
location = /colanode.crt {
default_type application/x-x509-ca-cert;
}
location / {
try_files \$uri \$uri/ /index.html;
}
}
EOF
ln -sf /etc/nginx/sites-available/colanode /etc/nginx/sites-enabled/colanode
rm -f /etc/nginx/sites-enabled/default
systemctl reload nginx
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/colanode-server.service
[Unit]
Description=Colanode Server
After=network.target postgresql.service redis-server.service
Requires=postgresql.service redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/colanode
EnvironmentFile=/opt/colanode/.env
ExecStart=/usr/bin/node apps/server/dist/index.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now colanode-server
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+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/get-convex/convex-backend
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "convex" "get-convex/convex-backend" "prebuild" "latest" "/opt/convex" "convex-local-backend-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.zip"
fetch_and_deploy_gh_release "convex-dashboard" "get-convex/convex-backend" "prebuild" "$(cat ~/.convex)" "/opt/convex-dashboard" "dashboard.zip"
msg_info "Configuring Convex"
mkdir -p /opt/convex_data/storage /opt/convex_data/tmp
INSTANCE_SECRET=$(openssl rand -hex 32)
ADMIN_KEY=$(/opt/convex/convex-local-backend keygen admin-key --instance-name convex-self-hosted --instance-secret "$INSTANCE_SECRET")
cat <<EOF >/opt/convex_data/.env
INSTANCE_NAME=convex-self-hosted
INSTANCE_SECRET=${INSTANCE_SECRET}
CONVEX_SELF_HOSTED_ADMIN_KEY="${ADMIN_KEY}"
CONVEX_CLOUD_ORIGIN=http://${LOCAL_IP}:3210
CONVEX_SITE_ORIGIN=http://${LOCAL_IP}:3211
TMPDIR=/opt/convex_data/tmp
RUST_LOG=info
DOCUMENT_RETENTION_DELAY=172800
DISABLE_METRICS_ENDPOINT=true
APPLICATION_MAX_CONCURRENT_MUTATIONS=16
APPLICATION_MAX_CONCURRENT_QUERIES=16
APPLICATION_MAX_CONCURRENT_V8_ACTIONS=16
APPLICATION_MAX_CONCURRENT_NODE_ACTIONS=16
EOF
chmod 600 /opt/convex_data/.env
msg_ok "Configured Convex"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/convex-dashboard
server {
listen 6791;
server_name _;
root /opt/convex-dashboard;
index index.html;
location / {
try_files \$uri \$uri.html \$uri/ =404;
}
}
EOF
nginx_enable_site "convex-dashboard"
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/convex.service
[Unit]
Description=Convex Backend
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/convex_data
EnvironmentFile=/opt/convex_data/.env
ExecStart=/opt/convex/convex-local-backend --instance-name \${INSTANCE_NAME} --instance-secret \${INSTANCE_SECRET} --port 3210 --site-proxy-port 3211 --convex-origin \${CONVEX_CLOUD_ORIGIN} --convex-site \${CONVEX_SITE_ORIGIN} --local-storage /opt/convex_data/storage /opt/convex_data/db.sqlite3
KillSignal=SIGINT
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now convex
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+84
View File
@@ -0,0 +1,84 @@
#!/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/cypht-org/cypht
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" PHP_MODULE="soap,ldap" setup_php
fetch_and_deploy_gh_release "cypht" "cypht-org/cypht" "prebuild" "latest" "/opt/cypht" "cypht.tar.gz"
msg_info "Configuring Cypht"
var_admin_user="${var_admin_user:-admin}"
var_admin_pass="${var_admin_pass:-$(random_password)}"
mkdir -p /opt/cypht_data/{users,attachments}
cp /opt/cypht/.env /opt/cypht_data/.env
sed -i \
-e 's|^DB_DRIVER=.*|DB_DRIVER=sqlite|' \
-e 's|^DB_NAME=.*|DB_NAME=/opt/cypht_data/users/cypht.db|' \
-e 's|^SESSION_TYPE=.*|SESSION_TYPE=DB|' \
-e 's|^AUTH_TYPE=.*|AUTH_TYPE=DB|' \
-e 's|^USER_CONFIG_TYPE=.*|USER_CONFIG_TYPE=DB|' \
-e 's|^USER_SETTINGS_DIR=.*|USER_SETTINGS_DIR=/opt/cypht_data/users|' \
-e 's|^ATTACHMENT_DIR=.*|ATTACHMENT_DIR=/opt/cypht_data/attachments|' \
-e "s|^ADMIN_USERS=.*|ADMIN_USERS=${var_admin_user}|" \
-e 's|^ENABLE_REDIS=.*|ENABLE_REDIS=false|' \
-e 's|^ENABLE_MEMCACHED=.*|ENABLE_MEMCACHED=false|' \
/opt/cypht_data/.env
cat <<EOF >>/opt/cypht_data/.env
CYPHT_ADMIN_USER='${var_admin_user}'
CYPHT_ADMIN_PASS='${var_admin_pass}'
EOF
ln -sf /opt/cypht_data/.env /opt/cypht/.env
cd /opt/cypht
$STD php scripts/setup_database.php
$STD php scripts/create_account.php "$var_admin_user" "$var_admin_pass"
$STD php scripts/config_gen.php
chown -R www-data:www-data /opt/cypht_data/users /opt/cypht_data/attachments
chown root:www-data /opt/cypht_data/.env
chmod 640 /opt/cypht_data/.env
msg_ok "Configured Cypht"
msg_info "Configuring Nginx"
PHP_SOCK=$(get_php_fpm_socket)
cat <<EOF >/etc/nginx/sites-available/cypht
server {
listen 80;
server_name _;
root /opt/cypht/site;
index index.php;
client_max_body_size 60M;
location / {
try_files \$uri /index.php\$is_args\$args;
}
location ~ \.php\$ {
try_files \$uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)\$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass unix:${PHP_SOCK};
}
}
EOF
nginx_enable_site "cypht"
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+96
View File
@@ -0,0 +1,96 @@
#!/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/Gentleman-Programming/engram
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"
PG_VERSION="16" setup_postgresql
PG_DB_NAME="engram" PG_DB_USER="engram" setup_postgresql_db
fetch_and_deploy_gh_release "engram" "Gentleman-Programming/engram" "prebuild" "latest" "/opt/engram" "engram_*_linux_$(arch_resolve).tar.gz"
msg_info "Configuring Engram Cloud"
ln -sf /opt/engram/engram /usr/local/bin/engram
mkdir -p /opt/engram_data
cat <<EOF >/opt/engram_data/.env
ENGRAM_DATABASE_URL=postgres://engram:${PG_DB_PASS}@127.0.0.1:5432/engram?sslmode=disable
ENGRAM_CLOUD_HOST=127.0.0.1
ENGRAM_PORT=18080
ENGRAM_CLOUD_TOKEN=${var_cloud_token:-$(random_password 48)}
ENGRAM_CLOUD_ADMIN=${var_admin_token:-$(random_password 48)}
ENGRAM_JWT_SECRET=$(random_password 64)
ENGRAM_CLOUD_TOKEN_PEPPER=$(random_password 64)
ENGRAM_CLOUD_ALLOWED_PROJECTS=${var_allowed_projects:-*}
EOF
chmod 600 /opt/engram_data/.env
msg_ok "Configured Engram Cloud"
create_self_signed_cert "engram"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/engram
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
server_name _;
client_max_body_size 32m;
ssl_certificate /etc/ssl/engram/engram.crt;
ssl_certificate_key /etc/ssl/engram/engram.key;
location / {
proxy_pass http://127.0.0.1:18080;
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 https;
proxy_read_timeout 300s;
}
}
EOF
nginx_enable_site "engram"
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/engram.service
[Unit]
Description=Engram Cloud
After=network-online.target postgresql.service
Wants=network-online.target postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/engram_data
EnvironmentFile=/opt/engram_data/.env
ExecStart=/opt/engram/engram cloud serve
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now engram
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+62
View File
@@ -0,0 +1,62 @@
#!/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/Euro-Office/DocumentServer
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_nonfree
msg_info "Installing Dependencies"
$STD apt install -y \
nginx-extras \
rabbitmq-server
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_DB_NAME="euro_office" PG_DB_USER="euro_office" setup_postgresql_db
msg_info "Configuring RabbitMQ"
RMQ_PASS=$(random_password)
$STD rabbitmqctl add_user euro_office "$RMQ_PASS"
$STD rabbitmqctl set_permissions -p / euro_office ".*" ".*" ".*"
msg_ok "Configured RabbitMQ"
msg_info "Preseeding Euro-Office"
debconf-set-selections <<EOF
ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true
euro-office-documentserver ds/db-type string postgres
euro-office-documentserver ds/db-host string localhost
euro-office-documentserver ds/db-port string 5432
euro-office-documentserver ds/db-name string euro_office
euro-office-documentserver ds/db-user string euro_office
euro-office-documentserver ds/db-pwd password ${PG_DB_PASS}
euro-office-documentserver ds/rabbitmq-host string localhost
euro-office-documentserver ds/rabbitmq-user string euro_office
euro-office-documentserver ds/rabbitmq-pwd password ${RMQ_PASS}
euro-office-documentserver ds/jwt-enabled boolean true
euro-office-documentserver ds/jwt-secret string $(random_password 32)
EOF
msg_ok "Preseeded Euro-Office"
fetch_and_deploy_gh_release "euro-office" "Euro-Office/DocumentServer" "binary" "latest" "" "euro-office-documentserver_*_$(arch_resolve).deb"
msg_info "Starting Euro-Office"
systemctl restart ds-metrics ds-converter ds-docservice nginx
for _ in {1..60}; do
[[ "$(curl -fs http://127.0.0.1/healthcheck)" == "true" ]] && break
sleep 2
done
msg_ok "Started Euro-Office"
motd_ssh
customize
cleanup_lxc
+61
View File
@@ -0,0 +1,61 @@
#!/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/arp242/goatcounter
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "goatcounter" "arp242/goatcounter" "singlefile" "latest" "/opt/goatcounter" "goatcounter-v*-linux-$(arch_resolve).gz"
mv /opt/goatcounter/goatcounter /opt/goatcounter/goatcounter.gz
gunzip -f /opt/goatcounter/goatcounter.gz
msg_info "Configuring GoatCounter"
ADMIN_EMAIL="${var_admin_email:-admin@goatcounter.local}"
ADMIN_PASS="${var_admin_pass:-$(random_password)}"
mkdir -p /opt/goatcounter_data
cat <<EOF >/opt/goatcounter_data/.env
GOATCOUNTER_DB=sqlite+/opt/goatcounter_data/db.sqlite3
GOATCOUNTER_LISTEN=:8080
GOATCOUNTER_TLS=http
ADMIN_EMAIL=${ADMIN_EMAIL}
ADMIN_PASSWORD=${ADMIN_PASS}
EOF
chmod 600 /opt/goatcounter_data/.env
$STD /opt/goatcounter/goatcounter db create site -createdb \
-db sqlite+/opt/goatcounter_data/db.sqlite3 \
-vhost "${var_goatcounter_domain:-$LOCAL_IP}" \
-user.email "$ADMIN_EMAIL" \
-user.password "$ADMIN_PASS"
msg_ok "Configured GoatCounter"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/goatcounter.service
[Unit]
Description=GoatCounter
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/goatcounter_data
EnvironmentFile=/opt/goatcounter_data/.env
ExecStart=/opt/goatcounter/goatcounter serve -automigrate
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now goatcounter
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+99
View File
@@ -0,0 +1,99 @@
#!/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/hatchet-dev/hatchet
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
var_admin_email="${var_admin_email:-admin@example.com}"
var_admin_pass="${var_admin_pass:-}"
until [[ ${#var_admin_pass} -ge 8 && ${#var_admin_pass} -le 64 && "$var_admin_pass" =~ [A-Z] && "$var_admin_pass" =~ [a-z] && "$var_admin_pass" =~ [0-9] ]]; do
var_admin_pass=$(random_password)
done
msg_info "Installing Dependencies"
$STD apt install -y python3
msg_ok "Installed Dependencies"
setup_postgresql
PG_DB_NAME="hatchet" PG_DB_USER="hatchet" setup_postgresql_db
setup_go
fetch_and_deploy_gh_release "hatchet" "hatchet-dev/hatchet" "tarball"
NODE_VERSION="24" NODE_MODULE="$(jq -r '.packageManager' /opt/hatchet/frontend/app/package.json)" setup_nodejs
msg_info "Building Hatchet"
cd /opt/hatchet/frontend/snippets
$STD python3 generate.py
cd /opt/hatchet/frontend/app
$STD pnpm install --frozen-lockfile
$STD pnpm run build
cd /opt/hatchet
for target in lite admin migrate; do
CGO_ENABLED=0 $STD go build -ldflags="-w -s -X main.Version=v$(cat ~/.hatchet)" -o "bin/hatchet-${target}" "./cmd/hatchet-${target}"
done
rm -rf /opt/hatchet/frontend/app/node_modules ~/.local/share/pnpm/store
$STD go clean -cache -modcache
msg_ok "Built Hatchet"
msg_info "Configuring Hatchet"
mkdir -p /opt/hatchet_data/config
cat <<EOF >/opt/hatchet_data/.env
DATABASE_URL=postgresql://hatchet:${PG_DB_PASS}@localhost:5432/hatchet?sslmode=disable
SERVER_URL=http://${LOCAL_IP}:8888
SERVER_AUTH_COOKIE_DOMAIN=${LOCAL_IP}
SERVER_AUTH_COOKIE_INSECURE=t
SERVER_AUTH_SET_EMAIL_VERIFIED=t
SERVER_ALLOW_SIGNUP=f
SERVER_GRPC_BIND_ADDRESS=0.0.0.0
SERVER_GRPC_PORT=7077
SERVER_GRPC_INSECURE=t
SERVER_GRPC_BROADCAST_ADDRESS=${LOCAL_IP}:7077
SERVER_INTERNAL_CLIENT_INTERNAL_GRPC_BROADCAST_ADDRESS=localhost:7077
SERVER_MSGQUEUE_KIND=postgres
LITE_STATIC_ASSET_DIR=/opt/hatchet/frontend/app/dist
LITE_FRONTEND_BASE_PATH=/
LITE_FRONTEND_PORT=8081
LITE_RUNTIME_PORT=8888
ADMIN_EMAIL=${var_admin_email}
ADMIN_PASSWORD=${var_admin_pass}
EOF
chmod 600 /opt/hatchet_data/.env
cd /opt/hatchet_data
set -a && source /opt/hatchet_data/.env && set +a
$STD /opt/hatchet/bin/hatchet-migrate
$STD /opt/hatchet/bin/hatchet-admin quickstart --config /opt/hatchet_data/config --generated-config-dir /opt/hatchet_data/config --skip certs --overwrite=false
msg_ok "Configured Hatchet"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/hatchet.service
[Unit]
Description=Hatchet
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
WorkingDirectory=/opt/hatchet_data
EnvironmentFile=/opt/hatchet_data/.env
ExecStartPre=/opt/hatchet/bin/hatchet-migrate
ExecStart=/opt/hatchet/bin/hatchet-lite --config /opt/hatchet_data/config
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now hatchet
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+62
View File
@@ -0,0 +1,62 @@
#!/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/inngest/inngest
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y redis-server
sed -i 's/^appendonly no/appendonly yes/' /etc/redis/redis.conf
systemctl restart redis-server
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
PG_DB_NAME="inngest" PG_DB_USER="inngest" setup_postgresql_db
fetch_and_deploy_gh_release "inngest" "inngest/inngest" "prebuild" "latest" "/opt/inngest" "inngest_*_linux_$(arch_resolve).tar.gz"
msg_info "Configuring Inngest"
mkdir -p /opt/inngest_data
cat <<EOF >/opt/inngest_data/.env
INNGEST_PORT=8288
INNGEST_POSTGRES_URI=postgres://inngest:${PG_DB_PASS}@127.0.0.1:5432/inngest?sslmode=disable
INNGEST_REDIS_URI=redis://127.0.0.1:6379
INNGEST_EVENT_KEY=$(openssl rand -hex 32)
INNGEST_SIGNING_KEY=$(openssl rand -hex 32)
DO_NOT_TRACK=1
EOF
chmod 600 /opt/inngest_data/.env
msg_ok "Configured Inngest"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/inngest.service
[Unit]
Description=Inngest
After=network.target postgresql.service redis-server.service
Requires=postgresql.service redis-server.service
[Service]
Type=simple
WorkingDirectory=/opt/inngest_data
EnvironmentFile=/opt/inngest_data/.env
ExecStart=/opt/inngest/inngest start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now inngest
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+68
View File
@@ -0,0 +1,68 @@
#!/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/langflow-ai/langflow
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="24" setup_nodejs
PYTHON_VERSION="3.14" USE_UVX="YES" setup_uv
LANGFLOW_VERSION="${var_appversion:-$(get_latest_github_release "langflow-ai/langflow")}"
msg_info "Installing Langflow ${LANGFLOW_VERSION#v}"
$STD uv venv --python 3.14 /opt/langflow/.venv
$STD uv pip install --python /opt/langflow/.venv/bin/python "langflow==${LANGFLOW_VERSION#v}"
cat <<EOF >~/.langflow
${LANGFLOW_VERSION#v}
EOF
msg_ok "Installed Langflow ${LANGFLOW_VERSION#v}"
msg_info "Configuring Langflow"
mkdir -p /opt/langflow_data/logs
cat <<EOF >/opt/langflow_data/.env
LANGFLOW_HOST=0.0.0.0
LANGFLOW_PORT=7860
LANGFLOW_CONFIG_DIR=/opt/langflow_data
LANGFLOW_DATABASE_URL=sqlite:////opt/langflow_data/langflow.db
LANGFLOW_KNOWLEDGE_BASES_DIR=/opt/langflow_data/knowledge_bases
LANGFLOW_LOG_FILE=/opt/langflow_data/logs/langflow.log
LANGFLOW_SECRET_KEY=$(/opt/langflow/.venv/bin/python -c "from secrets import token_urlsafe; print(token_urlsafe(32))")
LANGFLOW_AUTO_LOGIN=False
LANGFLOW_SUPERUSER='${var_admin_user:-langflow}'
LANGFLOW_SUPERUSER_PASSWORD='${var_admin_pass:-$(random_password)}'
EOF
chmod 600 /opt/langflow_data/.env
msg_ok "Configured Langflow"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/langflow.service
[Unit]
Description=Langflow
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/langflow_data
EnvironmentFile=/opt/langflow_data/.env
ExecStart=/opt/langflow/.venv/bin/langflow run
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now langflow
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+62
View File
@@ -0,0 +1,62 @@
#!/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/marimo-team/marimo
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PYTHON_VERSION="3.13" setup_uv
MARIMO_VERSION="${var_appversion:-$(get_latest_github_release "marimo-team/marimo")}"
msg_info "Installing marimo ${MARIMO_VERSION}"
$STD uv venv --python 3.13 /opt/marimo/.venv
$STD uv pip install --python /opt/marimo/.venv/bin/python "marimo[recommended]==${MARIMO_VERSION}" pandas
cat <<EOF >~/.marimo
${MARIMO_VERSION}
EOF
msg_ok "Installed marimo ${MARIMO_VERSION}"
msg_info "Configuring marimo"
mkdir -p /opt/marimo_data/notebooks /root/.config/marimo
cat <<EOF >/opt/marimo_data/.env
MARIMO_TOKEN_PASSWORD=${var_token_password:-$(random_password)}
EOF
chmod 600 /opt/marimo_data/.env
cat <<EOF >/root/.config/marimo/marimo.toml
[package_management]
manager = "uv"
EOF
msg_ok "Configured marimo"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/marimo.service
[Unit]
Description=marimo
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/marimo_data/notebooks
EnvironmentFile=/opt/marimo_data/.env
Environment=MARIMO_SKIP_UPDATE_CHECK=1
ExecStart=/opt/marimo/.venv/bin/marimo -y edit --headless --host 0.0.0.0 --port 2718 --token-password \${MARIMO_TOKEN_PASSWORD} /opt/marimo_data/notebooks
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now marimo
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+58
View File
@@ -0,0 +1,58 @@
#!/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/maplibre/martin
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "martin" "maplibre/martin" "prebuild" "latest" "/opt/martin" "martin-$(arch_resolve "x86_64" "aarch64")-unknown-linux-musl.tar.gz"
msg_info "Configuring Martin"
mkdir -p /opt/martin_data/tiles
cat <<EOF >/opt/martin_data/config.yaml
listen_addresses: 0.0.0.0:3000
web_ui: enable-for-all
mbtiles:
paths:
- /opt/martin_data/tiles
pmtiles:
paths:
- /opt/martin_data/tiles
# postgres:
# connection_string: postgres://user:password@host:5432/database
EOF
msg_ok "Configured Martin"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/martin.service
[Unit]
Description=Martin Tile Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/martin_data
ExecStart=/opt/martin/martin --config /opt/martin_data/config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now martin
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+67
View File
@@ -0,0 +1,67 @@
#!/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/QuantumNous/new-api
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "new-api" "QuantumNous/new-api" "singlefile" "latest" "/opt/new-api" "$(arch_resolve "new-api-v" "new-api-arm64-v")*[0-9]"
msg_info "Configuring New API"
ADMIN_USER="${var_admin_user:-admin}"
ADMIN_PASS="${var_admin_pass:-$(random_password)}"
mkdir -p /opt/new-api_data/logs
cat <<EOF >/opt/new-api_data/.env
PORT=3000
SQLITE_PATH=/opt/new-api_data/new-api.db
SESSION_SECRET=$(openssl rand -hex 32)
CRYPTO_SECRET=$(openssl rand -hex 32)
BATCH_UPDATE_ENABLED=true
NEW_API_ADMIN_USER=${ADMIN_USER}
NEW_API_ADMIN_PASSWORD=${ADMIN_PASS}
EOF
chmod 600 /opt/new-api_data/.env
msg_ok "Configured New API"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/new-api.service
[Unit]
Description=New API
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/new-api_data
EnvironmentFile=/opt/new-api_data/.env
ExecStart=/opt/new-api/new-api --log-dir /opt/new-api_data/logs
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now new-api
msg_ok "Created Service"
msg_info "Creating New API Admin Account"
for _ in {1..60}; do
curl -fsS http://127.0.0.1:3000/api/status &>/dev/null && break
sleep 1
done
jq -nc --arg u "$ADMIN_USER" --arg p "$ADMIN_PASS" \
'{username: $u, password: $p, confirmPassword: $p, SelfUseModeEnabled: false, DemoSiteEnabled: false}' |
curl -fsS -X POST http://127.0.0.1:3000/api/setup -H "Content-Type: application/json" --data-binary @- |
jq -e '.success' >/dev/null
msg_ok "Created New API Admin Account"
motd_ssh
customize
cleanup_lxc
+151
View File
@@ -0,0 +1,151 @@
#!/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/ccfos/nightingale
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y redis-server
msg_ok "Installed Dependencies"
setup_mariadb
MARIADB_DB_NAME="nightingale" MARIADB_DB_USER="nightingale" setup_mariadb_db
fetch_and_deploy_gh_release "nightingale" "ccfos/nightingale" "prebuild" "latest" "/opt/nightingale" "n9e-v*-linux-$(arch_resolve).tar.gz"
msg_info "Configuring Nightingale"
mkdir -p /opt/nightingale_data
cat <<EOF >/opt/nightingale_data/config.toml
[Global]
RunMode = "release"
[Log]
Dir = "/opt/nightingale_data/logs"
Level = "INFO"
Output = "stdout"
[HTTP]
Host = "0.0.0.0"
Port = 17000
CertFile = ""
KeyFile = ""
PrintAccessLog = false
PProf = false
ExposeMetrics = true
ShutdownTimeout = 30
MaxContentLength = 67108864
ReadTimeout = 20
WriteTimeout = 40
IdleTimeout = 120
[HTTP.ShowCaptcha]
Enable = false
[HTTP.APIForAgent]
Enable = true
[HTTP.APIForService]
Enable = false
[HTTP.JWTAuth]
AccessExpired = 1500
RefreshExpired = 10080
RedisKeyPrefix = "/jwt/"
[HTTP.ProxyAuth]
Enable = false
HeaderUserNameKey = "X-User-Name"
DefaultRoles = ["Standard"]
[HTTP.TokenAuth]
Enable = true
[HTTP.RSA]
OpenRSA = false
[DB]
DBType = "mysql"
DSN = "nightingale:${MARIADB_DB_PASS}@tcp(127.0.0.1:3306)/nightingale?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&loc=Local&allowNativePasswords=true"
Debug = false
MaxLifetime = 7200
MaxOpenConns = 150
MaxIdleConns = 50
[Redis]
Address = "127.0.0.1:6379"
RedisType = "standalone"
[Alert]
[Alert.Heartbeat]
IP = ""
Interval = 1000
EngineName = "default"
[Alert.EvalLog]
MaxDiskGB = 1
[Center]
MetricsYamlFile = "/opt/nightingale/etc/metrics.yaml"
I18NHeaderKey = "X-Language"
[Center.AnonymousAccess]
PromQuerier = false
AlertDetail = true
[EmbeddedTSDB]
Enable = true
Dir = "/opt/nightingale_data/tsdb"
RetentionDuration = "15d"
MaxBytes = "4GiB"
OutOfOrderTimeWindow = "10m"
QueryTimeout = "1m"
QueryMaxSamples = 50000000
LookbackDelta = "5m"
BasicAuthUser = ""
BasicAuthPass = ""
[Pushgw]
LabelRewrite = true
ForceUseServerTS = true
[Ibex]
Enable = true
RPCListen = "0.0.0.0:20090"
EOF
chmod 600 /opt/nightingale_data/config.toml
msg_ok "Configured Nightingale"
msg_info "Creating Service"
# integrations/, agents/ and the AI skill cache resolve against the working directory, so it stays the release dir
cat <<EOF >/etc/systemd/system/nightingale.service
[Unit]
Description=Nightingale
After=network.target mariadb.service redis-server.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/nightingale
ExecStart=/opt/nightingale/n9e --configs /opt/nightingale_data
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nightingale
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+230
View File
@@ -0,0 +1,230 @@
#!/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/simple-login/app
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
echo "postfix postfix/mailname string $(hostname -f)" | debconf-set-selections
echo "postfix postfix/main_mailer_type string Internet Site" | debconf-set-selections
$STD apt install -y \
build-essential \
libre2-dev \
pkg-config \
libpq-dev \
cmake \
ninja-build \
clang \
redis-server \
nginx \
postfix \
postfix-pgsql \
opendkim-tools
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
APPLICATION="simplelogin" PG_DB_NAME="simplelogin" PG_DB_USER="simplelogin" setup_postgresql_db
PYTHON_VERSION="3.12" setup_uv
NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "simplelogin" "simple-login/app"
msg_info "Installing SimpleLogin (Patience)"
cd /opt/simplelogin
$STD uv venv
$STD uv pip install setuptools hatchling editables
export CMAKE_POLICY_VERSION_MINIMUM=3.5
$STD uv sync --locked --no-dev --no-build-isolation --no-install-package newrelic
if [[ -f /opt/simplelogin/static/package.json ]]; then
cd /opt/simplelogin/static
$STD npm ci
fi
msg_ok "Installed SimpleLogin"
msg_info "Configuring SimpleLogin"
FLASK_SECRET=$(openssl rand -hex 32)
mkdir -p /opt/simplelogin/dkim
$STD openssl genrsa -traditional -out /opt/simplelogin/dkim/dkim.private 2048
$STD openssl rsa -in /opt/simplelogin/dkim/dkim.private -pubout -out /opt/simplelogin/dkim/dkim.public.key
DKIM_PUB=$(openssl rsa -in /opt/simplelogin/dkim/dkim.private -pubout 2>/dev/null | grep -v '^-----' | tr -d '\n')
cat <<EOF >/opt/simplelogin/dkim/dkim.dns.txt
dkim._domainkey.EMAIL_DOMAIN. IN TXT ( "v=DKIM1; k=rsa; p=${DKIM_PUB}" )
EOF
$STD openssl genrsa -out /opt/simplelogin/openid-rsa.key 2048
$STD openssl rsa -in /opt/simplelogin/openid-rsa.key -pubout -out /opt/simplelogin/openid-rsa.pub
mkdir -p /opt/simplelogin/uploads /opt/simplelogin/.gnupg
chmod 700 /opt/simplelogin/.gnupg
{
echo "URL=http://${LOCAL_IP}"
echo "EMAIL_DOMAIN=example.com"
echo "SUPPORT_EMAIL=support@example.com"
echo 'EMAIL_SERVERS_WITH_PRIORITY=[(10, "localhost.")]'
echo "POSTFIX_SERVER=localhost"
echo "DB_URI=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}"
echo "FLASK_SECRET=${FLASK_SECRET}"
echo "DKIM_PRIVATE_KEY_PATH=/opt/simplelogin/dkim/dkim.private"
echo "GNUPGHOME=/opt/simplelogin/.gnupg"
echo "LOCAL_FILE_UPLOAD=true"
echo "UPLOAD_DIR=/opt/simplelogin/uploads"
echo "DISABLE_ALIAS_SUFFIX=1"
echo "WORDS_FILE_PATH=/opt/simplelogin/local_data/words.txt"
echo "NAMESERVERS=1.1.1.1"
echo "MEM_STORE_URI=redis://localhost:6379/1"
echo "OPENID_PRIVATE_KEY_PATH=/opt/simplelogin/openid-rsa.key"
echo "OPENID_PUBLIC_KEY_PATH=/opt/simplelogin/openid-rsa.pub"
echo "METRICS_BACKENDS=noop"
} >/opt/simplelogin/.env
cd /opt/simplelogin
export FLASK_APP=server
export URL="http://${LOCAL_IP}"
export EMAIL_DOMAIN="example.com"
export SUPPORT_EMAIL="support@example.com"
export EMAIL_SERVERS_WITH_PRIORITY='[(10, "localhost.")]'
export POSTFIX_SERVER="localhost"
export DB_URI="postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}"
export FLASK_SECRET="${FLASK_SECRET}"
export DKIM_PRIVATE_KEY_PATH="/opt/simplelogin/dkim/dkim.private"
export GNUPGHOME="/opt/simplelogin/.gnupg"
export LOCAL_FILE_UPLOAD="true"
export UPLOAD_DIR="/opt/simplelogin/uploads"
export DISABLE_ALIAS_SUFFIX="1"
export WORDS_FILE_PATH="/opt/simplelogin/local_data/words.txt"
export NAMESERVERS="1.1.1.1"
export MEM_STORE_URI="redis://localhost:6379/1"
export OPENID_PRIVATE_KEY_PATH="/opt/simplelogin/openid-rsa.key"
export OPENID_PUBLIC_KEY_PATH="/opt/simplelogin/openid-rsa.pub"
export METRICS_BACKENDS="noop"
$STD .venv/bin/alembic upgrade head
$STD .venv/bin/python init_app.py
msg_ok "Configured SimpleLogin"
msg_info "Configuring Postfix"
cat <<EOF >/etc/postfix/pgsql-relay-domains.cf
hosts = localhost
dbname = ${PG_DB_NAME}
user = ${PG_DB_USER}
password = ${PG_DB_PASS}
query = SELECT domain FROM custom_domain WHERE domain='%s' AND verified=true
EOF
cat <<EOF >/etc/postfix/pgsql-transport-maps.cf
hosts = localhost
dbname = ${PG_DB_NAME}
user = ${PG_DB_USER}
password = ${PG_DB_PASS}
query = SELECT 'smtp:[127.0.0.1]:20381' FROM custom_domain WHERE domain='%s' AND verified=true
EOF
chmod 640 /etc/postfix/pgsql-*.cf
cat <<EOF >/etc/postfix/transport
example.com smtp:[127.0.0.1]:20381
EOF
$STD postmap /etc/postfix/transport
postconf -e "relay_domains = example.com, pgsql:/etc/postfix/pgsql-relay-domains.cf"
postconf -e "transport_maps = hash:/etc/postfix/transport, pgsql:/etc/postfix/pgsql-transport-maps.cf"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination"
postconf -e "inet_protocols = ipv4"
$STD systemctl restart postfix
msg_ok "Configured Postfix"
msg_info "Creating Services"
cat <<'EOF' >/etc/systemd/system/simplelogin-webapp.service
[Unit]
Description=SimpleLogin Web Application
After=network.target postgresql.service redis-server.service
Requires=postgresql.service redis-server.service
[Service]
Type=simple
WorkingDirectory=/opt/simplelogin
EnvironmentFile=/opt/simplelogin/.env
ExecStart=/opt/simplelogin/.venv/bin/gunicorn wsgi:app -b 127.0.0.1:7777 -w 2 --timeout 120
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<'EOF' >/etc/systemd/system/simplelogin-email.service
[Unit]
Description=SimpleLogin Email Handler
After=network.target postgresql.service redis-server.service postfix.service
Requires=postgresql.service redis-server.service
[Service]
Type=simple
WorkingDirectory=/opt/simplelogin
EnvironmentFile=/opt/simplelogin/.env
ExecStart=/opt/simplelogin/.venv/bin/python email_handler.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<'EOF' >/etc/systemd/system/simplelogin-job.service
[Unit]
Description=SimpleLogin Job Runner
After=network.target postgresql.service redis-server.service
Requires=postgresql.service redis-server.service
[Service]
Type=simple
WorkingDirectory=/opt/simplelogin
EnvironmentFile=/opt/simplelogin/.env
ExecStart=/opt/simplelogin/.venv/bin/python job_runner.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now redis-server simplelogin-webapp simplelogin-email simplelogin-job
msg_ok "Created Services"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/simplelogin.conf
server {
listen 80 default_server;
server_name _;
client_max_body_size 10M;
location / {
proxy_pass http://127.0.0.1:7777;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
ln -sf /etc/nginx/sites-available/simplelogin.conf /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
$STD nginx -t
$STD systemctl enable --now nginx
$STD systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+99
View File
@@ -0,0 +1,99 @@
#!/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/spacedriveapp/spacebot
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 \
bubblewrap \
fonts-liberation \
libnss3 \
libatk-bridge2.0-0t64 \
libdrm2 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
libgbm1 \
libasound2t64 \
libpango-1.0-0 \
libcairo2 \
libcups2t64 \
libxkbcommon0 \
libxss1 \
libxtst6 \
libxfixes3
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "spacebot" "spacedriveapp/spacebot" "prebuild" "latest" "/opt/spacebot" "spacebot-v*-$(arch_resolve "x86_64" "aarch64")-unknown-linux-gnu.tar.gz"
msg_info "Configuring Spacebot"
mkdir -p /opt/spacebot_data
cat <<EOF >/opt/spacebot_data/.env
SPACEBOT_DIR=/opt/spacebot_data
EOF
cat <<EOF >/opt/spacebot_data/config.toml
[api]
bind = "0.0.0.0"
port = 19898
[[agents]]
id = "main"
default = true
EOF
if [[ -n "${var_llm_base_url:-}" ]]; then
cat <<EOF >>/opt/spacebot_data/.env
LLM_API_KEY=${var_llm_api_key:-none}
EOF
cat <<EOF >>/opt/spacebot_data/config.toml
[llm.provider.custom]
api_type = "openai_chat_completions"
base_url = "${var_llm_base_url%/}"
api_key = "env:LLM_API_KEY"
name = "OpenAI-compatible"
[defaults.routing]
channel = "custom/${var_llm_model}"
branch = "custom/${var_llm_model}"
worker = "custom/${var_llm_model}"
compactor = "custom/${var_llm_model}"
cortex = "custom/${var_llm_model}"
EOF
fi
chmod 600 /opt/spacebot_data/.env /opt/spacebot_data/config.toml
msg_ok "Configured Spacebot"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/spacebot.service
[Unit]
Description=Spacebot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/spacebot_data
EnvironmentFile=/opt/spacebot_data/.env
ExecStart=/opt/spacebot/spacebot start --foreground
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now spacebot
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+206
View File
@@ -0,0 +1,206 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Renan Bastos (renanbastos93)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/temporalio/temporal
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
PG_VERSION="17" setup_postgresql
PG_DB_NAME="temporal" PG_DB_USER="temporal" PG_DB_SCHEMA_PERMS="true" setup_postgresql_db
fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"
fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"
fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"
msg_info "Configuring Temporal"
mkdir -p /etc/temporal/config/dynamicconfig /etc/temporal/ui
ln -sf /opt/temporal-cli/temporal /usr/bin/temporal
cat <<EOF >/etc/temporal/temporal.env
SQL_PLUGIN=postgres12
SQL_HOST=127.0.0.1
SQL_PORT=5432
SQL_USER=temporal
SQL_PASSWORD=${PG_DB_PASS}
EOF
chmod 600 /etc/temporal/temporal.env
cat <<'EOF' >/etc/temporal/config/production.yaml
# enable-template
log:
stdout: true
level: info
persistence:
defaultStore: postgres-default
visibilityStore: postgres-visibility
numHistoryShards: 4
datastores:
postgres-default:
sql:
pluginName: {{ env "SQL_PLUGIN" | quote }}
databaseName: "temporal"
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
connectProtocol: "tcp"
user: {{ env "SQL_USER" | quote }}
password: {{ env "SQL_PASSWORD" | quote }}
maxConns: 20
maxIdleConns: 20
maxConnLifetime: "1h"
postgres-visibility:
sql:
pluginName: {{ env "SQL_PLUGIN" | quote }}
databaseName: "temporal_visibility"
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
connectProtocol: "tcp"
user: {{ env "SQL_USER" | quote }}
password: {{ env "SQL_PASSWORD" | quote }}
maxConns: 10
maxIdleConns: 10
maxConnLifetime: "1h"
global:
membership:
maxJoinDuration: 30s
broadcastAddress: "127.0.0.1"
services:
frontend:
rpc:
grpcPort: 7233
membershipPort: 6933
bindOnIP: "0.0.0.0"
matching:
rpc:
grpcPort: 7235
membershipPort: 6935
bindOnLocalHost: true
history:
rpc:
grpcPort: 7234
membershipPort: 6934
bindOnLocalHost: true
worker:
rpc:
grpcPort: 7239
membershipPort: 6939
bindOnLocalHost: true
clusterMetadata:
enableGlobalNamespace: false
failoverVersionIncrement: 10
masterClusterName: "active"
currentClusterName: "active"
clusterInformation:
active:
enabled: true
initialFailoverVersion: 1
rpcName: "frontend"
rpcAddress: "127.0.0.1:7233"
dcRedirectionPolicy:
policy: "noop"
archival:
history:
state: "disabled"
visibility:
state: "disabled"
namespaceDefaults:
archival:
history:
state: "disabled"
visibility:
state: "disabled"
dynamicConfigClient:
filepath: "/etc/temporal/config/dynamicconfig/production.yaml"
pollInterval: "60s"
EOF
cat <<EOF >/etc/temporal/config/dynamicconfig/production.yaml
limit.maxIDLength:
- value: 255
constraints: {}
EOF
cat <<EOF >/etc/temporal/ui/production.yaml
temporalGrpcAddress: 127.0.0.1:7233
port: 8080
enableUi: true
defaultNamespace: default
cors:
cookieInsecure: true
allowOrigins:
- http://${LOCAL_IP}:8080
EOF
msg_ok "Configured Temporal"
msg_info "Initializing Temporal Database"
set -a && source /etc/temporal/temporal.env && set +a
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility create-database
$STD /opt/temporal/temporal-sql-tool --db temporal setup-schema -v 0.0
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility setup-schema -v 0.0
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
msg_ok "Initialized Temporal Database"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/temporal.service
[Unit]
Description=Temporal Server
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/temporal
EnvironmentFile=/etc/temporal/temporal.env
ExecStart=/opt/temporal/temporal-server --root /etc/temporal --env production --allow-no-auth start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/temporal-ui.service
[Unit]
Description=Temporal UI
After=network.target temporal.service
Wants=temporal.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/temporal-ui
ExecStart=/opt/temporal-ui/ui-server --root /etc/temporal --config ui --env production start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now temporal temporal-ui
msg_ok "Created Services"
msg_info "Creating Default Namespace"
for _ in {1..60}; do
temporal operator cluster health &>/dev/null && break
sleep 1
done
$STD temporal operator namespace create --namespace default
msg_ok "Created Default Namespace"
motd_ssh
customize
cleanup_lxc
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/trailbaseio/trailbase
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "trailbase" "trailbaseio/trailbase" "prebuild" "latest" "/opt/trailbase" "trailbase_v*_$(arch_resolve "x86_64" "aarch64")_linux.zip"
msg_info "Configuring TrailBase"
ADMIN_EMAIL="${var_admin_email:-admin@localhost}"
ADMIN_PASS="${var_admin_pass:-$(random_password)}"
mkdir -p /opt/trailbase_data
cat <<EOF >/opt/trailbase_data/.env
DEPOT=/opt/trailbase_data/traildepot
ADDRESS=0.0.0.0:4000
PUBLIC_URL=http://${LOCAL_IP}:4000
TRAILBASE_ADMIN_EMAIL=${ADMIN_EMAIL}
TRAILBASE_ADMIN_PASSWORD=${ADMIN_PASS}
EOF
chmod 600 /opt/trailbase_data/.env
# The first CLI call creates the depot and the admin user admin@localhost
$STD /opt/trailbase/trail --depot /opt/trailbase_data/traildepot user change-password admin@localhost "$ADMIN_PASS"
if [[ "$ADMIN_EMAIL" != "admin@localhost" ]]; then
$STD /opt/trailbase/trail --depot /opt/trailbase_data/traildepot user change-email admin@localhost "$ADMIN_EMAIL"
fi
msg_ok "Configured TrailBase"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/trailbase.service
[Unit]
Description=TrailBase
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/trailbase_data
EnvironmentFile=/opt/trailbase_data/.env
ExecStart=/opt/trailbase/trail run
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now trailbase
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+90
View File
@@ -0,0 +1,90 @@
#!/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/unslothai/unsloth
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 \
libgomp1 \
git
msg_ok "Installed Dependencies"
UV_PYTHON="3.12" setup_uv
NODE_VERSION="22" setup_nodejs
setup_hwaccel
msg_info "Setting up Unsloth Studio (Patience)"
mkdir -p /opt/unsloth_data
curl -fsSL https://unsloth.ai/install.sh -o /tmp/unsloth-install.sh
export UNSLOTH_STUDIO_HOME=/opt/unsloth
export UNSLOTH_SKIP_AUTOSTART=1
export UNSLOTH_PYTHON=3.12
$STD sh /tmp/unsloth-install.sh
unset UNSLOTH_SKIP_AUTOSTART UNSLOTH_PYTHON
rm -f /tmp/unsloth-install.sh
[[ -x /opt/unsloth/unsloth_studio/bin/unsloth ]] || {
msg_error "Unsloth Studio was not installed to /opt/unsloth/unsloth_studio"
exit 1
}
msg_ok "Set up Unsloth Studio"
msg_info "Configuring Unsloth Studio"
cat <<EOF >/opt/unsloth.env
UNSLOTH_STUDIO_HOME=/opt/unsloth
HF_HOME=/opt/unsloth_data/huggingface
EOF
chmod 600 /opt/unsloth.env
UNSLOTH_PASSWORD=$(UNSLOTH_STUDIO_HOME=/opt/unsloth \
/opt/unsloth/unsloth_studio/bin/unsloth studio reset-password |
sed -n "s/^New password for 'unsloth': //p")
[[ -n "$UNSLOTH_PASSWORD" ]] || {
msg_error "Could not set the initial Unsloth admin password"
exit 1
}
cat <<EOF >~/unsloth.creds
Unsloth Studio
Username: unsloth
Password: ${UNSLOTH_PASSWORD}
EOF
chmod 600 ~/unsloth.creds
msg_ok "Configured Unsloth Studio"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/unsloth.service
[Unit]
Description=Unsloth Studio
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/unsloth_data
EnvironmentFile=/opt/unsloth.env
ExecStart=/opt/unsloth/unsloth_studio/bin/unsloth studio -H 0.0.0.0 -p 8888
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now unsloth
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+64
View File
@@ -0,0 +1,64 @@
#!/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/weaviate/weaviate
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "weaviate" "weaviate/weaviate" "prebuild" "latest" "/opt/weaviate" "weaviate-v*-linux-$(arch_resolve).tar.gz"
msg_info "Configuring Weaviate"
mkdir -p /opt/weaviate_data/data
cat <<EOF >/opt/weaviate_data/.env
PERSISTENCE_DATA_PATH=/opt/weaviate_data/data
QUERY_DEFAULTS_LIMIT=25
CLUSTER_HOSTNAME=node1
CLUSTER_BIND_ADDR=127.0.0.1
CLUSTER_BASIC_AUTH_USERNAME=weaviate
CLUSTER_BASIC_AUTH_PASSWORD=$(random_password)
GRPC_PORT=50051
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=false
AUTHENTICATION_APIKEY_ENABLED=true
AUTHENTICATION_APIKEY_ALLOWED_KEYS=${var_api_key:-$(random_password 32)}
AUTHENTICATION_APIKEY_USERS=admin
AUTHENTICATION_DB_USERS_ENABLED=true
AUTHORIZATION_RBAC_ENABLED=true
AUTHORIZATION_RBAC_ROOT_USERS=admin
LIMIT_RESOURCES=true
GO_PROFILING_DISABLE=true
DISABLE_TELEMETRY=true
EOF
chmod 600 /opt/weaviate_data/.env
msg_ok "Configured Weaviate"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/weaviate.service
[Unit]
Description=Weaviate
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/weaviate_data
EnvironmentFile=/opt/weaviate_data/.env
ExecStart=/opt/weaviate/weaviate --host 0.0.0.0 --port 8080 --scheme http
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now weaviate
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc