diff --git a/ct/arm/adguard.sh b/ct/arm/adguard.sh new file mode 100644 index 000000000..f0c2b99d1 --- /dev/null +++ b/ct/arm/adguard.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://adguard.com/ + +APP="Adguard" +var_tags="${var_tags:-adblock}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-2}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_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/AdGuardHome ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_error "Adguard Home can only be updated via the user interface." + 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 "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" diff --git a/ct/arm/bazarr.sh b/ct/arm/bazarr.sh new file mode 100644 index 000000000..7c4642aff --- /dev/null +++ b/ct/arm/bazarr.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://www.bazarr.media/ + +APP="Bazarr" +var_tags="${var_tags:-arr}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /var/lib/bazarr/ ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + if check_for_gh_release "bazarr" "morpheus65535/bazarr"; then + apt-get install -y libicu76 &>/dev/null + msg_info "Stopping Service" + systemctl stop bazarr + msg_ok "Stopped Service" + + PYTHON_VERSION="3.12" setup_uv + fetch_and_deploy_gh_release "bazarr" "morpheus65535/bazarr" "prebuild" "latest" "/opt/bazarr" "bazarr.zip" + + msg_info "Setup Bazarr" + mkdir -p /var/lib/bazarr/ + chmod 775 /opt/bazarr /var/lib/bazarr/ + # Always ensure venv exists + if [[ ! -d /opt/bazarr/venv/ ]]; then + $STD uv venv --clear /opt/bazarr/venv --python 3.12 + fi + + # Always check and fix service file if needed + if [[ -f /etc/systemd/system/bazarr.service ]] && grep -q "ExecStart=/usr/bin/python3" /etc/systemd/system/bazarr.service; then + sed -i "s|ExecStart=/usr/bin/python3 /opt/bazarr/bazarr.py|ExecStart=/opt/bazarr/venv/bin/python3 /opt/bazarr/bazarr.py|g" /etc/systemd/system/bazarr.service + systemctl daemon-reload + fi + sed -i.bak 's/--only-binary=Pillow//g' /opt/bazarr/requirements.txt + $STD uv pip install -r /opt/bazarr/requirements.txt --python /opt/bazarr/venv/bin/python3 + msg_ok "Setup Bazarr" + + msg_info "Starting Service" + systemctl start bazarr + 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 "${TAB}${GATEWAY}${BGN}http://${IP}:6767${CL}" diff --git a/ct/arm/bentopdf.sh b/ct/arm/bentopdf.sh new file mode 100644 index 000000000..f7fb63e89 --- /dev/null +++ b/ct/arm/bentopdf.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/alam00000/bentopdf + +APP="BentoPDF" +var_tags="${var_tags:-pdf-editor}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-4096}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +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/bentopdf ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + NODE_VERSION="24" setup_nodejs + + if check_for_gh_release "bentopdf" "alam00000/bentopdf"; then + msg_info "Stopping Service" + systemctl stop bentopdf + msg_ok "Stopped Service" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "/opt/bentopdf" + + msg_info "Updating BentoPDF" + cd /opt/bentopdf + $STD npm ci --no-audit --no-fund + export SIMPLE_MODE=true + $STD npm run build -- --mode production + msg_ok "Updated BentoPDF" + + msg_info "Starting Service" + systemctl start bentopdf + 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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}" diff --git a/ct/arm/homeassistant.sh b/ct/arm/homeassistant.sh new file mode 100644 index 000000000..918f2d551 --- /dev/null +++ b/ct/arm/homeassistant.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://www.home-assistant.io/ + +APP="Home Assistant" +var_tags="${var_tags:-automation;smarthome}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-16}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /var/lib/docker/volumes/hass_config/_data ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + UPD=$(msg_menu "Home Assistant Update Options" \ + "1" "Update ALL Containers" \ + "2" "Remove ALL Unused Images" \ + "3" "Install HACS" \ + "4" "Install FileBrowser") + + if [ "$UPD" == "1" ]; then + msg_info "Updating All Containers" + CONTAINER_LIST="${1:-$(docker ps -q)}" + for container in ${CONTAINER_LIST}; do + CONTAINER_IMAGE="$(docker inspect --format "{{.Config.Image}}" --type container "${container}")" + RUNNING_IMAGE="$(docker inspect --format "{{.Image}}" --type container "${container}")" + docker pull "${CONTAINER_IMAGE}" + LATEST_IMAGE="$(docker inspect --format "{{.Id}}" --type image "${CONTAINER_IMAGE}")" + if [[ "${RUNNING_IMAGE}" != "${LATEST_IMAGE}" ]]; then + pip install -U runlike + echo "Updating ${container} image ${CONTAINER_IMAGE}" + DOCKER_COMMAND="$(runlike --use-volume-id "${container}")" + docker rm --force "${container}" + eval "${DOCKER_COMMAND}" + fi + done + msg_ok "Updated All Containers" + exit + fi + if [ "$UPD" == "2" ]; then + msg_info "Removing ALL Unused Images" + docker image prune -af + msg_ok "Removed ALL Unused Images" + exit + fi + if [ "$UPD" == "3" ]; then + msg_info "Installing Home Assistant Community Store (HACS)" + $STD apt update + cd /var/lib/docker/volumes/hass_config/_data + $STD bash <(curl -fsSL https://get.hacs.xyz) + msg_ok "Installed Home Assistant Community Store (HACS)" + echo -e "\n Reboot Home Assistant and clear browser cache then Add HACS integration.\n" + exit + fi + if [ "$UPD" == "4" ]; then + msg_info "Installing FileBrowser" + RELEASE=$(curl -fsSL https://api.github.com/repos/filebrowser/filebrowser/releases/latest | grep -o '"tag_name": ".*"' | sed 's/"//g' | sed 's/tag_name: //g') + $STD curl -fsSL https://github.com/filebrowser/filebrowser/releases/download/v2.23.0/linux-arm64-filebrowser.tar.gz | tar -xzv -C /usr/local/bin + $STD filebrowser config init -a '0.0.0.0' + $STD filebrowser config set -a '0.0.0.0' + $STD filebrowser users add admin helper-scripts.com --perm.admin + msg_ok "Installed FileBrowser" + + msg_info "Creating Service" + service_path="/etc/systemd/system/filebrowser.service" + echo "[Unit] +Description=Filebrowser +After=network-online.target +[Service] +User=root +WorkingDirectory=/root/ +ExecStart=/usr/local/bin/filebrowser -r / +[Install] +WantedBy=default.target" >$service_path + + $STD systemctl enable --now filebrowser + msg_ok "Created Service" + + msg_ok "Completed successfully!\n" + echo -e "FileBrowser should be reachable by going to the following URL. + ${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n" + exit + fi +} + +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 "${TAB}${GATEWAY}${BGN}HA: http://${IP}:8123${CL}" +echo -e "${TAB}${GATEWAY}${BGN}Portainer: https://${IP}:9443${CL}" diff --git a/ct/arm/jellyfin.sh b/ct/arm/jellyfin.sh new file mode 100644 index 000000000..2bba8fdf8 --- /dev/null +++ b/ct/arm/jellyfin.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://jellyfin.org/ + +APP="Jellyfin" +var_tags="${var_tags:-media}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-16}" +var_os="${var_os:-ubuntu}" +var_version="${var_version:-24.04}" +var_unprivileged="${var_unprivileged:-0}" +var_gpu="${var_gpu:-yes}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /usr/lib/jellyfin ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + msg_info "Updating Jellyfin" + ensure_dependencies libjemalloc2 + if [[ ! -f /usr/lib/libjemalloc.so ]]; then + ln -sf /usr/lib/aarch64-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so + fi + $STD apt update + $STD apt -y upgrade + $STD apt -y --with-new-pkgs upgrade jellyfin jellyfin-server + msg_ok "Updated Jellyfin" + msg_ok "Updated successfully!" + exit +} + +start +build_container +description + +msg_ok "Completed successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8096${CL}" diff --git a/ct/arm/kima-hub.sh b/ct/arm/kima-hub.sh new file mode 100644 index 000000000..c75230270 --- /dev/null +++ b/ct/arm/kima-hub.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk (CanbiZ) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/Chevron7Locked/kima-hub + +APP="Kima-Hub" +var_tags="${var_tags:-music;streaming;media}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-8192}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +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/kima-hub ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "kima-hub" "Chevron7Locked/kima-hub"; then + msg_info "Stopping Services" + systemctl stop kima-frontend kima-backend kima-analyzer kima-analyzer-clap + msg_ok "Stopped Services" + + msg_info "Backing up Data" + cp /opt/kima-hub/backend/.env /opt/kima-hub-backend-env.bak + cp /opt/kima-hub/frontend/.env /opt/kima-hub-frontend-env.bak + msg_ok "Backed up Data" + + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "kima-hub" "Chevron7Locked/kima-hub" "tarball" + + msg_info "Restoring Data" + cp /opt/kima-hub-backend-env.bak /opt/kima-hub/backend/.env + cp /opt/kima-hub-frontend-env.bak /opt/kima-hub/frontend/.env + rm -f /opt/kima-hub-backend-env.bak /opt/kima-hub-frontend-env.bak + msg_ok "Restored Data" + + msg_info "Rebuilding Backend" + cd /opt/kima-hub/backend + $STD npm install + $STD npm run build + $STD npx prisma generate + $STD npx prisma migrate deploy + msg_ok "Rebuilt Backend" + + msg_info "Rebuilding Frontend" + cd /opt/kima-hub/frontend + $STD npm install + $STD npm run build + msg_ok "Rebuilt Frontend" + + msg_info "Starting Services" + systemctl start kima-backend kima-frontend kima-analyzer kima-analyzer-clap + msg_ok "Started Services" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3030${CL}" diff --git a/ct/arm/lubelogger.sh b/ct/arm/lubelogger.sh new file mode 100644 index 000000000..5d314abf9 --- /dev/null +++ b/ct/arm/lubelogger.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: kristocopani +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://lubelogger.com/ + +APP="LubeLogger" +var_tags="${var_tags:-vehicle;car}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-2}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_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/lubelogger.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + if check_for_gh_release "lubelogger" "hargata/lubelog"; then + msg_info "Stopping Service" + systemctl stop lubelogger + msg_ok "Stopped Service" + + msg_info "Backing up data" + mkdir -p /tmp/lubeloggerData/data + cp /opt/lubelogger/appsettings.json /tmp/lubeloggerData/appsettings.json + cp -r /opt/lubelogger/data/ /tmp/lubeloggerData/ + + # Lubelogger has moved multiples folders to the 'data' folder, and we need to move them before the update to keep the user data + # Github Discussion: https://github.com/hargata/lubelog/discussions/787 + [[ -e /opt/lubelogger/config ]] && cp -r /opt/lubelogger/config /tmp/lubeloggerData/data/ + [[ -e /opt/lubelogger/wwwroot/translations ]] && cp -r /opt/lubelogger/wwwroot/translations /tmp/lubeloggerData/data/ + [[ -e /opt/lubelogger/wwwroot/documents ]] && cp -r /opt/lubelogger/wwwroot/documents /tmp/lubeloggerData/data/ + [[ -e /opt/lubelogger/wwwroot/images ]] && cp -r /opt/lubelogger/wwwroot/images /tmp/lubeloggerData/data/ + [[ -e /opt/lubelogger/wwwroot/temp ]] && cp -r /opt/lubelogger/wwwroot/temp /tmp/lubeloggerData/data/ + [[ -e /opt/lubelogger/log ]] && cp -r /opt/lubelogger/log /tmp/lubeloggerData/ + rm -rf /opt/lubelogger + msg_ok "Backed up data" + + fetch_and_deploy_gh_release "lubelogger" "hargata/lubelog" "prebuild" "latest" "/opt/lubelogger" "LubeLogger*linux_x64.zip" + + msg_info "Configuring LubeLogger" + chmod 700 /opt/lubelogger/CarCareTracker + cp -rf /tmp/lubeloggerData/* /opt/lubelogger/ + rm -rf /tmp/lubeloggerData + msg_ok "Configured LubeLogger" + + msg_info "Starting Service" + systemctl start lubelogger + 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 "${TAB}${GATEWAY}${BGN}http://${IP}:5000${CL}" diff --git a/ct/arm/pihole.sh b/ct/arm/pihole.sh new file mode 100644 index 000000000..b16aba5cc --- /dev/null +++ b/ct/arm/pihole.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://pi-hole.net/ + +APP="Pihole" +var_tags="${var_tags:-adblock}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-512}" +var_disk="${var_disk:-2}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /etc/pihole ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + msg_info "Updating PiHole" + set +e + $STD apt update + $STD apt upgrade -y + /usr/local/bin/pihole -up + msg_ok "Updated PiHole" + msg_ok "Updated successfully!" + exit +} + +start +build_container +description + +msg_ok "Completed successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}/admin${CL}" diff --git a/ct/arm/rdtclient.sh b/ct/arm/rdtclient.sh new file mode 100644 index 000000000..ad669a2bf --- /dev/null +++ b/ct/arm/rdtclient.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/rogerfar/rdt-client + +APP="RDTClient" +var_tags="${var_tags:-torrent}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_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/rdtc/ ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + if check_for_gh_release "rdt-client" "rogerfar/rdt-client"; then + msg_info "Stopping Service" + systemctl stop rdtc + msg_ok "Stopped Service" + + msg_info "Creating backup" + mkdir -p /opt/rdtc-backup + cp -R /opt/rdtc/appsettings.json /opt/rdtc-backup/ + msg_ok "Backup created" + + fetch_and_deploy_gh_release "rdt-client" "rogerfar/rdt-client" "prebuild" "latest" "/opt/rdtc" "RealDebridClient.zip" + cp -R /opt/rdtc-backup/appsettings.json /opt/rdtc/ + if dpkg-query -W dotnet-sdk-8.0 >/dev/null 2>&1; then + $STD apt remove --purge -y dotnet-sdk-8.0 + ensure_dependencies aspnetcore-runtime-9.0 + fi + rm -rf /opt/rdtc-backup + + msg_info "Starting Service" + systemctl start rdtc + 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 "${TAB}${GATEWAY}${BGN}http://${IP}:6500${CL}" diff --git a/ct/arm/vaultwarden.sh b/ct/arm/vaultwarden.sh new file mode 100644 index 000000000..ed03e84bf --- /dev/null +++ b/ct/arm/vaultwarden.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/asylumexp/Proxmox/main/misc/build.func) +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/dani-garcia/vaultwarden + +APP="Vaultwarden" +var_tags="${var_tags:-password-manager}" +var_cpu="${var_cpu:-4}" +var_ram="${var_ram:-6144}" +var_disk="${var_disk:-20}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +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/vaultwarden.service ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + VAULT=$(get_latest_github_release "dani-garcia/vaultwarden") + WVRELEASE=$(get_latest_github_release "dani-garcia/bw_web_builds") + + UPD=$(msg_menu "Vaultwarden Update Options" \ + "1" "Update VaultWarden + Web-Vault" \ + "2" "Set Admin Token") + + if [ "$UPD" == "1" ]; then + if check_for_gh_release "vaultwarden" "dani-garcia/vaultwarden"; then + msg_info "Stopping Service" + systemctl stop vaultwarden + msg_ok "Stopped Service" + + fetch_and_deploy_gh_release "vaultwarden" "dani-garcia/vaultwarden" "tarball" "latest" "/tmp/vaultwarden-src" + + msg_info "Updating VaultWarden to $VAULT (Patience)" + cd /tmp/vaultwarden-src + VW_VERSION="$VAULT" + export VW_VERSION + $STD cargo build --features "sqlite,mysql,postgresql" --release + if [[ -f /usr/bin/vaultwarden ]]; then + cp target/release/vaultwarden /usr/bin/ + else + cp target/release/vaultwarden /opt/vaultwarden/bin/ + fi + cd ~ && rm -rf /tmp/vaultwarden-src + msg_ok "Updated VaultWarden to ${VAULT}" + + msg_info "Starting Service" + systemctl start vaultwarden + msg_ok "Started Service" + else + msg_ok "VaultWarden is already up-to-date" + fi + + if check_for_gh_release "vaultwarden_webvault" "dani-garcia/bw_web_builds"; then + msg_info "Stopping Service" + systemctl stop vaultwarden + msg_ok "Stopped Service" + + msg_info "Updating Web-Vault to $WVRELEASE" + rm -rf /opt/vaultwarden/web-vault + mkdir -p /opt/vaultwarden/web-vault + + fetch_and_deploy_gh_release "vaultwarden_webvault" "dani-garcia/bw_web_builds" "prebuild" "latest" "/opt/vaultwarden/web-vault" "bw_web_*.tar.gz" + + chown -R root:root /opt/vaultwarden/web-vault/ + msg_ok "Updated Web-Vault to ${WVRELEASE}" + + msg_info "Starting Service" + systemctl start vaultwarden + msg_ok "Started Service" + else + msg_ok "Web-Vault is already up-to-date" + fi + + msg_ok "Updated successfully!" + exit + fi + + if [ "$UPD" == "2" ]; then + if [[ "${PHS_SILENT:-0}" == "1" ]]; then + msg_warn "Set Admin Token requires interactive mode, skipping." + exit + fi + read -r -s -p "Set the ADMIN_TOKEN: " NEWTOKEN + echo "" + if [[ -n "$NEWTOKEN" ]]; then + ensure_dependencies argon2 + TOKEN=$(echo -n "${NEWTOKEN}" | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) + sed -i "s|ADMIN_TOKEN=.*|ADMIN_TOKEN='${TOKEN}'|" /opt/vaultwarden/.env + if [[ -f /opt/vaultwarden/data/config.json ]]; then + sed -i "s|\"admin_token\":.*|\"admin_token\": \"${TOKEN}\"|" /opt/vaultwarden/data/config.json + fi + systemctl restart vaultwarden + msg_ok "Admin token updated" + fi + exit + fi +} + +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 "${TAB}${GATEWAY}${BGN}https://${IP}:8000${CL}" diff --git a/install/arm/adguard-install.sh b/install/arm/adguard-install.sh new file mode 100644 index 000000000..a2e9ee8d0 --- /dev/null +++ b/install/arm/adguard-install.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://adguard.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +fetch_and_deploy_gh_release "AdGuardHome" "AdguardTeam/AdGuardHome" "prebuild" "latest" "/opt/AdGuardHome" "AdGuardHome_linux_arm64.tar.gz" + +msg_info "Creating Service" +cat </etc/systemd/system/AdGuardHome.service +[Unit] +Description=AdGuard Home: Network-level blocker +ConditionFileIsExecutable=/opt/AdGuardHome/AdGuardHome +After=syslog.target network-online.target + +[Service] +StartLimitInterval=5 +StartLimitBurst=10 +ExecStart=/opt/AdGuardHome/AdGuardHome "-s" "run" +WorkingDirectory=/opt/AdGuardHome +StandardOutput=file:/var/log/AdGuardHome.out +StandardError=file:/var/log/AdGuardHome.err +Restart=always +RestartSec=10 +EnvironmentFile=-/etc/sysconfig/AdGuardHome + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now AdGuardHome +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/bazarr-install.sh b/install/arm/bazarr-install.sh new file mode 100644 index 000000000..879bcf599 --- /dev/null +++ b/install/arm/bazarr-install.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://www.bazarr.media/ + +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 libicu76 +msg_ok "Installed Dependencies" + +PYTHON_VERSION="3.12" setup_uv +fetch_and_deploy_gh_release "bazarr" "morpheus65535/bazarr" "prebuild" "latest" "/opt/bazarr" "bazarr.zip" + +msg_info "Installing Bazarr" +mkdir -p /var/lib/bazarr/ +chmod 775 /opt/bazarr /var/lib/bazarr/ +sed -i.bak 's/--only-binary=Pillow//g' /opt/bazarr/requirements.txt +$STD uv venv --clear /opt/bazarr/venv --python 3.12 +$STD uv pip install -r /opt/bazarr/requirements.txt --python /opt/bazarr/venv/bin/python3 +msg_ok "Installed Bazarr" + +msg_info "Creating Service" +cat </etc/systemd/system/bazarr.service +[Unit] +Description=Bazarr Daemon +After=syslog.target network.target + +[Service] +WorkingDirectory=/opt/bazarr/ +UMask=0002 +Restart=on-failure +RestartSec=5 +Type=simple +ExecStart=/opt/bazarr/venv/bin/python3 /opt/bazarr/bazarr.py +KillSignal=SIGINT +TimeoutStopSec=20 +SyslogIdentifier=bazarr + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now bazarr +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/bentopdf-install.sh b/install/arm/bentopdf-install.sh new file mode 100644 index 000000000..39545544c --- /dev/null +++ b/install/arm/bentopdf-install.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: vhsdream +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/alam00000/bentopdf + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +NODE_VERSION="24" setup_nodejs +fetch_and_deploy_gh_release "bentopdf" "alam00000/bentopdf" "tarball" "latest" "/opt/bentopdf" + +msg_info "Setup BentoPDF" +cd /opt/bentopdf +$STD npm ci --no-audit --no-fund +export SIMPLE_MODE=true +$STD npm run build -- --mode production +msg_ok "Setup BentoPDF" + +msg_info "Creating Service" +cat </etc/systemd/system/bentopdf.service +[Unit] +Description=BentoPDF Service +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/bentopdf +ExecStart=/usr/bin/npx serve dist -p 8080 +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable -q --now bentopdf +msg_ok "Created & started service" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/homeassistant-install.sh b/install/arm/homeassistant-install.sh new file mode 100644 index 000000000..369ef03ce --- /dev/null +++ b/install/arm/homeassistant-install.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://www.home-assistant.io/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Setup Python3" +$STD apt install -y \ + python3 \ + python3-dev \ + python3-pip \ + python3-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Setup Python3" + +msg_info "Installing runlike" +$STD pip install runlike +msg_ok "Installed runlike" + +get_latest_release() { + curl -fsSL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4 +} + +DOCKER_LATEST_VERSION=$(get_latest_release "moby/moby") +CORE_LATEST_VERSION=$(get_latest_release "home-assistant/core") +PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer") + +msg_info "Installing Docker $DOCKER_LATEST_VERSION" +DOCKER_CONFIG_PATH='/etc/docker/daemon.json' +mkdir -p $(dirname $DOCKER_CONFIG_PATH) +echo -e '{\n "log-driver": "journald"\n}' >/etc/docker/daemon.json +$STD sh <(curl -fsSL https://get.docker.com) +msg_ok "Installed Docker $DOCKER_LATEST_VERSION" + +msg_info "Pulling Portainer $PORTAINER_LATEST_VERSION Image" +$STD docker pull portainer/portainer-ce:latest +msg_ok "Pulled Portainer $PORTAINER_LATEST_VERSION Image" + +msg_info "Installing Portainer $PORTAINER_LATEST_VERSION" +$STD docker volume create portainer_data +$STD docker run -d \ + -p 8000:8000 \ + -p 9443:9443 \ + --name=portainer \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v portainer_data:/data \ + portainer/portainer-ce:latest +msg_ok "Installed Portainer $PORTAINER_LATEST_VERSION" + +msg_info "Pulling Home Assistant $CORE_LATEST_VERSION Image" +$STD docker pull ghcr.io/home-assistant/home-assistant:stable +msg_ok "Pulled Home Assistant $CORE_LATEST_VERSION Image" + +msg_info "Installing Home Assistant $CORE_LATEST_VERSION" +$STD docker volume create hass_config +$STD docker run -d \ + --name homeassistant \ + --privileged \ + --restart unless-stopped \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /dev:/dev \ + -v hass_config:/config \ + -v /etc/localtime:/etc/localtime:ro \ + --net=host \ + ghcr.io/home-assistant/home-assistant:stable +mkdir /root/hass_config +msg_ok "Installed Home Assistant $CORE_LATEST_VERSION" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/jellyfin-install.sh b/install/arm/jellyfin-install.sh new file mode 100644 index 000000000..8a68c47df --- /dev/null +++ b/install/arm/jellyfin-install.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://jellyfin.org/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_custom "ℹ️" "${GN}" "If NVIDIA GPU passthrough is detected, you'll be asked whether to install drivers in the container" +setup_hwaccel + +msg_info "Installing Jellyfin" +VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)" +if ! dpkg -s libjemalloc2 >/dev/null 2>&1; then + $STD apt install -y libjemalloc2 +fi +if [[ ! -f /usr/lib/libjemalloc.so ]]; then + ln -sf /usr/lib/aarch64-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so +fi +if [[ ! -d /etc/apt/keyrings ]]; then + mkdir -p /etc/apt/keyrings +fi +curl -fsSL https://repo.jellyfin.org/jellyfin_team.gpg.key | gpg --dearmor --yes --output /etc/apt/keyrings/jellyfin.gpg +cat </etc/apt/sources.list.d/jellyfin.sources +Types: deb +URIs: https://repo.jellyfin.org/${PCT_OSTYPE} +Suites: ${VERSION} +Components: main +Architectures: arm64 +Signed-By: /etc/apt/keyrings/jellyfin.gpg +EOF + +$STD apt update +$STD apt install -y jellyfin +# Configure log rotation to prevent disk fill (keeps fail2ban compatibility) (PR: #1690 / Issue: #11224) +cat </etc/logrotate.d/jellyfin +/var/log/jellyfin/*.log { + daily + rotate 3 + maxsize 100M + missingok + notifempty + compress + delaycompress + copytruncate +} +EOF +chown -R jellyfin:adm /etc/jellyfin +sleep 10 +systemctl restart jellyfin +if [[ "$CTTYPE" == "0" ]]; then + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:root,jellyfin/' -e 's/^render:x:108:root,jellyfin$/ssl-cert:x:108:/' /etc/group +else + sed -i -e 's/^ssl-cert:x:104:$/render:x:104:jellyfin/' -e 's/^render:x:108:jellyfin$/ssl-cert:x:108:/' /etc/group +fi +msg_ok "Installed Jellyfin" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/kima-hub-install.sh b/install/arm/kima-hub-install.sh new file mode 100644 index 000000000..71f1e9a4c --- /dev/null +++ b/install/arm/kima-hub-install.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: MickLesk +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://www.kimai.org/ + +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 \ + apt-transport-https \ + apache2 \ + git \ + expect +msg_ok "Installed Dependencies" + +setup_mariadb +PHP_VERSION="8.4" PHP_APACHE="YES" setup_php +setup_composer + +msg_info "Setting up database" +DB_NAME=kimai_db +DB_USER=kimai +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +MYSQL_VERSION=$(mariadb --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') +$STD mariadb -e "CREATE DATABASE $DB_NAME;" +$STD mariadb -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" +$STD mariadb -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "Kimai-Credentials" + echo "Kimai Database User: $DB_USER" + echo "Kimai Database Password: $DB_PASS" + echo "Kimai Database Name: $DB_NAME" +} >>~/kimai.creds +msg_ok "Set up database" + +fetch_and_deploy_gh_release "kimai" "kimai/kimai" "tarball" + +msg_info "Setup Kimai" +cd /opt/kimai +echo "export COMPOSER_ALLOW_SUPERUSER=1" >>~/.bashrc +source ~/.bashrc +$STD composer install --no-dev --optimize-autoloader --no-interaction +cp .env.dist .env +sed -i "/^DATABASE_URL=/c\DATABASE_URL=mysql://$DB_USER:$DB_PASS@127.0.0.1:3306/$DB_NAME?charset=utf8mb4&serverVersion=mariadb-$MYSQL_VERSION" /opt/kimai/.env +$STD bin/console kimai:install -n +$STD expect </opt/kimai/config/packages/local.yaml +kimai: + timesheet: + rounding: + default: + begin: 15 + end: 15 + +EOF +msg_ok "Installed Kimai" + +msg_info "Creating Service" +cat </etc/apache2/sites-available/kimai.conf + + ServerAdmin webmaster@localhost + DocumentRoot /opt/kimai/public/ + + + Options FollowSymLinks + AllowOverride All + Require all granted + + + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + + +EOF +$STD a2ensite kimai.conf +$STD a2dissite 000-default.conf +$STD systemctl reload apache2 +msg_ok "Created Service" + +msg_info "Setup Permissions" +chown -R :www-data /opt/* +chmod -R g+r /opt/* +chmod -R g+rw /opt/* +chown -R www-data:www-data /opt/* +chmod -R 777 /opt/* +msg_ok "Setup Permissions" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/lubelogger-install.sh b/install/arm/lubelogger-install.sh new file mode 100644 index 000000000..893e5c437 --- /dev/null +++ b/install/arm/lubelogger-install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: kristocopani +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://lubelogger.com/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +fetch_and_deploy_gh_release "lubelogger" "hargata/lubelog" "prebuild" "latest" "/opt/lubelogger" "LubeLogger*linux_x64.zip" + +msg_info "Configuring LubeLogger" +cd /opt/lubelogger +chmod 700 /opt/lubelogger/CarCareTracker +cp /opt/lubelogger/appsettings.json /opt/lubelogger/appsettings_bak.json +jq '.Kestrel = {"Endpoints": {"Http": {"Url": "http://0.0.0.0:5000"}}}' /opt/lubelogger/appsettings_bak.json >/opt/lubelogger/appsettings.json +rm -rf /opt/lubelogger/appsettings_bak.json +msg_ok "Configured LubeLogger" + +msg_info "Creating Service" +cat </etc/systemd/system/lubelogger.service +[Unit] +Description=LubeLogger Daemon +After=network.target + +[Service] +User=root + +Type=simple +WorkingDirectory=/opt/lubelogger +ExecStart=/opt/lubelogger/CarCareTracker +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable -q --now lubelogger +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/pihole-install.sh b/install/arm/pihole-install.sh new file mode 100644 index 000000000..24ef9d31b --- /dev/null +++ b/install/arm/pihole-install.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://pi-hole.net/ + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_warn "WARNING: This script will run an external installer from a third-party source (https://pi-hole.net/)." +msg_warn "The following code is NOT maintained or audited by our repository." +msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:" +msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://install.pi-hole.net" +echo +read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM +if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then + msg_error "Aborted by user. No changes have been made." + exit 10 +fi + +msg_info "Installing Dependencies" +$STD apt install -y ufw +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 +sed -i -E ' +/^\s*upstreams =/ s|=.*|= ["8.8.8.8", "8.8.4.4"]| +/^\s*interface =/ s|=.*|= "eth0"| +/^\s*queryLogging =/ s|=.*|= true| +/^\s*size =/ s|=.*|= 10000| +/^\s*active =/ s|=.*|= true| +/^\s*listeningMode =/ s|=.*|= "LOCAL"| +/^\s*port =/ s|=.*|= "80o,443os,[::]:80o,[::]:443os"| +/^\s*pwhash =/ s|=.*|= ""| + +# DHCP Disable +/^\s*\[dhcp\]/,/^\s*\[/{s/^\s*active = true/ active = false/} + +# NTP Disable +/^\s*\[ntp.ipv4\]/,/^\s*\[/{s/^\s*active = true/ active = false/} +/^\s*\[ntp.ipv6\]/,/^\s*\[/{s/^\s*active = true/ active = false/} +/^\s*\[ntp.sync\]/,/^\s*\[/{s/^\s*active = true/ active = false/} +/^\s*\[ntp.sync\]/,/^\s*\[/{s/^\s*interval = [0-9]+/ interval = 0/} +/^\s*\[ntp.sync.rtc\]/,/^\s*\[/{s/^\s*set = true/ set = false/} + +# set domainNeeded und expandHosts +/^\s*domainNeeded =/ s|=.*|= true| +/^\s*expandHosts =/ s|=.*|= true| +' /etc/pihole/pihole.toml + +cat </etc/dnsmasq.d/01-pihole.conf +server=8.8.8.8 +server=8.8.4.4 +EOF +$STD pihole-FTL --config ntp.sync.interval 0 +systemctl restart pihole-FTL.service +msg_ok "Installed Pi-hole" + +read -r -p "${TAB3}Would you like to add Unbound? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + read -r -p "${TAB3}Unbound is configured as a recursive DNS server by default, would you like it to be configured as a forwarding DNS server (using DNS-over-TLS (DoT)) instead? " prompt + msg_info "Installing Unbound" + mkdir -p /etc/unbound/unbound.conf.d + cat </etc/unbound/unbound.conf.d/pi-hole.conf +server: + verbosity: 0 + interface: 127.0.0.1 + port: 5335 + do-ip6: no + do-ip4: yes + do-udp: yes + do-tcp: yes + num-threads: 1 + hide-identity: yes + hide-version: yes + harden-glue: yes + harden-dnssec-stripped: yes + harden-referral-path: yes + use-caps-for-id: no + harden-algo-downgrade: no + qname-minimisation: yes + aggressive-nsec: yes + rrset-roundrobin: yes + cache-min-ttl: 300 + cache-max-ttl: 14400 + msg-cache-slabs: 8 + rrset-cache-slabs: 8 + infra-cache-slabs: 8 + key-cache-slabs: 8 + serve-expired: yes + serve-expired-ttl: 3600 + edns-buffer-size: 1232 + prefetch: yes + prefetch-key: yes + target-fetch-policy: "3 2 1 1 1" + unwanted-reply-threshold: 10000000 + rrset-cache-size: 256m + msg-cache-size: 128m + so-rcvbuf: 1m + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: 172.16.0.0/12 + private-address: 10.0.0.0/8 + private-address: fd00::/8 + private-address: fe80::/10 +EOF + mkdir -p /etc/dnsmasq.d/ + cat </etc/dnsmasq.d/99-edns.conf +edns-packet-max=1232 +EOF + + if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + cat <>/etc/unbound/unbound.conf.d/pi-hole.conf + tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt" +forward-zone: + name: "." + forward-tls-upstream: yes + forward-first: no + + forward-addr: 8.8.8.8@853#dns.google + forward-addr: 8.8.4.4@853#dns.google + forward-addr: 2001:4860:4860::8888@853#dns.google + forward-addr: 2001:4860:4860::8844@853#dns.google + + #forward-addr: 1.1.1.1@853#cloudflare-dns.com + #forward-addr: 1.0.0.1@853#cloudflare-dns.com + #forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com + #forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com + + #forward-addr: 9.9.9.9@853#dns.quad9.net + #forward-addr: 149.112.112.112@853#dns.quad9.net + #forward-addr: 2620:fe::fe@853#dns.quad9.net + #forward-addr: 2620:fe::9@853#dns.quad9.net +EOF + fi + $STD apt install -y unbound + cat </etc/dnsmasq.d/01-pihole.conf +server=127.0.0.1#5335 +server=8.8.8.8 +server=8.8.4.4 +EOF + + sed -i -E '/^\s*upstreams\s*=\s*\[/,/^\s*\]/c\ upstreams = [\n "127.0.0.1#5335",\n "8.8.4.4"\n ]' /etc/pihole/pihole.toml + systemctl restart unbound + systemctl restart pihole-FTL.service + msg_ok "Installed Unbound" +fi + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/rdtclient-install.sh b/install/arm/rdtclient-install.sh new file mode 100644 index 000000000..784107f30 --- /dev/null +++ b/install/arm/rdtclient-install.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/rogerfar/rdt-client + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y unzip +msg_ok "Installed Dependencies" + +msg_info "Installing ASP.NET Core Runtime" +$STD apt-get install -y libc6 +$STD apt-get install -y libgcc1 +$STD apt-get install -y libgssapi-krb5-2 +$STD apt-get install -y libicu72 +$STD apt-get install -y liblttng-ust1 +$STD apt-get install -y libssl3 +$STD apt-get install -y libstdc++6 +$STD apt-get install -y zlib1g + +curl -SL -o dotnet.tar.gz https://download.visualstudio.microsoft.com/download/pr/6f79d99b-dc38-4c44-a549-32329419bb9f/a411ec38fb374e3a4676647b236ba021/dotnet-sdk-9.0.100-linux-arm64.tar.gz +mkdir -p /usr/share/dotnet +$STD tar -zxf dotnet.tar.gz -C /usr/share/dotnet +$STD ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet +msg_ok "Installed ASP.NET Core Runtime" + +fetch_and_deploy_gh_release "rdt-client" "rogerfar/rdt-client" "prebuild" "latest" "/opt/rdtc" "RealDebridClient.zip" + +msg_info "Setting up rdtclient" +cd /opt/rdtc +mkdir -p data/{db,downloads} +sed -i 's#/data/db/#/opt/rdtc&#g' /opt/rdtc/appsettings.json +msg_ok "Configured rdtclient" + +msg_info "Creating Service" +cat </etc/systemd/system/rdtc.service +[Unit] +Description=RdtClient Service + +[Service] +WorkingDirectory=/opt/rdtc +ExecStart=/usr/bin/dotnet RdtClient.Web.dll +SyslogIdentifier=RdtClient +User=root + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now rdtc +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc diff --git a/install/arm/vaultwarden-install.sh b/install/arm/vaultwarden-install.sh new file mode 100644 index 000000000..a2c02db8d --- /dev/null +++ b/install/arm/vaultwarden-install.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 tteck +# Author: tteck (tteckster) +# License: MIT | https://github.com/asylumexp/Proxmox/raw/main/LICENSE +# Source: https://github.com/dani-garcia/vaultwarden + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt install -y \ + build-essential \ + pkgconf \ + libssl-dev \ + libmariadb-dev-compat \ + libpq-dev \ + argon2 \ + ssl-cert +msg_ok "Installed Dependencies" + +setup_rust +fetch_and_deploy_gh_release "vaultwarden" "dani-garcia/vaultwarden" "tarball" "latest" "/tmp/vaultwarden-src" + +msg_info "Building Vaultwarden (Patience)" +cd /tmp/vaultwarden-src +VW_VERSION=$(get_latest_github_release "dani-garcia/vaultwarden") +export VW_VERSION +$STD cargo build --features "sqlite,mysql,postgresql" --release +msg_ok "Built Vaultwarden" + +msg_info "Setting up Vaultwarden" +$STD addgroup --system vaultwarden +$STD adduser --system --home /opt/vaultwarden --shell /usr/sbin/nologin --no-create-home --gecos 'vaultwarden' --ingroup vaultwarden --disabled-login --disabled-password vaultwarden +mkdir -p /opt/vaultwarden/{bin,data,web-vault} +cp target/release/vaultwarden /opt/vaultwarden/bin/ +cd ~ && rm -rf /tmp/vaultwarden-src +msg_ok "Set up Vaultwarden" + +fetch_and_deploy_gh_release "vaultwarden_webvault" "dani-garcia/bw_web_builds" "prebuild" "latest" "/opt/vaultwarden/web-vault" "bw_web_*.tar.gz" + +msg_info "Configuring Vaultwarden" +cat </opt/vaultwarden/.env +ADMIN_TOKEN='' +ROCKET_ADDRESS=0.0.0.0 +ROCKET_TLS='{certs="/opt/vaultwarden/ssl-cert-snakeoil.pem",key="/opt/vaultwarden/ssl-cert-snakeoil.key"}' +DATA_FOLDER=/opt/vaultwarden/data +DATABASE_MAX_CONNS=10 +WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault +WEB_VAULT_ENABLED=true +EOF +mv /etc/ssl/certs/ssl-cert-snakeoil.pem /opt/vaultwarden/ +mv /etc/ssl/private/ssl-cert-snakeoil.key /opt/vaultwarden/ + +chown -R vaultwarden:vaultwarden /opt/vaultwarden/ +chown root:root /opt/vaultwarden/bin/vaultwarden +chmod +x /opt/vaultwarden/bin/vaultwarden +chown -R root:root /opt/vaultwarden/web-vault/ +chmod +r /opt/vaultwarden/.env +msg_ok "Configured Vaultwarden" + +msg_info "Creating Service" +cat </etc/systemd/system/vaultwarden.service +[Unit] +Description=Bitwarden Server (Powered by Vaultwarden) +Documentation=https://github.com/dani-garcia/vaultwarden +After=network.target + +[Service] +User=vaultwarden +Group=vaultwarden +EnvironmentFile=-/opt/vaultwarden/.env +ExecStart=/opt/vaultwarden/bin/vaultwarden +LimitNOFILE=65535 +LimitNPROC=4096 +PrivateTmp=true +PrivateDevices=true +ProtectHome=true +ProtectSystem=strict +DevicePolicy=closed +ProtectControlGroups=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +RestrictNamespaces=yes +RestrictRealtime=yes +MemoryDenyWriteExecute=yes +LockPersonality=yes +WorkingDirectory=/opt/vaultwarden +ReadWriteDirectories=/opt/vaultwarden/data +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now vaultwarden +msg_ok "Created Service" + +motd_ssh +customize +cleanup_lxc