Compare commits

..

3 Commits

62 changed files with 879 additions and 2153 deletions

View File

@ -10,136 +10,12 @@
> [!CAUTION] > [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes. Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2025-12-24
### 🚀 Updated Scripts
- recyclarr: increase cron path [@Uncloak2](https://github.com/Uncloak2) ([#10272](https://github.com/community-scripts/ProxmoxVE/pull/10272))
- #### 🔧 Refactor
- Overseerr: Update dependencies [@tremor021](https://github.com/tremor021) ([#10275](https://github.com/community-scripts/ProxmoxVE/pull/10275))
- Refactor: Paperless-GPT [@tremor021](https://github.com/tremor021) ([#10274](https://github.com/community-scripts/ProxmoxVE/pull/10274))
- Refactor: Outline [@tremor021](https://github.com/tremor021) ([#10276](https://github.com/community-scripts/ProxmoxVE/pull/10276))
- Refactor: OTS [@tremor021](https://github.com/tremor021) ([#10277](https://github.com/community-scripts/ProxmoxVE/pull/10277))
- Refactor: OpenProject [@tremor021](https://github.com/tremor021) ([#10278](https://github.com/community-scripts/ProxmoxVE/pull/10278))
- Refactor: Open Archiver [@tremor021](https://github.com/tremor021) ([#10280](https://github.com/community-scripts/ProxmoxVE/pull/10280))
- Refactor: Tautulli [@tremor021](https://github.com/tremor021) ([#10241](https://github.com/community-scripts/ProxmoxVE/pull/10241))
- Refactor: PrivateBin [@tremor021](https://github.com/tremor021) ([#10256](https://github.com/community-scripts/ProxmoxVE/pull/10256))
- Refactor: Podman-Home Assistant [@tremor021](https://github.com/tremor021) ([#10258](https://github.com/community-scripts/ProxmoxVE/pull/10258))
- Refactor: Plant-it [@tremor021](https://github.com/tremor021) ([#10259](https://github.com/community-scripts/ProxmoxVE/pull/10259))
- Refactor: PatchMon [@tremor021](https://github.com/tremor021) ([#10260](https://github.com/community-scripts/ProxmoxVE/pull/10260))
- Refactor: Part-DB [@tremor021](https://github.com/tremor021) ([#10262](https://github.com/community-scripts/ProxmoxVE/pull/10262))
### 💾 Core
- #### 🐞 Bug Fixes
- core: correct local template discovery regex pattern [@MickLesk](https://github.com/MickLesk) ([#10282](https://github.com/community-scripts/ProxmoxVE/pull/10282))
### ❔ Uncategorized
- Pocketbase: Add note for superuser account creation [@tremor021](https://github.com/tremor021) ([#10245](https://github.com/community-scripts/ProxmoxVE/pull/10245))
## 2025-12-23
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Technitium DNS: Migrate service [@tremor021](https://github.com/tremor021) ([#10240](https://github.com/community-scripts/ProxmoxVE/pull/10240))
- Update forgejo to debian13 and fix env var [@burgerga](https://github.com/burgerga) ([#10242](https://github.com/community-scripts/ProxmoxVE/pull/10242))
- #### 🔧 Refactor
- Passbolt: Small fixes [@tremor021](https://github.com/tremor021) ([#10261](https://github.com/community-scripts/ProxmoxVE/pull/10261))
- Refactor: ProjectSend [@tremor021](https://github.com/tremor021) ([#10255](https://github.com/community-scripts/ProxmoxVE/pull/10255))
- Prometheus Paperless NGX Exporter: Small fix [@tremor021](https://github.com/tremor021) ([#10254](https://github.com/community-scripts/ProxmoxVE/pull/10254))
- Podman: Fixes [@tremor021](https://github.com/tremor021) ([#10257](https://github.com/community-scripts/ProxmoxVE/pull/10257))
- Refactor: Beszel [@tremor021](https://github.com/tremor021) ([#10195](https://github.com/community-scripts/ProxmoxVE/pull/10195))
### 🧰 Tools
- #### 🐞 Bug Fixes
- fix: pihole-exporter: unknown function [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10249](https://github.com/community-scripts/ProxmoxVE/pull/10249))
### ❔ Uncategorized
- Fix Recyclarr page TypeError: schema mismatch in notes field [@Copilot](https://github.com/Copilot) ([#10253](https://github.com/community-scripts/ProxmoxVE/pull/10253))
## 2025-12-22
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- InvoiceNinja: add chromium dependencies for PDF generation [@MickLesk](https://github.com/MickLesk) ([#10230](https://github.com/community-scripts/ProxmoxVE/pull/10230))
- MediaManager) use npm install [@MickLesk](https://github.com/MickLesk) ([#10228](https://github.com/community-scripts/ProxmoxVE/pull/10228))
- Kometa: Fix update procedure [@tremor021](https://github.com/tremor021) ([#10217](https://github.com/community-scripts/ProxmoxVE/pull/10217))
- #### 💥 Breaking Changes
- refactor: reitti: v3.0.0 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10196](https://github.com/community-scripts/ProxmoxVE/pull/10196))
### 💾 Core
- #### ✨ New Features
- tools.func - hwaccel: skip setup without GPU passthrough and fix Ubuntu AMD firmware [@MickLesk](https://github.com/MickLesk) ([#10225](https://github.com/community-scripts/ProxmoxVE/pull/10225))
### 📚 Documentation
- contribution docs: update templates with modern patterns [@MickLesk](https://github.com/MickLesk) ([#10227](https://github.com/community-scripts/ProxmoxVE/pull/10227))
### ❔ Uncategorized
- InvoiceNinja: switch category [@DragoQC](https://github.com/DragoQC) ([#10223](https://github.com/community-scripts/ProxmoxVE/pull/10223))
## 2025-12-21
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Typo fix in Heimdall install script [@Turcid-uwu](https://github.com/Turcid-uwu) ([#10187](https://github.com/community-scripts/ProxmoxVE/pull/10187))
- #### ✨ New Features
- recyclarr: add default daily cron job for recyclarr sync [@MickLesk](https://github.com/MickLesk) ([#10208](https://github.com/community-scripts/ProxmoxVE/pull/10208))
- #### 🔧 Refactor
- Optimize Jotty installation with standalone mode [@MickLesk](https://github.com/MickLesk) ([#10207](https://github.com/community-scripts/ProxmoxVE/pull/10207))
- unifi: remove mongodb 4.4 support | bump to java 21 [@MickLesk](https://github.com/MickLesk) ([#10206](https://github.com/community-scripts/ProxmoxVE/pull/10206))
- Refactor: Backrest [@tremor021](https://github.com/tremor021) ([#10193](https://github.com/community-scripts/ProxmoxVE/pull/10193))
### 💾 Core
- #### ✨ New Features
- Fix AMD GPU firmware installation by adding non-free repositories [@MickLesk](https://github.com/MickLesk) ([#10205](https://github.com/community-scripts/ProxmoxVE/pull/10205))
### 🧰 Tools
- pihole-exporter ([#10091](https://github.com/community-scripts/ProxmoxVE/pull/10091))
## 2025-12-20
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Update Technitium DNS and Restart Service [@DrEVILish](https://github.com/DrEVILish) ([#10181](https://github.com/community-scripts/ProxmoxVE/pull/10181))
- bump: ersatztv: deb13 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10174](https://github.com/community-scripts/ProxmoxVE/pull/10174))
## 2025-12-19 ## 2025-12-19
### 🚀 Updated Scripts ### 🚀 Updated Scripts
- #### 🐞 Bug Fixes - #### 🐞 Bug Fixes
- Update Reitti to Java 25 for 3.0.0 compatibility [@Copilot](https://github.com/Copilot) ([#10164](https://github.com/community-scripts/ProxmoxVE/pull/10164))
- Bump Bar-Assistant to php 8.4 [@MickLesk](https://github.com/MickLesk) ([#10138](https://github.com/community-scripts/ProxmoxVE/pull/10138)) - Bump Bar-Assistant to php 8.4 [@MickLesk](https://github.com/MickLesk) ([#10138](https://github.com/community-scripts/ProxmoxVE/pull/10138))
- Zabbix: Add version-specific SQL script path for 7.0 LTS [@MickLesk](https://github.com/MickLesk) ([#10142](https://github.com/community-scripts/ProxmoxVE/pull/10142)) - Zabbix: Add version-specific SQL script path for 7.0 LTS [@MickLesk](https://github.com/MickLesk) ([#10142](https://github.com/community-scripts/ProxmoxVE/pull/10142))
- InfluxDB: Fix update function [@Liganic](https://github.com/Liganic) ([#10151](https://github.com/community-scripts/ProxmoxVE/pull/10151)) - InfluxDB: Fix update function [@Liganic](https://github.com/Liganic) ([#10151](https://github.com/community-scripts/ProxmoxVE/pull/10151))

View File

@ -27,18 +27,28 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
RELEASE=$(curl -fsSL https://api.github.com/repos/garethgeorge/backrest/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if check_for_gh_release "backrest" "garethgeorge/backrest"; then if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop backrest systemctl stop backrest
msg_ok "Stopped Service" msg_ok "Stopped Service"
fetch_and_deploy_gh_release "backrest" "garethgeorge/backrest" "prebuild" "latest" "/opt/backrest/bin" "backrest_Linux_x86_64.tar.gz" msg_info "Updating ${APP} to ${RELEASE}"
temp_file=$(mktemp)
rm -f /opt/backrest/bin/backrest
curl -fsSL "https://github.com/garethgeorge/backrest/releases/download/v${RELEASE}/backrest_Linux_x86_64.tar.gz" -o "$temp_file"
tar xzf $temp_file -C /opt/backrest/bin
chmod +x /opt/backrest/bin/backrest
rm -f "$temp_file"
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated ${APP} to ${RELEASE}"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start backrest systemctl start backrest
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi fi
exit exit
} }

View File

@ -27,22 +27,19 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if check_for_gh_release "beszel" "henrygd/beszel"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop beszel-hub systemctl stop beszel-hub
msg_info "Stopped Service" msg_info "Stopped Service"
msg_info "Updating Beszel" msg_info "Updating $APP"
$STD /opt/beszel/beszel update $STD /opt/beszel/beszel update
sleep 2 && chmod +x /opt/beszel/beszel sleep 2 && chmod +x /opt/beszel/beszel
msg_ok "Updated Beszel" msg_ok "Updated $APP"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start beszel-hub systemctl start beszel-hub
msg_ok "Started Service" msg_ok "Successfully started $APP"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi
exit exit
} }

View File

@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}" var_ram="${var_ram:-1024}"
var_disk="${var_disk:-5}" var_disk="${var_disk:-5}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}" var_gpu="${var_gpu:-yes}"

View File

@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}" var_disk="${var_disk:-10}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
@ -44,14 +44,6 @@ function update_script() {
rm -rf forgejo-$RELEASE-linux-amd64 rm -rf forgejo-$RELEASE-linux-amd64
msg_ok "Cleaned" msg_ok "Cleaned"
# Fix env var from older version of community script
if grep -q "GITEA_WORK_DIR" /etc/systemd/system/forgejo.service; then
msg_info "Updating Service File"
sed -i "s/GITEA_WORK_DIR/FORGEJO_WORK_DIR/g" /etc/systemd/system/forgejo.service
systemctl daemon-reload
msg_ok "Updated Service File"
fi
msg_info "Starting Service" msg_info "Starting Service"
systemctl start forgejo systemctl start forgejo
msg_ok "Started Service" msg_ok "Started Service"

View File

@ -48,17 +48,6 @@ function update_script() {
$STD yarn --frozen-lockfile $STD yarn --frozen-lockfile
$STD yarn next telemetry disable $STD yarn next telemetry disable
$STD yarn build $STD yarn build
[ -d "public" ] && cp -r public .next/standalone/
[ -d "howto" ] && cp -r howto .next/standalone/
mkdir -p .next/standalone/.next
cp -r .next/static .next/standalone/.next/
mv .next/standalone /tmp/jotty_standalone
rm -rf * .next .git .gitignore .yarn
mv /tmp/jotty_standalone/* .
mv /tmp/jotty_standalone/.[!.]* . 2>/dev/null || true
rm -rf /tmp/jotty_standalone
msg_ok "Updated jotty" msg_ok "Updated jotty"
msg_info "Restoring configuration & data" msg_info "Restoring configuration & data"
@ -66,24 +55,6 @@ function update_script() {
$STD tar -xf /opt/data_config.tar $STD tar -xf /opt/data_config.tar
msg_ok "Restored configuration & data" msg_ok "Restored configuration & data"
msg_info "Updating Service"
cat <<EOF >/etc/systemd/system/jotty.service
[Unit]
Description=jotty server
After=network.target
[Service]
WorkingDirectory=/opt/jotty
EnvironmentFile=/opt/jotty/.env
ExecStart=/usr/bin/node server.js
Restart=on-abnormal
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
msg_ok "Updated Service"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start jotty systemctl start jotty
msg_ok "Started Service" msg_ok "Started Service"

View File

@ -41,7 +41,6 @@ function update_script() {
fetch_and_deploy_gh_release "kometa" "Kometa-Team/Kometa" fetch_and_deploy_gh_release "kometa" "Kometa-Team/Kometa"
msg_info "Updating Kometa" msg_info "Updating Kometa"
cd /opt/kometa
$STD uv pip install -r requirements.txt --system $STD uv pip install -r requirements.txt --system
mkdir -p config/assets mkdir -p config/assets
cp /opt/config.yml config/config.yml cp /opt/config.yml config/config.yml

View File

@ -44,7 +44,7 @@ function update_script() {
export PUBLIC_API_URL="" export PUBLIC_API_URL=""
export BASE_PATH="/web" export BASE_PATH="/web"
cd /opt/mediamanager/web cd /opt/mediamanager/web
$STD npm install --no-fund --no-audit $STD npm ci --no-fund --no-audit
$STD npm run build $STD npm run build
rm -rf "$FRONTEND_FILES_DIR"/build rm -rf "$FRONTEND_FILES_DIR"/build
cp -r build "$FRONTEND_FILES_DIR" cp -r build "$FRONTEND_FILES_DIR"

View File

@ -34,7 +34,7 @@ function update_script() {
msg_ok "Stopped Services" msg_ok "Stopped Services"
cp /opt/openarchiver/.env /opt/openarchiver.env cp /opt/openarchiver/.env /opt/openarchiver.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball" "latest" "/opt/openarchiver"
mv /opt/openarchiver.env /opt/openarchiver/.env mv /opt/openarchiver.env /opt/openarchiver/.env
msg_info "Updating Open Archiver" msg_info "Updating Open Archiver"

View File

@ -27,19 +27,18 @@ function update_script() {
msg_error "No Paperless-GPT installation found!" msg_error "No Paperless-GPT installation found!"
exit exit
fi fi
RELEASE=$(curl -fsSL https://api.github.com/repos/icereed/paperless-gpt/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if check_for_gh_release "paperless-gpt" "icereed/paperless-gpt"; then if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop paperless-gpt systemctl stop paperless-gpt
msg_ok "Service Stopped" msg_ok "Service Stopped"
if should_update_tool "node" "24"; then msg_info "Updating Paperless-GPT to ${RELEASE}"
NODE_VERSION="24" setup_nodejs temp_file=$(mktemp)
fi curl -fsSL "https://github.com/icereed/paperless-gpt/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
tar zxf $temp_file
fetch_and_deploy_gh_release "paperless-gpt" "icereed/paperless-gpt" "tarball" rm -rf /opt/paperless-gpt
mv paperless-gpt-${RELEASE} /opt/paperless-gpt
msg_info "Updating Paperless-GPT"
cd /opt/paperless-gpt/web-app cd /opt/paperless-gpt/web-app
$STD npm install $STD npm install
$STD npm run build $STD npm run build
@ -48,12 +47,16 @@ function update_script() {
export CC=musl-gcc export CC=musl-gcc
CGO_ENABLED=1 go build -tags musl -o /dev/null github.com/mattn/go-sqlite3 CGO_ENABLED=1 go build -tags musl -o /dev/null github.com/mattn/go-sqlite3
CGO_ENABLED=1 go build -tags musl -o paperless-gpt . CGO_ENABLED=1 go build -tags musl -o paperless-gpt .
msg_ok "Updated Paperless-GPT" rm -f $temp_file
echo "${RELEASE}" >"/opt/paperless-gpt_version.txt"
msg_ok "Updated Paperless-GPT to ${RELEASE}"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start paperless-gpt systemctl start paperless-gpt
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at ${RELEASE}"
fi fi
exit exit
} }

View File

@ -27,9 +27,8 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
RELEASE=$(curl -fsSL https://api.github.com/repos/Part-DB/Part-DB-server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
RELEASE=$(get_latest_github_release "Part-DB/Part-DB-server") if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
if check_for_gh_release "partdb" "Part-DB/Part-DB-server"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop apache2 systemctl stop apache2
msg_ok "Stopped Service" msg_ok "Stopped Service"
@ -37,7 +36,7 @@ function update_script() {
msg_info "Updating $APP to v${RELEASE}" msg_info "Updating $APP to v${RELEASE}"
cd /opt cd /opt
mv /opt/partdb/ /opt/partdb-backup mv /opt/partdb/ /opt/partdb-backup
curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip" curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o $(basename "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip")
$STD unzip "v${RELEASE}.zip" $STD unzip "v${RELEASE}.zip"
mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb
@ -55,13 +54,15 @@ function update_script() {
chown -R www-data:www-data /opt/partdb chown -R www-data:www-data /opt/partdb
rm -r "/opt/v${RELEASE}.zip" rm -r "/opt/v${RELEASE}.zip"
rm -r /opt/partdb-backup rm -r /opt/partdb-backup
echo "${RELEASE}" >~/.partdb echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Updated $APP to v${RELEASE}" msg_ok "Updated $APP to v${RELEASE}"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start apache2 systemctl start apache2
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi fi
exit exit
} }

View File

@ -37,7 +37,7 @@ function update_script() {
if [ "$UPD" == "1" ]; then if [ "$UPD" == "1" ]; then
msg_info "Updating ${APP} LXC" msg_info "Updating ${APP} LXC"
$STD apt update $STD apt update
$STD apt upgrade -y $STD apt -y upgrade
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
msg_info "Updating All Containers\n" msg_info "Updating All Containers\n"
@ -65,7 +65,7 @@ function update_script() {
exit exit
fi fi
if [ "$UPD" == "3" ]; then if [ "$UPD" == "3" ]; then
import_local_ip IP=$(hostname -I | awk '{print $1}')
msg_info "Installing FileBrowser" msg_info "Installing FileBrowser"
$STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash $STD curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
$STD filebrowser config init -a '0.0.0.0' $STD filebrowser config init -a '0.0.0.0'
@ -74,25 +74,23 @@ function update_script() {
msg_ok "Installed FileBrowser" msg_ok "Installed FileBrowser"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/filebrowser.service service_path="/etc/systemd/system/filebrowser.service"
[Unit] echo "[Unit]
Description=Filebrowser Description=Filebrowser
After=network-online.target After=network-online.target
[Service]
User=root
WorkingDirectory=/root/
ExecStart=/usr/local/bin/filebrowser -r /
[Install]
WantedBy=default.target" >$service_path
[Service] $STD systemctl enable --now filebrowser
User=root
WorkingDirectory=/root/
ExecStart=/usr/local/bin/filebrowser -r /
[Install]
WantedBy=default.target
EOF
systemctl enable -q --now filebrowser
msg_ok "Created Service" msg_ok "Created Service"
msg_ok "Completed Successfully!\n" msg_ok "Completed Successfully!\n"
echo -e "FileBrowser should be reachable by going to the following URL. echo -e "FileBrowser should be reachable by going to the following URL.
${BL}http://$LOCAL_IP:8080${CL} admin|helper-scripts.com\n" ${BL}http://$IP:8080${CL} admin|helper-scripts.com\n"
exit exit
fi fi
if [ "$UPD" == "4" ]; then if [ "$UPD" == "4" ]; then
@ -101,6 +99,7 @@ EOF
msg_ok "Removed ALL Unused Images" msg_ok "Removed ALL Unused Images"
exit exit
fi fi
} }
start start

View File

@ -29,7 +29,7 @@ function update_script() {
fi fi
msg_info "Updating ${APP} LXC" msg_info "Updating ${APP} LXC"
$STD apt update $STD apt update
$STD apt upgrade -y $STD apt -y upgrade
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit
} }

View File

@ -48,6 +48,7 @@ function update_script() {
msg_info "Starting Service" msg_info "Starting Service"
systemctl start apache2 systemctl start apache2
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
exit exit

View File

@ -27,37 +27,6 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if [ ! -d /var/cache/nginx/tiles ]; then
msg_info "Installing Nginx Tile Cache"
mkdir -p /var/cache/nginx/tiles
$STD apt install -y nginx
cat <<EOF >/etc/nginx/nginx.conf
events {
worker_connections 1024;
}
http {
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
server {
listen 80;
location / {
proxy_pass https://tile.openstreetmap.org/;
proxy_set_header Host tile.openstreetmap.org;
proxy_set_header User-Agent "Reitti/1.0";
proxy_cache tiles;
proxy_cache_valid 200 30d;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
}
}
}
EOF
chown -R www-data:www-data /var/cache/nginx/tiles
systemctl restart nginx
echo "reitti.ui.tiles.cache.url=http://127.0.0.1" >> /opt/reitti/application.properties
systemctl restart reitti
msg_info "Installed Nginx Tile Cache"
fi
if check_for_gh_release "reitti" "dedicatedcode/reitti"; then if check_for_gh_release "reitti" "dedicatedcode/reitti"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop reitti systemctl stop reitti

View File

@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}" var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}" var_disk="${var_disk:-4}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-13}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"

View File

@ -27,10 +27,7 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if [[ -f /etc/systemd/system/dns.service ]]; then
mv /etc/systemd/system/dns.service /etc/systemd/system/technitium.service
systemctl daemon-reload
fi
if is_package_installed "aspnetcore-runtime-8.0"; then if is_package_installed "aspnetcore-runtime-8.0"; then
$STD apt remove -y aspnetcore-runtime-8.0 $STD apt remove -y aspnetcore-runtime-8.0
[ -f /etc/apt/sources.list.d/microsoft-prod.list ] && rm -f /etc/apt/sources.list.d/microsoft-prod.list [ -f /etc/apt/sources.list.d/microsoft-prod.list ] && rm -f /etc/apt/sources.list.d/microsoft-prod.list
@ -45,13 +42,11 @@ function update_script() {
fi fi
RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+') RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+')
if [[ ! -f ~/.technitium || ${RELEASE} != "$(cat ~/.technitium)" ]]; then if [[ ! -f ~/.technitium || "${RELEASE}" != "$(cat ~/.technitium)" ]]; then
msg_info "Updating Technitium DNS" msg_info "Updating Technitium DNS"
curl -fsSL "https://download.technitium.com/dns/DnsServerPortable.tar.gz" -o /opt/DnsServerPortable.tar.gz curl -fsSL "https://download.technitium.com/dns/DnsServerPortable.tar.gz" -o /opt/DnsServerPortable.tar.gz
$STD tar zxvf /opt/DnsServerPortable.tar.gz -C /opt/technitium/dns/ $STD tar zxvf /opt/DnsServerPortable.tar.gz -C /opt/technitium/dns/
rm -f /opt/DnsServerPortable.tar.gz rm -f /opt/DnsServerPortable.tar.gz
echo "${RELEASE}" >~/.technitium
systemctl restart technitium
msg_ok "Updated Technitium DNS" msg_ok "Updated Technitium DNS"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
else else

View File

@ -28,8 +28,6 @@ function update_script() {
exit exit
fi fi
JAVA_VERSION="21" setup_java
msg_info "Updating ${APP}" msg_info "Updating ${APP}"
$STD apt update --allow-releaseinfo-change $STD apt update --allow-releaseinfo-change
$STD apt install -y unifi $STD apt install -y unifi

View File

@ -1,690 +0,0 @@
# 🛠️ Helper Functions Reference
**Quick reference for all helper functions available in `tools.func`**
> These functions are automatically available in install scripts via `$FUNCTIONS_FILE_PATH`
---
## 📋 Table of Contents
- [Scripts to Watch](#scripts-to-watch)
- [Runtime & Language Setup](#runtime--language-setup)
- [Database Setup](#database-setup)
- [GitHub Release Helpers](#github-release-helpers)
- [Tools & Utilities](#tools--utilities)
- [SSL/TLS](#ssltls)
- [Utility Functions](#utility-functions)
- [Package Management](#package-management)
---
## 📚 Scripts to Watch
**Learn from real, well-implemented scripts. Each app requires TWO files that work together:**
| File | Location | Purpose |
| ------------------ | ---------------------------- | ------------------------------------------------------------------------ |
| **CT Script** | `ct/appname.sh` | Runs on **Proxmox host** - creates container, contains `update_script()` |
| **Install Script** | `install/appname-install.sh` | Runs **inside container** - installs and configures the app |
> ⚠️ **Both files are ALWAYS required!** The CT script calls the install script automatically during container creation.
### Node.js + PostgreSQL
**Koel** - Music streaming with PHP + Node.js + PostgreSQL
| File | Link |
|------|------|
| CT (update logic) | [ct/koel.sh](../../ct/koel.sh) |
| Install | [install/koel-install.sh](../../install/koel-install.sh) |
**Actual Budget** - Finance app with npm global install
| File | Link |
|------|------|
| CT (update logic) | [ct/actualbudget.sh](../../ct/actualbudget.sh) |
| Install | [install/actualbudget-install.sh](../../install/actualbudget-install.sh) |
### Python + uv
**MeTube** - YouTube downloader with Python uv + Node.js + Deno
| File | Link |
|------|------|
| CT (update logic) | [ct/metube.sh](../../ct/metube.sh) |
| Install | [install/metube-install.sh](../../install/metube-install.sh) |
**Endurain** - Fitness tracker with Python uv + PostgreSQL/PostGIS
| File | Link |
|------|------|
| CT (update logic) | [ct/endurain.sh](../../ct/endurain.sh) |
| Install | [install/endurain-install.sh](../../install/endurain-install.sh) |
### PHP + MariaDB/MySQL
**Wallabag** - Read-it-later with PHP + MariaDB + Redis + Nginx
| File | Link |
|------|------|
| CT (update logic) | [ct/wallabag.sh](../../ct/wallabag.sh) |
| Install | [install/wallabag-install.sh](../../install/wallabag-install.sh) |
**InvoiceNinja** - Invoicing with PHP + MariaDB + Supervisor
| File | Link |
|------|------|
| CT (update logic) | [ct/invoiceninja.sh](../../ct/invoiceninja.sh) |
| Install | [install/invoiceninja-install.sh](../../install/invoiceninja-install.sh) |
**BookStack** - Wiki/Docs with PHP + MariaDB + Apache
| File | Link |
|------|------|
| CT (update logic) | [ct/bookstack.sh](../../ct/bookstack.sh) |
| Install | [install/bookstack-install.sh](../../install/bookstack-install.sh) |
### PHP + SQLite (Simple)
**Speedtest Tracker** - Speedtest with PHP + SQLite + Nginx
| File | Link |
|------|------|
| CT (update logic) | [ct/speedtest-tracker.sh](../../ct/speedtest-tracker.sh) |
| Install | [install/speedtest-tracker-install.sh](../../install/speedtest-tracker-install.sh) |
---
## Runtime & Language Setup
### `setup_nodejs`
Install Node.js from NodeSource repository.
```bash
# Default (Node.js 22)
setup_nodejs
# Specific version
NODE_VERSION="20" setup_nodejs
NODE_VERSION="22" setup_nodejs
NODE_VERSION="24" setup_nodejs
```
### `setup_go`
Install Go programming language (latest stable).
```bash
setup_go
# Use in script
setup_go
cd /opt/myapp
$STD go build -o myapp .
```
### `setup_rust`
Install Rust via rustup.
```bash
setup_rust
# Use in script
setup_rust
source "$HOME/.cargo/env"
$STD cargo build --release
```
### `setup_uv`
Install Python uv package manager (fast pip/venv replacement).
```bash
setup_uv
# Use in script
setup_uv
cd /opt/myapp
$STD uv sync --locked
```
### `setup_ruby`
Install Ruby from official repositories.
```bash
setup_ruby
```
### `setup_php`
Install PHP with configurable modules and FPM/Apache support.
```bash
# Basic PHP
setup_php
# Full configuration
PHP_VERSION="8.3" \
PHP_MODULE="mysqli,gd,curl,mbstring,xml,zip,ldap" \
PHP_FPM="YES" \
PHP_APACHE="YES" \
setup_php
```
**Environment Variables:**
| Variable | Default | Description |
|----------|---------|-------------|
| `PHP_VERSION` | `8.3` | PHP version to install |
| `PHP_MODULE` | `""` | Comma-separated list of modules |
| `PHP_FPM` | `NO` | Install PHP-FPM |
| `PHP_APACHE` | `NO` | Install Apache module |
### `setup_composer`
Install PHP Composer package manager.
```bash
setup_php
setup_composer
# Use in script
$STD composer install --no-dev
```
### `setup_java`
Install Java (OpenJDK).
```bash
# Default (Java 21)
setup_java
# Specific version
JAVA_VERSION="17" setup_java
JAVA_VERSION="21" setup_java
```
---
## Database Setup
### `setup_mariadb`
Install MariaDB server.
```bash
setup_mariadb
```
### `setup_mariadb_db`
Create a MariaDB database and user. Sets `$MARIADB_DB_PASS` with the generated password.
```bash
setup_mariadb
MARIADB_DB_NAME="myapp_db" MARIADB_DB_USER="myapp_user" setup_mariadb_db
# After calling, these variables are available:
# $MARIADB_DB_NAME - Database name
# $MARIADB_DB_USER - Database user
# $MARIADB_DB_PASS - Generated password (saved to ~/[appname].creds)
```
### `setup_mysql`
Install MySQL server.
```bash
setup_mysql
```
### `setup_postgresql`
Install PostgreSQL server.
```bash
# Default (PostgreSQL 17)
setup_postgresql
# Specific version
PG_VERSION="16" setup_postgresql
PG_VERSION="17" setup_postgresql
```
### `setup_postgresql_db`
Create a PostgreSQL database and user. Sets `$PG_DB_PASS` with the generated password.
```bash
PG_VERSION="17" setup_postgresql
PG_DB_NAME="myapp_db" PG_DB_USER="myapp_user" setup_postgresql_db
# After calling, these variables are available:
# $PG_DB_NAME - Database name
# $PG_DB_USER - Database user
# $PG_DB_PASS - Generated password (saved to ~/[appname].creds)
```
### `setup_mongodb`
Install MongoDB server.
```bash
setup_mongodb
```
### `setup_clickhouse`
Install ClickHouse analytics database.
```bash
setup_clickhouse
```
---
## GitHub Release Helpers
> **Note**: `fetch_and_deploy_gh_release` is the **preferred method** for downloading GitHub releases. It handles version tracking automatically. Only use `get_latest_github_release` if you need the version number separately.
### `fetch_and_deploy_gh_release`
**Primary method** for downloading and extracting GitHub releases. Handles version tracking automatically.
```bash
# Basic usage - downloads tarball to /opt/appname
fetch_and_deploy_gh_release "appname" "owner/repo"
# With explicit parameters
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# Pre-built release with specific asset pattern
fetch_and_deploy_gh_release "koel" "koel/koel" "prebuild" "latest" "/opt/koel" "koel-*.tar.gz"
# Clean install (removes old directory first) - used in update_script
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
```
**Parameters:**
| Parameter | Default | Description |
|-----------|---------|-------------|
| `name` | required | App name (for version tracking) |
| `repo` | required | GitHub repo (`owner/repo`) |
| `type` | `tarball` | Release type: `tarball`, `zipball`, `prebuild`, `binary` |
| `version` | `latest` | Version tag or `latest` |
| `dest` | `/opt/[name]` | Destination directory |
| `asset_pattern` | `""` | For `prebuild`: glob pattern to match asset (e.g. `app-*.tar.gz`) |
**Environment Variables:**
| Variable | Description |
|----------|-------------|
| `CLEAN_INSTALL=1` | Remove destination directory before extracting (for updates) |
### `check_for_gh_release`
Check if a newer version is available. Returns 0 if update needed, 1 if already at latest. **Use in `update_script()` function.**
```bash
# In update_script() function in ct/appname.sh
if check_for_gh_release "appname" "owner/repo"; then
msg_info "Updating..."
# Stop services, backup, update, restore, start
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
msg_ok "Updated successfully"
fi
```
### `get_latest_github_release`
Get the latest release version from a GitHub repository. **Only use if you need the version number separately** (e.g., for manual download or display).
```bash
RELEASE=$(get_latest_github_release "owner/repo")
echo "Latest version: $RELEASE"
```
# Examples
fetch_and_deploy_gh_release "bookstack" "BookStackApp/BookStack"
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/myapp"
````
**Parameters:**
| Parameter | Default | Description |
|-----------|---------|-------------|
| `name` | required | App name (for version tracking) |
| `repo` | required | GitHub repo (`owner/repo`) |
| `type` | `tarball` | Release type: `tarball`, `zipball`, `binary` |
| `version` | `latest` | Version tag or `latest` |
| `dest` | `/opt/[name]` | Destination directory |
---
## Tools & Utilities
### `setup_yq`
Install yq YAML processor.
```bash
setup_yq
# Use in script
yq '.server.port = 8080' -i config.yaml
````
### `setup_ffmpeg`
Install FFmpeg with common codecs.
```bash
setup_ffmpeg
```
### `setup_hwaccel`
Setup GPU hardware acceleration (Intel/AMD/NVIDIA).
```bash
# Only runs if GPU passthrough is detected (/dev/dri, /dev/nvidia0, /dev/kfd)
setup_hwaccel
```
### `setup_imagemagick`
Install ImageMagick 7 from source.
```bash
setup_imagemagick
```
### `setup_docker`
Install Docker Engine.
```bash
setup_docker
```
### `setup_adminer`
Install Adminer for database management.
```bash
setup_mariadb
setup_adminer
# Access at http://IP/adminer
```
---
## SSL/TLS
### `create_self_signed_cert`
Create a self-signed SSL certificate.
```bash
create_self_signed_cert
# Creates files at:
# /etc/ssl/[appname]/[appname].key
# /etc/ssl/[appname]/[appname].crt
```
---
## Utility Functions
### `import_local_ip`
Set the `$LOCAL_IP` variable with the container's IP address.
```bash
import_local_ip
echo "Container IP: $LOCAL_IP"
# Use in config files
sed -i "s/localhost/$LOCAL_IP/g" /opt/myapp/config.yaml
```
### `ensure_dependencies`
Ensure packages are installed (installs if missing).
```bash
ensure_dependencies "jq" "unzip" "curl"
```
### `msg_info` / `msg_ok` / `msg_error` / `msg_warn`
Display formatted messages.
```bash
msg_info "Installing application..."
# ... do work ...
msg_ok "Installation complete"
msg_warn "Optional feature not available"
msg_error "Installation failed"
```
---
## Package Management
### `cleanup_lxc`
Final cleanup function - call at end of install script.
```bash
# At the end of your install script
motd_ssh
customize
cleanup_lxc # Handles autoremove, autoclean, cache cleanup
```
### `install_packages_with_retry`
Install packages with automatic retry on failure.
```bash
install_packages_with_retry "package1" "package2" "package3"
```
### `prepare_repository_setup`
Prepare system for adding new repositories (cleanup old repos, keyrings).
```bash
prepare_repository_setup "mariadb" "mysql"
```
---
## Complete Examples
### Example 1: Node.js App with PostgreSQL (install script)
```bash
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: YourUsername
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/example/myapp
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"
# Setup runtimes and databases FIRST
NODE_VERSION="22" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
import_local_ip
# Download app using fetch_and_deploy (handles version tracking)
fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp"
msg_info "Setting up MyApp"
cd /opt/myapp
$STD npm ci --production
msg_ok "Setup MyApp"
msg_info "Configuring MyApp"
cat <<EOF >/opt/myapp/.env
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
HOST=${LOCAL_IP}
PORT=3000
EOF
msg_ok "Configured MyApp"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/myapp.service
[Unit]
Description=MyApp
After=network.target postgresql.service
[Service]
Type=simple
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/server.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now myapp
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
```
### Example 2: Matching Container Script (ct script)
```bash
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: YourUsername
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/example/myapp
APP="MyApp"
var_tags="${var_tags:-webapp}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
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/myapp ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
# check_for_gh_release returns true if update available
if check_for_gh_release "myapp" "example/myapp"; then
msg_info "Stopping Service"
systemctl stop myapp
msg_ok "Stopped Service"
msg_info "Creating Backup"
cp /opt/myapp/.env /tmp/myapp_env.bak
msg_ok "Created Backup"
# CLEAN_INSTALL=1 removes old dir before extracting
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp"
msg_info "Restoring Config & Rebuilding"
cp /tmp/myapp_env.bak /opt/myapp/.env
rm /tmp/myapp_env.bak
cd /opt/myapp
$STD npm ci --production
msg_ok "Restored Config & Rebuilt"
msg_info "Starting Service"
systemctl start myapp
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}:3000${CL}"
```
### Example 3: PHP App with MariaDB (install script)
```bash
#!/usr/bin/env bash
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"
# PHP with FPM and common modules
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
setup_composer
setup_mariadb
MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
import_local_ip
# Download pre-built release (with asset pattern)
fetch_and_deploy_gh_release "myapp" "example/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
msg_info "Configuring MyApp"
cd /opt/myapp
cp .env.example .env
sed -i "s|APP_URL=.*|APP_URL=http://${LOCAL_IP}|" .env
sed -i "s|DB_DATABASE=.*|DB_DATABASE=${MARIADB_DB_NAME}|" .env
sed -i "s|DB_USERNAME=.*|DB_USERNAME=${MARIADB_DB_USER}|" .env
sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${MARIADB_DB_PASS}|" .env
$STD composer install --no-dev --no-interaction
$STD php artisan key:generate --force
$STD php artisan migrate --force
chown -R www-data:www-data /opt/myapp
msg_ok "Configured MyApp"
# ... nginx config, service creation ...
motd_ssh
customize
cleanup_lxc
```

View File

@ -65,7 +65,6 @@ bash docs/contribution/setup-fork.sh
``` ```
This will: This will:
- Auto-detect your GitHub username - Auto-detect your GitHub username
- Update all documentation links to point to your fork - Update all documentation links to point to your fork
- Create `.git-setup-info` with recommended git workflows - Create `.git-setup-info` with recommended git workflows
@ -98,8 +97,6 @@ All scripts and configurations must follow our coding standards to ensure consis
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Essential coding standards and best practices - **[CONTRIBUTING.md](CONTRIBUTING.md)** - Essential coding standards and best practices
- **[CODE_AUDIT.md](CODE_AUDIT.md)** - Code review checklist and audit procedures - **[CODE_AUDIT.md](CODE_AUDIT.md)** - Code review checklist and audit procedures
- **[GUIDE.md](GUIDE.md)** - Comprehensive contribution guide
- **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions
- **Container Scripts** - `/ct/` templates and guidelines - **Container Scripts** - `/ct/` templates and guidelines
- **Install Scripts** - `/install/` templates and guidelines - **Install Scripts** - `/install/` templates and guidelines
- **JSON Configurations** - `/json/` structure and format - **JSON Configurations** - `/json/` structure and format
@ -124,7 +121,6 @@ Before submitting a pull request, ensure your code passes our audit:
**See**: [CODE_AUDIT.md](CODE_AUDIT.md) for complete audit checklist **See**: [CODE_AUDIT.md](CODE_AUDIT.md) for complete audit checklist
Key points: Key points:
- Code consistency with existing scripts - Code consistency with existing scripts
- Proper error handling - Proper error handling
- Correct variable naming - Correct variable naming
@ -149,7 +145,6 @@ Key points:
### Community Guides ### Community Guides
See [USER_SUBMITTED_GUIDES.md](USER_SUBMITTED_GUIDES.md) for excellent community-written guides: See [USER_SUBMITTED_GUIDES.md](USER_SUBMITTED_GUIDES.md) for excellent community-written guides:
- Home Assistant installation and configuration - Home Assistant installation and configuration
- Frigate setup on Proxmox - Frigate setup on Proxmox
- Docker and Portainer installation - Docker and Portainer installation
@ -161,24 +156,16 @@ See [USER_SUBMITTED_GUIDES.md](USER_SUBMITTED_GUIDES.md) for excellent community
Use these templates when creating new scripts: Use these templates when creating new scripts:
```bash ```bash
# Container script template # Container script
cp docs/contribution/templates_ct/AppName.sh ct/my-app.sh cp ct/example.sh ct/my-app.sh
# Installation script template # Installation script
cp docs/contribution/templates_install/AppName-install.sh install/my-app-install.sh cp install/example-install.sh install/my-app-install.sh
# JSON configuration template # JSON configuration (if needed)
cp docs/contribution/templates_json/AppName.json frontend/public/json/my-app.json cp json/example.json json/my-app.json
``` ```
**Template Features:**
- Updated to match current codebase patterns
- Includes all available helper functions from `tools.func`
- Examples for Node.js, Python, PHP, Go applications
- Database setup examples (MariaDB, PostgreSQL)
- Proper service creation and cleanup
--- ---
## 🔄 Git Workflow ## 🔄 Git Workflow
@ -215,21 +202,18 @@ git push origin feature/my-feature
### Before Submitting PR ### Before Submitting PR
1. **Sync with upstream** 1. **Sync with upstream**
```bash ```bash
git fetch upstream git fetch upstream
git rebase upstream/main git rebase upstream/main
``` ```
2. **Test your changes** 2. **Test your changes**
```bash ```bash
bash ct/my-app.sh bash ct/my-app.sh
# Follow prompts and test the container # Follow prompts and test the container
``` ```
3. **Check code standards** 3. **Check code standards**
- [ ] Follows template structure - [ ] Follows template structure
- [ ] Proper error handling - [ ] Proper error handling
- [ ] Documentation updated (if needed) - [ ] Documentation updated (if needed)

View File

@ -1,31 +1,27 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourGitHubUsername] # Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL e.g. https://github.com/example/app] # Source: [SOURCE_URL]
# App Default Values # App Default Values
APP="[AppName]" APP="[APP_NAME]"
var_tags="${var_tags:-[category]}" # Name of the app (e.g. Google, Adventurelog, Apache-Guacamole"
var_cpu="${var_cpu:-2}" var_tags="[TAGS]"
var_ram="${var_ram:-2048}" # Tags for Proxmox VE, maximum 2 pcs., no spaces allowed, separated by a semicolon ; (e.g. database | adblock;dhcp)
var_disk="${var_disk:-4}" var_cpu="[CPU]"
var_os="${var_os:-debian}" # Number of cores (1-X) (e.g. 4) - default are 2
var_version="${var_version:-12}" var_ram="[RAM]"
var_unprivileged="${var_unprivileged:-1}" # Amount of used RAM in MB (e.g. 2048 or 4096)
var_disk="[DISK]"
# ============================================================================= # Amount of used disk space in GB (e.g. 4 or 10)
# CONFIGURATION GUIDE var_os="[OS]"
# ============================================================================= # Default OS (e.g. debian, ubuntu, alpine)
# APP - Display name, title case (e.g. "Koel", "Wallabag", "Actual Budget") var_version="[VERSION]"
# var_tags - Max 2 tags, semicolon separated (e.g. "music;streaming", "finance") # Default OS version (e.g. 12 for debian, 24.04 for ubuntu, 3.20 for alpine)
# var_cpu - CPU cores: 1-4 typical var_unprivileged="[UNPRIVILEGED]"
# var_ram - RAM in MB: 512, 1024, 2048, 4096 typical # 1 = unprivileged container, 0 = privileged container
# var_disk - Disk in GB: 4, 6, 8, 10, 20 typical
# var_os - OS: debian, ubuntu, alpine
# var_version - OS version: 12/13 (debian), 22.04/24.04 (ubuntu), 3.20/3.21 (alpine)
# var_unprivileged - 1 = unprivileged (secure, default), 0 = privileged (for docker etc.)
header_info "$APP" header_info "$APP"
variables variables
@ -37,49 +33,45 @@ function update_script() {
check_container_storage check_container_storage
check_container_resources check_container_resources
# Check if installation exists # Check if installation is present | -f for file, -d for folder
if [[ ! -d /opt/[appname] ]]; then if [[ ! -f [INSTALLATION_CHECK_PATH] ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
# check_for_gh_release returns 0 (true) if update available, 1 (false) if not # Crawling the new version and checking whether an update is required
if check_for_gh_release "[appname]" "[owner/repo]"; then RELEASE=$(curl -fsSL [RELEASE_URL] | [PARSE_RELEASE_COMMAND])
msg_info "Stopping Services" if [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]] || [[ ! -f /opt/${APP}_version.txt ]]; then
systemctl stop [appname] # Stopping Services
msg_ok "Stopped Services" msg_info "Stopping $APP"
systemctl stop [SERVICE_NAME]
msg_ok "Stopped $APP"
# Optional: Backup important data before update # Creating Backup
msg_info "Creating Backup" msg_info "Creating Backup"
mkdir -p /tmp/[appname]_backup tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" [IMPORTANT_PATHS]
cp /opt/[appname]/.env /tmp/[appname]_backup/ 2>/dev/null || true msg_ok "Backup Created"
cp -r /opt/[appname]/data /tmp/[appname]_backup/ 2>/dev/null || true
msg_ok "Created Backup"
# CLEAN_INSTALL=1 removes old directory before extracting new version # Execute Update
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]" msg_info "Updating $APP to v${RELEASE}"
[UPDATE_COMMANDS]
msg_ok "Updated $APP to v${RELEASE}"
# Restore configuration and data # Starting Services
msg_info "Restoring Data" msg_info "Starting $APP"
cp /tmp/[appname]_backup/.env /opt/[appname]/ 2>/dev/null || true systemctl start [SERVICE_NAME]
cp -r /tmp/[appname]_backup/data/* /opt/[appname]/data/ 2>/dev/null || true msg_ok "Started $APP"
rm -rf /tmp/[appname]_backup
msg_ok "Restored Data"
# Optional: Run any post-update commands # Cleaning up
msg_info "Running Post-Update Tasks" msg_info "Cleaning Up"
cd /opt/[appname] rm -rf [TEMP_FILES]
# Examples: msg_ok "Cleanup Completed"
# $STD npm ci --production
# $STD php artisan migrate --force
# $STD composer install --no-dev
msg_ok "Ran Post-Update Tasks"
msg_info "Starting Services" # Last Action
systemctl start [appname] echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Started Services" msg_ok "Update Successful"
else
msg_ok "Updated Successfully" msg_ok "No update required. ${APP} is already at v${RELEASE}"
fi fi
exit exit
} }

View File

@ -1,11 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG # Copyright (c) 2021-2025 community-scripts ORG
# Author: [YourGitHubUsername] # Author: [YourUserName]
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: [SOURCE_URL e.g. https://github.com/example/app] # Source: [SOURCE_URL]
# Import Functions and Setup # Import Functions und Setup
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color color
verb_ip6 verb_ip6
@ -14,177 +14,70 @@ setting_up_container
network_check network_check
update_os update_os
# ============================================================================= # Installing Dependencies with the 3 core dependencies (curl;sudo;mc)
# DEPENDENCIES
# =============================================================================
# Only install what's actually needed - curl/sudo/mc are already in the base image
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y \ $STD apt-get install -y \
nginx \ curl \
build-essential sudo \
mc \
[PACKAGE_1] \
[PACKAGE_2] \
[PACKAGE_3]
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
# ============================================================================= # Template: MySQL Database
# HELPER FUNCTIONS FROM tools.func msg_info "Setting up Database"
# ============================================================================= DB_NAME=[DB_NAME]
# These functions are available via $FUNCTIONS_FILE_PATH (tools.func) DB_USER=[DB_USER]
# Call them with optional environment variables for configuration DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "${APPLICATION} Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/$APP_NAME.creds
msg_ok "Set up Database"
# Temp
# Setup App
msg_info "Setup ${APPLICATION}"
RELEASE=$(curl -s https://api.github.com/repos/[REPO]/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }')
curl -fsSL "https://github.com/[REPO]/archive/refs/tags/${RELEASE}.zip"
unzip -q ${RELEASE}.zip
mv ${APPLICATION}-${RELEASE}/ /opt/${APPLICATION}
# #
# --- Runtime & Language Setup ---
# NODE_VERSION="22" setup_nodejs # Install Node.js (22, 24)
# NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs # With pnpm
# PYTHON_VERSION="3.13" setup_uv # Python with uv package manager
# setup_go # Install Go (latest)
# setup_rust # Install Rust via rustup
# setup_ruby # Install Ruby
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="mysqli,gd" setup_php
# PHP_VERSION="8.3" PHP_FPM="YES" PHP_APACHE="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
# setup_composer # Install PHP Composer
# JAVA_VERSION="21" setup_java # Install Java (17, 21)
# #
# --- Database Setup ---
# setup_mariadb # Install MariaDB server
# MARIADB_DB_NAME="mydb" MARIADB_DB_USER="myuser" setup_mariadb_db
# setup_mysql # Install MySQL server
# PG_VERSION="17" setup_postgresql # Install PostgreSQL (16, 17)
# PG_VERSION="17" PG_MODULES="postgis" setup_postgresql # With extensions
# PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db
# setup_mongodb # Install MongoDB
# #
# --- GitHub Release (PREFERRED METHOD) --- echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
# fetch_and_deploy_gh_release "appname" "owner/repo" # Downloads, extracts, tracks version msg_ok "Setup ${APPLICATION}"
# fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
# fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "app-*.tar.gz"
#
# --- Tools & Utilities ---
# import_local_ip # Sets $LOCAL_IP variable (call early!)
# setup_ffmpeg # Install FFmpeg with codecs
# setup_hwaccel # Setup GPU hardware acceleration
# setup_imagemagick # Install ImageMagick 7
# setup_docker # Install Docker Engine
# setup_adminer # Install Adminer for DB management
# create_self_signed_cert # Creates cert in /etc/ssl/[appname]/
# =============================================================================
# EXAMPLE 1: Node.js Application with PostgreSQL
# =============================================================================
# NODE_VERSION="22" setup_nodejs
# PG_VERSION="17" setup_postgresql
# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
# import_local_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
#
# msg_info "Configuring MyApp"
# cd /opt/myapp
# $STD npm ci
# cat <<EOF >/opt/myapp/.env
# DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
# HOST=${LOCAL_IP}
# PORT=3000
# EOF
# msg_ok "Configured MyApp"
# =============================================================================
# EXAMPLE 2: Python Application with uv
# =============================================================================
# PYTHON_VERSION="3.13" setup_uv
# import_local_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
#
# msg_info "Setting up MyApp"
# cd /opt/myapp
# $STD uv sync
# cat <<EOF >/opt/myapp/.env
# HOST=${LOCAL_IP}
# PORT=8000
# EOF
# msg_ok "Setup MyApp"
# =============================================================================
# EXAMPLE 3: PHP Application with MariaDB + Nginx
# =============================================================================
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
# setup_composer
# setup_mariadb
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
# import_local_ip
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
#
# msg_info "Configuring MyApp"
# cd /opt/myapp
# cp .env.example .env
# sed -i "s|APP_URL=.*|APP_URL=http://${LOCAL_IP}|" .env
# sed -i "s|DB_DATABASE=.*|DB_DATABASE=${MARIADB_DB_NAME}|" .env
# sed -i "s|DB_USERNAME=.*|DB_USERNAME=${MARIADB_DB_USER}|" .env
# sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${MARIADB_DB_PASS}|" .env
# $STD composer install --no-dev --no-interaction
# chown -R www-data:www-data /opt/myapp
# msg_ok "Configured MyApp"
# =============================================================================
# YOUR APPLICATION INSTALLATION
# =============================================================================
# 1. Setup runtimes and databases FIRST
# 2. Call import_local_ip if you need the container IP
# 3. Use fetch_and_deploy_gh_release to download the app (handles version tracking)
# 4. Configure the application
# 5. Create systemd service
# 6. Finalize with motd_ssh, customize, cleanup_lxc
# --- Setup runtimes/databases ---
NODE_VERSION="22" setup_nodejs
import_local_ip
# --- Download and install app ---
fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"
msg_info "Setting up [AppName]"
cd /opt/[appname]
$STD npm ci
msg_ok "Setup [AppName]"
# =============================================================================
# CONFIGURATION
# =============================================================================
msg_info "Configuring [AppName]"
cat <<EOF >/opt/[appname]/.env
HOST=${LOCAL_IP}
PORT=8080
EOF
msg_ok "Configured [AppName]"
# =============================================================================
# SERVICE CREATION
# =============================================================================
# Creating Service (if needed)
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/[appname].service cat <<EOF >/etc/systemd/system/${APPLICATION}.service
[Unit] [Unit]
Description=[AppName] Service Description=${APPLICATION} Service
After=network.target After=network.target
[Service] [Service]
Type=simple ExecStart=[START_COMMAND]
User=root Restart=always
WorkingDirectory=/opt/[appname]
ExecStart=/usr/bin/node /opt/[appname]/server.js
Restart=on-failure
RestartSec=5
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
systemctl enable -q --now [appname] systemctl enable -q --now ${APPLICATION}.service
msg_ok "Created Service" msg_ok "Created Service"
# =============================================================================
# CLEANUP & FINALIZATION
# =============================================================================
motd_ssh motd_ssh
customize customize
# cleanup_lxc handles: apt autoremove, autoclean, temp files, bash history # Cleanup
cleanup_lxc msg_info "Cleaning up"
rm -f ${RELEASE}.zip
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@ -8,7 +8,7 @@
"type": "ct", "type": "ct",
"updateable": true, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": "DEFAULT-PORT", "interface_port": DEFAULT-PORT,
"documentation": null, "documentation": null,
"website": "LINK TO WEBSITE", "website": "LINK TO WEBSITE",
"logo": "LINK TO LOGO", "logo": "LINK TO LOGO",

View File

@ -23,7 +23,7 @@
"ram": 1024, "ram": 1024,
"hdd": 5, "hdd": 5,
"os": "debian", "os": "debian",
"version": "13" "version": "12"
} }
} }
], ],

View File

@ -23,7 +23,7 @@
"ram": 2048, "ram": 2048,
"hdd": 10, "hdd": 10,
"os": "debian", "os": "debian",
"version": "13" "version": "12"
} }
}, },
{ {

View File

@ -2,7 +2,7 @@
"name": "InvoiceNinja", "name": "InvoiceNinja",
"slug": "invoiceninja", "slug": "invoiceninja",
"categories": [ "categories": [
25 3
], ],
"date_created": "2025-12-12", "date_created": "2025-12-12",
"type": "ct", "type": "ct",

View File

@ -1,46 +0,0 @@
{
"name": "Pi-Hole Exporter",
"slug": "pihole-exporter",
"categories": [
9
],
"date_created": "2025-12-21",
"type": "addon",
"updateable": true,
"privileged": false,
"interface_port": 9617,
"documentation": "https://github.com/eko/pihole-exporter",
"website": "https://github.com/eko/pihole-exporter",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/pi-hole.webp",
"config_path": "/opt/pihole-exporter.env",
"description": "A Prometheus exporter for PI-Hole's Raspberry PI ad blocker",
"install_methods": [
{
"type": "default",
"script": "tools/addon/pihole-exporter.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
},
{
"type": "alpine",
"script": "tools/addon/pihole-exporter.sh",
"resources": {
"cpu": null,
"ram": null,
"hdd": null,
"os": null,
"version": null
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@ -31,10 +31,5 @@
"username": null, "username": null,
"password": null "password": null
}, },
"notes": [ "notes": []
{
"text": "Type `/opt/pocketbase/pocketbase superuser create YOUREMAIL PASSWORD` to create your superuser account.",
"type": "info"
}
]
} }

View File

@ -31,14 +31,5 @@
"username": null, "username": null,
"password": null "password": null
}, },
"notes": [ "notes": []
{
"type": "warning",
"text": "Configure your Radarr/Sonarr instances in `/root/.config/recyclarr/recyclarr.yml` before the first sync."
},
{
"type": "info",
"text": "Automatic daily sync is configured via `/etc/cron.d/recyclarr`. Sync logs are saved to `/root/.config/recyclarr/sync.log`."
}
]
} }

View File

@ -12,7 +12,7 @@
"documentation": "https://github.com/Tautulli/Tautulli/wiki", "documentation": "https://github.com/Tautulli/Tautulli/wiki",
"website": "https://tautulli.com/", "website": "https://tautulli.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/tautulli.webp", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/tautulli.webp",
"config_path": "/opt/Tautulli/config.ini", "config_path": "",
"description": "Tautulli allows you to monitor and track your Plex Media Server usage, such as viewing statistics and analysis of your media library. It can be used to monitor user activity, get notifications about new media added to your library, and even generate reports on your media usage.", "description": "Tautulli allows you to monitor and track your Plex Media Server usage, such as viewing statistics and analysis of your media library. It can be used to monitor user activity, get notifications about new media added to your library, and even generate reports on your media usage.",
"install_methods": [ "install_methods": [
{ {
@ -23,7 +23,7 @@
"ram": 1024, "ram": 1024,
"hdd": 4, "hdd": 4,
"os": "debian", "os": "debian",
"version": "13" "version": "12"
} }
} }
], ],

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,16 @@ setting_up_container
network_check network_check
update_os update_os
fetch_and_deploy_gh_release "backrest" "garethgeorge/backrest" "prebuild" "latest" "/opt/backrest/bin" "backrest_Linux_x86_64.tar.gz" msg_info "Installing Backrest"
RELEASE=$(curl -fsSL https://api.github.com/repos/garethgeorge/backrest/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
temp_file=$(mktemp)
mkdir -p /opt/backrest/{bin,config,data}
curl -fsSL "https://github.com/garethgeorge/backrest/releases/download/v${RELEASE}/backrest_Linux_x86_64.tar.gz" -o "$temp_file"
tar xzf $temp_file -C /opt/backrest/bin
chmod +x /opt/backrest/bin/backrest
rm -f "$temp_file"
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
msg_ok "Installed Backrest"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/backrest.service cat <<EOF >/etc/systemd/system/backrest.service
@ -23,6 +32,7 @@ After=network.target
[Service] [Service]
Type=simple Type=simple
User=root
ExecStart=/opt/backrest/bin/backrest ExecStart=/opt/backrest/bin/backrest
Environment="BACKREST_PORT=9898" Environment="BACKREST_PORT=9898"
Environment="BACKREST_CONFIG=/opt/backrest/config/config.json" Environment="BACKREST_CONFIG=/opt/backrest/config/config.json"
@ -38,3 +48,4 @@ msg_ok "Created Service"
motd_ssh motd_ssh
customize customize
cleanup_lxc cleanup_lxc

View File

@ -13,7 +13,11 @@ setting_up_container
network_check network_check
update_os update_os
fetch_and_deploy_gh_release "beszel" "henrygd/beszel" "prebuild" "latest" "/opt/beszel" "beszel_linux_amd64.tar.gz" msg_info "Installing Beszel"
mkdir -p /opt/beszel
curl -fsSL "https://github.com/henrygd/beszel/releases/latest/download/beszel_$(uname -s)_$(uname -m | sed -e 's/x86_64/amd64/' -e 's/armv6l/arm/' -e 's/armv7l/arm/' -e 's/aarch64/arm64/').tar.gz" | tar -xz -O beszel | tee /opt/beszel/beszel >/dev/null
chmod +x /opt/beszel/beszel
msg_ok "Installed Beszel"
msg_info "Creating Service" msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/beszel-hub.service cat <<EOF >/etc/systemd/system/beszel-hub.service

View File

@ -14,6 +14,7 @@ network_check
update_os update_os
setup_hwaccel setup_hwaccel
fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz" fetch_and_deploy_gh_release "ersatztv" "ErsatzTV/ErsatzTV" "prebuild" "latest" "/opt/ErsatzTV" "*linux-x64.tar.gz"
fetch_and_deploy_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg" "prebuild" "latest" "/opt/ErsatzTV-ffmpeg" "*-linux64-gpl-7.1.tar.xz" fetch_and_deploy_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg" "prebuild" "latest" "/opt/ErsatzTV-ffmpeg" "*-linux64-gpl-7.1.tar.xz"

View File

@ -50,7 +50,7 @@ Group=git
WorkingDirectory=/var/lib/forgejo/ WorkingDirectory=/var/lib/forgejo/
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=always Restart=always
Environment=USER=git HOME=/home/git FORGEJO_WORK_DIR=/var/lib/forgejo Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF

View File

@ -43,7 +43,7 @@ ExecStart=/usr/bin/php artisan serve --port 7990 --host 0.0.0.0
TimeoutStopSec=30 TimeoutStopSec=30
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target"
EOF EOF
systemctl enable -q --now heimdall systemctl enable -q --now heimdall
cd /opt/Heimdall cd /opt/Heimdall

View File

@ -16,21 +16,7 @@ update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y \ $STD apt install -y \
nginx \ nginx \
supervisor \ supervisor
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libasound2 \
libpango-1.0-0 \
libcairo2
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
setup_mariadb setup_mariadb
@ -89,12 +75,6 @@ chown -R www-data:www-data /opt/invoiceninja
chmod -R 775 /opt/invoiceninja/storage /opt/invoiceninja/bootstrap/cache chmod -R 775 /opt/invoiceninja/storage /opt/invoiceninja/bootstrap/cache
msg_ok "Configured InvoiceNinja" msg_ok "Configured InvoiceNinja"
msg_info "Downloading Chromium for PDF Generation"
cd /opt/invoiceninja
$STD ./vendor/bin/snappdf download
chown -R www-data:www-data /opt/invoiceninja/vendor/beganovich/snappdf/versions
msg_ok "Downloaded Chromium for PDF Generation"
msg_info "Setting up Database" msg_info "Setting up Database"
cd /opt/invoiceninja cd /opt/invoiceninja
$STD php artisan config:clear $STD php artisan config:clear
@ -103,7 +83,6 @@ $STD php artisan route:clear
$STD php artisan view:clear $STD php artisan view:clear
$STD php artisan migrate --force $STD php artisan migrate --force
$STD php artisan db:seed --force $STD php artisan db:seed --force
$STD php artisan ninja:post-update
$STD php artisan optimize $STD php artisan optimize
msg_ok "Set up Database" msg_ok "Set up Database"

View File

@ -21,18 +21,6 @@ cd /opt/jotty
$STD yarn --frozen-lockfile $STD yarn --frozen-lockfile
$STD yarn next telemetry disable $STD yarn next telemetry disable
$STD yarn build $STD yarn build
[ -d "public" ] && cp -r public .next/standalone/
[ -d "howto" ] && cp -r howto .next/standalone/
mkdir -p .next/standalone/.next
cp -r .next/static .next/standalone/.next/
mv .next/standalone /tmp/jotty_standalone
rm -rf * .next .git .gitignore .yarn
mv /tmp/jotty_standalone/* .
mv /tmp/jotty_standalone/.[!.]* . 2>/dev/null || true
rm -rf /tmp/jotty_standalone
mkdir -p data/{users,checklists,notes} mkdir -p data/{users,checklists,notes}
cat <<EOF >/opt/jotty/.env cat <<EOF >/opt/jotty/.env
@ -67,7 +55,7 @@ After=network.target
[Service] [Service]
WorkingDirectory=/opt/jotty WorkingDirectory=/opt/jotty
EnvironmentFile=/opt/jotty/.env EnvironmentFile=/opt/jotty/.env
ExecStart=/usr/bin/node server.js ExecStart=yarn start
Restart=on-abnormal Restart=on-abnormal
[Install] [Install]

View File

@ -49,7 +49,7 @@ export PUBLIC_VERSION=""
export PUBLIC_API_URL="" export PUBLIC_API_URL=""
export BASE_PATH="/web" export BASE_PATH="/web"
cd /opt/mediamanager/web cd /opt/mediamanager/web
$STD npm install --no-fund --no-audit $STD npm ci --no-fund --no-audit
$STD npm run build $STD npm run build
mkdir -p {"$MM_DIR"/web,"$MEDIA_DIR","$CONFIG_DIR"} mkdir -p {"$MM_DIR"/web,"$MEDIA_DIR","$CONFIG_DIR"}
cp -r build "$FRONTEND_FILES_DIR" cp -r build "$FRONTEND_FILES_DIR"

View File

@ -19,12 +19,28 @@ msg_ok "Installed dependendencies"
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="openarchiver_db" PG_DB_USER="openarchiver" setup_postgresql_db
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary"
fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball" fetch_and_deploy_gh_release "openarchiver" "LogicLabs-OU/OpenArchiver" "tarball"
JWT_KEY="$(openssl rand -hex 32)" JWT_KEY="$(openssl rand -hex 32)"
SECRET_KEY="$(openssl rand -hex 32)" SECRET_KEY="$(openssl rand -hex 32)"
import_local_ip IP_ADDR=$(hostname -I | awk '{print $1}')
msg_info "Setting up PostgreSQL"
DB_NAME="openarchiver_db"
DB_USER="openarchiver"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-18)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
echo "Open Archiver DB Credentials"
echo "Database Name: $DB_NAME"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
} >>~/openarchiver.creds
msg_ok "Set up PostgreSQL"
msg_info "Configuring MeiliSearch" msg_info "Configuring MeiliSearch"
curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml curl -fsSL https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -o /etc/meilisearch.toml
@ -60,10 +76,10 @@ mkdir -p /opt/openarchiver-data
cd /opt/openarchiver cd /opt/openarchiver
cp .env.example .env cp .env.example .env
sed -i "s|^NODE_ENV=.*|NODE_ENV=production|g" /opt/openarchiver/.env sed -i "s|^NODE_ENV=.*|NODE_ENV=production|g" /opt/openarchiver/.env
sed -i "s|^POSTGRES_DB=.*|POSTGRES_DB=$PG_DB_NAME|g" /opt/openarchiver/.env sed -i "s|^POSTGRES_DB=.*|POSTGRES_DB=openarchiver_db|g" /opt/openarchiver/.env
sed -i "s|^POSTGRES_USER=.*|POSTGRES_USER=$PG_DB_USER|g" /opt/openarchiver/.env sed -i "s|^POSTGRES_USER=.*|POSTGRES_USER=openarchiver|g" /opt/openarchiver/.env
sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$PG_DB_PASS|g" /opt/openarchiver/.env sed -i "s|^POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASS|g" /opt/openarchiver/.env
sed -i "s|^DATABASE_URL=.*|DATABASE_URL=\"postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME\"|g" /opt/openarchiver/.env sed -i "s|^DATABASE_URL=.*|DATABASE_URL=\"postgresql://openarchiver:$DB_PASS@localhost:5432/openarchiver_db\"|g" /opt/openarchiver/.env
sed -i "s|^MEILI_HOST=.*|MEILI_HOST=http://localhost:7700|g" /opt/openarchiver/.env sed -i "s|^MEILI_HOST=.*|MEILI_HOST=http://localhost:7700|g" /opt/openarchiver/.env
sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$MASTER_KEY|g" /opt/openarchiver/.env sed -i "s|^MEILI_MASTER_KEY=.*|MEILI_MASTER_KEY=$MASTER_KEY|g" /opt/openarchiver/.env
sed -i "s|^REDIS_HOST=.*|REDIS_HOST=localhost|g" /opt/openarchiver/.env sed -i "s|^REDIS_HOST=.*|REDIS_HOST=localhost|g" /opt/openarchiver/.env
@ -72,7 +88,7 @@ sed -i "s|^STORAGE_LOCAL_ROOT_PATH=.*|STORAGE_LOCAL_ROOT_PATH=/opt/openarchiver-
sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$JWT_KEY|g" /opt/openarchiver/.env sed -i "s|^JWT_SECRET=.*|JWT_SECRET=$JWT_KEY|g" /opt/openarchiver/.env
sed -i "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=$SECRET_KEY|g" /opt/openarchiver/.env sed -i "s|^ENCRYPTION_KEY=.*|ENCRYPTION_KEY=$SECRET_KEY|g" /opt/openarchiver/.env
sed -i "s|^TIKA_URL=.*|TIKA_URL=|g" /opt/openarchiver/.env sed -i "s|^TIKA_URL=.*|TIKA_URL=|g" /opt/openarchiver/.env
sed -i "s|^ORIGIN=.*|ORIGIN=http://$LOCAL_IP:3000|g" /opt/openarchiver/.env sed -i "s|^ORIGIN=.*|ORIGIN=http://$IP_ADDR:3000|g" /opt/openarchiver/.env
$STD pnpm install --shamefully-hoist --frozen-lockfile --prod=false $STD pnpm install --shamefully-hoist --frozen-lockfile --prod=false
$STD pnpm run build:oss $STD pnpm run build:oss
$STD pnpm db:migrate $STD pnpm db:migrate

View File

@ -14,14 +14,28 @@ network_check
update_os update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y apt-transport-https $STD apt install -y \
apt-transport-https \
ca-certificates
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="openproject" PG_DB_USER="openproject" setup_postgresql_db
msg_info "Setting up PostgreSQL"
DB_NAME=openproject
DB_USER=openproject
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
API_KEY=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13) API_KEY=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
echo "OpenProject API Key: $API_KEY" >>~/openproject.creds $STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
import_local_ip $STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;"
{
echo "OpenProject-Credentials"
echo -e "OpenProject Database User: $DB_USER"
echo -e "OpenProject Database Password: $DB_PASS"
echo -e "OpenProject Database Name: $DB_NAME"
echo -e "OpenProject API Key: $API_KEY"
} >>~/openproject.creds
msg_ok "Set up PostgreSQL"
msg_info "Setting up OpenProject Repository" msg_info "Setting up OpenProject Repository"
curl -fsSL "https://dl.packager.io/srv/opf/openproject/key" | gpg --dearmor >/etc/apt/trusted.gpg.d/packager-io.gpg curl -fsSL "https://dl.packager.io/srv/opf/openproject/key" | gpg --dearmor >/etc/apt/trusted.gpg.d/packager-io.gpg
@ -34,6 +48,7 @@ $STD apt install -y openproject
msg_ok "Installed OpenProject" msg_ok "Installed OpenProject"
msg_info "Configuring OpenProject" msg_info "Configuring OpenProject"
IP_ADDR=$(hostname -I | cut -d' ' -f1)
cat <<EOF >/etc/openproject/installer.dat cat <<EOF >/etc/openproject/installer.dat
openproject/edition default openproject/edition default
@ -41,13 +56,13 @@ postgres/retry retry
postgres/autoinstall reuse postgres/autoinstall reuse
postgres/db_host 127.0.0.1 postgres/db_host 127.0.0.1
postgres/db_port 5432 postgres/db_port 5432
postgres/db_username ${PG_DB_USER} postgres/db_username ${DB_USER}
postgres/db_password ${PG_DB_PASS} postgres/db_password ${DB_PASS}
postgres/db_name ${PG_DB_NAME} postgres/db_name ${DB_NAME}
server/autoinstall install server/autoinstall install
server/variant apache2 server/variant apache2
server/hostname ${LOCAL_IP} server/hostname ${IP_ADDR}
server/server_path_prefix /openproject server/server_path_prefix /openproject
server/ssl no server/ssl no
server/variant apache2 server/variant apache2
@ -60,6 +75,7 @@ memcached/autoinstall install
openproject/admin_email admin@example.net openproject/admin_email admin@example.net
openproject/default_language en openproject/default_language en
EOF EOF
$STD sudo openproject configure $STD sudo openproject configure
msg_ok "Configured OpenProject" msg_ok "Configured OpenProject"

View File

@ -16,11 +16,11 @@ update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y \ $STD apt install -y \
redis-server \ redis-server \
nginx nginx \
openssl
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "ots" "Luzifer/ots" "prebuild" "latest" "/opt/ots" "ots_linux_amd64.tgz" fetch_and_deploy_gh_release "ots" "Luzifer/ots" "prebuild" "latest" "/opt/ots" "ots_linux_amd64.tgz"
create_self_signed_cert
msg_info "Setup OTS" msg_info "Setup OTS"
cat <<EOF >/opt/ots/.env cat <<EOF >/opt/ots/.env
@ -31,6 +31,14 @@ STORAGE_TYPE=redis
EOF EOF
msg_ok "Setup OTS" msg_ok "Setup OTS"
msg_info "Generating Universal SSL Certificate"
mkdir -p /etc/ssl/ots
$STD openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/ots/key.pem \
-out /etc/ssl/ots/cert.pem \
-subj "/CN=ots"
msg_ok "Certificate Generated"
msg_info "Setting up nginx" msg_info "Setting up nginx"
cat <<EOF >/etc/nginx/sites-available/ots.conf cat <<EOF >/etc/nginx/sites-available/ots.conf
server { server {
@ -44,8 +52,8 @@ server {
listen [::]:443 ssl; listen [::]:443 ssl;
server_name ots; server_name ots;
ssl_certificate /etc/ssl/ots/ots.crt; ssl_certificate /etc/ssl/ots/cert.pem;
ssl_certificate_key /etc/ssl/ots/ots.key; ssl_certificate_key /etc/ssl/ots/key.pem;
location / { location / {
add_header X-Robots-Tag noindex; add_header X-Robots-Tag noindex;

View File

@ -22,12 +22,29 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="outline" PG_DB_USER="outline" setup_postgresql_db
msg_info "Set up PostgreSQL Database"
DB_NAME="outline"
DB_USER="outline"
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET timezone TO 'UTC';"
{
echo "Outline-Credentials"
echo "Outline Database User: $DB_USER"
echo "Outline Database Password: $DB_PASS"
echo "Outline Database Name: $DB_NAME"
} >>~/outline.creds
msg_ok "Set up PostgreSQL Database"
fetch_and_deploy_gh_release "outline" "outline/outline" "tarball" fetch_and_deploy_gh_release "outline" "outline/outline" "tarball"
import_local_ip
msg_info "Configuring Outline (Patience)" msg_info "Configuring Outline (Patience)"
SECRET_KEY="$(openssl rand -hex 32)" SECRET_KEY="$(openssl rand -hex 32)"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
cd /opt/outline cd /opt/outline
cp .env.sample .env cp .env.sample .env
export NODE_ENV=development export NODE_ENV=development

View File

@ -13,6 +13,10 @@ setting_up_container
network_check network_check
update_os update_os
msg_info "Installing Dependencies"
$STD apt install -y ca-certificates
msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
fetch_and_deploy_gh_release "overseerr" "sct/overseerr" "tarball" fetch_and_deploy_gh_release "overseerr" "sct/overseerr" "tarball"

View File

@ -16,17 +16,22 @@ update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y \ $STD apt install -y \
gcc \ gcc \
ca-certificates \
musl-dev \ musl-dev \
mupdf \ mupdf \
libc6-dev \ libc6-dev \
musl-tools musl-tools
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs NODE_VERSION="22" setup_nodejs
setup_go setup_go
fetch_and_deploy_gh_release "paperless-gpt" "icereed/paperless-gpt" "tarball"
msg_info "Setup Paperless-GPT" msg_info "Setup Paperless-GPT"
temp_file=$(mktemp)
RELEASE=$(curl -fsSL https://api.github.com/repos/icereed/paperless-gpt/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
curl -fsSL "https://github.com/icereed/paperless-gpt/archive/refs/tags/v${RELEASE}.tar.gz" -o "$temp_file"
tar zxf "$temp_file"
mv paperless-gpt-"${RELEASE}" /opt/paperless-gpt
cd /opt/paperless-gpt/web-app cd /opt/paperless-gpt/web-app
$STD npm install $STD npm install
$STD npm run build $STD npm run build
@ -35,19 +40,21 @@ go mod download
export CC=musl-gcc export CC=musl-gcc
CGO_ENABLED=1 go build -tags musl -o /dev/null github.com/mattn/go-sqlite3 CGO_ENABLED=1 go build -tags musl -o /dev/null github.com/mattn/go-sqlite3
CGO_ENABLED=1 go build -tags musl -o paperless-gpt . CGO_ENABLED=1 go build -tags musl -o paperless-gpt .
rm -f "$temp_file"
echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt"
msg_ok "Setup Paperless-GPT" msg_ok "Setup Paperless-GPT"
mkdir -p /opt/paperless-gpt-data mkdir -p /opt/paperless-gpt-data
read -rp "${TAB3}Do you want to enter the Paperless local URL now? (y/n) " input_url read -p "${TAB3}Do you want to enter the Paperless local URL now? (y/n) " input_url
if [[ $input_url =~ ^[Yy]$ ]]; then if [[ "$input_url" =~ ^[Yy]$ ]]; then
read -rp "${TAB3}Enter your Paperless-NGX instance URL (e.g., http://192.168.1.100:8000): " PAPERLESS_BASE_URL read -p "${TAB3}Enter your Paperless-NGX instance URL (e.g., http://192.168.1.100:8000): " PAPERLESS_BASE_URL
else else
PAPERLESS_BASE_URL="http://your_paperless_ngx_url" PAPERLESS_BASE_URL="http://your_paperless_ngx_url"
fi fi
read -rp "${TAB3}Do you want to enter the Paperless API token now? (y/n) " input_token read -p "${TAB3}Do you want to enter the Paperless API token now? (y/n) " input_token
if [[ $input_token =~ ^[Yy]$ ]]; then if [[ "$input_token" =~ ^[Yy]$ ]]; then
read -rp "${TAB3}Enter your Paperless API token: " PAPERLESS_API_TOKEN read -p "${TAB3}Enter your Paperless API token: " PAPERLESS_API_TOKEN
else else
PAPERLESS_API_TOKEN="your_paperless_api_token" PAPERLESS_API_TOKEN="your_paperless_api_token"
fi fi

View File

@ -15,20 +15,39 @@ update_os
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
PG_VERSION="16" setup_postgresql PG_VERSION="16" setup_postgresql
PG_DB_NAME="partdb" PG_DB_USER="partdb" setup_postgresql_db PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="xsl,pgsql" setup_php
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="xsl,pgsql" PHP_POST_MAX_SIZE="100M" PHP_UPLOAD_MAX_FILESIZE="100M" setup_php
setup_composer setup_composer
msg_info "Setting up PHP"
PHPVER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "\n";')
sed -i "s@post_max_size = 8M@post_max_size = 100M@g" /etc/php/${PHPVER}/apache2/php.ini
sed -i "s@upload_max_filesize = 2M@upload_max_filesize = 100M@g" /etc/php/${PHPVER}/apache2/php.ini
msg_ok "Setting up PHP"
msg_info "Setting up PostgreSQL"
DB_NAME=partdb
DB_USER=partdb
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER TEMPLATE template0;"
{
echo "Part-DB Credentials"
echo "Part-DB Database User: $DB_USER"
echo "Part-DB Database Password: $DB_PASS"
echo "Part-DB Database Name: $DB_NAME"
} >>~/partdb.creds
msg_ok "Set up PostgreSQL"
msg_info "Installing Part-DB (Patience)" msg_info "Installing Part-DB (Patience)"
cd /opt cd /opt
RELEASE=$(get_latest_github_release "Part-DB/Part-DB-server") RELEASE=$(curl -fsSL https://api.github.com/repos/Part-DB/Part-DB-server/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip" curl -fsSL "https://github.com/Part-DB/Part-DB-server/archive/refs/tags/v${RELEASE}.zip" -o "/opt/v${RELEASE}.zip"
$STD unzip "v${RELEASE}.zip" $STD unzip "v${RELEASE}.zip"
mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb mv /opt/Part-DB-server-${RELEASE}/ /opt/partdb
cd /opt/partdb/ cd /opt/partdb/
cp .env .env.local cp .env .env.local
sed -i "s|DATABASE_URL=\"sqlite:///%kernel.project_dir%/var/app.db\"|DATABASE_URL=\"postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}?serverVersion=12.19&charset=utf8\"|" .env.local sed -i "s|DATABASE_URL=\"sqlite:///%kernel.project_dir%/var/app.db\"|DATABASE_URL=\"postgresql://${DB_USER}:${DB_PASS}@127.0.0.1:5432/${DB_NAME}?serverVersion=12.19&charset=utf8\"|" .env.local
export COMPOSER_ALLOW_SUPERUSER=1 export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev -o --no-interaction $STD composer install --no-dev -o --no-interaction
@ -45,7 +64,7 @@ ADMIN_PASS=$(grep -oP 'The initial password for the "admin" user is: \K\w+' ~/da
} >>~/partdb.creds } >>~/partdb.creds
rm -rf ~/database-migration-output rm -rf ~/database-migration-output
rm -rf "/opt/v${RELEASE}.zip" rm -rf "/opt/v${RELEASE}.zip"
echo "${RELEASE}" >~/.partdb echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
msg_ok "Installed Part-DB" msg_ok "Installed Part-DB"
msg_info "Creating Service" msg_info "Creating Service"

View File

@ -21,18 +21,18 @@ $STD apt install -y \
msg_ok "Installed dependencies" msg_ok "Installed dependencies"
setup_mariadb setup_mariadb
MARIADB_DB_NAME="passboltdb" MARIADB_DB_USER="passbolt" setup_mariadb_db MARIADB_DB_NAME="passboltdb" MARIADB_DB_USER="passbolt" MARIADB_DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)" setup_mariadb_db
create_self_signed_cert
import_local_ip
setup_deb822_repo \ setup_deb822_repo \
"passbolt" \ "passbolt" \
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \ "https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \
"https://download.passbolt.com/ce/debian" \ "https://download.passbolt.com/ce/debian" \
"buster" \ "buster" \
"stable" "stable"
create_self_signed_cert "passbolt"
msg_info "Setting up Passbolt (Patience)" msg_info "Setting up Passbolt (Patience)"
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
IP_ADDR=$(hostname -I | awk '{print $1}')
echo passbolt-ce-server passbolt/mysql-configuration boolean true | debconf-set-selections echo passbolt-ce-server passbolt/mysql-configuration boolean true | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-username string $MARIADB_DB_USER | debconf-set-selections echo passbolt-ce-server passbolt/mysql-passbolt-username string $MARIADB_DB_USER | debconf-set-selections
echo passbolt-ce-server passbolt/mysql-passbolt-password password $MARIADB_DB_PASS | debconf-set-selections echo passbolt-ce-server passbolt/mysql-passbolt-password password $MARIADB_DB_PASS | debconf-set-selections
@ -40,7 +40,7 @@ echo passbolt-ce-server passbolt/mysql-passbolt-password-repeat password $MARIAD
echo passbolt-ce-server passbolt/mysql-passbolt-dbname string $MARIADB_DB_NAME | debconf-set-selections echo passbolt-ce-server passbolt/mysql-passbolt-dbname string $MARIADB_DB_NAME | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-configuration boolean true | debconf-set-selections echo passbolt-ce-server passbolt/nginx-configuration boolean true | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-configuration-three-choices select manual | debconf-set-selections echo passbolt-ce-server passbolt/nginx-configuration-three-choices select manual | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-domain string $LOCAL_IP | debconf-set-selections echo passbolt-ce-server passbolt/nginx-domain string $IP_ADDR | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-certificate-file string /etc/ssl/passbolt/passbolt.crt | debconf-set-selections echo passbolt-ce-server passbolt/nginx-certificate-file string /etc/ssl/passbolt/passbolt.crt | debconf-set-selections
echo passbolt-ce-server passbolt/nginx-certificate-key-file string /etc/ssl/passbolt/passbolt.key | debconf-set-selections echo passbolt-ce-server passbolt/nginx-certificate-key-file string /etc/ssl/passbolt/passbolt.key | debconf-set-selections
$STD apt install -y --no-install-recommends passbolt-ce-server $STD apt install -y --no-install-recommends passbolt-ce-server

View File

@ -22,9 +22,24 @@ msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
PG_VERSION="17" setup_postgresql PG_VERSION="17" setup_postgresql
PG_DB_NAME="patchmon_db" PG_DB_USER="patchmon_usr" setup_postgresql_db
msg_info "Setup PostgreSQL Database"
DB_NAME=patchmon_db
DB_USER=patchmon_usr
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER ENCODING 'UTF8' TEMPLATE template0;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
{
echo "PatchMon Credentials"
echo "PatchMon Database Name: $DB_NAME"
echo "PatchMon Database User: $DB_USER"
echo "PatchMon Database Password: $DB_PASS"
} >>~/patchmon.creds
msg_ok "Setup PostgreSQL Database"
fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon" fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
import_local_ip
msg_info "Configuring PatchMon" msg_info "Configuring PatchMon"
cd /opt/patchmon cd /opt/patchmon
@ -35,10 +50,12 @@ $STD npm install --no-audit --no-fund --no-save --ignore-scripts
cd /opt/patchmon/frontend cd /opt/patchmon/frontend
$STD npm install --include=dev --no-audit --no-fund --no-save --ignore-scripts $STD npm install --include=dev --no-audit --no-fund --no-save --ignore-scripts
$STD npm run build $STD npm run build
JWT_SECRET="$(openssl rand -base64 64 | tr -d "=+/" | cut -c1-50)" JWT_SECRET="$(openssl rand -base64 64 | tr -d "=+/" | cut -c1-50)"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
cat <<EOF >/opt/patchmon/backend/.env cat <<EOF >/opt/patchmon/backend/.env
# Database Configuration # Database Configuration
DATABASE_URL="postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME" DATABASE_URL="postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME"
PY_THRESHOLD=3M_DB_CONN_MAX_ATTEMPTS=30 PY_THRESHOLD=3M_DB_CONN_MAX_ATTEMPTS=30
PM_DB_CONN_WAIT_INTERVAL=2 PM_DB_CONN_WAIT_INTERVAL=2
@ -255,6 +272,7 @@ async function updateSettings() {
updateSettings(); updateSettings();
EOF EOF
cd /opt/patchmon/backend cd /opt/patchmon/backend
$STD node update-settings.js $STD node update-settings.js
msg_ok "Settings updated successfully" msg_ok "Settings updated successfully"

View File

@ -20,8 +20,24 @@ $STD apt install -y \
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
setup_mariadb setup_mariadb
MARIADB_DB_NAME="plantit" MARIADB_DB_USER="plantit_usr" setup_mariadb_db
JAVA_VERSION="21" setup_java JAVA_VERSION="21" setup_java
msg_info "Setting up MariaDB"
JWT_SECRET=$(openssl rand -base64 24 | tr -d '/+=')
DB_NAME=plantit
DB_USER=plantit_usr
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "Plant-it Credentials"
echo "Plant-it Database User: $DB_USER"
echo "Plant-it Database Password: $DB_PASS"
echo "Plant-it Database Name: $DB_NAME"
} >>~/plant-it.creds
msg_ok "Set up MariaDB"
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "0.10.0" "/opt/plant-it/backend" "server.jar" USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "plant-it" "MDeLuise/plant-it" "singlefile" "0.10.0" "/opt/plant-it/backend" "server.jar"
fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "0.10.0" "/opt/plant-it/frontend" "client.tar.gz" fetch_and_deploy_gh_release "plant-it-front" "MDeLuise/plant-it" "prebuild" "0.10.0" "/opt/plant-it/frontend" "client.tar.gz"
@ -30,10 +46,10 @@ mkdir -p /opt/plant-it-data
cat <<EOF >/opt/plant-it/backend/server.env cat <<EOF >/opt/plant-it/backend/server.env
MYSQL_HOST=localhost MYSQL_HOST=localhost
MYSQL_PORT=3306 MYSQL_PORT=3306
MYSQL_USERNAME=$MARIADB_DB_USER MYSQL_USERNAME=$DB_USER
MYSQL_PSW=$MARIADB_DB_PASS MYSQL_PSW=$DB_PASS
MYSQL_DATABASE=$MARIADB_DB_NAME MYSQL_DATABASE=$DB_NAME
MYSQL_ROOT_PASSWORD=$MARIADB_DB_PASS MYSQL_ROOT_PASSWORD=$DB_PASS
JWT_SECRET=$JWT_SECRET JWT_SECRET=$JWT_SECRET
JWT_EXP=1 JWT_EXP=1
@ -70,7 +86,7 @@ Restart=on-failure
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
EOF EOF
systemctl enable -q --now plant-it systemctl enable --now -q plant-it
cat <<EOF >/etc/nginx/nginx.conf cat <<EOF >/etc/nginx/nginx.conf
events { events {

View File

@ -13,8 +13,12 @@ setting_up_container
network_check network_check
update_os update_os
PORTAINER_LATEST_VERSION=$(get_latest_github_release "portainer/portainer") get_latest_release() {
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_github_release "portainer/agent") curl -fsSL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer")
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
if $STD mount | grep 'on / type zfs' >null && echo "ZFS"; then if $STD mount | grep 'on / type zfs' >null && echo "ZFS"; then
msg_info "Enabling ZFS support." msg_info "Enabling ZFS support."
@ -40,8 +44,8 @@ EOF
fi fi
msg_info "Installing Podman" msg_info "Installing Podman"
$STD apt install -y podman $STD apt -y install podman
systemctl enable -q --now podman.socket $STD systemctl enable --now podman.socket
echo -e 'unqualified-search-registries=["docker.io"]' >>/etc/containers/registries.conf echo -e 'unqualified-search-registries=["docker.io"]' >>/etc/containers/registries.conf
msg_ok "Installed Podman" msg_ok "Installed Podman"
@ -93,7 +97,7 @@ $STD podman run -d \
podman generate systemd \ podman generate systemd \
--new --name homeassistant \ --new --name homeassistant \
>/etc/systemd/system/homeassistant.service >/etc/systemd/system/homeassistant.service
systemctl enable -q --now homeassistant $STD systemctl enable --now homeassistant
msg_ok "Installed Home Assistant" msg_ok "Installed Home Assistant"
motd_ssh motd_ssh

View File

@ -13,8 +13,12 @@ setting_up_container
network_check network_check
update_os update_os
PORTAINER_LATEST_VERSION=$(get_latest_github_release "portainer/portainer") get_latest_release() {
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_github_release "portainer/agent") curl -fsSL https://api.github.com/repos/$1/releases/latest | grep '"tag_name":' | cut -d'"' -f4
}
PORTAINER_LATEST_VERSION=$(get_latest_release "portainer/portainer")
PORTAINER_AGENT_LATEST_VERSION=$(get_latest_release "portainer/agent")
if $STD mount | grep 'on / type zfs' >null && echo "ZFS"; then if $STD mount | grep 'on / type zfs' >null && echo "ZFS"; then
msg_info "Enabling ZFS support." msg_info "Enabling ZFS support."
@ -40,8 +44,8 @@ EOF
fi fi
msg_info "Installing Podman" msg_info "Installing Podman"
$STD apt install -y podman $STD apt -y install podman
systemctl enable -q --now podman.socket $STD systemctl enable --now podman.socket
echo -e 'unqualified-search-registries=["docker.io"]' >>/etc/containers/registries.conf echo -e 'unqualified-search-registries=["docker.io"]' >>/etc/containers/registries.conf
msg_ok "Installed Podman" msg_ok "Installed Podman"

View File

@ -20,9 +20,16 @@ $STD apt install -y \
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PHP_VERSION="8.2" PHP_MODULE="common,fpm" setup_php PHP_VERSION="8.2" PHP_MODULE="common,fpm" setup_php
create_self_signed_cert
fetch_and_deploy_gh_release "privatebin" "PrivateBin/PrivateBin" "tarball" fetch_and_deploy_gh_release "privatebin" "PrivateBin/PrivateBin" "tarball"
msg_info "Generating Universal SSL Certificate"
mkdir -p /etc/ssl/privatebin
$STD openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/privatebin/key.pem \
-out /etc/ssl/privatebin/cert.pem \
-subj "/CN=PrivateBin"
msg_ok "Certificate Generated"
msg_info "Configuring Environment" msg_info "Configuring Environment"
mkdir -p /opt/privatebin/data mkdir -p /opt/privatebin/data
cp /opt/privatebin/cfg/conf.sample.php /opt/privatebin/cfg/conf.php cp /opt/privatebin/cfg/conf.sample.php /opt/privatebin/cfg/conf.php
@ -48,8 +55,8 @@ server {
listen 443 ssl default_server; listen 443 ssl default_server;
listen [::]:443 ssl default_server; listen [::]:443 ssl default_server;
ssl_certificate /etc/ssl/privatebin/privatebin.crt; ssl_certificate /etc/ssl/privatebin/cert.pem;
ssl_certificate_key /etc/ssl/privatebin/privatebin.key; ssl_certificate_key /etc/ssl/privatebin/key.pem;
root /opt/privatebin; root /opt/privatebin;
index index.php; index index.php;

View File

@ -15,17 +15,31 @@ update_os
PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="pdo,mysql,gettext,fileinfo" setup_php PHP_VERSION="8.4" PHP_APACHE="YES" PHP_MODULE="pdo,mysql,gettext,fileinfo" setup_php
setup_mariadb setup_mariadb
MARIADB_DB_NAME="projectsend" MARIADB_DB_USER="projectsend" setup_mariadb_db
fetch_and_deploy_gh_release "projectsend" "projectsend/projectsend" "prebuild" "latest" "/opt/projectsend" "projectsend-r*.zip" fetch_and_deploy_gh_release "projectsend" "projectsend/projectsend" "prebuild" "latest" "/opt/projectsend" "projectsend-r*.zip"
msg_info "Setting up MariaDB"
DB_NAME=projectsend
DB_USER=projectsend
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME;"
$STD mariadb -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "projectsend-Credentials"
echo "projectsend Database User: $DB_USER"
echo "projectsend Database Password: $DB_PASS"
echo "projectsend Database Name: $DB_NAME"
} >>~/projectsend.creds
msg_ok "Set up MariaDB"
msg_info "Installing ProjectSend" msg_info "Installing ProjectSend"
mv /opt/projectsend/includes/sys.config.sample.php /opt/projectsend/includes/sys.config.php mv /opt/projectsend/includes/sys.config.sample.php /opt/projectsend/includes/sys.config.php
chown -R www-data:www-data /opt/projectsend chown -R www-data:www-data /opt/projectsend
chmod -R 775 /opt/projectsend chmod -R 775 /opt/projectsend
chmod 644 /opt/projectsend/includes/sys.config.php chmod 644 /opt/projectsend/includes/sys.config.php
sed -i -e "s/\(define('DB_NAME', \).*/\1'$MARIADB_DB_NAME');/" \ sed -i -e "s/\(define('DB_NAME', \).*/\1'$DB_NAME');/" \
-e "s/\(define('DB_USER', \).*/\1'$MARIADB_DB_USER');/" \ -e "s/\(define('DB_USER', \).*/\1'$DB_USER');/" \
-e "s/\(define('DB_PASSWORD', \).*/\1'$MARIADB_DB_PASS');/" \ -e "s/\(define('DB_PASSWORD', \).*/\1'$DB_PASS');/" \
/opt/projectsend/includes/sys.config.php /opt/projectsend/includes/sys.config.php
sed -i -e "s/^\(memory_limit = \).*/\1 256M/" \ sed -i -e "s/^\(memory_limit = \).*/\1 256M/" \
-e "s/^\(post_max_size = \).*/\1 256M/" \ -e "s/^\(post_max_size = \).*/\1 256M/" \

View File

@ -17,7 +17,9 @@ fetch_and_deploy_gh_release "prom-paperless-exp" "hansmi/prometheus-paperless-ex
msg_info "Configuring Prometheus Paperless NGX Exporter" msg_info "Configuring Prometheus Paperless NGX Exporter"
mkdir -p /etc/prometheus-paperless-ngx-exporter mkdir -p /etc/prometheus-paperless-ngx-exporter
echo "SECRET_AUTH_TOKEN" >/etc/prometheus-paperless-ngx-exporter/paperless_auth_token_file cat <<EOF >/etc/prometheus-paperless-ngx-exporter/paperless_auth_token_file
SECRET_AUTH_TOKEN
EOF
msg_ok "Configured Prometheus Paperless NGX Exporter" msg_ok "Configured Prometheus Paperless NGX Exporter"
msg_info "Creating Service" msg_info "Creating Service"

View File

@ -24,14 +24,6 @@ mkdir -p /root/.config/recyclarr
$STD recyclarr config create $STD recyclarr config create
msg_ok "Configured Recyclarr" msg_ok "Configured Recyclarr"
msg_info "Setting up Daily Sync Cron"
cat <<EOF >/etc/cron.d/recyclarr
# Run recyclarr sync daily
@daily root /usr/local/bin/recyclarr sync >> /root/.config/recyclarr/sync.log 2>&1
EOF
chmod 644 /etc/cron.d/recyclarr
msg_ok "Setup Daily Sync Cron"
motd_ssh motd_ssh
customize customize
cleanup_lxc cleanup_lxc

View File

@ -18,8 +18,7 @@ $STD apt install -y \
redis-server \ redis-server \
rabbitmq-server \ rabbitmq-server \
libpq-dev \ libpq-dev \
zstd \ zstd
nginx
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
JAVA_VERSION="25" setup_java JAVA_VERSION="25" setup_java
@ -47,31 +46,6 @@ mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "photon" "komoot/photon" "singlefile" "latest" "/opt/photon" "photon-0*.jar" USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "photon" "komoot/photon" "singlefile" "latest" "/opt/photon" "photon-0*.jar"
mv /opt/photon/photon-*.jar /opt/photon/photon.jar mv /opt/photon/photon-*.jar /opt/photon/photon.jar
msg_info "Installing Nginx Tile Cache"
mkdir -p /var/cache/nginx/tiles
cat <<EOF >/etc/nginx/nginx.conf
events {
worker_connections 1024;
}
http {
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
server {
listen 80;
location / {
proxy_pass https://tile.openstreetmap.org/;
proxy_set_header Host tile.openstreetmap.org;
proxy_set_header User-Agent "Reitti/1.0";
proxy_cache tiles;
proxy_cache_valid 200 30d;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
}
}
}
EOF
chown -R www-data:www-data /var/cache/nginx/tiles
systemctl restart nginx
msg_info "Installed Nginx Tile Cache"
msg_info "Creating Reitti Configuration-File" msg_info "Creating Reitti Configuration-File"
mkdir -p /opt/reitti/data mkdir -p /opt/reitti/data
cat <<EOF >/opt/reitti/application.properties cat <<EOF >/opt/reitti/application.properties
@ -118,9 +92,6 @@ PROCESSING_WORKERS_PER_QUEUE=4-16
# Disable potentially dangerous features unless needed # Disable potentially dangerous features unless needed
DANGEROUS_LIFE=false DANGEROUS_LIFE=false
# Tiles Cache
reitti.ui.tiles.cache.url=http://127.0.0.1
EOF EOF
msg_ok "Created Configuration-File for Reitti" msg_ok "Created Configuration-File for Reitti"

View File

@ -14,17 +14,20 @@ network_check
update_os update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y git $STD apt install -y \
git \
pip \
python3 \
python3-dev \
python3-pip
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PYTHON_VERSION="3.13" setup_uv
fetch_and_deploy_gh_release "Tautulli" "Tautulli/Tautulli" "tarball"
msg_info "Installing Tautulli" msg_info "Installing Tautulli"
cd /opt/Tautulli cd /opt
uv venv -q $STD git clone https://github.com/Tautulli/Tautulli.git
uv pip install -q -r requirements.txt $STD pip install -q -r /opt/Tautulli/requirements.txt
uv pip install -q pyopenssl $STD pip install pyopenssl
msg_ok "Installed Tautulli" msg_ok "Installed Tautulli"
msg_info "Creating Service" msg_info "Creating Service"
@ -38,7 +41,7 @@ WorkingDirectory=/opt/Tautulli/
Restart=on-failure Restart=on-failure
RestartSec=5 RestartSec=5
Type=simple Type=simple
ExecStart=/opt/Tautulli/.venv/bin/python3 /opt/Tautulli/Tautulli.py ExecStart=/usr/bin/python3 /opt/Tautulli/Tautulli.py
KillSignal=SIGINT KillSignal=SIGINT
TimeoutStopSec=20 TimeoutStopSec=20
SyslogIdentifier=tautulli SyslogIdentifier=tautulli

View File

@ -17,6 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y apt-transport-https $STD apt install -y apt-transport-https
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
JAVA_VERION="17" setup_java
setup_deb822_repo \ setup_deb822_repo \
"unifi" \ "unifi" \
"https://dl.ui.com/unifi/unifi-repo.gpg" \ "https://dl.ui.com/unifi/unifi-repo.gpg" \
@ -25,22 +26,17 @@ setup_deb822_repo \
"ubiquiti" \ "ubiquiti" \
"amd64" "amd64"
JAVA_VERSION="21" setup_java if ! grep -q -m1 'avx[^ ]*' /proc/cpuinfo; then
msg_warn "No AVX Support Detected. MongoDB v4.4 will be installed"
if lscpu | grep -q 'avx'; then if ! dpkg -l | grep -q "libssl1.1"; then
MONGO_VERSION="8.0" setup_mongodb curl -fsSL "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u4_amd64.deb" -o "libssl1.1_1.1.1w-0+deb11u4_amd64.deb"
$STD dpkg -i libssl1.1_1.1.1w-0+deb11u4_amd64.deb
fi
MONGO_VERSION="4.4" setup_mongodb
else else
msg_error "No AVX detected (CPU-Flag)! We have discontinued support for this. You are welcome to try it manually with a Debian LXC, but due to the many issues with Unifi, we currently only support AVX CPUs." MONGO_VERSION="7.0" setup_mongodb
exit 10
fi
if ! dpkg -l | grep -q 'libssl1.1'; then
msg_info "Installing libssl (if needed)"
curl -fsSL "https://security.debian.org/debian-security/pool/updates/main/o/openssl/libssl1.1_1.1.1w-0+deb11u4_amd64.deb" -o "/tmp/libssl.deb"
$STD dpkg -i /tmp/libssl.deb
rm -f /tmp/libssl.deb
msg_ok "Installed libssl1.1"
fi fi
msg_ok "Installed MongoDB"
msg_info "Installing UniFi Network Server" msg_info "Installing UniFi Network Server"
$STD apt install -y unifi $STD apt install -y unifi

View File

@ -3743,9 +3743,12 @@ create_lxc_container() {
msg_info "Searching for template '$TEMPLATE_SEARCH'" msg_info "Searching for template '$TEMPLATE_SEARCH'"
# Build regex patterns outside awk/grep for clarity
SEARCH_PATTERN="^${TEMPLATE_SEARCH}"
mapfile -t LOCAL_TEMPLATES < <( mapfile -t LOCAL_TEMPLATES < <(
pveam list "$TEMPLATE_STORAGE" 2>/dev/null | pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' | awk -v search="${SEARCH_PATTERN}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
sed 's|.*/||' | sort -t - -k 2 -V sed 's|.*/||' | sort -t - -k 2 -V
) )
@ -3754,7 +3757,7 @@ create_lxc_container() {
msg_ok "Template search completed" msg_ok "Template search completed"
set +u set +u
mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "^${TEMPLATE_SEARCH}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true) mapfile -t ONLINE_TEMPLATES < <(pveam available -section system 2>/dev/null | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | awk '{print $2}' | grep -E "${SEARCH_PATTERN}.*${TEMPLATE_PATTERN}" | sort -t - -k 2 -V 2>/dev/null || true)
set -u set -u
ONLINE_TEMPLATE="" ONLINE_TEMPLATE=""
@ -3803,12 +3806,13 @@ create_lxc_container() {
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#AVAILABLE_VERSIONS[@]} ]]; then
PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}" PCT_OSVERSION="${AVAILABLE_VERSIONS[$((choice - 1))]}"
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION}" TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION}"
SEARCH_PATTERN="^${TEMPLATE_SEARCH}-"
mapfile -t ONLINE_TEMPLATES < <( mapfile -t ONLINE_TEMPLATES < <(
pveam available -section system 2>/dev/null | pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' | awk -F'\t' '{print $1}' |
grep -E "^${TEMPLATE_SEARCH}-.*${TEMPLATE_PATTERN}" | grep -E "${SEARCH_PATTERN}.*${TEMPLATE_PATTERN}" |
sort -t - -k 2 -V 2>/dev/null || true sort -t - -k 2 -V 2>/dev/null || true
) )
@ -3869,17 +3873,18 @@ create_lxc_container() {
# Retry template search with new version # Retry template search with new version
TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}" TEMPLATE_SEARCH="${PCT_OSTYPE}-${PCT_OSVERSION:-}"
SEARCH_PATTERN="^${TEMPLATE_SEARCH}-"
mapfile -t LOCAL_TEMPLATES < <( mapfile -t LOCAL_TEMPLATES < <(
pveam list "$TEMPLATE_STORAGE" 2>/dev/null | pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v search="${TEMPLATE_SEARCH}-" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' | awk -v search="${SEARCH_PATTERN}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
sed 's|.*/||' | sort -t - -k 2 -V sed 's|.*/||' | sort -t - -k 2 -V
) )
mapfile -t ONLINE_TEMPLATES < <( mapfile -t ONLINE_TEMPLATES < <(
pveam available -section system 2>/dev/null | pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
awk '{print $2}' | awk -F'\t' '{print $1}' |
grep -E "^${TEMPLATE_SEARCH}-.*${TEMPLATE_PATTERN}" | grep -E "${SEARCH_PATTERN}.*${TEMPLATE_PATTERN}" |
sort -t - -k 2 -V 2>/dev/null || true sort -t - -k 2 -V 2>/dev/null || true
) )
ONLINE_TEMPLATE="" ONLINE_TEMPLATE=""

View File

@ -2571,15 +2571,6 @@ function setup_gs() {
# - Some things are fetched from intel repositories due to not being in debian repositories. # - Some things are fetched from intel repositories due to not being in debian repositories.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
function setup_hwaccel() { function setup_hwaccel() {
# Check if GPU passthrough is enabled (device nodes must exist)
# /dev/dri = Intel iGPU, AMD GPU (open-source drivers)
# /dev/nvidia* = NVIDIA proprietary drivers
# /dev/kfd = AMD ROCm compute
if [[ ! -d /dev/dri && ! -e /dev/nvidia0 && ! -e /dev/kfd ]]; then
msg_warn "No GPU passthrough detected (/dev/dri, /dev/nvidia*, /dev/kfd not found) - skipping hardware acceleration setup"
return 0
fi
msg_info "Setup Hardware Acceleration" msg_info "Setup Hardware Acceleration"
if ! command -v lspci &>/dev/null; then if ! command -v lspci &>/dev/null; then
@ -2743,53 +2734,11 @@ EOF
return 1 return 1
} }
# For AMD GPUs, firmware-amd-graphics requires non-free repositories # AMD firmware for better GPU support
if [[ "$os_id" == "debian" ]]; then if [[ "$os_id" == "debian" ]]; then
# Add non-free-firmware repository if not already present $STD apt -y install firmware-amd-graphics 2>/dev/null || true
if [[ ! -f /etc/apt/sources.list.d/non-free-firmware.sources ]]; then
if [[ "$os_codename" == "bookworm" ]]; then
cat <<EOF >/etc/apt/sources.list.d/non-free-firmware.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: non-free-firmware
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: bookworm-security
Components: non-free-firmware
EOF
elif [[ "$os_codename" == "trixie" || "$os_codename" == "sid" ]]; then
cat <<EOF >/etc/apt/sources.list.d/non-free-firmware.sources
Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie trixie-updates
Components: non-free-firmware
Types: deb
URIs: http://deb.debian.org/debian-security
Suites: trixie-security
Components: non-free-firmware
EOF
fi fi
$STD apt update
fi
# Install AMD firmware and libdrm
$STD apt -y install libdrm-amdgpu1 firmware-amd-graphics 2>/dev/null || {
msg_warn "Failed to install AMD firmware - may need manual installation"
}
elif [[ "$os_id" == "ubuntu" ]]; then
# For Ubuntu, firmware-amd-graphics does not exist (it's Debian-specific from non-free-firmware)
# Ubuntu includes AMD firmware in linux-firmware package which is installed by default
# Only install libdrm-amdgpu1 for userspace driver support
$STD apt -y install libdrm-amdgpu1 2>/dev/null || {
msg_warn "Failed to install libdrm-amdgpu1 - may need manual installation"
}
else
# For other distributions, try without adding repositories
$STD apt -y install libdrm-amdgpu1 2>/dev/null || true $STD apt -y install libdrm-amdgpu1 2>/dev/null || true
fi
;; ;;
NVIDIA) NVIDIA)

View File

@ -1,249 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/eko/pihole-exporter/
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
load_functions
# ==============================================================================
# CONFIGURATION
# ==============================================================================
VERBOSE=${var_verbose:-no}
APP="pihole-exporter"
APP_TYPE="tools"
INSTALL_PATH="/opt/pihole-exporter"
CONFIG_PATH="/opt/pihole-exporter.env"
header_info
ensure_usr_local_bin_persist
import_local_ip
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
OS="Alpine"
SERVICE_PATH="/etc/init.d/pihole-exporter"
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/pihole-exporter.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling Pihole-Exporter"
if [[ "$OS" == "Alpine" ]]; then
rc-service pihole-exporter stop &>/dev/null
rc-update del pihole-exporter &>/dev/null
rm -f "$SERVICE_PATH"
else
systemctl disable -q --now pihole-exporter
rm -f "$SERVICE_PATH"
fi
rm -rf "$INSTALL_PATH" "$CONFIG_PATH"
rm -f "/usr/local/bin/update_pihole-exporter"
rm -f "$HOME/.pihole-exporter"
msg_ok "Pihole-Exporter has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "pihole-exporter" "eko/pihole-exporter"; then
msg_info "Stopping service"
if [[ "$OS" == "Alpine" ]]; then
rc-service pihole-exporter stop &>/dev/null
else
systemctl stop pihole-exporter
fi
msg_ok "Stopped service"
fetch_and_deploy_gh_release "pihole-exporter" "eko/pihole-exporter" "tarball" "latest"
setup_go
msg_info "Building Pihole-Exporter"
cd /opt/pihole-exporter/
$STD /usr/local/bin/go build -o ./pihole-exporter
msg_ok "Built Pihole-Exporter"
msg_info "Starting service"
if [[ "$OS" == "Alpine" ]]; then
rc-service pihole-exporter start &>/dev/null
else
systemctl start pihole-exporter
fi
msg_ok "Started service"
msg_ok "Updated successfully"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
read -erp "Enter the protocol to use (http/https), default https: " pihole_PROTOCOL
read -erp "Enter the hostname of Pihole, example: (127.0.0.1): " pihole_HOSTNAME
read -erp "Enter the port of Pihole, default 443: " pihole_PORT
read -rsp "Enter Pihole password: " pihole_PASSWORD
printf "\n"
read -erp "Do you want to skip TLS-Verification (if using a self-signed Certificate on Pi-Hole) [y/N]: " SKIP_TLS
if [[ "${SKIP_TLS,,}" =~ ^(y|yes)$ ]]; then
pihole_SKIP_TLS="true"
fi
fetch_and_deploy_gh_release "pihole-exporter" "eko/pihole-exporter" "tarball" "latest"
setup_go
msg_info "Building Pihole-Exporter on ${OS}"
cd /opt/pihole-exporter/
$STD /usr/local/bin/go build -o ./pihole-exporter
msg_ok "Built Pihole-Exporter"
msg_info "Creating configuration"
cat <<EOF >"$CONFIG_PATH"
# https://github.com/eko/pihole-exporter/?tab=readme-ov-file#available-cli-options
PIHOLE_PASSWORD="${pihole_PASSWORD}"
PIHOLE_HOSTNAME="${pihole_HOSTNAME:-127.0.0.1}"
PIHOLE_PORT="${pihole_PORT:-443}"
SKIP_TLS_VERIFICATION="${pihole_SKIP_TLS:-false}"
PIHOLE_PROTOCOL="${pihole_PROTOCOL:-https}"
EOF
msg_ok "Created configuration"
msg_info "Creating service"
if [[ "$OS" == "Debian" ]]; then
cat <<EOF >"$SERVICE_PATH"
[Unit]
Description=pihole-exporter
After=network.target
[Service]
User=root
WorkingDirectory=/opt/pihole-exporter
EnvironmentFile=$CONFIG_PATH
ExecStart=/opt/pihole-exporter/pihole-exporter
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now pihole-exporter
else
cat <<EOF >"$SERVICE_PATH"
#!/sbin/openrc-run
name="pihole-exporter"
description="Pi-hole Exporter for Prometheus"
command="${INSTALL_PATH}/pihole-exporter"
command_background=true
directory="/opt/pihole-exporter"
pidfile="/run/\${RC_SVCNAME}.pid"
output_log="/var/log/pihole-exporter.log"
error_log="/var/log/pihole-exporter.log"
depend() {
need net
after firewall
}
start_pre() {
if [ -f "$CONFIG_PATH" ]; then
export \$(grep -v '^#' $CONFIG_PATH | xargs)
fi
}
EOF
chmod +x "$SERVICE_PATH"
$STD rc-update add pihole-exporter default
$STD rc-service pihole-exporter start
fi
msg_ok "Created and started service"
# Create update script
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'UPDATEEOF' >/usr/local/bin/update_pihole-exporter
#!/usr/bin/env bash
# pihole-exporter Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/pihole-exporter.sh)"
UPDATEEOF
chmod +x /usr/local/bin/update_pihole-exporter
msg_ok "Created update script (/usr/local/bin/update_pihole-exporter)"
echo ""
msg_ok "Pihole-Exporter installed successfully"
msg_ok "Metrics: ${BL}http://${CURRENT_IP}:9617/metrics${CL}"
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
}
# ==============================================================================
# MAIN
# ==============================================================================
header_info
ensure_usr_local_bin_persist
import_local_ip
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/pihole-exporter" ]]; then
update
else
msg_error "Pihole-Exporter is not installed. Nothing to update."
exit 1
fi
exit 0
fi
# Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/pihole-exporter" ]]; then
msg_warn "Pihole-Exporter is already installed."
echo ""
echo -n "${TAB}Uninstall Pihole-Exporter? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update Pihole-Exporter? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi
# Fresh installation
msg_warn "Pihole-Exporter is not installed."
echo ""
echo -e "${TAB}${INFO} This will install:"
echo -e "${TAB} - Pi-hole Exporter (Go binary)"
echo -e "${TAB} - Systemd/OpenRC service"
echo ""
echo -n "${TAB}Install Pihole-Exporter? (y/N): "
read -r install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
install
else
msg_warn "Installation cancelled. Exiting."
exit 0
fi

View File

@ -1,6 +0,0 @@
_ __ __ __
____ (_) /_ ____ / /__ ___ _ ______ ____ _____/ /____ _____
/ __ \/ / __ \/ __ \/ / _ \______/ _ \| |/_/ __ \/ __ \/ ___/ __/ _ \/ ___/
/ /_/ / / / / / /_/ / / __/_____/ __/> </ /_/ / /_/ / / / /_/ __/ /
/ .___/_/_/ /_/\____/_/\___/ \___/_/|_/ .___/\____/_/ \__/\___/_/
/_/ /_/