Compare commits

...

21 Commits

Author SHA1 Message Date
github-actions[bot]
23f1131c50 Update CHANGELOG.md 2026-10-12 12:13:50 +00:00
community-scripts-pr-app[bot]
093d4edd4b Update CHANGELOG.md (#17883)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 12:03:18 +00:00
push-app-to-main[bot]
9bf6586611 WatchState (#17881)
* Add watchstate (ct)

* Clean up comments in watchstate.sh

Removed comments about version sorting and Redis cache namespacing.

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-10-12 14:02:50 +02:00
community-scripts-pr-app[bot]
e5148e07e0 Update CHANGELOG.md (#17878)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 08:00:57 +00:00
community-scripts-pr-app[bot]
718a3e4f52 Update CHANGELOG.md (#17877)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 08:00:41 +00:00
CanbiZ (MickLesk)
c91c0e6597 Immich Public Proxy: optional visitor upload service (#17875)
IPP 4.0 lets visitors upload through a second, optional app in the same
repository. The addon now builds the whole workspace, so upload-app is
always ready, and can run it as immich-proxy-upload on port 3001: asked
on install (var_ipp_uploads), offered in the menu of an existing
install, rebuilt and restarted on update with its config.json kept, and
removed on uninstall. It stays off unless chosen.
2026-10-12 10:00:25 +02:00
CanbiZ (MickLesk)
eb6382a399 Wanderer: bring back the wanderer-pb wrapper (#17874)
The path refactor in #16487 deleted the wrapper instead of pointing it
at the new layout, while the documented way to create the first
superuser is still wanderer-pb superuser upsert. Calling pocketbase
directly without --dir would quietly start an empty database. Install
the wrapper again, and write it on every update so containers set up
since then get it too.
2026-10-12 10:00:24 +02:00
CanbiZ (MickLesk)
e980d01cd6 Tracearr: install only the server's production dependencies (#17873)
pnpm 12.10 refuses a frozen install when the lockfile names apps/web but
that directory has no package.json, which is how the runtime tree is
built, so the update to 2.8.0 failed. Filter to @tracearr/server... the
way the upstream Dockerfile does, and copy assets/logo.png, which the
e-mail and newsletter code reads.
2026-10-12 10:00:21 +02:00
CanbiZ (MickLesk)
08a924a87a Paperless-ngx: convert glob ignore patterns, restart crashed services (#17812)
v3 compiles PAPERLESS_CONSUMER_IGNORE_PATTERNS as regex, so a v2 glob
like "*.tmp" kills the consumer on start and "._*" ignores every file.
The update now rewrites such globs to anchored regex instead of only
warning.

The four units had no Restart=, so an OOM kill during a large mail
import left the webserver and task queue down. Install sets
Restart=on-failure and the update adds it to existing units.
2026-10-12 10:00:14 +02:00
community-scripts-pr-app[bot]
169f8178d0 Update CHANGELOG.md (#17876)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 07:31:34 +00:00
Robert Castley
6f740aeccb Splunk Enterprise: start the service as the splunk user (#17816)
* Splunk Enterprise: start the service as the splunk user

Splunk Enterprise 10.2 rejects a root start, and the init boot script still launched splunkd as root.

* Ask for the Splunk terms on the Proxmox host

The installer runs under lxc-attach, which has no terminal, so read failed before the terms could be accepted.

* Restore the Splunk terms prompt to the install script

The prompt already runs where the keyboard is attached. The failed read came from launching the test through a pipe.

* Drop Splunk install comments and always start Splunkd
2026-10-12 09:31:04 +02:00
community-scripts-pr-app[bot]
691a8461f2 Update CHANGELOG.md (#17866)
Some checks failed
Create Changelog Pull Request / update-changelog-pull-request (push) Has been cancelled
Set state to is_deleted in pocketbase / delete-pocketbase-entry (push) Has been cancelled
Sync ct/install to Incus / dispatch (push) Has been cancelled
Update script timestamp on .sh changes / update-script-timestamp (push) Has been cancelled
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 14:16:28 +00:00
CanbiZ (MickLesk)
e0f72e3428 Immich: build libvips with JPEG 2000 support (#17864)
Only the libopenjp2-7 runtime was installed, so meson found no OpenJPEG
and libvips came out without jp2kload. Immich lists .jp2 as supported
and the upstream image builds against libopenjp2-7-dev. Install the
headers, and rebuild libvips on update when it lacks jp2kload, the way
ImageMagick is rebuilt when its LibRaw define is missing.
2026-10-11 16:16:06 +02:00
community-scripts-pr-app[bot]
57316cd66b Update CHANGELOG.md (#17865)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 14:15:13 +00:00
CanbiZ (MickLesk)
192834716e RustDesk Server: run the official server, make the web UI optional (#17854)
* RustDesk Server: run the official server, make the web UI optional

lejianwen/rustdesk-server has had no commit since 2025-09-01 and is 45
commits behind upstream, missing the UDP reflection/amplification and
mio security fixes. hbbs, hbbr and utils now come from
rustdesk/rustdesk-server; the packages and units are the same, so
existing installs upgrade in place and keep their keys.

lejianwen/rustdesk-api is unmaintained as well and becomes an opt-in
prompt. When chosen it is configured with this server's IP and key
instead of its 192.168.1.66 defaults, and Debian gets an admin password
like Alpine did. ~/rustdesk.creds now always holds the server key, and
the API is only updated where it is installed.

* RustDesk Server: answer the web UI prompt with var_rustdesk_api

yes or no skips the question, so unattended installs can choose; unset still asks.

* RustDesk Server: write the creds file with heredocs

Matches how the other install scripts write their creds; the file is unchanged.
2026-10-11 16:14:47 +02:00
CanbiZ (MickLesk)
3845cf97f7 Caddy: install the .deb from GitHub instead of the Cloudsmith repo (#17862)
* Caddy: install the .deb from GitHub instead of the Cloudsmith repo

Cloudsmith answered 402 Payment Required for two days once Caddy's
bandwidth quota ran out, and upstream expects it to happen again
(caddyserver/dist#142). Each GitHub release carries the identical
package (same SHA256), so Debian installs it from there now. The update
drops the Cloudsmith source, seeds ~/.caddy from the installed package
so nothing is reinstalled, and keeps a customised Caddyfile.

* Remove outdated comment from caddy.sh

---------

Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-10-11 16:14:44 +02:00
community-scripts-pr-app[bot]
fb82f7084a Update CHANGELOG.md (#17861)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 13:44:32 +00:00
CanbiZ (MickLesk)
7198d218be Let var_* answer the optional add-on prompts (#17858)
Thirty-six yes/no prompts for optional components in 26 install
scripts could only be answered at the terminal, so an unattended
install stopped at the first one. Each now takes var_<app>_<option>
first and still asks when it is unset. The four conditions that only
matched a single y now take yes as well, since that is what the website
sends.
2026-10-11 15:44:05 +02:00
community-scripts-pr-app[bot]
afdd1560ae Update CHANGELOG.md (#17860)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 13:37:59 +00:00
CanbiZ (MickLesk)
560bd81537 Confirm third-party installers through confirm_external_installer (#17857)
The thirteen install scripts and two update paths that run an external
installer each carried the same warning and y/N read. The core helper
does the same and also takes var_external_installer, so unattended
installs can answer it. Needs community-scripts/core
feat/confirm-external-installer merged first.
2026-10-11 15:37:33 +02:00
community-scripts-pr-app[bot]
33f516930b Update CHANGELOG.md (#17859)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-11 13:07:05 +00:00
55 changed files with 614 additions and 339 deletions

View File

@@ -562,6 +562,31 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-10-12
### 🆕 New Scripts
- WatchState ([#17881](https://github.com/community-scripts/ProxmoxVE/pull/17881))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Wanderer: bring back the wanderer-pb wrapper [@MickLesk](https://github.com/MickLesk) ([#17874](https://github.com/community-scripts/ProxmoxVE/pull/17874))
- Tracearr: install only the server's production dependencies [@MickLesk](https://github.com/MickLesk) ([#17873](https://github.com/community-scripts/ProxmoxVE/pull/17873))
- Paperless-ngx: QoL restart crashed services | patch regex [@MickLesk](https://github.com/MickLesk) ([#17812](https://github.com/community-scripts/ProxmoxVE/pull/17812))
- Splunk Enterprise: start the service as the splunk user [@rcastley](https://github.com/rcastley) ([#17816](https://github.com/community-scripts/ProxmoxVE/pull/17816))
### 💾 Core
- gh: curl_download: wait between attempts [@MickLesk](https://github.com/MickLesk) ([core#131](https://github.com/community-scripts/core/pull/131))
### 🧰 Tools
- #### ✨ New Features
- Immich Public Proxy: optional visitor upload service (v4 Release) [@MickLesk](https://github.com/MickLesk) ([#17875](https://github.com/community-scripts/ProxmoxVE/pull/17875))
## 2026-10-11
### 🆕 New Scripts
@@ -572,17 +597,26 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes
- Immich: build libvips with JPEG 2000 support [@MickLesk](https://github.com/MickLesk) ([#17864](https://github.com/community-scripts/ProxmoxVE/pull/17864))
- hermesagent: match the relaunched root gateway regardless of interpreter [@MickLesk](https://github.com/MickLesk) ([#17847](https://github.com/community-scripts/ProxmoxVE/pull/17847))
- Radicale: install the bcrypt and argon2 extras [@MickLesk](https://github.com/MickLesk) ([#17813](https://github.com/community-scripts/ProxmoxVE/pull/17813))
- fix(zigbee2mqtt): preserve backup stream and prevent filename collisions [@petermnt](https://github.com/petermnt) ([#17751](https://github.com/community-scripts/ProxmoxVE/pull/17751))
- #### ✨ New Features
- QoL: let var_* answer the optional add-on prompts [@MickLesk](https://github.com/MickLesk) ([#17858](https://github.com/community-scripts/ProxmoxVE/pull/17858))
- QoL: Confirm third-party installers through confirm_external_installer [@MickLesk](https://github.com/MickLesk) ([#17857](https://github.com/community-scripts/ProxmoxVE/pull/17857))
- docker: take the lxcfs toggle, TCP socket and Compose choice from app variables [@MickLesk](https://github.com/MickLesk) ([#17850](https://github.com/community-scripts/ProxmoxVE/pull/17850))
- #### 🔧 Refactor
- RustDesk Server: run the official server, make the web UI optional [@MickLesk](https://github.com/MickLesk) ([#17854](https://github.com/community-scripts/ProxmoxVE/pull/17854))
- Caddy: install the .deb from GitHub instead of the Cloudsmith repo [@MickLesk](https://github.com/MickLesk) ([#17862](https://github.com/community-scripts/ProxmoxVE/pull/17862))
### 💾 Core
- setup_docker: make LXC resource limits visible to nested containers [@andrebrait](https://github.com/andrebrait) ([core#9](https://github.com/community-scripts/core/pull/9))
- Add confirm_external_installer [@MickLesk](https://github.com/MickLesk) ([core#130](https://github.com/community-scripts/core/pull/130))
- setup_docker: make LXC resource limits visible to nested containers [@andrebrait](https://github.com/andrebrait) ([core#9](https://github.com/community-scripts/core/pull/9))
- Incus: fix ENABLE_FUSE / TUN vars [@MickLesk](https://github.com/MickLesk) ([core#127](https://github.com/community-scripts/core/pull/127))
- Resolve a uv required-version range to the newest release inside it [@MickLesk](https://github.com/MickLesk) ([core#126](https://github.com/community-scripts/core/pull/126))
- Upgrade MongoDB in place when an app package depends on it [@MickLesk](https://github.com/MickLesk) ([core#128](https://github.com/community-scripts/core/pull/128))

View File

@@ -38,11 +38,18 @@ update_deb_based() {
exit
fi
cleanup_old_repo_files "caddy"
msg_info "Updating Caddy LXC"
apt_update_safe
$STD apt upgrade -y
msg_ok "Updated Caddy LXC"
[[ -f ~/.caddy ]] || dpkg-query -W -f='${Version}' caddy >~/.caddy 2>/dev/null || true
if check_for_gh_release "caddy" "caddyserver/caddy"; then
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "caddy" "caddyserver/caddy" "binary" "latest" "/opt/caddy" "caddy_*_linux_$(arch_resolve).deb"
systemctl restart caddy
fi
if command -v xcaddy >/dev/null 2>&1; then
if check_for_gh_release "xcaddy" "caddyserver/xcaddy"; then
setup_go

View File

@@ -31,16 +31,7 @@ function update_script() {
exit
fi
msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ hermes update (https://hermes-agent.nousresearch.com/)"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://hermes-agent.nousresearch.com/" "hermes update (https://hermes-agent.nousresearch.com/)"
msg_info "Stopping Services"
systemctl stop hermes-dashboard

View File

@@ -106,7 +106,7 @@ EOF
libraries=("libjxl" "jpegli" "libheif" "libraw" "imagemagick" "libvips")
cd "$BASE_DIR"
msg_warn "Checking for updates to custom image-processing libraries (recompile time: 2-15min per library)"
ensure_dependencies liblcms2-dev libjpeg62-turbo-dev libspng-dev libexif-dev
ensure_dependencies liblcms2-dev libjpeg62-turbo-dev libspng-dev libexif-dev libopenjp2-7-dev
$STD git pull
for library in "${libraries[@]}"; do
compile_"$library"
@@ -565,7 +565,8 @@ function compile_imagemagick() {
function compile_libvips() {
SOURCE=$SOURCE_DIR/libvips
LIBVIPS_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)"
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]] ||
[[ "$(vips -l foreign 2>/dev/null)" != *jp2kload* ]]; then
msg_info "Recompiling libvips"
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"

View File

@@ -62,16 +62,7 @@ function update_script() {
msg_info "Updating Kasm"
cd /tmp
msg_warn "WARNING: This script will run an external installer from a third-party source (https://www.kasmweb.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ upgrade.sh inside tar.gz $KASM_URL"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://www.kasmweb.com/" "upgrade.sh inside tar.gz $KASM_URL"
curl_download "/tmp/kasm_release_${KASM_VERSION}.tar.gz" "$KASM_URL"
tar -xf "kasm_release_${KASM_VERSION}.tar.gz"
chmod +x /tmp/kasm_release/install.sh

View File

@@ -157,8 +157,6 @@ function update_script() {
sed -i '$a\PAPERLESS_ARCHIVE_FILE_GENERATION=never' "$PAPERLESS_CONF"
fi
fi
[[ -n "$(sed -n '/^PAPERLESS_CONSUMER_IGNORE_PATTERNS=/p' "$PAPERLESS_CONF")" ]] &&
msg_warn "PAPERLESS_CONSUMER_IGNORE_PATTERNS now uses regex patterns; please verify custom values."
[[ -n "$(sed -n '/^PAPERLESS_PRE_CONSUME_SCRIPT=/p;/^PAPERLESS_POST_CONSUME_SCRIPT=/p' "$PAPERLESS_CONF")" ]] &&
msg_warn "Pre/post consume scripts no longer receive positional arguments in v3; please verify custom scripts."
msg_ok "Migrated Paperless-ngx configuration"
@@ -172,7 +170,9 @@ function update_script() {
fi
for svc in consumer scheduler task-queue webserver; do
unit="/etc/systemd/system/paperless-${svc}.service"
[[ -f "$unit" ]] && sed -i 's|uv run -- |uv run --no-sync -- |g' "$unit"
[[ -f "$unit" ]] || continue
sed -i 's|uv run -- |uv run --no-sync -- |g' "$unit"
grep -q '^Restart=' "$unit" || sed -i '/^\[Service\]/a Restart=on-failure\nRestartSec=5' "$unit"
done
$STD systemctl daemon-reload
cd /opt/paperless
@@ -181,6 +181,34 @@ function update_script() {
$STD uv run -- python manage.py migrate
msg_ok "Updated Paperless-ngx"
if ((BRIDGE_UPDATE == 0)); then
IGNORE_FIXED="$(
/opt/paperless/.venv/bin/python - /opt/paperless/paperless.conf <<'EOF'
import json, re, sys
key = "PAPERLESS_CONSUMER_IGNORE_PATTERNS="
lines = open(sys.argv[1]).read().splitlines(True)
def is_glob(p):
if p.startswith("^") or p.endswith("$"):
return False
try:
return bool(re.search(p, "scan.pdf"))
except re.error:
return True
for i, line in enumerate(lines):
if line.startswith(key):
patterns = json.loads(line[len(key):].strip().strip("'"))
fixed = ["^" + re.escape(p).replace(r"\*", ".*").replace(r"\?", ".") + "$" if is_glob(p) else p for p in patterns]
if fixed != patterns:
lines[i] = key + json.dumps(fixed) + "\n"
print(json.dumps(fixed))
open(sys.argv[1], "w").writelines(lines)
EOF
)" || IGNORE_FIXED=""
[[ -n "$IGNORE_FIXED" ]] && msg_warn "Converted glob PAPERLESS_CONSUMER_IGNORE_PATTERNS to regex (required since v3): ${IGNORE_FIXED}"
fi
if ((BRIDGE_UPDATE == 0)) && [[ "$PAPERLESS_INSTALLED_VERSION" == "2.20.15" ]]; then
$STD apt -y purge libzbar0t64 libzbar0 2>/dev/null || true
$STD apt -y autoremove 2>/dev/null || true

View File

@@ -11,6 +11,7 @@ var_tags="${var_tags:-remote-desktop}"
var_cpu="${var_cpu:-1}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_rustdesk_api="${var_rustdesk_api:-}"
if [[ -z "${var_os:-}" ]] && command -v pveversion >/dev/null 2>&1; then
var_os=$(msg_menu "Choose the container OS" \
"debian" "Debian 13" \
@@ -38,25 +39,32 @@ update_deb_based() {
exit
fi
if check_for_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server"; then
msg_info "Stopping Service"
systemctl stop rustdesk-hbbr
systemctl stop rustdesk-hbbs
if [[ -f /lib/systemd/system/rustdesk-api.service ]]; then
systemctl stop rustdesk-api
fi
msg_ok "Stopped Service"
if check_for_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server"; then
msg_info "Stopping RustDesk Server"
systemctl stop rustdesk-hbbr rustdesk-hbbs
msg_ok "Stopped RustDesk Server"
fetch_and_deploy_gh_release "rustdesk-hbbr" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*$(arch_resolve).deb"
msg_info "Starting RustDesk Server"
systemctl start rustdesk-hbbs rustdesk-hbbr
msg_ok "Started RustDesk Server"
msg_ok "Updated RustDesk Server"
fi
if [[ -f /lib/systemd/system/rustdesk-api.service ]] && check_for_gh_release "rustdesk-api" "lejianwen/rustdesk-api"; then
msg_info "Stopping RustDesk API"
systemctl stop rustdesk-api
msg_ok "Stopped RustDesk API"
fetch_and_deploy_gh_release "rustdesk-hbbr" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-utils" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*$(arch_resolve).deb"
msg_info "Starting services"
systemctl start -q rustdesk-*
msg_ok "Services started"
msg_ok "Updated successfully!"
msg_info "Starting RustDesk API"
systemctl start rustdesk-api
msg_ok "Started RustDesk API"
msg_ok "Updated RustDesk API"
fi
}
@@ -66,21 +74,26 @@ update_alpine() {
exit
fi
if check_for_gh_release "rustdesk-server" "lejianwen/rustdesk-server"; then
msg_info "Updating Alpine Packages"
$STD apk -U upgrade
msg_ok "Updated Alpine Packages"
if check_for_gh_release "rustdesk-server" "rustdesk/rustdesk-server"; then
msg_info "Stopping RustDesk Server"
$STD apk -U upgrade
$STD service rustdesk-server-hbbs stop
$STD service rustdesk-server-hbbr stop
msg_ok "Stopped RustDesk Server"
fetch_and_deploy_gh_release "rustdesk-server" "lejianwen/rustdesk-server" "prebuild" "latest" "/opt/rustdesk-server" "rustdesk-server-linux-$(arch_resolve "amd64" "arm64v8").zip"
fetch_and_deploy_gh_release "rustdesk-server" "rustdesk/rustdesk-server" "prebuild" "latest" "/opt/rustdesk-server" "rustdesk-server-linux-$(arch_resolve "amd64" "arm64v8").zip"
msg_info "Starting RustDesk Server"
$STD service rustdesk-server-hbbs start
$STD service rustdesk-server-hbbr start
msg_ok "Started RustDesk Server"
msg_ok "Updated RustDesk Server"
fi
if check_for_gh_release "rustdesk-api" "lejianwen/rustdesk-api"; then
if [[ -x /opt/rustdesk-api/apimain ]] && check_for_gh_release "rustdesk-api" "lejianwen/rustdesk-api"; then
msg_info "Stopping RustDesk API"
$STD service rustdesk-api stop
msg_ok "Stopped RustDesk API"
@@ -90,8 +103,8 @@ update_alpine() {
msg_info "Starting RustDesk API"
$STD service rustdesk-api start
msg_ok "Started RustDesk API"
msg_ok "Updated RustDesk API"
fi
msg_ok "Updated successfully!"
}
function update_script() {
@@ -107,5 +120,7 @@ description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:21114${CL}"
echo -e "${INFO}${YW}Set this as ID server in the RustDesk client, the key is in ~/rustdesk.creds:${CL}"
echo -e "${GATEWAY}${BGN}${IP}${CL}"
echo -e "${INFO}${YW}Web UI, if selected during setup:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:21114/_admin/${CL}"

View File

@@ -125,7 +125,7 @@ EOF
$STD ./scripts/fetch-basemap.sh || msg_warn "Basemap download failed, keeping the existing map"
[[ -d /opt/tracearr/data ]] && mv /opt/tracearr/data /opt/tracearr.data
rm -rf /opt/tracearr
mkdir -p /opt/tracearr/{packages/shared,packages/emails,apps/server,apps/web,apps/server/src/db}
mkdir -p /opt/tracearr/{packages/shared,packages/emails,apps/server,apps/web,apps/server/src/db,assets}
cp -rf package.json /opt/tracearr/
cp -rf pnpm-workspace.yaml /opt/tracearr/
cp -rf pnpm-lock.yaml /opt/tracearr/
@@ -138,13 +138,14 @@ EOF
cp -rf packages/emails/package.json /opt/tracearr/packages/emails/
cp -rf packages/emails/dist /opt/tracearr/packages/emails/dist
cp -rf apps/server/src/db/migrations /opt/tracearr/apps/server/src/db/migrations
cp -f assets/logo.png /opt/tracearr/assets/
[[ -d /opt/tracearr.data ]] && mv /opt/tracearr.data /opt/tracearr/data
mkdir -p /opt/tracearr/data
cp -rf data/. /opt/tracearr/data/
mkdir -p /opt/tracearr/data/image-cache
rm -rf /opt/tracearr.build
cd /opt/tracearr
$STD pnpm install --prod --frozen-lockfile --ignore-scripts
$STD pnpm install --prod --frozen-lockfile --ignore-scripts --filter @tracearr/server...
$STD chown -R tracearr:tracearr /opt/tracearr
msg_ok "Built Tracearr"

View File

@@ -100,7 +100,6 @@ EOF
-e "s|^MEILI_DB_PATH=.*|MEILI_DB_PATH=/opt/wanderer_data/meili_data|" \
/opt/wanderer/.env
sed -i "s|^db_path =.*|db_path = \"/opt/wanderer_data/meili_data\"|" /etc/meilisearch.toml
rm -f /usr/local/bin/wanderer-pb
cat <<EOF >/etc/systemd/system/wanderer-pocketbase.service
[Unit]
@@ -155,6 +154,16 @@ EOF
msg_ok "Added POCKETBASE_PROXY_SECRET"
fi
cat <<'EOF' >/usr/local/bin/wanderer-pb
#!/usr/bin/env bash
set -a
source /opt/wanderer/.env
set +a
cd /opt/wanderer/db
exec ./pocketbase "$@" --dir="$PB_DB_LOCATION"
EOF
chmod +x /usr/local/bin/wanderer-pb
if [[ -f /opt/wanderer_data/plugins/plugin.json ]]; then
msg_info "Reinstalling wanderer plugins, one directory each"
find /opt/wanderer_data/plugins -maxdepth 1 -type f -delete

77
ct/watchstate.sh Normal file
View File

@@ -0,0 +1,77 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/arabcoders/watchstate
APP="WatchState"
var_tags="${var_tags:-media;plex;jellyfin;emby}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/watchstate ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "watchstate" "arabcoders/watchstate" "" "" "v"; then
msg_info "Stopping WatchState"
systemctl stop watchstate-worker php8.5-fpm
msg_ok "Stopped WatchState"
create_backup /opt/watchstate/.env
setup_composer
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "watchstate" "arabcoders/watchstate" "tarball" "latest" "/opt/watchstate" "" "v"
restore_backup
msg_info "Building WatchState"
cd /opt/watchstate
sed -i "s/'version' => 'dev-master'/'version' => 'v$(cat ~/.watchstate)'/" config/config.php
$STD composer install --no-dev --optimize-autoloader --no-interaction
cd /opt/watchstate/frontend
$STD bun install --frozen-lockfile --production
NODE_ENV=production $STD bun run generate
mv /opt/watchstate/frontend/exported /opt/watchstate/public/exported
rm -rf /opt/watchstate/frontend/node_modules /opt/watchstate/frontend/.nuxt
msg_ok "Built WatchState"
msg_info "Migrating WatchState Database"
$STD php /opt/watchstate/bin/console db:migrate --execute
$STD php /opt/watchstate/bin/console db:index
chown -R www-data:www-data /opt/watchstate_data
msg_ok "Migrated WatchState Database"
msg_info "Starting WatchState"
systemctl start php8.5-fpm watchstate-worker
msg_ok "Started WatchState"
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}"

View File

@@ -17,7 +17,8 @@ msg_info "Installing Aria2"
$STD apt install -y aria2
msg_ok "Installed Aria2"
read -r -p "${TAB3}Would you like to add AriaNG? <y/N> " prompt
prompt="${var_aria2_ariang:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add AriaNG? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Dependencies"
$STD apt install -y nginx

View File

@@ -20,16 +20,7 @@ $STD apt install -y \
msg_ok "Installed Dependencies"
RELEASE=$(get_latest_github_release "bunkerity/bunkerweb")
msg_warn "WARNING: This script will run an external installer from a third-party source (install-bunkerweb.sh)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://github.com/bunkerity/bunkerweb/raw/v${RELEASE}/misc/install-bunkerweb.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "install-bunkerweb.sh" "https://github.com/bunkerity/bunkerweb/raw/v${RELEASE}/misc/install-bunkerweb.sh"
msg_info "Installing BunkerWeb (Patience)"
curl -fsSL -o install-bunkerweb.sh "https://github.com/bunkerity/bunkerweb/raw/v${RELEASE}/misc/install-bunkerweb.sh"
chmod +x install-bunkerweb.sh

View File

@@ -24,7 +24,8 @@ cd /opt/bytestash/client
$STD npm install
msg_ok "Installed ByteStash"
read -rp "${TAB3}Do you want to allow registration of multiple accounts? [y/n]: " allowreg
allowreg="${var_bytestash_registration:-}"
[[ -n "$allowreg" ]] || read -rp "${TAB3}Do you want to allow registration of multiple accounts? [y/n]: " allowreg
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/bytestash-backend.service
@@ -42,7 +43,7 @@ Environment=JWT_SECRET=$JWT_SECRET
WantedBy=multi-user.target
EOF
if [[ "$allowreg" =~ ^[Yy]$ ]]; then
if [[ "${allowreg,,}" =~ ^(y|yes)$ ]]; then
sed -i '8i\Environment=ALLOW_NEW_ACCOUNTS=true' /etc/systemd/system/bytestash-backend.service
fi

View File

@@ -14,23 +14,11 @@ network_check
update_os
setup_deb_based() {
msg_info "Installing Dependencies"
$STD apt install -y \
debian-keyring \
debian-archive-keyring \
apt-transport-https
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "caddy" "caddyserver/caddy" "binary" "latest" "/opt/caddy" "caddy_*_linux_$(arch_resolve).deb"
systemctl enable -q --now caddy
msg_info "Installing Caddy"
setup_deb822_repo \
"caddy" \
"https://dl.cloudsmith.io/public/caddy/stable/gpg.key" \
"https://dl.cloudsmith.io/public/caddy/stable/deb/debian" \
"any-version"
$STD apt install -y caddy
msg_ok "Installed Caddy"
read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt
prompt="${var_caddy_xcaddy:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
setup_go
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
@@ -75,7 +63,8 @@ EOF
EOF
msg_ok "Installed Caddy"
read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt
prompt="${var_caddy_xcaddy:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
GO_VERSION="$(curl -fsSL https://go.dev/VERSION?m=text | head -1 | cut -c3-)" setup_go
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "prebuild" "latest" "/opt/xcaddy" "xcaddy_*_linux_$(arch_resolve).tar.gz"

View File

@@ -13,16 +13,7 @@ setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://casaos.zimaspace.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://get.casaos.io/"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://casaos.zimaspace.com/" "https://get.casaos.io/"
msg_info "Installing CasaOS (Patience)"
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p $(dirname $DOCKER_CONFIG_PATH)

View File

@@ -19,16 +19,7 @@ $STD apt install -y \
xvfb
msg_ok "Installed Dependencies"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://getchannels.com)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://getchannels.com/dvr/setup.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://getchannels.com" "https://getchannels.com/dvr/setup.sh"
setup_hwaccel

View File

@@ -31,7 +31,10 @@ sed -i "s/root//g" /etc/cockpit/disallowed-users
msg_ok "Installed Cockpit"
# 45Drives only publishes amd64 packages
[[ "$(arch_resolve)" == "arm64" ]] || read -r -p "Would you like to install 45Drives' cockpit-file-sharing, cockpit-identities, and cockpit-navigator <y/N> " prompt
if [[ "$(arch_resolve)" != "arm64" ]]; then
prompt="${var_cockpit_45drives:-}"
[[ -n "$prompt" ]] || read -r -p "Would you like to install 45Drives' cockpit-file-sharing, cockpit-identities, and cockpit-navigator <y/N> " prompt
fi
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing 45Drives' cockpit extensions"
setup_deb822_repo "45drives" \

View File

@@ -19,14 +19,15 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
read -rp "${TAB3}Install OnlyOffice components instead of CKEditor? (Y/N): " onlyoffice
onlyoffice="${var_cryptpad_onlyoffice:-}"
[[ -n "$onlyoffice" ]] || read -rp "${TAB3}Install OnlyOffice components instead of CKEditor? (Y/N): " onlyoffice
fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad" "tarball"
msg_info "Setup CryptPad"
cd /opt/cryptpad
$STD npm ci --allow-git=all
$STD npm run install:components
if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then
if [[ "${onlyoffice,,}" =~ ^(y|yes)$ ]]; then
$STD bash -c "./install-onlyoffice.sh --accept-license"
fi
cp config/config.example.js config/config.js

View File

@@ -38,7 +38,8 @@ rm -f "$DEB_FILE"
echo "$LATEST_VERSION" >~/.emqx
msg_ok "Installed EMQX"
read -r -p "${TAB3}Would you like to disable the EMQX MQ feature? (reduces disk/CPU usage) <y/N> " prompt
prompt="${var_emqx_disable_mq:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to disable the EMQX MQ feature? (reduces disk/CPU usage) <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Disabling EMQX MQ feature"
mkdir -p /etc/emqx

View File

@@ -15,7 +15,8 @@ update_os
fetch_and_deploy_gh_release "headscale" "juanfont/headscale" "binary"
read -r -p "${TAB3}Would you like to add headscale-admin UI? <y/N> " prompt
prompt="${var_headscale_admin:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add headscale-admin UI? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
fetch_and_deploy_gh_release "headscale-admin" "GoodiesHQ/headscale-admin" "prebuild" "latest" "/opt/headscale-admin" "admin.zip"

View File

@@ -33,16 +33,7 @@ NODE_OPTIONS=${NODE_OPTIONS}
EOF
msg_ok "Configured Service Environment"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://hermes-agent.nousresearch.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://hermes-agent.nousresearch.com/install.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://hermes-agent.nousresearch.com/" "https://hermes-agent.nousresearch.com/install.sh"
msg_info "Installing Hermes Agent"
curl -fsSL https://hermes-agent.nousresearch.com/install.sh -o /tmp/hermes-install.sh

View File

@@ -84,6 +84,7 @@ $STD apt install --no-install-recommends -y \
liblqr-1-0 \
libltdl7 \
libopenjp2-7 \
libopenjp2-7-dev \
meson \
ninja-build \
pkg-config \

View File

@@ -50,7 +50,8 @@ else
fi
msg_ok "Installed InfluxDB"
read -r -p "${TAB3}Would you like to add Telegraf? <y/N> " prompt
prompt="${var_influxdb_telegraf:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Telegraf? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing Telegraf"
$STD apt install -y telegraf

View File

@@ -17,16 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y ca-certificates
msg_ok "Installed Dependencies"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://iobroker.net/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://iobroker.net/install.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://iobroker.net/" "https://iobroker.net/install.sh"
NODE_VERSION="24" NPM_VERSION="11" setup_nodejs

View File

@@ -56,16 +56,7 @@ if [[ -z "$KASM_VERSION" ]] || [[ -z "$KASM_URL" ]]; then
fi
msg_ok "Detected Kasm Workspaces version $KASM_VERSION"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://www.kasmweb.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ install.sh inside tar.gz $KASM_URL"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://www.kasmweb.com/" "install.sh inside tar.gz $KASM_URL"
msg_info "Installing Kasm Workspaces"
curl_download "/opt/kasm_release_${KASM_VERSION}.tar.gz" "$KASM_URL"

View File

@@ -24,7 +24,8 @@ PG_VERSION="16" setup_postgresql
RUST_CRATES="monolith" setup_rust
PG_DB_NAME="linkwardendb" PG_DB_USER="linkwarden" setup_postgresql_db
read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
prompt="${var_linkwarden_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
setup_adminer
fi

View File

@@ -28,16 +28,7 @@ export HOME=/opt/livebook
$STD adduser --system --group --home /opt/livebook --shell /bin/bash livebook
msg_ok "Created livebook user"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://elixir-lang.org)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://elixir-lang.org/install.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://elixir-lang.org" "https://elixir-lang.org/install.sh"
curl -fsSO https://elixir-lang.org/install.sh
$STD sh install.sh elixir@latest otp@latest

View File

@@ -21,7 +21,8 @@ setup_deb_based() {
sed -i 's/^bind-address/#bind-address/g' /etc/mysql/mariadb.conf.d/50-server.cnf
msg_ok "Setup MariaDB"
read -r -p "${TAB3}Would you like to add PhpMyAdmin? <y/N> " prompt
prompt="${var_mariadb_phpmyadmin:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add PhpMyAdmin? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing phpMyAdmin"
$STD apt install -y \
@@ -58,7 +59,8 @@ setup_alpine() {
$STD rc-service mariadb start
msg_ok "MariaDB Configured"
read -r -p "${TAB3}Would you like to install Adminer with lighttpd? <y/N>: " prompt
prompt="${var_mariadb_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install Adminer with lighttpd? <y/N>: " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Adminer and dependencies"
$STD apk add --no-cache \

View File

@@ -13,16 +13,7 @@ setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://mattermost.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://deb.packages.mattermost.com/repo-setup.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://mattermost.com/" "https://deb.packages.mattermost.com/repo-setup.sh"
PG_VERSION="16" setup_postgresql

View File

@@ -15,7 +15,8 @@ update_os
MEILISEARCH_BIND="0.0.0.0:7700" setup_meilisearch
read -r -p "${TAB3}Do you want add meilisearch-ui? [y/n]: " prompt
prompt="${var_meilisearch_ui:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Do you want add meilisearch-ui? [y/n]: " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
NODE_VERSION="22" NODE_MODULE="pnpm@latest" setup_nodejs
fetch_and_deploy_gh_release "meilisearch-ui" "riccox/meilisearch-ui" "tarball"

View File

@@ -13,16 +13,7 @@ setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://nextcloudpi.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://nextcloudpi.com/" "https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh"
msg_info "Making ssh.service reloads behave like restarts"
mkdir -p /etc/systemd/system/ssh.service.d

View File

@@ -26,7 +26,8 @@ setup_hwaccel
PYTHON_VERSION="3.12" setup_uv
OTEL_ARGS=()
read -r -p "${TAB3}Would you like to install OpenTelemetry instrumentation packages (requires manual .env configuration)? <y/N> " prompt
prompt="${var_openwebui_otel:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install OpenTelemetry instrumentation packages (requires manual .env configuration)? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
for pkg in \
opentelemetry-api \
@@ -52,7 +53,8 @@ for attempt in $(seq 1 3); do
done
msg_ok "Installed Open WebUI"
read -r -p "${TAB3}Would you like to add Ollama? <y/N> " prompt
prompt="${var_openwebui_ollama:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Ollama? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
if [[ "$(arch_resolve)" == "amd64" ]]; then
msg_info "Setting up Intel® Repositories"

View File

@@ -109,6 +109,8 @@ Requires=redis.service
[Service]
WorkingDirectory=/opt/paperless/src
ExecStart=uv run --no-sync -- celery --app paperless beat --loglevel INFO
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
@@ -123,6 +125,8 @@ After=postgresql.service
[Service]
WorkingDirectory=/opt/paperless/src
ExecStart=uv run --no-sync -- celery --app paperless worker --loglevel INFO
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
@@ -137,6 +141,8 @@ Requires=redis.service
WorkingDirectory=/opt/paperless/src
ExecStartPre=/bin/sleep 2
ExecStart=uv run --no-sync -- python manage.py document_consumer
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
@@ -153,6 +159,8 @@ Requires=redis.service
WorkingDirectory=/opt/paperless/src
#ExecStartPre=uv run --no-sync -- python manage.py document_index reindex --if-needed --no-progress-bar
ExecStart=uv run --no-sync -- granian --interface asginl --ws --loop uvloop "paperless.asgi:application"
Restart=on-failure
RestartSec=5
Environment=GRANIAN_HOST=::
Environment=GRANIAN_PORT=8000
Environment=GRANIAN_WORKERS=1
@@ -163,7 +171,8 @@ EOF
systemctl enable -q --now paperless-webserver paperless-scheduler paperless-task-queue paperless-consumer
msg_ok "Created Services"
read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
prompt="${var_paperless_ngx_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
setup_adminer
fi

View File

@@ -13,16 +13,7 @@ setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://pi-hole.net/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://install.pi-hole.net"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://pi-hole.net/" "https://install.pi-hole.net"
msg_info "Installing Dependencies"
$STD apt install -y ufw
@@ -65,9 +56,11 @@ $STD pihole-FTL --config ntp.sync.interval 0
systemctl restart pihole-FTL.service
msg_ok "Installed Pi-hole"
read -r -p "${TAB3}Would you like to add Unbound? <y/N> " prompt
prompt="${var_pihole_unbound:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Unbound? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
read -r -p "${TAB3}Unbound is configured as a recursive DNS server by default, would you like it to be configured as a forwarding DNS server (using DNS-over-TLS (DoT)) instead? <y/N> " prompt
prompt="${var_pihole_unbound_dot:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Unbound is configured as a recursive DNS server by default, would you like it to be configured as a forwarding DNS server (using DNS-over-TLS (DoT)) instead? <y/N> " prompt
msg_info "Installing Unbound"
mkdir -p /etc/unbound/unbound.conf.d
cat <<EOF >/etc/unbound/unbound.conf.d/pi-hole.conf

View File

@@ -48,7 +48,8 @@ msg_ok "Installed Podman"
mkdir -p /etc/containers/systemd
read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
prompt="${var_podman_homeassistant_portainer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"
podman volume create portainer_data >/dev/null
@@ -75,7 +76,8 @@ EOF
$STD systemctl start portainer
msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION"
else
read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
prompt="${var_podman_homeassistant_portainer_agent:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION"
cat <<EOF >/etc/containers/systemd/portainer-agent.container

View File

@@ -48,7 +48,8 @@ msg_ok "Installed Podman"
mkdir -p /etc/containers/systemd
read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
prompt="${var_podman_portainer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer $PORTAINER_LATEST_VERSION"
podman volume create portainer_data >/dev/null
@@ -76,7 +77,8 @@ EOF
$STD systemctl start portainer
msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION"
else
read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
prompt="${var_podman_portainer_agent:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add the Portainer Agent? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Portainer agent $PORTAINER_AGENT_LATEST_VERSION"
$STD podman pull docker.io/portainer/agent:latest

View File

@@ -124,7 +124,8 @@ EOF
systemctl restart postgresql
msg_ok "Installed PostgreSQL"
read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
prompt="${var_postgresql_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Adminer? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing Adminer"
$STD apt install -y adminer
@@ -158,7 +159,8 @@ setup_alpine() {
$STD rc-service postgresql restart
msg_ok "Configured and Restarted PostgreSQL"
read -r -p "${TAB3}Would you like to install Adminer with lighttpd? <y/N>: " prompt
prompt="${var_postgresql_adminer:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install Adminer with lighttpd? <y/N>: " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Adminer and dependencies"
$STD apk add --no-cache \

View File

@@ -13,108 +13,126 @@ setting_up_container
network_check
update_os
if [[ -n "${var_rustdesk_api:-}" ]]; then
prompt="$var_rustdesk_api"
else
read -r -p "${TAB3}Would you like to add the RustDesk API web UI (lejianwen/rustdesk-api, unmaintained since 09/2025)? <y/N> " prompt
fi
INSTALL_API=0
[[ "${prompt,,}" =~ ^(y|yes|true)$ ]] && INSTALL_API=1
API_PASS="$(random_password 16)"
# rustdesk-api hands these to clients; its shipped defaults point at 192.168.1.66
api_env() {
printf '%s\n' \
"RUSTDESK_API_RUSTDESK_ID_SERVER=${LOCAL_IP}:21116" \
"RUSTDESK_API_RUSTDESK_RELAY_SERVER=${LOCAL_IP}:21117" \
"RUSTDESK_API_RUSTDESK_API_SERVER=http://${LOCAL_IP}:21114" \
"RUSTDESK_API_RUSTDESK_KEY_FILE=$1"
}
# hbbs creates its key pair in its working directory on first start
write_creds() {
local key_file="$1"
for _ in $(seq 1 30); do
[[ -s "$key_file" ]] && break
sleep 1
done
if [[ ! -s "$key_file" ]]; then
msg_error "hbbs did not create ${key_file}"
exit 1
fi
cat <<EOF >~/rustdesk.creds
RustDesk Server
ID Server: ${LOCAL_IP}
Key: $(<"$key_file")
EOF
if ((INSTALL_API)); then
cat <<EOF >>~/rustdesk.creds
RustDesk API Web UI: http://${LOCAL_IP}:21114/_admin/
Username: admin
Password: ${API_PASS}
EOF
fi
}
setup_deb_based() {
fetch_and_deploy_gh_release "rustdesk-hbbr" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-hbbs" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-utils" "lejianwen/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*$(arch_resolve).deb"
systemctl enable -q --now rustdesk-hbbr
systemctl enable -q --now rustdesk-hbbs
systemctl enable -q --now rustdesk-api
fetch_and_deploy_gh_release "rustdesk-hbbr" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbr*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-hbbs" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-hbbs*$(arch_resolve).deb"
fetch_and_deploy_gh_release "rustdesk-utils" "rustdesk/rustdesk-server" "binary" "latest" "/opt/rustdesk" "rustdesk-server-utils*$(arch_resolve).deb"
systemctl enable -q --now rustdesk-hbbs rustdesk-hbbr
write_creds /var/lib/rustdesk-server/id_ed25519.pub
if ((INSTALL_API)); then
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "binary" "latest" "/opt/rustdesk" "rustdesk-api-server*$(arch_resolve).deb"
msg_info "Configuring RustDesk API"
mkdir -p /etc/systemd/system/rustdesk-api.service.d
{
echo "[Service]"
api_env /var/lib/rustdesk-server/id_ed25519.pub | sed 's/^/Environment=/'
} >/etc/systemd/system/rustdesk-api.service.d/override.conf
systemctl daemon-reload
systemctl stop rustdesk-api
cd /var/lib/rustdesk-api
$STD rustdesk-api reset-admin-pwd "$API_PASS"
systemctl enable -q --now rustdesk-api
msg_ok "Configured RustDesk API"
fi
}
setup_alpine() {
fetch_and_deploy_gh_release "rustdesk-server" "lejianwen/rustdesk-server" "prebuild" "latest" "/opt/rustdesk-server" "rustdesk-server-linux-$(arch_resolve "amd64" "arm64v8").zip"
fetch_and_deploy_gh_release "rustdesk-server" "rustdesk/rustdesk-server" "prebuild" "latest" "/opt/rustdesk-server" "rustdesk-server-linux-$(arch_resolve "amd64" "arm64v8").zip"
msg_info "Configuring RustDesk Server"
mkdir -p /root/.config/rustdesk
cd /opt/rustdesk-server
./rustdesk-utils genkeypair >/tmp/rustdesk_keys.txt
grep "Public Key" /tmp/rustdesk_keys.txt | awk '{print $3}' >/root/.config/rustdesk/id_ed25519.pub
grep "Secret Key" /tmp/rustdesk_keys.txt | awk '{print $3}' >/root/.config/rustdesk/id_ed25519
chmod 600 /root/.config/rustdesk/id_ed25519
chmod 644 /root/.config/rustdesk/id_ed25519.pub
rm /tmp/rustdesk_keys.txt
msg_ok "Configured RustDesk Server"
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "prebuild" "latest" "/opt/rustdesk-api" "linux-$(arch_resolve).tar.gz"
msg_info "Configuring RustDesk API"
cd /opt/rustdesk-api
ADMINPASS=$(head -c 16 /dev/urandom | xxd -p -c 16)
$STD ./apimain reset-admin-pwd "$ADMINPASS"
cat <<EOF >~/rustdesk.creds
RustDesk WebUI
Username: admin
Password: $ADMINPASS
EOF
msg_ok "Configured RustDesk API"
msg_info "Enabling RustDesk Server Services"
cat <<EOF >/etc/init.d/rustdesk-server-hbbs
msg_info "Creating RustDesk Server Services"
for svc in hbbs hbbr; do
cat <<EOF >"/etc/init.d/rustdesk-server-${svc}"
#!/sbin/openrc-run
description="RustDesk HBBS Service"
description="RustDesk ${svc^^} Service"
directory="/opt/rustdesk-server"
command="/opt/rustdesk-server/hbbs"
command_args=""
command="/opt/rustdesk-server/${svc}"
command_background="true"
command_user="root"
pidfile="/var/run/rustdesk-server-hbbs.pid"
output_log="/var/log/rustdesk-hbbs.log"
error_log="/var/log/rustdesk-hbbs.err"
pidfile="/var/run/rustdesk-server-${svc}.pid"
output_log="/var/log/rustdesk-${svc}.log"
error_log="/var/log/rustdesk-${svc}.err"
depend() {
use net
}
EOF
chmod +x "/etc/init.d/rustdesk-server-${svc}"
$STD rc-update add "rustdesk-server-${svc}" default
$STD service "rustdesk-server-${svc}" start
done
msg_ok "Created RustDesk Server Services"
write_creds /opt/rustdesk-server/id_ed25519.pub
cat <<EOF >/etc/init.d/rustdesk-server-hbbr
#!/sbin/openrc-run
description="RustDesk HBBR Service"
directory="/opt/rustdesk-server"
command="/opt/rustdesk-server/hbbr"
command_args=""
command_background="true"
command_user="root"
pidfile="/var/run/rustdesk-server-hbbr.pid"
output_log="/var/log/rustdesk-hbbr.log"
error_log="/var/log/rustdesk-hbbr.err"
depend() {
use net
}
EOF
cat <<EOF >/etc/init.d/rustdesk-api
if ((INSTALL_API)); then
fetch_and_deploy_gh_release "rustdesk-api" "lejianwen/rustdesk-api" "prebuild" "latest" "/opt/rustdesk-api" "linux-$(arch_resolve).tar.gz"
msg_info "Configuring RustDesk API"
api_env /opt/rustdesk-server/id_ed25519.pub | sed 's/^/export /' >/etc/conf.d/rustdesk-api
cd /opt/rustdesk-api
$STD ./apimain reset-admin-pwd "$API_PASS"
cat <<EOF >/etc/init.d/rustdesk-api
#!/sbin/openrc-run
description="RustDesk API Service"
directory="/opt/rustdesk-api"
command="/opt/rustdesk-api/apimain"
command_args=""
command_background="true"
command_user="root"
pidfile="/var/run/rustdesk-api.pid"
output_log="/var/log/rustdesk-api.log"
error_log="/var/log/rustdesk-api.err"
depend() {
use net
after rustdesk-server-hbbs
}
EOF
chmod +x /etc/init.d/rustdesk-server-hbbs
chmod +x /etc/init.d/rustdesk-server-hbbr
chmod +x /etc/init.d/rustdesk-api
$STD rc-update add rustdesk-server-hbbs default
$STD rc-update add rustdesk-server-hbbr default
$STD rc-update add rustdesk-api default
msg_ok "Enabled RustDesk Server Services"
msg_info "Starting RustDesk Server"
$STD service rustdesk-server-hbbs start
$STD service rustdesk-server-hbbr start
$STD service rustdesk-api start
msg_ok "Started RustDesk Server"
chmod +x /etc/init.d/rustdesk-api
$STD rc-update add rustdesk-api default
$STD service rustdesk-api start
msg_ok "Configured RustDesk API"
fi
}
run_os_setup

View File

@@ -40,7 +40,8 @@ $STD uv venv --clear /opt/sabnzbd/venv
$STD uv pip install -r /opt/sabnzbd/requirements.txt --python=/opt/sabnzbd/venv/bin/python
msg_ok "Installed SABnzbd"
read -r -p "Would you like to install par2cmdline-turbo? <y/N> " prompt
prompt="${var_sabnzbd_par2_turbo:-}"
[[ -n "$prompt" ]] || read -r -p "Would you like to install par2cmdline-turbo? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
mv /usr/bin/par2 /usr/bin/par2.old
fetch_and_deploy_gh_release "par2cmdline-turbo" "animetosho/par2cmdline-turbo" "prebuild" "latest" "/usr/bin/" "*-linux-$(arch_resolve).zip"

View File

@@ -17,7 +17,8 @@ fetch_and_deploy_gh_release "silverbullet" "silverbulletmd/silverbullet" "prebui
mkdir -p /opt/silverbullet/space
RUNTIME_API_ENV=""
read -rp "${TAB3}Enable Silverbullet Runtime API? Requires Chromium (~700MB). Uses ~200MB extra RAM. (y/N): " runtime_api_prompt
runtime_api_prompt="${var_silverbullet_runtime_api:-}"
[[ -n "$runtime_api_prompt" ]] || read -rp "${TAB3}Enable Silverbullet Runtime API? Requires Chromium (~700MB). Uses ~200MB extra RAM. (y/N): " runtime_api_prompt
if [[ "${runtime_api_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing Chromium for Runtime API"
$STD apt install -y chromium

View File

@@ -36,7 +36,8 @@ sed -i \
-e 's/^.*picture/#&/' /opt/slskd/config/slskd.yml
msg_ok "Configured Slskd"
read -rp "${TAB3}Do you want to install Soularr? y/N " soularr
soularr="${var_slskd_soularr:-}"
[[ -n "$soularr" ]] || read -rp "${TAB3}Do you want to install Soularr? y/N " soularr
if [[ ${soularr,,} =~ ^(y|yes)$ ]]; then
PYTHON_VERSION="3.11" setup_uv
fetch_and_deploy_gh_release "Soularr" "mrusse/soularr" "tarball" "latest" "/opt/soularr"

View File

@@ -51,8 +51,8 @@ $STD curl -fsSL -o "splunk-enterprise.tgz" "$DOWNLOAD_URL" || {
}
$STD tar -xzf "splunk-enterprise.tgz" -C /opt
rm -f "splunk-enterprise.tgz"
addgroup --system splunk
adduser --system --home /opt/splunk --shell /bin/bash --ingroup splunk --no-create-home splunk
$STD addgroup --system splunk
$STD adduser --system --home /opt/splunk --shell /bin/bash --ingroup splunk --no-create-home splunk
chown -R splunk:splunk /opt/splunk
msg_ok "Setup Splunk Enterprise v${RELEASE}"
@@ -64,17 +64,35 @@ Splunk-Credentials
Username: $ADMIN_USER
Password: $ADMIN_PASS
EOF
chmod 600 ~/splunk.creds
cat <<EOF >"/opt/splunk/etc/system/local/user-seed.conf"
install -d -o splunk -g splunk -m 755 /opt/splunk/etc/system/local
cat <<EOF >/opt/splunk/etc/system/local/user-seed.conf
[user_info]
USERNAME = $ADMIN_USER
PASSWORD = $ADMIN_PASS
EOF
chown splunk:splunk /opt/splunk/etc/system/local/user-seed.conf
chmod 600 /opt/splunk/etc/system/local/user-seed.conf
if ! grep -q '^SPLUNK_OS_USER=' /opt/splunk/etc/splunk-launch.conf; then
echo 'SPLUNK_OS_USER=splunk' >>/opt/splunk/etc/splunk-launch.conf
fi
chown splunk:splunk /opt/splunk/etc/splunk-launch.conf
msg_ok "Created Splunk admin user"
msg_info "Starting Service"
$STD sudo -u splunk /opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt
$STD /opt/splunk/bin/splunk enable boot-start -user splunk
$STD sudo -H -u splunk /opt/splunk/bin/splunk start --accept-license --answer-yes --no-prompt
$STD sudo -H -u splunk /opt/splunk/bin/splunk stop --answer-yes --no-prompt
$STD /opt/splunk/bin/splunk enable boot-start \
-systemd-managed 1 \
-user splunk \
-group splunk \
--accept-license \
--answer-yes \
--no-prompt
chown -R splunk:splunk /opt/splunk
$STD systemctl daemon-reload
$STD systemctl enable --now Splunkd
msg_ok "Started Service"
motd_ssh

View File

@@ -34,7 +34,8 @@ msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
JAVA_VERSION="25" setup_java
if ! read -r -p "${TAB3}Do you want to use Stirling-PDF with Login? (no/n = without Login) [Y/n] " response; then
response="${var_stirling_pdf_login:-}"
if [[ -z "$response" ]] && ! read -r -p "${TAB3}Do you want to use Stirling-PDF with Login? (no/n = without Login) [Y/n] " response; then
# No interactive stdin (EOF): fall back to the no-login install instead of
# silently selecting login, which the -z test below would otherwise do.
response="n"

View File

@@ -68,7 +68,7 @@ $STD pnpm install --frozen-lockfile --force
$STD pnpm turbo telemetry disable
$STD pnpm turbo run build --no-daemon --filter=@tracearr/shared --filter=@tracearr/server --filter=@tracearr/web
$STD ./scripts/fetch-basemap.sh || msg_warn "Basemap download failed, the map will show without base tiles"
mkdir -p /opt/tracearr/{packages/shared,packages/emails,apps/server,apps/web,apps/server/src/db}
mkdir -p /opt/tracearr/{packages/shared,packages/emails,apps/server,apps/web,apps/server/src/db,assets}
cp -rf package.json /opt/tracearr/
cp -rf pnpm-workspace.yaml /opt/tracearr/
cp -rf pnpm-lock.yaml /opt/tracearr/
@@ -81,11 +81,12 @@ cp -rf packages/shared/dist /opt/tracearr/packages/shared/dist
cp -rf packages/emails/package.json /opt/tracearr/packages/emails/
cp -rf packages/emails/dist /opt/tracearr/packages/emails/dist
cp -rf apps/server/src/db/migrations /opt/tracearr/apps/server/src/db/migrations
cp -f assets/logo.png /opt/tracearr/assets/
cp -rf data /opt/tracearr/data
mkdir -p /opt/tracearr/data/image-cache
rm -rf /opt/tracearr.build
cd /opt/tracearr
$STD pnpm install --prod --frozen-lockfile --ignore-scripts
$STD pnpm install --prod --frozen-lockfile --ignore-scripts --filter @tracearr/server...
msg_ok "Built Tracearr"
msg_info "Configuring Tracearr"

View File

@@ -105,8 +105,9 @@ setup_alpine() {
$STD apk add traefik --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community
msg_ok "Installed Traefik"
read -p "${TAB3}Enable Traefik WebUI (Port 8080)? [y/N]: " enable_webui
if [[ "$enable_webui" =~ ^[Yy]$ ]]; then
enable_webui="${var_traefik_webui:-}"
[[ -n "$enable_webui" ]] || read -p "${TAB3}Enable Traefik WebUI (Port 8080)? [y/N]: " enable_webui
if [[ "${enable_webui,,}" =~ ^(y|yes)$ ]]; then
msg_info "Configuring Traefik WebUI"
sed -i 's/localhost//g' /etc/traefik/traefik.yaml
msg_ok "Configured Traefik WebUI"

View File

@@ -36,9 +36,11 @@ setup_deb_based() {
msg_ok "Installed Valkey"
echo
read -r -p "${TAB3}Enable TLS for Valkey (Sentinel mode does not supported)? [y/N]: " prompt
prompt="${var_valkey_tls:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Enable TLS for Valkey (Sentinel mode does not supported)? [y/N]: " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
read -r -p "${TAB3}Use TLS-only mode (disable TCP port 6379)? [y/N]: " tls_only
tls_only="${var_valkey_tls_only:-}"
[[ -n "$tls_only" ]] || read -r -p "${TAB3}Use TLS-only mode (disable TCP port 6379)? [y/N]: " tls_only
msg_info "Configuring TLS for Valkey..."
create_self_signed_cert "Valkey"

View File

@@ -16,7 +16,8 @@ update_os
fetch_and_deploy_gh_release "versitygw" "versity/versitygw" "binary"
WEBUI_CONF=""
read -rp "Would you like to enable the VersityGW WebGUI (Beta)? (y/N): " webui_prompt
webui_prompt="${var_versitygw_webgui:-}"
[[ -n "$webui_prompt" ]] || read -rp "Would you like to enable the VersityGW WebGUI (Beta)? (y/N): " webui_prompt
if [[ "${webui_prompt,,}" =~ ^(y|yes)$ ]]; then
WEBUI_CONF="\nVGW_WEBUI_PORT=:7071\nVGW_WEBUI_NO_TLS=true"
msg_ok "WebGUI will be enabled on port 7071"

View File

@@ -27,7 +27,8 @@ msg_ok "Got version $victoriametrics_release of VictoriaMetrics"
fetch_and_deploy_gh_release "victoriametrics" "VictoriaMetrics/VictoriaMetrics" "prebuild" "$victoriametrics_release" "/opt/victoriametrics" "$victoriametrics_filename"
fetch_and_deploy_gh_release "vmutils" "VictoriaMetrics/VictoriaMetrics" "prebuild" "$victoriametrics_release" "/opt/victoriametrics" "$vmutils_filename"
read -r -p "${TAB3}Would you like to add VictoriaLogs? <y/N> " prompt
prompt="${var_victoriametrics_logs:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add VictoriaLogs? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
vl_release_json="$(mktemp)"

View File

@@ -54,6 +54,16 @@ PB_DB_LOCATION=/opt/wanderer_data/pb_data
MEILI_DB_PATH=/opt/wanderer_data/meili_data
EOF
cat <<'EOF' >/usr/local/bin/wanderer-pb
#!/usr/bin/env bash
set -a
source /opt/wanderer/.env
set +a
cd /opt/wanderer/db
exec ./pocketbase "$@" --dir="$PB_DB_LOCATION"
EOF
chmod +x /usr/local/bin/wanderer-pb
cat <<EOF >/etc/systemd/system/wanderer-pocketbase.service
[Unit]
Description=wanderer PocketBase

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/arabcoders/watchstate
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 \
redis-server \
ripgrep \
sqlite3
msg_ok "Installed Dependencies"
PHP_VERSION="8.5" PHP_FPM="YES" setup_php
setup_composer
setup_ffmpeg
NODE_VERSION="24" NODE_MODULE="bun" setup_nodejs
fetch_and_deploy_gh_release "watchstate" "arabcoders/watchstate" "tarball" "latest" "/opt/watchstate" "" "v"
msg_info "Building WatchState"
cd /opt/watchstate
sed -i "s/'version' => 'dev-master'/'version' => 'v$(cat ~/.watchstate)'/" config/config.php
$STD composer install --no-dev --optimize-autoloader --no-interaction
cd /opt/watchstate/frontend
$STD bun install --frozen-lockfile --production
NODE_ENV=production $STD bun run generate
mv /opt/watchstate/frontend/exported /opt/watchstate/public/exported
rm -rf /opt/watchstate/frontend/node_modules /opt/watchstate/frontend/.nuxt
msg_ok "Built WatchState"
msg_info "Configuring WatchState"
# loaded first by CLI, worker and php-fpm alike; the default data dir is /opt/watchstate/var, which every update wipes
cat <<EOF >/opt/watchstate/.env
WS_DATA_PATH=/opt/watchstate_data
EOF
$STD php /opt/watchstate/bin/console db:migrate --execute
$STD php /opt/watchstate/bin/console system:apikey
chown -R www-data:www-data /opt/watchstate_data
msg_ok "Configured WatchState"
msg_info "Configuring Nginx"
PHP_SOCK=$(get_php_fpm_socket)
cat <<EOF >/etc/nginx/sites-available/watchstate
server {
listen 8080;
server_name _;
root /opt/watchstate/public;
index index.php;
client_max_body_size 100M;
location / {
try_files \$uri /index.php\$is_args\$args;
}
location ~ \.php\$ {
fastcgi_pass unix:${PHP_SOCK};
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 600;
}
}
EOF
nginx_enable_site "watchstate"
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/watchstate-worker.service
[Unit]
Description=WatchState Worker
After=network.target redis-server.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/watchstate
ExecStart=/usr/bin/php /opt/watchstate/bin/console system:worker -v
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now watchstate-worker
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

View File

@@ -15,16 +15,7 @@ update_os
RELEASE=$(get_latest_github_release "wazuh/wazuh" | cut -d. -f1,2)
msg_warn "WARNING: This script will run an external installer from a third-party source (https://wazuh.com/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://packages.wazuh.com/$RELEASE/wazuh-install.sh "
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://wazuh.com/" "https://packages.wazuh.com/$RELEASE/wazuh-install.sh"
msg_info "Setup Wazuh"
curl -fsSL https://packages.wazuh.com/$RELEASE/wazuh-install.sh -o wazuh-install.sh

View File

@@ -24,7 +24,8 @@ setup_deb_based() {
$STD netfilter-persistent reload
msg_ok "Installed WireGuard"
read -r -p "${TAB3}Would you like to add WGDashboard? <y/N> " prompt
prompt="${var_wireguard_wgdashboard:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add WGDashboard? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
git clone -q https://github.com/WGDashboard/WGDashboard.git /etc/wgdashboard
@@ -109,8 +110,9 @@ EOF
$STD sysctl -p /etc/sysctl.conf
msg_ok "Installed WireGuard"
read -rp "${TAB3}Do you want to install WGDashboard? (y/N): " INSTALL_WGD
if [[ "$INSTALL_WGD" =~ ^[Yy]$ ]]; then
INSTALL_WGD="${var_wireguard_wgdashboard:-}"
[[ -n "$INSTALL_WGD" ]] || read -rp "${TAB3}Do you want to install WGDashboard? (y/N): " INSTALL_WGD
if [[ "${INSTALL_WGD,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing additional dependencies for WGDashboard"
$STD apk add --no-cache \
python3 \

View File

@@ -20,16 +20,7 @@ $STD apt install -y \
ca-certificates
msg_ok "Installed Dependencies"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://yunohost.org/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://install.yunohost.org"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://yunohost.org/" "https://install.yunohost.org"
msg_info "Installing YunoHost (Patience)"
touch /etc/.pve-ignore.resolv.conf

View File

@@ -13,16 +13,7 @@ setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://install.zerotier.com)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://install.zerotier.com"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! $CONFIRM =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
confirm_external_installer "https://install.zerotier.com" "https://install.zerotier.com"
msg_info "Setting up Zerotier-One"
curl -fsSL https://raw.githubusercontent.com/zerotier/ZeroTierOne/main/doc/contact%40zerotier.com.gpg | gpg --import >/dev/null 2>&1

View File

@@ -33,7 +33,9 @@ APP_TYPE="addon"
INSTALL_PATH="/opt/immich-proxy"
CONFIG_PATH="/opt/immich-proxy/app"
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
UPLOAD_SERVICE_PATH="/etc/systemd/system/immich-proxy-upload.service"
DEFAULT_PORT=3000
UPLOAD_PORT=3001
# Initialize all core functions (colors, formatting, icons, $STD mode)
load_functions
@@ -44,8 +46,8 @@ require_debian_like
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now immich-proxy.service &>/dev/null || true
rm -f "$SERVICE_PATH"
systemctl disable --now immich-proxy.service immich-proxy-upload.service &>/dev/null || true
rm -f "$SERVICE_PATH" "$UPLOAD_SERVICE_PATH"
rm -rf "$INSTALL_PATH"
rm -f "/usr/local/bin/update_immich-public-proxy"
rm -f "$HOME/.immichpublicproxy"
@@ -58,32 +60,33 @@ function uninstall() {
function update() {
if check_for_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy"; then
msg_info "Stopping service"
systemctl stop immich-proxy.service &>/dev/null || true
systemctl stop immich-proxy.service immich-proxy-upload.service &>/dev/null || true
msg_ok "Stopped service"
BACKUP_DIR="/opt/immich-public-proxy_backup"
create_backup "$CONFIG_PATH"/.env "$CONFIG_PATH"/config.json
if [[ -f "$UPLOAD_SERVICE_PATH" ]]; then
create_backup "$INSTALL_PATH"/upload-app/config.json
fi
NODE_VERSION="24" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
restore_backup
msg_info "Installing dependencies"
cd "$CONFIG_PATH"
$STD npm ci
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
build_app
msg_info "Updating service"
create_service
if [[ -f "$UPLOAD_SERVICE_PATH" ]]; then
create_upload_service
fi
msg_ok "Updated service"
msg_info "Starting service"
systemctl start immich-proxy
if [[ -f "$UPLOAD_SERVICE_PATH" ]]; then
systemctl start immich-proxy-upload
fi
msg_ok "Started service"
msg_ok "Updated successfully"
exit
@@ -111,6 +114,55 @@ EOF
systemctl daemon-reload
}
# The workspace root builds shared, app and upload-app together
function build_app() {
msg_info "Installing dependencies"
cd "$INSTALL_PATH"
$STD npm ci
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
}
# env sets the port after EnvironmentFile, so an IPP_PORT in .env cannot clash with IPP
function create_upload_service() {
cat <<EOF >"$UPLOAD_SERVICE_PATH"
[Unit]
Description=Immich Public Proxy visitor uploads
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_PATH}/upload-app
EnvironmentFile=${CONFIG_PATH}/.env
ExecStart=/usr/bin/env IPP_PORT=${UPLOAD_PORT} /usr/bin/node ${INSTALL_PATH}/upload-app/dist/index.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
}
function enable_uploads() {
if [[ ! -d "$INSTALL_PATH"/upload-app ]]; then
msg_error "Visitor uploads need ${APP} 4.0 or newer. Update first."
exit 1
fi
if [[ ! -f "$INSTALL_PATH"/upload-app/dist/index.js ]]; then
build_app
fi
msg_info "Enabling visitor uploads"
create_upload_service
systemctl enable -q --now immich-proxy-upload
msg_ok "Enabled visitor uploads on port ${UPLOAD_PORT}"
msg_warn "Route /upload/* on your reverse proxy to http://${LOCAL_IP}:${UPLOAD_PORT} and turn on 'Allow public user to upload' for the share in Immich"
}
# ==============================================================================
# INSTALL
# ==============================================================================
@@ -120,15 +172,7 @@ function install() {
# Force fresh download by removing version cache
rm -f "$HOME/.immichpublicproxy"
fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
msg_info "Installing dependencies"
cd "$CONFIG_PATH"
$STD npm ci
msg_ok "Installed dependencies"
msg_info "Building ${APP}"
$STD npm run build
msg_ok "Built ${APP}"
build_app
MAX_ATTEMPTS=3
attempt=0
@@ -176,6 +220,12 @@ EOF
systemctl enable -q --now immich-proxy
msg_ok "Created and started service"
prompt="${var_ipp_uploads:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Enable visitor uploads (second service on port ${UPLOAD_PORT})? <y/N> " prompt
if [[ "${prompt,,}" =~ ^(y|yes|true)$ ]]; then
enable_uploads
fi
# Create update script (simple wrapper that calls this addon with type=update)
msg_info "Creating update script"
cat <<'UPDATEEOF' >/usr/local/bin/update_immich-public-proxy
@@ -230,6 +280,15 @@ if [[ -d "$INSTALL_PATH" && -f "$SERVICE_PATH" ]]; then
exit 0
fi
if [[ ! -f "$UPLOAD_SERVICE_PATH" ]]; then
echo -n "${TAB}Enable visitor uploads (second service on port ${UPLOAD_PORT})? (y/N): "
read -r upload_prompt
if [[ "${upload_prompt,,}" =~ ^(y|yes)$ ]]; then
enable_uploads
exit 0
fi
fi
msg_warn "No action selected. Exiting."
exit 0
fi