Compare commits

...
Author SHA1 Message Date
github-actions[bot] 79bea05974 Update CHANGELOG.md 2026-10-25 18:52:18 +00:00
CanbiZ (MickLesk) 94a3374039 Hermes Agent: install, update and run everything as the hermes user (#18203)
hermes update refuses a checkout its caller does not own, so the
root-run update stopped working for every install. The installer and
hermes update now run as hermes, and the dashboard becomes a user unit
next to the gateways, so Hermes Desktop and the dashboard can update
and restart it themselves. libatomic1 is installed up front, the one
package Hermes would otherwise ask sudo for.

update moves existing containers over once: the system unit becomes a
user unit, leftover root processes are stopped and /home/hermes is
handed back to hermes.
2026-10-25 19:51:57 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 65a4410c97 Update CHANGELOG.md (#18206)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 18:47:59 +00:00
push-app-to-main[bot] b5c4b37d89 Add dreeve (ct) (#18167)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-10-25 19:47:32 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 1dee4473eb Update CHANGELOG.md (#18202)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 14:24:46 +00:00
CanbiZ (MickLesk) cbefc8590e Element Synapse: remove the registration line by its text, not line 34 (#18201)
Line 34 was media_store_path in the packaged homeserver.yaml; since #18180 drops the ::1 line it is signing_key_path, and Synapse no longer starts.
2026-10-25 15:24:18 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 193659402e Update CHANGELOG.md (#18199)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 14:08:13 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] ff2645698a Update CHANGELOG.md (#18198)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 14:07:50 +00:00
CanbiZ (MickLesk) 359fd5d01a post-pmg-install: hide the subscription nag in the PMG 9 mobile quarantine (#18140)
* post-pmg-install: hide the subscription nag in the PMG 9 mobile quarantine

PMG 9 replaced pmgmanagerlib-mobile.js with the Yew/WASM app in
pmg-mobile-quarantine-ui, so the mobile hook no longer found its file.
The status check is compiled into the WASM, so the helper now injects a
fetch wrapper into the mobile index template that reports the
subscription as active to the app. The API response itself is unchanged.

All patches move into /usr/local/bin/pmg-remove-nag.sh behind a single
apt hook. "no" now also removes the mobile hook and the helper, and the
reinstall covers pmg-mobile-quarantine-ui so its template is restored.

Fixes #16217

* post-pmg-install: reinstall the mobile quarantine UI only where it exists

pmg-mobile-quarantine-ui is not in the PMG 8 (bookworm) repository, so
naming it in the reinstall made apt abort there and skip the widget
toolkit reinstall as well.
2026-10-25 15:07:47 +01:00
CanbiZ (MickLesk) 43ec20463e Heimdall: generate the app key without the production prompt (#18156) 2026-10-25 15:07:24 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 507b5a1556 Update CHANGELOG.md (#18197)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 13:36:10 +00:00
CanbiZ (MickLesk) 469da44126 Frigate: fetch the Intel graphics key with retries before building the media driver (#18192) 2026-10-25 14:35:42 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] b0a39be6c0 Update CHANGELOG.md (#18196)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 13:35:39 +00:00
CanbiZ (MickLesk) ecf5376265 TREK: build 5.0 with 4 GB RAM and without dependency install scripts (#18194)
tsc on the 5.0 server needs about 3 GB of heap; the 2 GB default left it 2.3 GB and the update died in the build. npm ci runs with --ignore-scripts like upstream, so better-sqlite3 keeps its prebuilt binary instead of an addon built against the running Node's headers. kitinerary-extractor sits in libexec on Debian, so link it into PATH where TREK looks for it.
2026-10-25 14:35:06 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 6717059b8c Update CHANGELOG.md (#18195)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 13:24:41 +00:00
Tobias ef0579b39d tubearchivist: fix: prepare tubearchivist for v0.6.0 (#17867)
* fix: prepare tubearchivist for v0.6.0

* feat: add clear end msg
2026-10-25 14:24:14 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 80cc9edf9c Update CHANGELOG.md (#18193)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 13:20:14 +00:00
CanbiZ (MickLesk) c50aa2dfe3 Pterodactyl Panel: default the admin's first and last name when left empty (#18177) 2026-10-25 14:19:46 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] e045557655 Update CHANGELOG.md (#18191)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:48:25 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] bedc06d73f Update CHANGELOG.md (#18190)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:48:02 +00:00
CanbiZ (MickLesk) 74c8ba79fa Jellyseerr: point fresh installs to Seerr instead of a missing install script (#18183) 2026-10-25 13:47:58 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 4dd47de8ff Update CHANGELOG.md (#18189)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:47:37 +00:00
CanbiZ (MickLesk) 31560bceba Pi-hole: download the installer before running it (#18182)
bash <(curl ...) runs an empty script and exits 0 when the download fails,
so the install went on and broke at /etc/dnsmasq.d/01-pihole.conf instead.
2026-10-25 13:47:30 +01:00
CanbiZ (MickLesk) d2053aaf6b OmniTools: give the build a git commit to read (#18181) 2026-10-25 13:47:12 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] 264386a338 Update CHANGELOG.md (#18188)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:47:11 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 7595fbf0fe Update CHANGELOG.md (#18187)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:46:45 +00:00
CanbiZ (MickLesk) 714dd4d739 iVentoy: stop early in an unprivileged container (#18179) 2026-10-25 13:46:35 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] f52c8e1ea4 Update CHANGELOG.md (#18186)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:46:24 +00:00
CanbiZ (MickLesk) 6018a31dd1 Immich: stop early on Debian 12 instead of failing at apt (#18178) 2026-10-25 13:46:17 +01:00
CanbiZ (MickLesk) ac51382b21 Element Synapse: drop the ::1 listener so a container without IPv6 starts (#18180) 2026-10-25 13:45:56 +01:00
CanbiZ (MickLesk) c62f9da4c6 Remove reindex command from paperless-ngx install
Removed reindex command from installation script.
2026-10-25 13:38:19 +01:00
community-scripts-pr-app[bot]andgithub-actions[bot] e62f5a91ae Update CHANGELOG.md (#18176)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:11:05 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] ab223217bf Update CHANGELOG.md (#18175)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-25 12:10:40 +00:00
push-app-to-main[bot] b7add5b2d7 Add taskview (ct) (#18166)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-10-25 13:10:27 +01:00
push-app-to-main[bot] 4e22061f07 Add emdash (ct) (#18165)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-10-25 13:10:08 +01:00
25 changed files with 780 additions and 154 deletions

No files matched your search

+26
View File
@@ -570,10 +570,26 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
## 2026-10-25
### 🆕 New Scripts
- Dreeve ([#18167](https://github.com/community-scripts/ProxmoxVE/pull/18167))
- TaskView ([#18166](https://github.com/community-scripts/ProxmoxVE/pull/18166))
- EmDash ([#18165](https://github.com/community-scripts/ProxmoxVE/pull/18165))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Element Synapse: remove the registration line by its text, not line 34 [@MickLesk](https://github.com/MickLesk) ([#18201](https://github.com/community-scripts/ProxmoxVE/pull/18201))
- Element Synapse: drop the ::1 listener so a container without IPv6 starts [@MickLesk](https://github.com/MickLesk) ([#18180](https://github.com/community-scripts/ProxmoxVE/pull/18180))
- Heimdall: generate the app key without the production prompt [@MickLesk](https://github.com/MickLesk) ([#18156](https://github.com/community-scripts/ProxmoxVE/pull/18156))
- Frigate: fetch the Intel graphics key with retries before building the media driver [@MickLesk](https://github.com/MickLesk) ([#18192](https://github.com/community-scripts/ProxmoxVE/pull/18192))
- Pterodactyl Panel: default the admin's first and last name when left empty [@MickLesk](https://github.com/MickLesk) ([#18177](https://github.com/community-scripts/ProxmoxVE/pull/18177))
- Jellyseerr: point fresh installs to Seerr instead of a missing install script [@MickLesk](https://github.com/MickLesk) ([#18183](https://github.com/community-scripts/ProxmoxVE/pull/18183))
- Pi-hole: download the installer before running it [@MickLesk](https://github.com/MickLesk) ([#18182](https://github.com/community-scripts/ProxmoxVE/pull/18182))
- OmniTools: give the build a git commit to read [@MickLesk](https://github.com/MickLesk) ([#18181](https://github.com/community-scripts/ProxmoxVE/pull/18181))
- iVentoy: stop early in an unprivileged container [@MickLesk](https://github.com/MickLesk) ([#18179](https://github.com/community-scripts/ProxmoxVE/pull/18179))
- Immich: stop early on Debian 12 instead of failing at apt [@MickLesk](https://github.com/MickLesk) ([#18178](https://github.com/community-scripts/ProxmoxVE/pull/18178))
- paperless-ngx: fix missing index folder [@Segelzwerg](https://github.com/Segelzwerg) ([#18142](https://github.com/community-scripts/ProxmoxVE/pull/18142))
- Anytype Server: keep the .env across updates and recreate a lost one [@MickLesk](https://github.com/MickLesk) ([#18155](https://github.com/community-scripts/ProxmoxVE/pull/18155))
- changedetection: build Browserless from its lockfile on update [@MickLesk](https://github.com/MickLesk) ([#18157](https://github.com/community-scripts/ProxmoxVE/pull/18157))
@@ -584,6 +600,15 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- Gramps-Web: run the Celery task queue with Redis [@MickLesk](https://github.com/MickLesk) ([#18141](https://github.com/community-scripts/ProxmoxVE/pull/18141))
- #### 💥 Breaking Changes
- Hermes Agent: install, update and run everything as the hermes user [@MickLesk](https://github.com/MickLesk) ([#18203](https://github.com/community-scripts/ProxmoxVE/pull/18203))
- tubearchivist: fix: prepare tubearchivist for v0.6.0 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#17867](https://github.com/community-scripts/ProxmoxVE/pull/17867))
- #### 🔧 Refactor
- TREK: build 5.0 with 4 GB RAM and without dependency install scripts [@MickLesk](https://github.com/MickLesk) ([#18194](https://github.com/community-scripts/ProxmoxVE/pull/18194))
### 💾 Core
- alpine: fix uv release url [@mfelipe](https://github.com/mfelipe) ([core#168](https://github.com/community-scripts/core/pull/168))
@@ -594,6 +619,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### ✨ New Features
- post-pmg-install: hide the subscription nag in the PMG 9 mobile quarantine [@MickLesk](https://github.com/MickLesk) ([#18140](https://github.com/community-scripts/ProxmoxVE/pull/18140))
- post-pve-install: hide the mobile subscription nag in every UI language [@MickLesk](https://github.com/MickLesk) ([#18143](https://github.com/community-scripts/ProxmoxVE/pull/18143))
## 2026-10-24
+80
View File
@@ -0,0 +1,80 @@
#!/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/dreeveapp/dreeve
APP="Dreeve"
var_tags="${var_tags:-fitness;dashboard}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/dreeve ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "dreeve" "dreeveapp/dreeve"; then
msg_info "Stopping Service"
systemctl stop dreeve
msg_ok "Stopped Service"
create_backup /opt/dreeve/.env.local /opt/dreeve/Caddyfile
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "dreeve" "dreeveapp/dreeve" "tarball"
restore_backup
msg_info "Installing PHP Dependencies (Patience)"
cd /opt/dreeve
export COMPOSER_ALLOW_SUPERUSER=1
export APP_ENV=prod
$STD /opt/frankenphp/frankenphp php-cli /usr/local/bin/composer install --no-dev --optimize-autoloader --no-interaction --no-scripts
msg_ok "Installed PHP Dependencies"
msg_info "Running Migrations"
mkdir -p /opt/dreeve/var/{cache,log}
set -a
source /opt/dreeve/.env.local
set +a
$STD /opt/frankenphp/frankenphp php-cli bin/console app:db:migrate --no-interaction
$STD /opt/frankenphp/frankenphp php-cli bin/console assets:install public --no-interaction
rm -rf /opt/dreeve/var/cache/prod
$STD /opt/frankenphp/frankenphp php-cli bin/console cache:warmup --env=prod
msg_ok "Ran Migrations"
msg_info "Starting Service"
systemctl start dreeve
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
echo -e "${INFO}${YW}Admin credentials: ~/dreeve.creds (inside the container)${CL}"
echo -e "${INFO}${YW}Add your Strava API credentials to /opt/dreeve/.env.local first${CL}"
+72
View File
@@ -0,0 +1,72 @@
#!/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/emdash-cms/emdash
APP="EmDash"
var_tags="${var_tags:-cms;blog}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_emdash_url="${var_emdash_url:-}"
export var_emdash_template="${var_emdash_template:-}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/emdash ]]; then
msg_error "No EmDash Installation Found!"
exit
fi
if check_for_gh_release "emdash" "emdash-cms/emdash" "" "" "emdash@"; then
msg_info "Stopping EmDash"
systemctl stop emdash
msg_ok "Stopped EmDash"
NODE_VERSION="24" NODE_MODULE="pnpm@11" setup_nodejs
msg_info "Updating EmDash"
cd /opt/emdash
set -a && source /opt/emdash_data/.env && set +a
$STD pnpm add "${CHECK_UPDATE_RELEASE}"
$STD pnpm build
$STD pnpm store prune
cat <<EOF >~/.emdash
${CHECK_UPDATE_RELEASE}
EOF
msg_ok "Updated EmDash"
msg_info "Starting EmDash"
systemctl start emdash
msg_ok "Started EmDash"
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}:4321${CL}"
echo -e "${INFO}${YW}The admin at /_emdash/admin signs in with passkeys only, and browsers allow those on HTTPS with a domain or on localhost, never on an IP address.${CL}"
echo -e "${INFO}${YW}Put EmDash behind a reverse proxy with a trusted certificate, set EMDASH_SITE_URL in /opt/emdash_data/.env to that address and rebuild (see the notes), then create the admin there.${CL}"
+44 -20
View File
@@ -33,36 +33,60 @@ function update_script() {
confirm_external_installer "https://hermes-agent.nousresearch.com/" "hermes update (https://hermes-agent.nousresearch.com/)"
msg_info "Stopping Services"
systemctl stop hermes-dashboard
msg_ok "Stopped Services"
msg_info "Updating Hermes Agent"
$STD setsid --wait bash -c '
set -a; source /etc/default/hermes; set +a
/home/hermes/.local/bin/hermes update --yes
'
mapfile -t root_gateway_pids < <(ps -eo user=,pid=,args= | awk '$1 == "root" && /\/home\/hermes\/\.hermes\// && /hermes_cli[.]main/ && / gateway run --replace$/ { print $2 }')
if ((${#root_gateway_pids[@]})); then
kill -TERM "${root_gateway_pids[@]}"
for pid in "${root_gateway_pids[@]}"; do
while kill -0 "$pid" 2>/dev/null; do
sleep 0.1
if [[ -f /etc/systemd/system/hermes-dashboard.service ]]; then
msg_info "Moving Hermes to its own user"
systemctl disable -q --now hermes-dashboard
rm -f /etc/systemd/system/hermes-dashboard.service
systemctl daemon-reload
mapfile -t root_hermes_pids < <(ps -eo user=,pid=,args= | awk '$1 == "root" && /\/home\/hermes\/\.hermes\// && /hermes_cli[.]main/ { print $2 }')
if ((${#root_hermes_pids[@]})); then
kill -TERM "${root_hermes_pids[@]}" 2>/dev/null || true
for pid in "${root_hermes_pids[@]}"; do
while kill -0 "$pid" 2>/dev/null; do
sleep 0.1
done
done
done
fi
if ps -eo user=,args= | awk '$1 == "root" && /\/home\/hermes\/\.hermes\// { found = 1 } END { exit !found }'; then
msg_warn "A root-owned Hermes process is still running; it may keep writing root-owned files"
fi
ensure_dependencies libatomic1
sed -i '/^HOME=/d' /etc/default/hermes
grep -q '^GATEWAY_HEALTH_URL=' /etc/default/hermes || echo "GATEWAY_HEALTH_URL=http://127.0.0.1:8642/health" >>/etc/default/hermes
mkdir -p /home/hermes/.config/systemd/user
cat <<EOF >/home/hermes/.config/systemd/user/hermes-dashboard.service
[Unit]
Description=Hermes Agent Web Dashboard
After=network-online.target
[Service]
Type=simple
UMask=0077
WorkingDirectory=%h
EnvironmentFile=/etc/default/hermes
ExecStart=%h/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
EOF
msg_ok "Moved Hermes to its own user"
fi
# A writer racing chown makes files vanish between readdir and chown; one retry covers it.
if ! chown -R hermes:hermes /home/hermes 2>/dev/null; then
sleep 1
chown -R hermes:hermes /home/hermes || msg_warn "Could not take ownership of everything under /home/hermes"
fi
$STD runuser -l hermes -c 'systemctl --user daemon-reload && systemctl --user enable hermes-dashboard'
msg_info "Updating Hermes Agent"
$STD setsid --wait runuser -l hermes -c '
set -a; source /etc/default/hermes; set +a
hermes update --yes
'
msg_ok "Updated Hermes Agent"
msg_info "Starting Services"
systemctl start hermes-dashboard
$STD runuser -l hermes -c 'systemctl --user start hermes-dashboard'
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
+6
View File
@@ -96,6 +96,12 @@ EOF
exit
}
if [[ ! -d /opt/jellyseerr ]]; then
msg_error "Jellyseerr is now Seerr and can no longer be installed with this script."
msg_warn "Install Seerr instead: https://community-scripts.org/scripts/seerr"
exit 1
fi
start
build_container
description
+3
View File
@@ -34,12 +34,15 @@ function update_script() {
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "omnitools" "iib0011/omni-tools"; then
ensure_dependencies git
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "omnitools" "iib0011/omni-tools" "tarball"
msg_info "Building OmniTools"
cd /opt/omnitools
export HUSKY=0
$STD npm ci --allow-remote=all
$STD git init -q
$STD git -c user.name=build -c user.email=build@localhost commit -q --allow-empty -m build
$STD npm run build
msg_ok "Built OmniTools"
+74
View File
@@ -0,0 +1,74 @@
#!/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/Gimanh/taskview-community
APP="TaskView"
var_tags="${var_tags:-project-management;tasks;kanban}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-6144}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/taskview ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "taskview" "Gimanh/taskview-community"; then
msg_info "Stopping TaskView"
systemctl stop taskview
msg_ok "Stopped TaskView"
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "taskview" "Gimanh/taskview-community" "tarball"
msg_info "Building TaskView"
cd /opt/taskview
$STD pnpm install --frozen-lockfile
cd /opt/taskview/api
$STD pnpm run build:docker
$STD pnpm run build:migration
cp -r src/migrations/taskview dist-migration/
cd /opt/taskview/web
$STD pnpm run build:packages
$STD pnpm run build-only
msg_ok "Built TaskView"
msg_info "Migrating TaskView Database"
cd /opt/taskview_data
$STD node /opt/taskview/api/dist-migration/taskview-db-migration.js
msg_ok "Migrated TaskView Database"
msg_info "Starting TaskView"
systemctl start taskview
msg_ok "Started TaskView"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}${CL}"
+4 -3
View File
@@ -9,7 +9,7 @@ source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_
APP="TREK"
var_tags="${var_tags:-travel;planning;collaboration}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
@@ -43,6 +43,7 @@ function update_script() {
msg_ok "Stopped Service"
ensure_dependencies "libkitinerary-bin"
ln -sf "$(find /usr/lib -name kitinerary-extractor -type f | head -1)" /usr/local/bin/kitinerary-extractor
create_backup /opt/trek/server/.env \
/opt/trek/data \
@@ -52,7 +53,7 @@ function update_script() {
msg_info "Building TREK"
cd /opt/trek
$STD npm ci
$STD npm ci --ignore-scripts
$STD npm run build --workspace=shared
$STD npm run build --workspace=client
$STD npm run build --workspace=server
@@ -72,7 +73,7 @@ function update_script() {
rm -rf /opt/trek/node_modules
cd /opt/trek
$STD npm ci --workspace=server --omit=dev
$STD npm ci --workspace=server --omit=dev --ignore-scripts
msg_ok "Set up TREK Workspace"
if [[ "$MIGRATION" == "1" ]]; then
+37 -1
View File
@@ -71,6 +71,41 @@ EOF
restore_backup
if grep -q '^TA_BACKEND_PORT=' /opt/tubearchivist/.env 2>/dev/null; then
msg_info "Migrating to v0.6.0 (dropping Nginx)"
systemctl disable -q --now nginx
$STD apt autoremove --purge -y nginx
sed -i 's/^TA_BACKEND_PORT=.*/TA_PORT=8000/' /opt/tubearchivist/.env
cat <<'RUNEOF' >/opt/tubearchivist/backend/run.sh
#!/bin/bash
set -e
cd /opt/tubearchivist/backend
set -a
source /opt/tubearchivist/.env
set +a
PYTHON=/opt/tubearchivist/.venv/bin/python
echo "Waiting for ElasticSearch..."
for i in $(seq 1 30); do
if curl -sf http://localhost:9200/_cluster/health >/dev/null 2>&1; then
break
fi
sleep 2
done
$PYTHON manage.py ta_stop_on_error
$PYTHON manage.py migrate
$PYTHON manage.py collectstatic --noinput -c
$PYTHON manage.py ta_envcheck
$PYTHON manage.py ta_connection
$PYTHON manage.py ta_startup
exec $PYTHON backend_start.py
RUNEOF
chmod +x /opt/tubearchivist/backend/run.sh
msg_ok "Migrated to v0.6.0 (dropping Nginx)"
fi
msg_info "Rebuilding Tube Archivist"
cd /opt/tubearchivist/frontend
$STD npm install
@@ -113,7 +148,6 @@ EOF
msg_info "Starting Services"
systemctl start bgutil-provider tubearchivist tubearchivist-celery tubearchivist-beat
systemctl reload nginx
msg_ok "Started Services"
msg_ok "Updated successfully!"
fi
@@ -128,3 +162,5 @@ msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}"
echo -e "${INFO}${YW}Admin credentials saved to ~/tubearchivist.creds${CL}"
echo -e "${INFO}${YW}The WebUI may take a couple of minutes to become available on first start, while Elasticsearch and the backend initialize.${CL}"
+136
View File
@@ -0,0 +1,136 @@
#!/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/dreeveapp/dreeve
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 \
libsqlite3-0 \
libcap2-bin \
ca-certificates
msg_ok "Installed Dependencies"
# 1.13.0's php-cli shifts the script into argv[1], which breaks composer and bin/console (php/frankenphp#2690); unpin once 1.13.1 is out
fetch_and_deploy_gh_release "frankenphp" "php/frankenphp" "singlefile" "v1.12.7" "/opt/frankenphp" "frankenphp-linux-$(arch_resolve x86_64 aarch64)-gnu"
fetch_and_deploy_gh_release "dreeve" "dreeveapp/dreeve" "tarball"
msg_info "Providing php CLI"
cat <<'EOF' >/usr/local/bin/php
#!/usr/bin/env bash
exec /opt/frankenphp/frankenphp php-cli "$@"
EOF
chmod +x /usr/local/bin/php
msg_ok "Provided php CLI"
msg_info "Installing Composer"
curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php
$STD /opt/frankenphp/frankenphp php-cli /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
rm -f /tmp/composer-setup.php
msg_ok "Installed Composer"
msg_info "Installing PHP Dependencies (Patience)"
cd /opt/dreeve
export COMPOSER_ALLOW_SUPERUSER=1
export APP_ENV=prod
$STD /opt/frankenphp/frankenphp php-cli /usr/local/bin/composer install --no-dev --optimize-autoloader --no-interaction --no-scripts
msg_ok "Installed PHP Dependencies"
msg_info "Configuring Dreeve"
mkdir -p /opt/dreeve_data /opt/dreeve/var/{cache,log}
DREEVE_PASSWORD=$(openssl rand -base64 18)
DREEVE_HASH=$(DREEVE_PASSWORD="$DREEVE_PASSWORD" /opt/frankenphp/frankenphp php-cli -r 'echo password_hash(getenv("DREEVE_PASSWORD"), PASSWORD_BCRYPT, ["cost" => 13]);')
[[ "$DREEVE_HASH" =~ ^\$2y\$ ]] || {
msg_error "Could not generate the admin password hash"
exit 1
}
cat <<EOF >/opt/dreeve/.env.local
APP_ENV=prod
APP_DEBUG=0
APP_SECRET=$(openssl rand -hex 32)
APP_URL=http://${LOCAL_IP}:8080
DATABASE_DIRECTORY=/opt/dreeve_data
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH='${DREEVE_HASH}'
TZ=UTC
# Create an API application at https://www.strava.com/settings/api
STRAVA_CLIENT_ID=replace-me
STRAVA_CLIENT_SECRET=replace-me
STRAVA_REFRESH_TOKEN=replace-me
EOF
chmod 600 /opt/dreeve/.env.local
cat <<EOF >~/dreeve.creds
Dreeve Admin
Username: admin
Password: ${DREEVE_PASSWORD}
EOF
chmod 600 ~/dreeve.creds
cat <<EOF >/opt/dreeve/Caddyfile
{
http_port 8080
auto_https off
frankenphp {
num_threads 3
worker {
num 2
file /opt/dreeve/public/index.php
}
}
}
:8080 {
root /opt/dreeve/public
encode zstd br gzip
php_server
}
EOF
msg_ok "Configured Dreeve"
msg_info "Initializing Database"
cd /opt/dreeve
set -a
source /opt/dreeve/.env.local
set +a
$STD /opt/frankenphp/frankenphp php-cli bin/console app:db:migrate --no-interaction
$STD /opt/frankenphp/frankenphp php-cli bin/console assets:install public --no-interaction
$STD /opt/frankenphp/frankenphp php-cli bin/console cache:warmup --env=prod
msg_ok "Initialized Database"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/dreeve.service
[Unit]
Description=Dreeve
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/dreeve
EnvironmentFile=/opt/dreeve/.env.local
ExecStart=/opt/frankenphp/frankenphp run --config /opt/dreeve/Caddyfile
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now dreeve
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+2 -2
View File
@@ -40,7 +40,7 @@ chmod +x /usr/sbin/policy-rc.d
$STD apt install matrix-synapse-py3 -y
rm -f /usr/sbin/policy-rc.d
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/matrix-synapse/homeserver.yaml
sed -i 's/'\''::1'\'', //g' /etc/matrix-synapse/homeserver.yaml
sed -i '/^ *- ::1$/d' /etc/matrix-synapse/homeserver.yaml
SECRET=$(openssl rand -hex 32)
ADMIN_PASS="$(random_password 13)"
echo "enable_registration_without_verification: true" >>/etc/matrix-synapse/homeserver.yaml
@@ -71,7 +71,7 @@ Admin username: admin
Admin password: $ADMIN_PASS
EOF
systemctl stop matrix-synapse
sed -i '34d' /etc/matrix-synapse/homeserver.yaml
sed -i '/^enable_registration_without_verification: true$/d' /etc/matrix-synapse/homeserver.yaml
systemctl start matrix-synapse
msg_ok "Installed Element Synapse"
+70
View File
@@ -0,0 +1,70 @@
#!/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/emdash-cms/emdash
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
NODE_VERSION="24" NODE_MODULE="pnpm@11" setup_nodejs
msg_info "Creating EmDash Site"
cd /opt
$STD pnpm dlx create-emdash@latest emdash --platform node --template "${var_emdash_template:-blog}" --pm pnpm --no-install --yes
mkdir -p /opt/emdash_data/uploads
mv /opt/emdash/.env /opt/emdash_data/.env
sed -i -e 's|file:./data.db|file:/opt/emdash_data/data.db|' -e 's|"./uploads"|"/opt/emdash_data/uploads"|' /opt/emdash/astro.config.mjs
cat <<EOF >>/opt/emdash_data/.env
HOST=0.0.0.0
PORT=4321
# The address in the browser bar. Passkeys are bound to its hostname, and the build bakes it in for image optimization:
# after a change run cd /opt/emdash && set -a && . /opt/emdash_data/.env && set +a && pnpm build && systemctl restart emdash
EMDASH_SITE_URL=${var_emdash_url:-http://${LOCAL_IP}:4321}
EOF
chmod 600 /opt/emdash_data/.env
msg_ok "Created EmDash Site"
msg_info "Building EmDash"
cd /opt/emdash
# pnpm keeps Astro's sharp out of the site's reach, and every /_image request then fails with MissingSharp
$STD pnpm add sharp
set -a && source /opt/emdash_data/.env && set +a
$STD pnpm build
cat <<EOF >~/.emdash
emdash@$(node -p 'require("/opt/emdash/node_modules/emdash/package.json").version')
EOF
msg_ok "Built EmDash"
msg_info "Creating EmDash Service"
cat <<EOF >/etc/systemd/system/emdash.service
[Unit]
Description=EmDash
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/emdash
EnvironmentFile=/opt/emdash_data/.env
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/emdash/dist/server/entry.mjs
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now emdash
msg_ok "Created EmDash Service"
motd_ssh
customize
cleanup_lxc
+2
View File
@@ -124,6 +124,8 @@ msg_ok "Built SQLite Extensions"
if [[ "$(arch_resolve)" == "amd64" ]]; then
msg_info "Building Intel Media Driver (Patience)"
download_gpg_key "https://repositories.intel.com/gpu/intel-graphics.key" "/usr/share/keyrings/intel-graphics.gpg" "dearmor"
sed -i '/intel-graphics.key/d' /opt/frigate/docker/main/build_intel_media_driver.sh
$STD bash /opt/frigate/docker/main/build_intel_media_driver.sh
cp -a /rootfs/. /
rm -rf /rootfs
+1 -1
View File
@@ -25,7 +25,7 @@ msg_info "Setting up Heimdall-Dashboard"
cd /opt/Heimdall
cp .env.example .env
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env
$STD php artisan key:generate
$STD php artisan key:generate --force
msg_ok "Setup Heimdall-Dashboard"
msg_info "Creating Service"
+17 -23
View File
@@ -14,7 +14,9 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y git
$STD apt install -y \
git \
libatomic1
msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
@@ -27,9 +29,9 @@ msg_ok "Created Hermes User"
msg_info "Configuring Service Environment"
cat <<EOF >/etc/default/hermes
HOME=/home/hermes
PATH=/home/hermes/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NODE_OPTIONS=${NODE_OPTIONS}
GATEWAY_HEALTH_URL=http://127.0.0.1:8642/health
EOF
msg_ok "Configured Service Environment"
@@ -38,68 +40,60 @@ confirm_external_installer "https://hermes-agent.nousresearch.com/" "https://her
msg_info "Installing Hermes Agent"
curl_with_retry "https://hermes-agent.nousresearch.com/install.sh" /tmp/hermes-install.sh ||
curl_with_retry "https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh" /tmp/hermes-install.sh
$STD setsid --wait bash -c '
chmod 644 /tmp/hermes-install.sh
$STD setsid --wait runuser -l hermes -c '
set -a; source /etc/default/hermes; set +a
export npm_config_yes=true
bash /tmp/hermes-install.sh --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent
bash /tmp/hermes-install.sh --skip-setup --hermes-home ~/.hermes --dir ~/.hermes/hermes-agent
'
rm -f /tmp/hermes-install.sh
chown -R hermes:hermes /home/hermes
chmod 750 /home/hermes
chmod 700 /home/hermes/.hermes
git config --system --add safe.directory /home/hermes/.hermes/hermes-agent 2>/dev/null || true
msg_ok "Installed Hermes Agent"
msg_info "Configuring API Server"
API_SERVER_KEY=$(random_password 32)
mkdir -p /home/hermes/.hermes
cat <<EOF >/home/hermes/.hermes/.env
API_SERVER_ENABLED=true
API_SERVER_HOST=0.0.0.0
API_SERVER_PORT=8642
API_SERVER_KEY=${API_SERVER_KEY}
EOF
chown hermes:hermes /home/hermes/.hermes/.env
chmod 600 /home/hermes/.hermes/.env
msg_ok "Configured API Server"
msg_info "Creating Dashboard Service"
cat <<EOF >/etc/systemd/system/hermes-dashboard.service
mkdir -p /home/hermes/.config/systemd/user
cat <<EOF >/home/hermes/.config/systemd/user/hermes-dashboard.service
[Unit]
Description=Hermes Agent Web Dashboard
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=hermes
Group=hermes
UMask=0077
WorkingDirectory=/home/hermes
ExecStart=/home/hermes/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open
WorkingDirectory=%h
EnvironmentFile=/etc/default/hermes
ExecStart=%h/.local/bin/hermes dashboard --host 127.0.0.1 --port 9119 --no-open
Restart=on-failure
RestartSec=5
ProtectProc=invisible
ProcSubset=pid
[Install]
WantedBy=multi-user.target
WantedBy=default.target
EOF
systemctl enable -q --now hermes-dashboard
chown -R hermes:hermes /home/hermes/.config
$STD runuser -l hermes -c 'systemctl --user daemon-reload && systemctl --user enable --now hermes-dashboard'
msg_ok "Created Dashboard Service"
msg_info "Creating Setup Helper"
cat <<'SETUP' >/usr/bin/hermes-setup
#!/usr/bin/env bash
set -a; source /etc/default/hermes; set +a
/home/hermes/.local/bin/hermes setup
chown -R hermes:hermes /home/hermes
chmod 750 /home/hermes
chmod 700 /home/hermes/.hermes
su - hermes -c 'set -a; source /etc/default/hermes; set +a; hermes setup'
if [[ -f /home/hermes/.config/systemd/user/hermes-gateway.service ]]; then
su - hermes -c 'systemctl --user enable --now hermes-gateway'
fi
echo "Hermes setup complete. File permissions restored."
echo "Hermes setup complete."
SETUP
chmod +x /usr/bin/hermes-setup
msg_ok "Created Setup Helper"
+5
View File
@@ -13,6 +13,11 @@ setting_up_container
network_check
update_os
if is_debian && [[ "$(get_os_version_major)" -lt 13 ]]; then
msg_error "Immich needs Debian 13: its build dependencies and Intel runtime packages are not available on Debian 12."
exit 238
fi
RELEASE="v3.3.5"
if lscpu | grep -q 'GenuineIntel'; then
echo ""
+6
View File
@@ -13,6 +13,12 @@ setting_up_container
network_check
update_os
if [[ "${CTTYPE:-1}" != "0" ]]; then
msg_error "iVentoy requires a privileged LXC container."
msg_error "Recreate the container with unprivileged=0."
exit 10
fi
fetch_and_deploy_gh_release "iventoy" "ventoy/PXE" "prebuild" "latest" "/opt/iventoy" "iventoy-*-linux-$(arch_resolve x86_64-free arm64-trial).tar.gz"
mkdir -p /opt/iventoy/{data,iso}
+5 -1
View File
@@ -14,7 +14,9 @@ network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
$STD apt install -y \
git \
nginx
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
@@ -24,6 +26,8 @@ msg_info "Building OmniTools"
cd /opt/omnitools
export HUSKY=0
$STD npm ci --allow-remote=all
$STD git init -q
$STD git -c user.name=build -c user.email=build@localhost commit -q --allow-empty -m build
$STD npm run build
msg_ok "Built OmniTools"
-1
View File
@@ -80,7 +80,6 @@ set -a
. /opt/paperless/paperless.conf
set +a
$STD uv run -- python manage.py migrate
$STD uv run -- python manage.py reindex
msg_ok "Setup Paperless-ngx"
msg_info "Setting up admin Paperless-ngx User & Password"
+3 -1
View File
@@ -22,7 +22,9 @@ msg_ok "Installed Dependencies"
msg_info "Installing Pi-hole"
mkdir -p /etc/pihole
touch /etc/pihole/pihole.toml
$STD bash <(curl -fsSL https://install.pi-hole.net) --unattended
curl_with_retry "https://install.pi-hole.net" /tmp/pihole-install.sh
$STD bash /tmp/pihole-install.sh --unattended
rm -f /tmp/pihole-install.sh
sed -i -E '
/^\s*upstreams =/ s|=.*|= ["8.8.8.8", "8.8.4.4"]|
/^\s*interface =/ s|=.*|= "eth0"|
+4 -4
View File
@@ -51,11 +51,11 @@ ADMIN_EMAIL="${var_pterodactyl_panel_admin_email:-}"
[[ -n "$ADMIN_EMAIL" ]] || read -r -p "${TAB3}Provide an email address for admin login, this should be a valid email address: " ADMIN_EMAIL || true
[[ -n "$ADMIN_EMAIL" ]] || { msg_error "No admin email given; set var_pterodactyl_panel_admin_email or answer the prompt"; exit 64; }
NAME_FIRST="${var_pterodactyl_panel_first_name:-}"
[[ -n "$NAME_FIRST" ]] || read -r -p "${TAB3}Enter your First Name: " NAME_FIRST || true
[[ -n "$NAME_FIRST" ]] || { msg_error "No first name given; set var_pterodactyl_panel_first_name or answer the prompt"; exit 64; }
[[ -n "$NAME_FIRST" ]] || read -r -p "${TAB3}Enter your First Name [Admin]: " NAME_FIRST || true
NAME_FIRST="${NAME_FIRST:-Admin}"
NAME_LAST="${var_pterodactyl_panel_last_name:-}"
[[ -n "$NAME_LAST" ]] || read -r -p "${TAB3}Enter your Last Name: " NAME_LAST || true
[[ -n "$NAME_LAST" ]] || { msg_error "No last name given; set var_pterodactyl_panel_last_name or answer the prompt"; exit 64; }
[[ -n "$NAME_LAST" ]] || read -r -p "${TAB3}Enter your Last Name [User]: " NAME_LAST || true
NAME_LAST="${NAME_LAST:-User}"
fetch_and_deploy_gh_release "pterodactyl-panel" "pterodactyl/panel" "prebuild" "latest" "/opt/pterodactyl-panel" "panel.tar.gz"
+135
View File
@@ -0,0 +1,135 @@
#!/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/Gimanh/taskview-community
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
PG_VERSION="18" setup_postgresql
PG_DB_NAME="taskview" PG_DB_USER="taskview" setup_postgresql_db
msg_info "Configuring PostgreSQL for TaskView"
# Every migration run terminates all other sessions on the database, autovacuum workers included
$STD sudo -u postgres psql -c "GRANT pg_signal_autovacuum_worker TO taskview;"
msg_ok "Configured PostgreSQL for TaskView"
fetch_and_deploy_gh_release "taskview" "Gimanh/taskview-community" "tarball"
msg_info "Building TaskView"
cd /opt/taskview
$STD pnpm install --frozen-lockfile
cd /opt/taskview/api
$STD pnpm run build:docker
$STD pnpm run build:migration
cp -r src/migrations/taskview dist-migration/
cd /opt/taskview/web
# upstream's build script type-checks before Vite has generated the auto-import types, which fails on a fresh checkout
$STD pnpm run build:packages
$STD pnpm run build-only
msg_ok "Built TaskView"
msg_info "Configuring TaskView"
mkdir -p /opt/taskview_data
cat <<EOF >/opt/taskview_data/.env
NODE_ENV=production
DB_HOST=localhost
DB_PORT=5432
DB_NAME=taskview
DB_USER=taskview
DB_PASSWORD=${PG_DB_PASS}
APP_PORT=1401
APP_URL=http://${LOCAL_IP}
CORS_ALLOWED_ORIGINS=http://${LOCAL_IP}
TRUST_PROXY=1
JWT_ALG=HS256
JWT_SIGN=$(openssl rand -hex 64)
ACCESS_LIFE_TIME=3d
REFRESH_LIFE_TIME=9d
ENCRYPTION_KEY=$(openssl rand -hex 32)
PASSWORD_CHANGE_CONFIRMATION=password
EOF
chmod 600 /opt/taskview_data/.env
msg_ok "Configured TaskView"
msg_info "Creating TaskView Database Schema"
# The migration reads DB_* from the .env in its working directory
cd /opt/taskview_data
$STD node /opt/taskview/api/dist-migration/taskview-db-migration.js --create
msg_ok "Created TaskView Database Schema"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/taskview
server {
listen 80;
server_name _;
root /opt/taskview/web/dist;
index index.html;
gzip_types text/css application/javascript application/json image/svg+xml;
location ~ ^/(module|scim|\.well-known)/ {
proxy_pass http://127.0.0.1:1401;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Pins the web client to the API behind this same origin and hides the server selector
location = /config.js {
default_type application/javascript;
add_header Cache-Control "no-cache, no-store, must-revalidate";
return 200 'window.__TASKVIEW_CONFIG__ = { apiUrl: window.location.origin };';
}
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
location / {
try_files $uri $uri/ /index.html;
}
}
EOF
nginx_enable_site "taskview"
msg_ok "Configured Nginx"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/taskview.service
[Unit]
Description=TaskView API
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/taskview_data
EnvironmentFile=/opt/taskview_data/.env
ExecStart=/usr/bin/node /opt/taskview/api/dist/taskview-server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now taskview
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+7 -3
View File
@@ -17,6 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
libkitinerary-bin
ln -sf "$(find /usr/lib -name kitinerary-extractor -type f | head -1)" /usr/local/bin/kitinerary-extractor
msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
@@ -24,7 +25,7 @@ fetch_and_deploy_gh_release "trek" "liketrek/TREK" "tarball"
msg_info "Setup TREK"
cd /opt/trek
$STD npm ci
$STD npm ci --ignore-scripts
$STD npm run build --workspace=shared
$STD npm run build --workspace=client
$STD npm run build --workspace=server
@@ -43,13 +44,16 @@ mkdir -p \
/opt/trek/uploads/files \
/opt/trek/uploads/covers \
/opt/trek/uploads/avatars \
/opt/trek/uploads/photos
/opt/trek/uploads/photos \
/opt/trek/uploads/journey \
/opt/trek/uploads/places
rm -rf /opt/trek/server/data
rm -rf /opt/trek/server/uploads
ln -s /opt/trek/data /opt/trek/server/data
ln -s /opt/trek/uploads /opt/trek/server/uploads
rm -rf /opt/trek/node_modules
cd /opt/trek
$STD npm prune --omit=dev
$STD npm ci --workspace=server --omit=dev --ignore-scripts
msg_ok "Set up TREK Workspace"
msg_info "Configuring TREK"
+2 -88
View File
@@ -17,7 +17,6 @@ msg_info "Installing Dependencies"
$STD apt install -y \
build-essential \
git \
nginx \
redis-server \
atomicparsley \
python3-dev \
@@ -107,7 +106,7 @@ cat <<EOF >/opt/tubearchivist/.env
TA_HOST=http://${LOCAL_IP}:8000
TA_USERNAME=admin
TA_PASSWORD=${TA_PASSWORD}
TA_BACKEND_PORT=8080
TA_PORT=8000
TA_APP_DIR=/opt/tubearchivist/backend
TA_CACHE_DIR=/cache
TA_MEDIA_DIR=/youtube
@@ -133,92 +132,6 @@ msg_info "Installing yt-dlp Nightly"
$STD uv pip install --python /opt/tubearchivist/.venv/bin/python -U --prerelease allow "yt-dlp[default]"
msg_ok "Installed yt-dlp Nightly"
msg_info "Configuring Nginx"
sed -i 's/^user www-data;$/user root;/' /etc/nginx/nginx.conf
cat <<'EOF' >/etc/nginx/sites-available/default
server {
listen 8000;
location = /_auth {
internal;
proxy_pass http://localhost:8080/api/ping/;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /cache/videos/ {
auth_request /_auth;
alias /cache/videos/;
}
location /cache/channels/ {
auth_request /_auth;
alias /cache/channels/;
}
location /cache/playlists/ {
auth_request /_auth;
alias /cache/playlists/;
}
location /media/ {
auth_request /_auth;
alias /youtube/;
types {
text/vtt vtt;
}
}
location /youtube/ {
auth_request /_auth;
alias /youtube/;
types {
video/mp4 mp4;
}
}
location /api {
include proxy_params;
proxy_pass http://localhost:8080;
}
location /admin {
include proxy_params;
proxy_pass http://localhost:8080;
}
location /static/ {
alias /opt/tubearchivist/backend/staticfiles/;
}
root /opt/tubearchivist/backend/static;
index index.html;
location ~* ^/(?!static/|cache/).*\.(?:css|js|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
try_files $uri $uri/ /index.html =404;
}
location = /index.html {
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
expires 0;
}
location / {
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
expires 0;
try_files $uri $uri/ /index.html =404;
}
}
EOF
systemctl enable -q nginx
systemctl restart nginx
msg_ok "Configured Nginx"
msg_info "Creating Services"
cat <<'RUNEOF' >/opt/tubearchivist/backend/run.sh
#!/bin/bash
@@ -237,6 +150,7 @@ for i in $(seq 1 30); do
sleep 2
done
$PYTHON manage.py ta_stop_on_error
$PYTHON manage.py migrate
$PYTHON manage.py collectstatic --noinput -c
$PYTHON manage.py ta_envcheck
+39 -6
View File
@@ -314,21 +314,54 @@ EOF
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox --title "Support Subscriptions" \
"Supporting the software's development team is essential.\nPlease consider buying a subscription." 10 58
msg_info "Disabling subscription nag"
cat >/etc/apt/apt.conf.d/no-nag-script <<'EOF'
DPkg::Post-Invoke { "if [ -s /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js ] && ! grep -q -F 'NoMoreNagging' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; then sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js; fi"; };
EOF
mkdir -p /usr/local/bin
cat >/usr/local/bin/pmg-remove-nag.sh <<'EOF'
#!/bin/sh
WEB_JS=/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
if [ -s "$WEB_JS" ] && ! grep -q NoMoreNagging "$WEB_JS"; then
sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' "$WEB_JS"
fi
cat >/etc/apt/apt.conf.d/no-nag-script-pmgmanagerlib-mobile <<'EOF'
DPkg::Post-Invoke { "if [ -s /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js ] && ! grep -q -F 'NoMoreNagging' /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js; then sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' /usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js; fi"; };
MOBILE_JS=/usr/share/javascript/pmg-gui/js/pmgmanagerlib-mobile.js
if [ -s "$MOBILE_JS" ] && ! grep -q NoMoreNagging "$MOBILE_JS"; then
sed -i '/data\.status/{s/\!//;s/active/NoMoreNagging/}' "$MOBILE_JS"
fi
MOBILE_TPL=/usr/share/pmg-mobile-quarantine-ui/pmg-mobile-index.html.tt
if [ -s "$MOBILE_TPL" ] && ! grep -q NoMoreNagging "$MOBILE_TPL"; then
sed -i '/<head>/r /dev/stdin' "$MOBILE_TPL" <<'HTML'
<script>
// NoMoreNagging
const nativeFetch = window.fetch.bind(window);
window.fetch = async (...args) => {
const res = await nativeFetch(...args);
if (!String(args[0]?.url ?? args[0]).includes('/nodes/localhost/subscription')) return res;
const body = await res.clone().json().catch(() => null);
if (!body?.data) return res;
body.data.status = 'active';
return new Response(JSON.stringify(body), { status: res.status, headers: res.headers });
};
</script>
HTML
fi
EOF
chmod 755 /usr/local/bin/pmg-remove-nag.sh
cat >/etc/apt/apt.conf.d/no-nag-script <<'EOF'
DPkg::Post-Invoke { "/usr/local/bin/pmg-remove-nag.sh"; };
EOF
rm -f /etc/apt/apt.conf.d/no-nag-script-pmgmanagerlib-mobile
msg_ok "Disabled subscription nag (clear browser cache!)"
;;
no)
msg_error "Selected no to Disabling subscription nag"
rm -f /etc/apt/apt.conf.d/no-nag-script 2>/dev/null
rm -f /etc/apt/apt.conf.d/no-nag-script /etc/apt/apt.conf.d/no-nag-script-pmgmanagerlib-mobile /usr/local/bin/pmg-remove-nag.sh
;;
esac
apt --reinstall install proxmox-widget-toolkit pmg-gui &>/dev/null || msg_error "Widget toolkit reinstall failed"
if dpkg -s pmg-mobile-quarantine-ui &>/dev/null; then
apt --reinstall install pmg-mobile-quarantine-ui &>/dev/null || msg_error "Mobile quarantine UI reinstall failed"
fi
# ---- UPDATE ----
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --menu \