Compare commits

...

22 Commits

Author SHA1 Message Date
github-actions[bot]
976160e5ff Update CHANGELOG.md 2026-09-12 15:17:56 +00:00
community-scripts-pr-app[bot]
95d80a4941 Update CHANGELOG.md (#17217)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 15:15:09 +00:00
community-scripts-pr-app[bot]
5f1b71a85e Update CHANGELOG.md (#17213)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 12:31:07 +00:00
eXistC
2c6a578343 fix(dispatcharr): add comskip installation and build dependencies (#16224) 2026-09-12 14:30:42 +02:00
community-scripts-pr-app[bot]
b068e7cd8a Update CHANGELOG.md (#17212)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 12:25:32 +00:00
Kevin Langhans
02cf8a0a8f feat(jitsi-meet): optional public setup (FQDN, Let's Encrypt, NAT, secure domain) (#17132)
Adds five optional var_jitsi_* settings to the install script. All default
to empty, which keeps the previous LAN-only behaviour (container IP,
self-signed certificate):

- var_jitsi_domain     public hostname instead of the container IP
- var_jitsi_le_email   Let's Encrypt via the packaged debconf option
- var_jitsi_public_ip  static NAT mapping in jvb.conf (JVB 2.3+)
- var_jitsi_admin_user secure domain: only authenticated users create rooms
- var_jitsi_admin_pass password for that user (generated when empty)

Tested on Proxmox VE 9.2 as unprivileged Debian 13 LXC, both with all
variables set (self-signed) and with none set.

Co-authored-by: klanghans <13657862+klanghans@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-12 14:25:09 +02:00
community-scripts-pr-app[bot]
9580c0f5bd Update CHANGELOG.md (#17211)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 12:24:23 +00:00
push-app-to-main[bot]
3dbfe54701 Add hammer (ct) (#17189)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-09-12 14:24:00 +02:00
community-scripts-pr-app[bot]
ab5f20ec71 Update CHANGELOG.md (#17207)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 10:01:49 +00:00
CanbiZ (MickLesk)
0a48435ef9 poznote: serve from src/public docroot (#17187) 2026-09-12 12:01:26 +02:00
community-scripts-pr-app[bot]
9e22ffe10d Update CHANGELOG.md (#17206)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 09:53:19 +00:00
push-app-to-main[bot]
4412cc0eae gotenberg (#17205)
* Add gotenberg (ct)

* Update messages in gotenberg.sh for clarity

* Implement unoconverter update in gotenberg.sh

* Fix formatting and add Go version setup in script

* Update Gotenberg installation script for Go version

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-09-12 11:52:55 +02:00
community-scripts-pr-app[bot]
fe823143fb Update CHANGELOG.md (#17204)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 06:31:53 +00:00
CanbiZ (MickLesk)
24e006cd81 calibre-web: use calibreweb release identifier to avoid version file collision (#17186) 2026-09-12 08:31:29 +02:00
community-scripts-pr-app[bot]
1b581bddea Update CHANGELOG.md (#17202)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-11 21:41:29 +00:00
push-app-to-main[bot]
c1fc07d937 Lemonade-Server (#17190)
* Add lemonade-server (ct)

* Enable ARM64 support by default in script

---------

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-09-11 23:40:58 +02:00
community-scripts-pr-app[bot]
c98008cc16 Update CHANGELOG.md (#17201)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-11 18:12:50 +00:00
thieneret
8713dabc56 update authentik to 2026.8.2 (#17198) 2026-09-11 20:12:18 +02:00
community-scripts-pr-app[bot]
6b30d4462d Update .app files (#17194)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-09-11 10:18:07 +02:00
community-scripts-pr-app[bot]
fc40e198b6 Update CHANGELOG.md (#17195)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-11 08:17:34 +00:00
push-app-to-main[bot]
b875f780bb Dockhand (#17191)
* Add dockhand (addon)

* Revise copyright and license details in dockhand.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
2026-09-11 10:17:05 +02:00
MickLesk
10ab064f26 formatting fix issue report 2026-09-11 08:37:28 +02:00
23 changed files with 778 additions and 41 deletions

View File

@@ -6,13 +6,17 @@ body:
attributes: attributes:
value: | value: |
## ⚠️ **IMPORTANT - READ FIRST** ## ⚠️ **IMPORTANT - READ FIRST**
- 🔍 **Search first:** Before submitting, check if the issue has already been reported or resolved in [closed issues](https://github.com/community-scripts/ProxmoxVE/issues?q=is%3Aissue+is%3Aclosed). If found, comment on that issue instead of creating a new one.
Alternatively, check the **[Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)** under the *"Announcement"* or *"Guide"* categories for relevant information.
- 🔎 If you encounter `[ERROR] in line 23: exit code *: while executing command "$@" > /dev/null 2>&1`, rerun the script with verbose mode before submitting the issue.
- 📜 **Read the script:** Familiarize yourself with the script's content and its purpose. This will help you understand the issue better and provide more relevant information
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently. **1. Reproduce the issue with verbose mode - this is mandatory.**
Set `var_verbose=yes` (or *Advanced Settings → Verbose Mode*) and run the script again.
Only a verbose log shows what actually failed - a bare `[ERROR] in line 23: exit code *` tells us nothing.
**Reports without a verbose log will most likely be closed.**
**2. Search before you post.**
Check the [closed issues](https://github.com/community-scripts/ProxmoxVE/issues?q=is%3Aissue+is%3Aclosed) and the [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) (*Announcement* / *Guide*). If it is already known, comment there instead of opening a new issue.
**3. Read the script.**
Knowing what it does makes it much easier to describe the problem - and often to solve it yourself.
- type: input - type: input
id: guidelines id: guidelines
@@ -89,30 +93,34 @@ body:
value: "💡 **Tip:** If you are using Advanced Settings, please test with Default Settings before submitting an issue." value: "💡 **Tip:** If you are using Advanced Settings, please test with Default Settings before submitting an issue."
- type: dropdown - type: dropdown
id: linux_distribution id: os_distribution
attributes: attributes:
label: 🖥️ Which Linux distribution are you using? label: 🖥️ Which Linux distribution is the container running?
options: options:
- Debian
- Ubuntu
- Alpine - Alpine
- Debian 12 - Devuan
- Debian 13 - AlmaLinux
- Devuan 5 - Rocky Linux
- Ubuntu 22.04 - CentOS Stream
- Ubuntu 24.04 - Fedora
- Ubuntu 25.04 - openSUSE
- AlmaLinux 9 - openEuler
- AlmaLinux 10
- Rocky Linux 9
- Rocky Linux 10
- CentOS Stream 9
- Fedora 42
- openSUSE 15
- openEuler 25
- Gentoo - Gentoo
- Other / not listed - Other / not listed
validations: validations:
required: true required: true
- type: input
id: os_version
attributes:
label: 🔢 Which version of that distribution?
description: "Run `cat /etc/os-release` inside the container if unsure."
placeholder: "e.g. 13 (Debian), 24.04 (Ubuntu), 3.22 (Alpine)"
validations:
required: true
- type: dropdown - type: dropdown
id: host_arm64 id: host_arm64
attributes: attributes:

View File

@@ -540,16 +540,42 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details> </details>
## 2026-09-12
### 🆕 New Scripts
- Hammer ([#17189](https://github.com/community-scripts/ProxmoxVE/pull/17189))
- gotenberg ([#17205](https://github.com/community-scripts/ProxmoxVE/pull/17205))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(dispatcharr): add comskip installation and build dependencies [@eXistC](https://github.com/eXistC) ([#16224](https://github.com/community-scripts/ProxmoxVE/pull/16224))
- poznote: serve from src/public docroot [@MickLesk](https://github.com/MickLesk) ([#17187](https://github.com/community-scripts/ProxmoxVE/pull/17187))
- calibre-web: use calibreweb release identifier to avoid version file collision [@MickLesk](https://github.com/MickLesk) ([#17186](https://github.com/community-scripts/ProxmoxVE/pull/17186))
- #### ✨ New Features
- feat(jitsi-meet): optional public setup (FQDN, Let's Encrypt, NAT, secure domain) [@klanghans](https://github.com/klanghans) ([#17132](https://github.com/community-scripts/ProxmoxVE/pull/17132))
### 💾 Core
- VM's: show the selected CPU model instead of doubling it [@MickLesk](https://github.com/MickLesk) ([core#37](https://github.com/community-scripts/core/pull/37))
- Generate app headers [@github-actions[bot]](https://github.com/github-actions[bot]) ([core#36](https://github.com/community-scripts/core/pull/36))
## 2026-09-11 ## 2026-09-11
### 🆕 New Scripts ### 🆕 New Scripts
- Lemonade-Server ([#17190](https://github.com/community-scripts/ProxmoxVE/pull/17190))
- OneTimeSecret ([#17097](https://github.com/community-scripts/ProxmoxVE/pull/17097)) - OneTimeSecret ([#17097](https://github.com/community-scripts/ProxmoxVE/pull/17097))
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- update authentik to 2026.8.2 [@thieneret](https://github.com/thieneret) ([#17198](https://github.com/community-scripts/ProxmoxVE/pull/17198))
- passwordpusher: restore data before running migrations [@MickLesk](https://github.com/MickLesk) ([#17141](https://github.com/community-scripts/ProxmoxVE/pull/17141)) - passwordpusher: restore data before running migrations [@MickLesk](https://github.com/MickLesk) ([#17141](https://github.com/community-scripts/ProxmoxVE/pull/17141))
- paperclip: install the rust toolchain needed by the runner build [@MickLesk](https://github.com/MickLesk) ([#17142](https://github.com/community-scripts/ProxmoxVE/pull/17142)) - paperclip: install the rust toolchain needed by the runner build [@MickLesk](https://github.com/MickLesk) ([#17142](https://github.com/community-scripts/ProxmoxVE/pull/17142))
- homepage: run next directly instead of through pnpm [@MickLesk](https://github.com/MickLesk) ([#17155](https://github.com/community-scripts/ProxmoxVE/pull/17155)) - homepage: run next directly instead of through pnpm [@MickLesk](https://github.com/MickLesk) ([#17155](https://github.com/community-scripts/ProxmoxVE/pull/17155))
@@ -563,6 +589,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
### 🧰 Tools ### 🧰 Tools
- Dockhand ([#17191](https://github.com/community-scripts/ProxmoxVE/pull/17191))
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- update-apps: rewrite the retired Gitea base in every container before updating it [@MickLesk](https://github.com/MickLesk) ([#17156](https://github.com/community-scripts/ProxmoxVE/pull/17156)) - update-apps: rewrite the retired Gitea base in every container before updating it [@MickLesk](https://github.com/MickLesk) ([#17156](https://github.com/community-scripts/ProxmoxVE/pull/17156))

View File

@@ -49,7 +49,7 @@ function update_script() {
RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust
setup_yq setup_yq
AUTHENTIK_VERSION="version/2026.8.1" AUTHENTIK_VERSION="version/2026.8.2"
# Source: https://github.com/goauthentik/fips/blob/main/Makefile#L26 # Source: https://github.com/goauthentik/fips/blob/main/Makefile#L26
XMLSEC_VERSION="1.3.12" XMLSEC_VERSION="1.3.12"
@@ -184,8 +184,12 @@ EOF
msg_info "Updating services" msg_info "Updating services"
sed -i 's/authentik Go Server (API Gateway)/authentik Server/g' /etc/systemd/system/authentik-server.service sed -i 's/authentik Go Server (API Gateway)/authentik Server/g' /etc/systemd/system/authentik-server.service
if ! grep -qF -- 'ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-server.service; then
sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-server.service sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-server.service
fi
if ! grep -qF -- 'ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-worker.service; then
sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-worker.service sed -i '/ExecStart=/i ExecStartPre=/usr/bin/mkdir -p "${TMPDIR}"' /etc/systemd/system/authentik-worker.service
fi
systemctl daemon-reload systemctl daemon-reload
msg_ok "Updated services" msg_ok "Updated services"
@@ -224,8 +228,8 @@ for i in {1..10}; do
sleep 1 sleep 1
done done
$STD pct exec "$CTID" -- bash -c "mkdir -p /opt/authentik-data/{certs,media,geoip,templates}; \ $STD pct exec "$CTID" -- bash -c "mkdir -p /opt/authentik-data/{certs,media,geoip,templates}; \
cp /opt/authentik/tests/GeoLite2-ASN-Test.mmdb /opt/authentik-data/geoip/GeoLite2-ASN.mmdb; \ cp /opt/authentik/tests/geoip/GeoLite2-ASN-Test.mmdb /opt/authentik-data/geoip/GeoLite2-ASN.mmdb; \
cp /opt/authentik/tests/GeoLite2-City-Test.mmdb /opt/authentik-data/geoip/GeoLite2-City.mmdb; \ cp /opt/authentik/tests/geoip/GeoLite2-City-Test.mmdb /opt/authentik-data/geoip/GeoLite2-City.mmdb; \
cp -r /opt/authentik/blueprints /opt/authentik-data/; \ cp -r /opt/authentik/blueprints /opt/authentik-data/; \
rm -r /opt/authentik/blueprints; \ rm -r /opt/authentik/blueprints; \
find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +" find /opt/authentik-data -path '*/lost+found' -prune -o -exec chown authentik:authentik {} +"

View File

@@ -32,14 +32,18 @@ function update_script() {
exit exit
fi fi
if check_for_gh_release "Calibre-Web" "janeczku/calibre-web"; then if [[ -f /root/.calibre-web && ! -e /root/.calibreweb ]]; then
mv /root/.calibre-web /root/.calibreweb
fi
if check_for_gh_release "calibreweb" "janeczku/calibre-web"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop calibre-web systemctl stop calibre-web
msg_ok "Stopped Service" msg_ok "Stopped Service"
create_backup /opt/calibre-web/data create_backup /opt/calibre-web/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Calibre-Web" "janeczku/calibre-web" "prebuild" "latest" "/opt/calibre-web" "calibreweb*.tar.gz" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "calibreweb" "janeczku/calibre-web" "prebuild" "latest" "/opt/calibre-web" "calibreweb*.tar.gz"
setup_uv setup_uv
msg_info "Installing Dependencies" msg_info "Installing Dependencies"

View File

@@ -106,7 +106,18 @@ EOF
msg_ok "Migrated Nginx Configuration" msg_ok "Migrated Nginx Configuration"
fi fi
ensure_dependencies vlc-bin vlc-plugin-base ensure_dependencies vlc-bin vlc-plugin-base build-essential autoconf libtool libargtable2-dev libavformat-dev libsdl2-dev libswscale-dev
if ! command -v comskip &> /dev/null; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Comskip" "erikkaashoek/Comskip" "tarball"
msg_info "Compiling Comskip"
cd /opt/Comskip
$STD ./autogen.sh
$STD ./configure
$STD make
$STD make install
msg_ok "Compiled and Installed Comskip"
fi
if check_for_gh_release "Dispatcharr" "Dispatcharr/Dispatcharr"; then if check_for_gh_release "Dispatcharr" "Dispatcharr/Dispatcharr"; then
msg_info "Stopping Services" msg_info "Stopping Services"

75
ct/gotenberg.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main"
_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: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/gotenberg/gotenberg
APP="Gotenberg"
var_tags="${var_tags:-document;pdf}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-15}"
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 [[ ! -f /etc/systemd/system/gotenberg.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "gotenberg" "gotenberg/gotenberg"; then
msg_info "Stopping Service"
systemctl stop gotenberg
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gotenberg" "gotenberg/gotenberg" "tarball" "latest" "/opt/gotenberg"
GO_VERSION="$(awk '$1=="go"{print $2}' /opt/gotenberg/go.mod | cut -d. -f1,2)" setup_go
msg_info "Building gotenberg (Patience)"
cd /opt/gotenberg
export CGO_ENABLED=0
$STD go mod download
$STD go build -o /usr/local/bin/gotenberg \
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v8/cmd.Version=$(cat ~/.gotenberg)'" \
cmd/gotenberg/main.go
msg_ok "Built gotenberg"
msg_info "Updating unoconverter"
UNOCONVERTER_VERSION=$(get_latest_github_release "gotenberg/unoconverter" "false")
download_file "https://raw.githubusercontent.com/gotenberg/unoconverter/${UNOCONVERTER_VERSION}/unoconv" /usr/local/bin/unoconverter
chmod +x /usr/local/bin/unoconverter
msg_ok "Updated unoconverter"
msg_info "Starting Service"
systemctl start gotenberg
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}Gotenberg is a stateless API and has no web interface.${CL}"
echo -e "${INFO}${YW}Check the health endpoint using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:3000/health${CL}"

58
ct/hammer.sh Normal file
View File

@@ -0,0 +1,58 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main"
_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/Darkrock-Studios/hammer-editor
APP="Hammer"
var_tags="${var_tags:-writing;sync-server}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_arm64="${var_arm64:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/hammer ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "hammer" "Darkrock-Studios/hammer-editor"; then
msg_info "Stopping Service"
systemctl stop hammer
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hammer" "Darkrock-Studios/hammer-editor" "prebuild" "latest" "/opt/hammer" "server.zip"
chmod +x /opt/hammer/bin/server
msg_info "Starting Service"
systemctl start hammer
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}"

6
ct/headers/gotenberg Normal file
View File

@@ -0,0 +1,6 @@
______ __ __
/ ____/___ / /____ ____ / /_ ___ _________ _
/ / __/ __ \/ __/ _ \/ __ \/ __ \/ _ \/ ___/ __ `/
/ /_/ / /_/ / /_/ __/ / / / /_/ / __/ / / /_/ /
\____/\____/\__/\___/_/ /_/_.___/\___/_/ \__, /
/____/

6
ct/headers/hammer Normal file
View File

@@ -0,0 +1,6 @@
__ __
/ / / /___ _____ ___ ____ ___ ___ _____
/ /_/ / __ `/ __ `__ \/ __ `__ \/ _ \/ ___/
/ __ / /_/ / / / / / / / / / / / __/ /
/_/ /_/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_/

View File

@@ -0,0 +1,6 @@
__ __ _____
/ / ___ ____ ___ ____ ____ ____ _____/ /__ / ___/___ ______ _____ _____
/ / / _ \/ __ `__ \/ __ \/ __ \/ __ `/ __ / _ \______\__ \/ _ \/ ___/ | / / _ \/ ___/
/ /___/ __/ / / / / / /_/ / / / / /_/ / /_/ / __/_____/__/ / __/ / | |/ / __/ /
/_____/\___/_/ /_/ /_/\____/_/ /_/\__,_/\__,_/\___/ /____/\___/_/ |___/\___/_/

View File

@@ -17,6 +17,14 @@ var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}" var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
# Optional public setup, read by the install script (all empty = LAN-only install as before).
# Without the export they never reach the container.
export var_jitsi_domain="${var_jitsi_domain:-}"
export var_jitsi_le_email="${var_jitsi_le_email:-}"
export var_jitsi_public_ip="${var_jitsi_public_ip:-}"
export var_jitsi_admin_user="${var_jitsi_admin_user:-}"
export var_jitsi_admin_pass="${var_jitsi_admin_pass:-}"
header_info "$APP" header_info "$APP"
variables variables
color color
@@ -50,4 +58,7 @@ description
msg_ok "Completed Successfully!\n" msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}" echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}${CL}" echo -e "${GATEWAY}${BGN}https://${var_jitsi_domain:-$IP}${CL}"
if [[ -n "${var_jitsi_domain}" ]]; then
echo -e "${INFO}${YW}Forward TCP 80/443 and UDP 10000 to the container. Secure-domain credentials (if enabled) are in ~/jitsi-meet.creds inside the container.${CL}"
fi

57
ct/lemonade-server.sh Normal file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main"
_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: Jamie (jamiej)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/lemonade-sdk/lemonade
APP="Lemonade-Server"
var_tags="${var_tags:-ai}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-80}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if ! command -v lemonade &>/dev/null; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "lemonade-server" "lemonade-sdk/lemonade"; then
msg_info "Stopping Service"
systemctl stop lemond
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "lemonade-server" "lemonade-sdk/lemonade" "binary" "latest" "/tmp" "lemonade-server_*-debian13_$(arch_resolve).deb"
msg_info "Starting Service"
systemctl start lemond
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}:13305${CL}"

View File

@@ -68,7 +68,7 @@ map \$uri \$poznote_coop {
server { server {
listen 8040; listen 8040;
root /var/www/html; root /var/www/html/public;
index index.php index.html; index index.php index.html;
gzip on; gzip on;
@@ -144,10 +144,12 @@ server {
} }
location ~ ^/data/users/[0-9]+/backgrounds/ { location ~ ^/data/users/[0-9]+/backgrounds/ {
root /var/www/html;
try_files \$uri =404; try_files \$uri =404;
} }
location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ { location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ {
root /var/www/html;
try_files \$uri =404; try_files \$uri =404;
} }

View File

@@ -58,7 +58,7 @@ PG_VERSION="17" setup_postgresql
PG_DB_NAME="authentik" PG_DB_USER="authentik" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db PG_DB_NAME="authentik" PG_DB_USER="authentik" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
XMLSEC_VERSION="1.3.12" XMLSEC_VERSION="1.3.12"
AUTHENTIK_VERSION="version/2026.8.1" AUTHENTIK_VERSION="version/2026.8.2"
fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "${XMLSEC_VERSION}" "/opt/xmlsec" fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "${XMLSEC_VERSION}" "/opt/xmlsec"
fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik" fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
GO_VERSION="$(grep -m1 '^go ' /opt/authentik/go.mod | awk '{print $2}')" setup_go GO_VERSION="$(grep -m1 '^go ' /opt/authentik/go.mod | awk '{print $2}')" setup_go

View File

@@ -32,7 +32,7 @@ msg_info "Installing Calibre (for eBook conversion)"
$STD apt install -y calibre $STD apt install -y calibre
msg_ok "Installed Calibre" msg_ok "Installed Calibre"
fetch_and_deploy_gh_release "Calibre-Web" "janeczku/calibre-web" "prebuild" "latest" "/opt/calibre-web" "calibreweb*.tar.gz" fetch_and_deploy_gh_release "calibreweb" "janeczku/calibre-web" "prebuild" "latest" "/opt/calibre-web" "calibreweb*.tar.gz"
setup_uv setup_uv
msg_info "Installing Python Dependencies" msg_info "Installing Python Dependencies"

View File

@@ -25,7 +25,13 @@ $STD apt install -y \
procps \ procps \
vlc-bin \ vlc-bin \
vlc-plugin-base \ vlc-plugin-base \
streamlink streamlink \
autoconf \
libtool \
libargtable2-dev \
libavformat-dev \
libsdl2-dev \
libswscale-dev
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
setup_uv setup_uv
@@ -33,6 +39,15 @@ NODE_VERSION="24" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="dispatcharr_db" PG_DB_USER="dispatcharr_usr" setup_postgresql_db PG_DB_NAME="dispatcharr_db" PG_DB_USER="dispatcharr_usr" setup_postgresql_db
fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr" "tarball" fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr" "tarball"
fetch_and_deploy_gh_release "Comskip" "erikkaashoek/Comskip" "tarball"
msg_info "Compiling Comskip"
cd /opt/Comskip
$STD ./autogen.sh
$STD ./configure
$STD make
$STD make install
msg_ok "Compiled and Installed Comskip"
msg_info "Installing Python Dependencies with uv" msg_info "Installing Python Dependencies with uv"
cd /opt/dispatcharr cd /opt/dispatcharr

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/gotenberg/gotenberg
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 \
chromium \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
libreoffice-draw \
libreoffice-math \
python3-uno \
python-is-python3 \
pdftk-java \
qpdf \
libimage-exiftool-perl \
fonts-crosextra-carlito \
fonts-crosextra-caladea \
fonts-liberation \
fonts-liberation2 \
fonts-dejavu \
fonts-noto-cjk \
fonts-noto-color-emoji \
fonts-noto-core
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "pdfcpu" "pdfcpu/pdfcpu" "prebuild" "latest" "/opt/pdfcpu" "pdfcpu_*_Linux_$(arch_resolve "x86_64" "arm64").tar.xz"
ln -sf "$(find /opt/pdfcpu -type f -name pdfcpu | head -n1)" /usr/local/bin/pdfcpu
msg_info "Installing unoconverter"
UNOCONVERTER_VERSION=$(get_latest_github_release "gotenberg/unoconverter" "false")
download_file "https://raw.githubusercontent.com/gotenberg/unoconverter/${UNOCONVERTER_VERSION}/unoconv" /usr/local/bin/unoconverter
chmod +x /usr/local/bin/unoconverter
msg_ok "Installed unoconverter"
fetch_and_deploy_gh_release "gotenberg" "gotenberg/gotenberg" "tarball" "latest" "/opt/gotenberg"
GO_VERSION="$(awk '$1=="go"{print $2}' /opt/gotenberg/go.mod | cut -d. -f1,2)" setup_go
msg_info "Building Gotenberg (Patience)"
cd /opt/gotenberg
export CGO_ENABLED=0
$STD go mod download
$STD go build -o /usr/local/bin/gotenberg \
-ldflags "-s -w -X 'github.com/gotenberg/gotenberg/v8/cmd.Version=$(cat ~/.gotenberg)'" \
cmd/gotenberg/main.go
msg_ok "Built Gotenberg"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/gotenberg.service
[Unit]
Description=Gotenberg
Documentation=https://gotenberg.dev
After=network.target
[Service]
Type=simple
User=root
Environment=LANG=C.UTF-8
Environment=LC_ALL=C.UTF-8
Environment=PDFTK_BIN_PATH=/usr/bin/pdftk
Environment=QPDF_BIN_PATH=/usr/bin/qpdf
Environment=EXIFTOOL_BIN_PATH=/usr/bin/exiftool
Environment=PDFCPU_BIN_PATH=/usr/local/bin/pdfcpu
Environment=CHROMIUM_BIN_PATH=/usr/bin/chromium
Environment=CHROMIUM_HYPHEN_DATA_DIR_PATH=/opt/gotenberg/build/chromium-hyphen-data
Environment=LIBREOFFICE_BIN_PATH=/usr/lib/libreoffice/program/soffice.bin
Environment=UNOCONVERTER_BIN_PATH=/usr/local/bin/unoconverter
Environment=OTEL_TRACES_EXPORTER=none
Environment=OTEL_METRICS_EXPORTER=none
Environment=OTEL_LOGS_EXPORTER=none
ExecStart=/usr/local/bin/gotenberg --api-port=3000
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now gotenberg
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc

100
install/hammer-install.sh Normal file
View File

@@ -0,0 +1,100 @@
#!/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/Darkrock-Studios/hammer-editor
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 \
unzip \
fontconfig \
libfreetype6
msg_ok "Installed Dependencies"
JAVA_VERSION="21" setup_java
fetch_and_deploy_gh_release "hammer" "Darkrock-Studios/hammer-editor" "prebuild" "latest" "/opt/hammer" "server.zip"
msg_info "Configuring Hammer Sync Server"
chmod +x /opt/hammer/bin/server
mkdir -p /opt/hammer_data
cat <<EOF >/opt/hammer_data/config.toml
# Hammer Sync Server configuration
# Reference: https://github.com/Darkrock-Studios/hammer-editor/blob/develop/docs/HOW-TO-RUN-A-SERVER.md
# Loaded automatically from the data directory. Apply changes with:
# systemctl restart hammer
host = "${LOCAL_IP}"
port = 8080
# Hammer clients speak https only and will not connect to plain HTTP. Either put
# a TLS reverse proxy in front of this port, or let Hammer terminate TLS itself
# with a real certificate (self-signed certs are rejected by the clients).
#
# Behind a reverse proxy on this host, restrict the plain port to loopback and
# set the URL the clients actually use:
# bindHosts = ["127.0.0.1", "::1"]
# publicUrl = "https://hammer.example.com"
#
# Hammer terminating TLS itself:
# sslPort = 443
# [sslCert]
# certChainPath = "/etc/letsencrypt/live/hammer.example.com/fullchain.pem"
# privateKeyPath = "/etc/letsencrypt/live/hammer.example.com/privkey.pem"
# forceHttps = true
# Per-page social share images. fontconfig and libfreetype6 are already installed.
# richLinkPreviews = true
# communityEnabled = true
# Storage defaults to an in-process PostgreSQL under /opt/hammer_data/pgdata.
# To use an external PostgreSQL instead:
# [storage]
# type = "remote"
# [storage.remote]
# host = "db.example.com"
# port = 5432
# database = "hammer"
# user = "hammer"
# password = "change-me"
# useSsl = true
# Regenerable render/preview caches, default <data dir>/cache.
# [cache]
# directory = "/var/tmp/hammer-cache"
# maxSizeMb = 200
EOF
cat <<EOF >/etc/systemd/system/hammer.service
[Unit]
Description=Hammer Sync Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/hammer
Environment=SERVER_OPTS=-Duser.home=/opt
ExecStart=/opt/hammer/bin/server
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now hammer
msg_ok "Configured Hammer Sync Server"
motd_ssh
customize
cleanup_lxc

View File

@@ -13,6 +13,29 @@ setting_up_container
network_check network_check
update_os update_os
# Optional public setup. Leave the hostname empty for a LAN-only install
# (container IP, self-signed certificate) - the previous default behaviour.
if [[ -z "${var_jitsi_domain:-}" ]]; then
read -rp "${TAB3}Public hostname (FQDN, leave empty to use the container IP): " var_jitsi_domain || true
fi
var_jitsi_domain="${var_jitsi_domain:-$LOCAL_IP}"
if [[ "$var_jitsi_domain" != "$LOCAL_IP" ]]; then
if [[ -z "${var_jitsi_le_email:-}" ]]; then
read -rp "${TAB3}E-mail for Let's Encrypt (leave empty for a self-signed certificate): " var_jitsi_le_email || true
fi
if [[ -z "${var_jitsi_public_ip:-}" ]]; then
read -rp "${TAB3}Public IP behind NAT (leave empty to detect via STUN): " var_jitsi_public_ip || true
fi
if [[ -z "${var_jitsi_admin_user:-}" ]]; then
read -rp "${TAB3}Admin user for secure domain (leave empty to let anyone create rooms): " var_jitsi_admin_user || true
fi
if [[ -n "${var_jitsi_admin_user:-}" && -z "${var_jitsi_admin_pass:-}" ]]; then
read -rsp "${TAB3}Admin password (leave empty to generate): " var_jitsi_admin_pass || true
echo
fi
fi
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y nginx $STD apt install -y nginx
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
@@ -25,11 +48,72 @@ setup_deb822_repo "jitsi" \
"" ""
msg_info "Installing Jitsi Meet" msg_info "Installing Jitsi Meet"
echo "jitsi-videobridge2 jitsi-videobridge/jvb-hostname string ${LOCAL_IP}" | debconf-set-selections echo "jitsi-videobridge2 jitsi-videobridge/jvb-hostname string ${var_jitsi_domain}" | debconf-set-selections
if [[ -n "${var_jitsi_le_email:-}" ]]; then
# acme.sh (used by the packaged Let's Encrypt helper) refuses to install without cron
$STD apt install -y cron
echo "jitsi-meet-web-config jitsi-meet/cert-choice select Let's Encrypt certificates" | debconf-set-selections
echo "jitsi-meet-web-config jitsi-meet/email string ${var_jitsi_le_email}" | debconf-set-selections
else
echo "jitsi-meet-web-config jitsi-meet/cert-choice select Generate a new self-signed certificate" | debconf-set-selections echo "jitsi-meet-web-config jitsi-meet/cert-choice select Generate a new self-signed certificate" | debconf-set-selections
fi
echo "jitsi-meet-web-config jitsi-meet/jaas-choice boolean false" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive $STD apt install -y jitsi-meet DEBIAN_FRONTEND=noninteractive $STD apt install -y jitsi-meet
msg_ok "Installed Jitsi Meet" msg_ok "Installed Jitsi Meet"
if [[ -n "${var_jitsi_public_ip:-}" ]]; then
msg_info "Configuring NAT mapping"
# JVB 2.3+ reads this from jvb.conf; sip-communicator.properties is no longer used
cat <<EOF >>/etc/jitsi/videobridge/jvb.conf
ice4j {
harvest {
mapping {
static-mappings = [
{ local-address = "${LOCAL_IP}", public-address = "${var_jitsi_public_ip}" }
]
}
}
}
EOF
systemctl restart jitsi-videobridge2
msg_ok "Configured NAT mapping"
fi
if [[ -n "${var_jitsi_admin_user:-}" ]]; then
msg_info "Configuring Secure Domain"
# Only authenticated users may create rooms; guests join via the anonymous domain.
# https://jitsi.github.io/handbook/docs/devops-guide/secure-domain/
var_jitsi_admin_pass="${var_jitsi_admin_pass:-$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-16)}"
sed -i "0,/authentication = \"jitsi-anonymous\"/s//authentication = \"internal_hashed\"/" \
"/etc/prosody/conf.avail/${var_jitsi_domain}.cfg.lua"
cat <<EOF >>"/etc/prosody/conf.avail/${var_jitsi_domain}.cfg.lua"
VirtualHost "guest.${var_jitsi_domain}"
authentication = "anonymous"
c2s_require_encryption = false
EOF
cat <<EOF >>/etc/jitsi/jicofo/jicofo.conf
jicofo {
authentication {
enabled = true
type = XMPP
login-url = "${var_jitsi_domain}"
}
}
EOF
sed -i "s|^\s*// anonymousdomain: 'guest.example.com',| anonymousdomain: 'guest.${var_jitsi_domain}',|" \
"/etc/jitsi/meet/${var_jitsi_domain}-config.js"
$STD prosodyctl register "${var_jitsi_admin_user}" "${var_jitsi_domain}" "${var_jitsi_admin_pass}"
cat <<EOF >~/jitsi-meet.creds
Jitsi Meet Secure Domain
Admin User: ${var_jitsi_admin_user}
Admin Password: ${var_jitsi_admin_pass}
Add more users: prosodyctl register <name> ${var_jitsi_domain} <password>
EOF
systemctl restart prosody jicofo jitsi-videobridge2
msg_ok "Configured Secure Domain"
fi
motd_ssh motd_ssh
customize customize
cleanup_lxc cleanup_lxc

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Jamie (jamiej)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/lemonade-sdk/lemonade
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_deb822_repo \
"backports" \
"https://ftp-master.debian.org/keys/archive-key-13.asc" \
"http://deb.debian.org/debian" \
"trixie-backports" \
"main"
msg_info "Installing Lemonade Server dependencies"
$STD apt install -y \
fonts-katex \
libcpp-httplib0.41 \
libmbedcrypto16 \
libwebsockets19t64
msg_ok "Installed Lemonade Server dependencies"
setup_hwaccel
fetch_and_deploy_gh_release "lemonade-server" "lemonade-sdk/lemonade" "binary" "latest" "/tmp" "lemonade-server_*-debian13_$(arch_resolve).deb"
msg_info "Configuring Remote Access"
systemctl enable -q --now lemond
for _ in $(seq 1 60); do
lemonade status >/dev/null 2>&1 && break
sleep 2
done
$STD lemonade config set host=0.0.0.0
systemctl restart lemond
msg_ok "Configured Remote Access"
motd_ssh
customize
cleanup_lxc

View File

@@ -46,7 +46,7 @@ map \$uri \$poznote_coop {
server { server {
listen 8040; listen 8040;
root /var/www/html; root /var/www/html/public;
index index.php index.html; index index.php index.html;
gzip on; gzip on;
@@ -122,10 +122,12 @@ server {
} }
location ~ ^/data/users/[0-9]+/backgrounds/ { location ~ ^/data/users/[0-9]+/backgrounds/ {
root /var/www/html;
try_files \$uri =404; try_files \$uri =404;
} }
location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ { location ~ ^/data/css/[A-Za-z0-9._-]+\.css$ {
root /var/www/html;
try_files \$uri =404; try_files \$uri =404;
} }

111
tools/addon/dockhand.sh Normal file
View File

@@ -0,0 +1,111 @@
#!/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/Finsys/dockhand
if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL ${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/core.func)
load_functions
elif command -v wget >/dev/null 2>&1; then
source <(wget -qO- ${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/core.func)
load_functions
fi
source <(curl -fsSL ${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/lib/tools.func)
color
catch_errors
APP="Dockhand"
APP_TYPE="addon"
INSTALL_PATH="/opt/dockhand"
COMPOSE_FILE="${INSTALL_PATH}/docker-compose.yaml"
DEFAULT_PORT=3000
header_info "$APP"
IP=$(_get_current_ip)
function check_docker() {
if ! command -v docker >/dev/null 2>&1; then
msg_error "Docker is not installed. This addon requires an existing Docker host/LXC. Exiting."
exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
msg_error "Docker Compose plugin is not available. Install it before running this addon. Exiting."
exit 1
fi
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
}
function install_dockhand() {
local port="${1:-$DEFAULT_PORT}"
check_docker
msg_info "Creating Compose Project"
mkdir -p "$INSTALL_PATH"
cat <<EOF >"$COMPOSE_FILE"
services:
dockhand:
image: fnsys/dockhand:latest
container_name: dockhand
restart: unless-stopped
ports:
- ${port}:3000
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- dockhand_data:/app/data
volumes:
dockhand_data:
EOF
msg_ok "Created Compose Project"
msg_info "Starting ${APP}"
cd "$INSTALL_PATH"
$STD docker compose up -d
msg_ok "Started ${APP}"
msg_ok "${APP} is reachable at http://${IP}:${port}"
echo -e "${TAB}Open the URL and complete the first-run setup wizard to create the admin account."
}
function update_dockhand() {
msg_info "Pulling latest ${APP} image"
cd "$INSTALL_PATH"
$STD docker compose pull
msg_ok "Pulled latest image"
msg_info "Restarting ${APP}"
$STD docker compose up -d --remove-orphans
msg_ok "Restarted ${APP}"
msg_ok "${APP} updated successfully"
}
function uninstall_dockhand() {
msg_info "Removing ${APP}"
cd "$INSTALL_PATH"
$STD docker compose down --remove-orphans
cd /
rm -rf "$INSTALL_PATH"
msg_ok "${APP} uninstalled (the dockhand_data volume was kept; remove it with: docker volume rm dockhand_data)"
}
if [[ -f "$COMPOSE_FILE" ]]; then
read -r -p "Update (1), Uninstall (2), Cancel (3)? [1/2/3]: " action
action="${action//[[:space:]]/}"
case "$action" in
1) update_dockhand ;;
2) uninstall_dockhand ;;
3) msg_info "Cancelled" ;;
*) msg_error "Invalid input" ;;
esac
else
read -r -p "Enter port number (default: ${DEFAULT_PORT}): " PORT_INPUT
PORT="${PORT_INPUT:-$DEFAULT_PORT}"
read -r -p "Install ${APP}? (y/n): " answer
answer="${answer//[[:space:]]/}"
[[ "${answer,,}" =~ ^(y|yes)$ ]] && install_dockhand "$PORT" || msg_info "Installation skipped"
fi

6
tools/headers/dockhand Normal file
View File

@@ -0,0 +1,6 @@
____ __ __ __
/ __ \____ _____/ /__/ /_ ____ _____ ____/ /
/ / / / __ \/ ___/ //_/ __ \/ __ `/ __ \/ __ /
/ /_/ / /_/ / /__/ ,< / / / / /_/ / / / / /_/ /
/_____/\____/\___/_/|_/_/ /_/\__,_/_/ /_/\__,_/