Compare commits

..

23 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
24fefdbd83 Update wikijs.sh for version 2 support 2026-10-12 20:34:57 +02:00
CanbiZ (MickLesk)
2b464338b1 WikiJS: use v2 Repo until v3 is stable 2026-10-12 20:33:20 +02:00
community-scripts-pr-app[bot]
1a14f2f9af Update CHANGELOG.md (#17893)
Some checks are pending
Create Changelog Pull Request / update-changelog-pull-request (push) Waiting to run
Set state to is_deleted in pocketbase / delete-pocketbase-entry (push) Waiting to run
Sync ct/install to Incus / dispatch (push) Waiting to run
Update script timestamp on .sh changes / update-script-timestamp (push) Waiting to run
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 18:12:33 +00:00
community-scripts-pr-app[bot]
9d7356f2b1 Update CHANGELOG.md (#17892)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 18:11:31 +00:00
community-scripts-pr-app[bot]
ff78087273 Update CHANGELOG.md (#17891)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 16:05:54 +00:00
community-scripts-pr-app[bot]
43f3fac7da Update CHANGELOG.md (#17890)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-12 16:05:22 +00:00
github-actions[bot]
12b02e156e chore(ct): sync wazuh defaults from PocketBase (#17889)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-12 18:04:51 +02:00
community-scripts-pr-app[bot]
2cc029fc6a Update CHANGELOG.md (#17885)
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-12 12:14:16 +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
19 changed files with 533 additions and 161 deletions

View File

@@ -562,6 +562,34 @@ 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
- chore(ct): sync wazuh defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17889](https://github.com/community-scripts/ProxmoxVE/pull/17889))
- 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
- Draw a Community Scripts banner while a script has no header of its own [@MickLesk](https://github.com/MickLesk) ([core#133](https://github.com/community-scripts/core/pull/133))
- Order pre-release labels when comparing versions [@MickLesk](https://github.com/MickLesk) ([core#132](https://github.com/community-scripts/core/pull/132))
- 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,6 +600,7 @@ 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))
@@ -582,6 +611,11 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- 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
- Add confirm_external_installer [@MickLesk](https://github.com/MickLesk) ([core#130](https://github.com/community-scripts/core/pull/130))

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

@@ -565,7 +565,6 @@ function compile_imagemagick() {
function compile_libvips() {
SOURCE=$SOURCE_DIR/libvips
LIBVIPS_REVISION="$(jq -cr '.revision' "$BASE_DIR"/server/sources/libvips.json)"
# Builds made before libopenjp2-7-dev was installed lack JPEG 2000
if [[ "$LIBVIPS_REVISION" != "$(grep 'libvips' ~/.immich_library_revisions | awk '{print $2}')" ]] ||
[[ "$(vips -l foreign 2>/dev/null)" != *jp2kload* ]]; then
msg_info "Recompiling libvips"

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

@@ -10,7 +10,7 @@ APP="Wazuh"
var_tags="${var_tags:-security;monitoring}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-25}"
var_disk="${var_disk:-35}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"

View File

@@ -32,14 +32,14 @@ function update_script() {
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
if check_for_gh_release "wikijs" "requarks/wiki"; then
msg_info "Verifying whether ${APP}' new release is v3.x+ and current install uses SQLite."
SQLITE_INSTALL=$([ -f /opt/wikijs/db.sqlite ] && echo "true" || echo "false")
if [[ "${SQLITE_INSTALL}" == "true" && "${CHECK_UPDATE_RELEASE}" =~ ^3.* ]]; then
echo "SQLite is not supported in v3.x+, currently there is no update path availble."
exit
fi
msg_ok "There is an update path available for ${APP}"
if check_for_gh_release "wikijs" "requarks/wiki-v2"; then
#msg_info "Verifying whether ${APP}' new release is v3.x+ and current install uses SQLite."
#SQLITE_INSTALL=$([ -f /opt/wikijs/db.sqlite ] && echo "true" || echo "false")
#if [[ "${SQLITE_INSTALL}" == "true" && "${CHECK_UPDATE_RELEASE}" =~ ^3.* ]]; then
# echo "SQLite is not supported in v3.x+, currently there is no update path availble."
# exit
#fi
#msg_ok "There is an update path available for ${APP}"
msg_info "Stopping Service"
systemctl stop wikijs
@@ -47,15 +47,17 @@ function update_script() {
msg_info "Backing up Data"
mkdir /opt/wikijs-backup
$SQLITE_INSTALL && cp /opt/wikijs/db.sqlite /opt/wikijs-backup
#$SQLITE_INSTALL &&
cp /opt/wikijs/db.sqlite /opt/wikijs-backup
cp -R /opt/wikijs/{config.yml,/data} /opt/wikijs-backup
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wikijs" "requarks/wiki-v2" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
msg_info "Restoring Data"
cp -R /opt/wikijs-backup/* /opt/wikijs
$SQLITE_INSTALL && $STD npm rebuild sqlite3
#$SQLITE_INSTALL &&
$STD npm rebuild sqlite3
rm -rf /opt/wikijs-backup
msg_ok "Restored Data"

View File

@@ -14,21 +14,8 @@ 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"
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"
fetch_and_deploy_gh_release "caddy" "caddyserver/caddy" "binary" "latest" "/opt/caddy" "caddy_*_linux_$(arch_resolve).deb"
systemctl enable -q --now caddy
prompt="${var_caddy_xcaddy:-}"
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to install xCaddy Addon? <y/N> " prompt

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

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

@@ -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

@@ -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

@@ -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

@@ -20,7 +20,7 @@ msg_ok "Installed Dependencies"
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="wiki" PG_DB_USER="wikijs_user" PG_DB_EXTENSIONS="pg_trgm" setup_postgresql_db
fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
fetch_and_deploy_gh_release "wikijs" "requarks/wiki-v2" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
msg_info "Configuring Wiki.js"
mv /opt/wikijs/config.sample.yml /opt/wikijs/config.yml

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