Merge branch 'main' into livebook

This commit is contained in:
Daniel Kukula
2025-09-07 15:05:59 +02:00
117 changed files with 6125 additions and 5591 deletions

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://garagehq.deuxfleurs.fr/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Preparing directories"
mkdir -p /var/lib/garage/meta /var/lib/garage/data /var/lib/garage/snapshots
msg_ok "Prepared directories"
msg_info "Setup Garage packages"
$STD apk add --no-cache garage garage-openrc openssl
msg_ok "Setup Garage packages"
# msg_info "Generating RPC secret"
# if [[ ! -s /etc/garage.rpc_secret ]]; then
# openssl rand -hex 32 | tr -d '\n' >/etc/garage.rpc_secret
# chmod 600 /etc/garage.rpc_secret
# fi
# msg_ok "Generated RPC secret"
# msg_info "Generating tokens"
# if [[ ! -s /etc/garage.tokens.env ]]; then
# ADMIN_TOKEN="$(openssl rand -base64 32)"
# METRICS_TOKEN="$(openssl rand -base64 32)"
# cat >/etc/garage.tokens.env <<EOF
# GARAGE_ADMIN_TOKEN="${ADMIN_TOKEN}"
# GARAGE_METRICS_TOKEN="${METRICS_TOKEN}"
# EOF
# chmod 600 /etc/garage.tokens.env
# else
# source /etc/garage.tokens.env
# ADMIN_TOKEN="${GARAGE_ADMIN_TOKEN}"
# METRICS_TOKEN="${GARAGE_METRICS_TOKEN}"
# fi
# msg_ok "Generated tokens"
msg_info "Writing config"
if [[ ! -f /etc/garage.toml ]]; then
cat >/etc/garage.toml <<EOF
replication_factor = 1
consistency_mode = "consistent"
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
metadata_snapshots_dir = "/var/lib/garage/snapshots"
db_engine = "lmdb"
metadata_fsync = true
data_fsync = false
metadata_auto_snapshot_interval = "6h"
rpc_bind_addr = "0.0.0.0:3901"
rpc_public_addr = "127.0.0.1:3901"
allow_world_readable_secrets = false
[s3_api]
api_bind_addr = "0.0.0.0:3900"
s3_region = "garage"
root_domain = ".s3.garage"
[s3_web]
bind_addr = "0.0.0.0:3902"
root_domain = ".web.garage"
add_host_to_metrics = true
[admin]
api_bind_addr = "0.0.0.0:3903"
metrics_require_token = false
EOF
fi
msg_ok "Wrote config"
msg_info "Enable + start service"
$STD rc-update add garage default
$STD rc-service garage restart || $STD rc-service garage start
$STD rc-service garage status || true
msg_ok "Service active"
msg_info "Setup Node"
garage node id
NODE_ID=$(garage node id | cut -d@ -f1)
garage layout assign $NODE_ID --capacity 1T
garage layout apply
garage status
msg_ok "Node setup"
motd_ssh
customize

View File

@@ -21,5 +21,7 @@ $STD apk add nano
$STD apk add mc
msg_ok "Installed Dependencies"
fetch_and_deploy_gh_release "redlib" "redlib-org/redlib" "prebuild" "latest" "/opt/redlib" "redlib-x86_64-unknown-linux-musl.tar.gz"
motd_ssh
customize

View File

@@ -0,0 +1,332 @@
#!/usr/bin/env bash
# Copyright (c) 2025 Community Scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/gelbphoenix/autocaliweb
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y --no-install-recommends \
python3-dev \
sqlite3 \
build-essential \
libldap2-dev \
libssl-dev \
libsasl2-dev \
imagemagick \
ghostscript \
libmagic1 \
libxi6 \
libxslt1.1 \
libxtst6 \
libxrandr2 \
libxkbfile1 \
libxcomposite1 \
libopengl0 \
libnss3 \
libxkbcommon0 \
libegl1 \
libxdamage1 \
libgl1 \
libglx-mesa0 \
xz-utils \
xdg-utils \
inotify-tools \
binutils \
unrar-free \
zip
msg_ok "Installed dependencies"
fetch_and_deploy_gh_release "kepubify" "pgaskin/kepubify" "singlefile" "latest" "/usr/bin" "kepubify-linux-64bit"
KEPUB_VERSION="$(/usr/bin/kepubify --version)"
msg_info "Installing Calibre"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
CALIBRE_VERSION=${CALIBRE_RELEASE#v}
curl -fsSL https://github.com/kovidgoyal/calibre/releases/download/${CALIBRE_RELEASE}/calibre-${CALIBRE_VERSION}-x86_64.txz -o /tmp/calibre.txz
mkdir -p /opt/calibre
$STD tar -xf /tmp/calibre.txz -C /opt/calibre
rm /tmp/calibre.txz
$STD /opt/calibre/calibre_postinstall
msg_ok "Calibre installed"
setup_uv
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Configuring Autocaliweb"
INSTALL_DIR="/opt/autocaliweb"
CONFIG_DIR="/etc/autocaliweb"
CALIBRE_LIB_DIR="/opt/calibre-library"
INGEST_DIR="/opt/acw-book-ingest"
SERVICE_USER="acw"
SERVICE_GROUP="acw"
SCRIPTS_DIR="${INSTALL_DIR}/scripts"
export VIRTUAL_ENV="${INSTALL_DIR}/venv"
mkdir -p "$CONFIG_DIR"/{.config/calibre/plugins,log_archive,.acw_conversion_tmp}
mkdir -p "$CONFIG_DIR"/processed_books/{converted,imported,failed,fixed_originals}
mkdir -p "$INSTALL_DIR"/{metadata_change_logs,metadata_temp}
mkdir -p {"$CALIBRE_LIB_DIR","$INGEST_DIR"}
echo "$CALIBRE_VERSION" >"$INSTALL_DIR"/CALIBRE_RELEASE
echo "${KEPUB_VERSION#v}" >"$INSTALL_DIR"/KEPUBIFY_RELEASE
sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
cd "$INSTALL_DIR"
$STD uv venv "$VIRTUAL_ENV"
$STD uv sync --all-extras --active
cat <<EOF >./dirs.json
{
"ingest_folder": "$INGEST_DIR",
"calibre_library_dir": "$CALIBRE_LIB_DIR",
"tmp_conversion_dir": "$CONFIG_DIR/.acw_conversion_tmp"
}
EOF
useradd -s /usr/sbin/nologin -d "$CONFIG_DIR" -M "$SERVICE_USER"
ln -sf "$CONFIG_DIR"/.config/calibre/plugins "$CONFIG_DIR"/calibre_plugins
cat <<EOF >"$INSTALL_DIR"/.env
ACW_INSTALL_DIR=$INSTALL_DIR
ACW_CONFIG_DIR=$CONFIG_DIR
ACW_USER=$SERVICE_USER
ACW_GROUP=$SERVICE_GROUP
LIBRARY_DIR=$CALIBRE_LIB_DIR
EOF
msg_ok "Configured Autocaliweb"
msg_info "Creating ACWSync Plugin for KOReader"
cd "$INSTALL_DIR"/koreader/plugins
PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
$STD zip -r koplugin.zip acwsync.koplugin/
cp -r koplugin.zip "$INSTALL_DIR"/cps/static
msg_ok "Created ACWSync Plugin"
msg_info "Initializing databases"
KEPUBIFY_PATH=$(command -v kepubify 2>/dev/null || echo "/usr/bin/kepubify")
EBOOK_CONVERT_PATH=$(command -v ebook-convert 2>/dev/null || echo "/usr/bin/ebook-convert")
CALIBRE_BIN_DIR=$(dirname "$EBOOK_CONVERT_PATH")
curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/main/library/metadata.db -o "$CALIBRE_LIB_DIR"/metadata.db
curl -fsSL https://github.com/gelbphoenix/autocaliweb/raw/refs/heads/main/library/app.db -o "$CONFIG_DIR"/app.db
sqlite3 "$CONFIG_DIR/app.db" <<EOS
UPDATE settings SET
config_kepubifypath='$KEPUBIFY_PATH',
config_converterpath='$EBOOK_CONVERT_PATH',
config_binariesdir='$CALIBRE_BIN_DIR',
config_calibre_dir='$CALIBRE_LIB_DIR',
config_logfile='$CONFIG_DIR/autocaliweb.log',
config_access_logfile='$CONFIG_DIR/access.log'
WHERE 1=1;
EOS
msg_ok "Initialized databases"
msg_info "Creating scripts and service files"
# auto-ingest watcher
cat <<EOF >"$SCRIPTS_DIR"/ingest_watcher.sh
#!/bin/bash
INSTALL_PATH="$INSTALL_DIR"
WATCH_FOLDER=\$(grep -o '"ingest_folder": "[^"]*' \${INSTALL_PATH}/dirs.json | grep -o '[^"]*\$')
echo "[acw-ingest-service] Watching folder: \$WATCH_FOLDER"
# Monitor the folder for new files
/usr/bin/inotifywait -m -r --format="%e %w%f" -e close_write -e moved_to "\$WATCH_FOLDER" |
while read -r events filepath ; do
echo "[acw-ingest-service] New files detected - \$filepath - Starting Ingest Processor..."
# Use the Python interpreter from the virtual environment
\${INSTALL_PATH}/venv/bin/python \${INSTALL_PATH}/scripts/ingest_processor.py "\$filepath"
done
EOF
# auto-zipper
cat <<EOF >"$SCRIPTS_DIR"/auto_zipper_wrapper.sh
#!/bin/bash
# Source virtual environment
source ${INSTALL_DIR}/venv/bin/activate
WAKEUP="23:59"
while true; do
# Replace expr with modern Bash arithmetic (safer and less prone to parsing issues)
# fix: expr: non-integer argument and sleep: missing operand
SECS=\$(( \$(date -d "\$WAKEUP" +%s) - \$(date -d "now" +%s) ))
if [[ \$SECS -lt 0 ]]; then
SECS=\$(( \$(date -d "tomorrow \$WAKEUP" +%s) - \$(date -d "now" +%s) ))
fi
echo "[acw-auto-zipper] Next run in \$SECS seconds."
sleep \$SECS &
wait \$!
# Use virtual environment python
python ${SCRIPTS_DIR}/auto_zip.py
if [[ \$? == 1 ]]; then
echo "[acw-auto-zipper] Error occurred during script initialisation."
elif [[ \$? == 2 ]]; then
echo "[acw-auto-zipper] Error occurred while zipping today's files."
elif [[ \$? == 3 ]]; then
echo "[acw-auto-zipper] Error occurred while trying to remove zipped files."
fi
sleep 60
done
EOF
# metadata change detector
cat <<EOF >"$SCRIPTS_DIR"/metadata_change_detector_wrapper.sh
#!/bin/bash
# metadata_change_detector_wrapper.sh - Wrapper for periodic metadata enforcement
# Source virtual environment
source ${INSTALL_DIR}/venv/bin/activate
# Configuration
CHECK_INTERVAL=300 # Check every 5 minutes (300 seconds)
METADATA_LOGS_DIR="${INSTALL_DIR}/metadata_change_logs"
echo "[metadata-change-detector] Starting metadata change detector service..."
echo "[metadata-change-detector] Checking for changes every \$CHECK_INTERVAL seconds"
while true; do
# Check if there are any log files to process
if [ -d "\$METADATA_LOGS_DIR" ] && [ "\$(ls -A \$METADATA_LOGS_DIR 2>/dev/null)" ]; then
echo "[metadata-change-detector] Found metadata change logs, processing..."
# Process each log file
for log_file in "\$METADATA_LOGS_DIR"/*.json; do
if [ -f "\$log_file" ]; then
log_name=\$(basename "\$log_file")
echo "[metadata-change-detector] Processing log: \$log_name"
# Call cover_enforcer.py with the log file
${INSTALL_DIR}/venv/bin/python ${SCRIPTS_DIR}/cover_enforcer.py --log "\$log_name"
if [ \$? -eq 0 ]; then
echo "[metadata-change-detector] Successfully processed \$log_name"
else
echo "[metadata-change-detector] Error processing \$log_name"
fi
fi
done
else
echo "[metadata-change-detector] No metadata changes detected"
fi
echo "[metadata-change-detector] Sleeping for \$CHECK_INTERVAL seconds..."
sleep \$CHECK_INTERVAL
done
EOF
chmod +x "$SCRIPTS_DIR"/{ingest_watcher.sh,auto_zipper_wrapper.sh,metadata_change_detector_wrapper.sh}
chown -R "$SERVICE_USER":"$SERVICE_GROUP" {"$INSTALL_DIR","$CONFIG_DIR","$INGEST_DIR","$CALIBRE_LIB_DIR"}
# systemd service files
SYS_PATH="/etc/systemd/system"
cat <<EOF >"$SYS_PATH"/autocaliweb.service
[Unit]
Description=Autocaliweb
After=network.target
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=$SERVICE_USER
Group=$SERVICE_GROUP
WorkingDirectory=$INSTALL_DIR
Environment=PATH=$INSTALL_DIR/venv/bin:/usr/bin:/bin
Environment=PYTHONPATH=$SCRIPTS_DIR:$INSTALL_DIR
Environment=PYTHONDONTWRITEBYTECODE=1
Environment=PYTHONUNBUFFERED=1
Environment=CALIBRE_DBPATH=$CONFIG_DIR
EnvironmentFile=$INSTALL_DIR/.env
ExecStart=$INSTALL_DIR/venv/bin/python $INSTALL_DIR/cps.py -p $CONFIG_DIR/app.db
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >"$SYS_PATH"/acw-ingest-service.service
[Unit]
Description=Autocaliweb Ingest Processor Service
After=autocaliweb.service
Requires=autocaliweb.service
[Service]
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${INSTALL_DIR}
Environment=CALIBRE_DBPATH=${CONFIG_DIR}
Environment=HOME=${CONFIG_DIR}
ExecStart=/bin/bash ${SCRIPTS_DIR}/ingest_watcher.sh
Restart=always
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >"$SYS_PATH"/acw-auto-zipper.service
[Unit]
Description=Autocaliweb Auto Zipper Service
After=network.target
[Service]
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${INSTALL_DIR}
Environment=CALIBRE_DBPATH=${CONFIG_DIR}
ExecStart=${SCRIPTS_DIR}/auto_zipper_wrapper.sh
Restart=always
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >"$SYS_PATH"/metadata-change-detector.service
[Unit]
Description=Autocaliweb Metadata Change Detector
After=network.target
[Service]
User=${SERVICE_USER}
Group=${SERVICE_GROUP}
WorkingDirectory=${INSTALL_DIR}
ExecStart=/bin/bash ${SCRIPTS_DIR}/metadata_change_detector_wrapper.sh
Restart=always
StandardOutput=journal
StandardError=journal
Environment=CALIBRE_DBPATH=${CONFIG_DIR}
Environment=HOME=${CONFIG_DIR}
[Install]
WantedBy=multi-user.target
EOF
systemctl -q enable --now autocaliweb acw-ingest-service acw-auto-zipper metadata-change-detector
msg_ok "Created scripts and service files"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt-get install -y gpg
msg_ok "Installed Dependencies"
setup_mariadb
#setup_mariadb
#FFMPEG_VERSION="n7.1.1" FFMPEG_TYPE="full" setup_ffmpeg

View File

@@ -0,0 +1,220 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: ekke85
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Dispatcharr/Dispatcharr
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
# msg_info "Creating ${APP_USER} user"
# groupadd -f $APP_GROUP
# useradd -M -s /usr/sbin/nologin -g $APP_GROUP $APP_USER || true
# msg_ok "Created ${APP_USER} user"
msg_info "Installing Dependencies"
$STD apt-get install -y \
build-essential \
gcc \
libpcre3-dev \
libpq-dev \
nginx \
redis-server \
ffmpeg \
procps \
streamlink
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.13" setup_uv
NODE_VERSION="22" setup_nodejs
PG_VERSION="16" setup_postgresql
fetch_and_deploy_gh_release "dispatcharr" "Dispatcharr/Dispatcharr"
msg_info "Set up PostgreSQL Database"
DB_NAME=dispatcharr_db
DB_USER=dispatcharr_usr
DB_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)"
DB_URL="postgresql://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}"
$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 "Dispatcharr-Credentials"
echo "Dispatcharr Database Name: $DB_NAME"
echo "Dispatcharr Database User: $DB_USER"
echo "Dispatcharr Database Password: $DB_PASS"
} >>~/dispatcharr.creds
msg_ok "Set up PostgreSQL Database"
msg_info "Setup Python (uv) requirements (system)"
UV_PY="${PYTHON_VERSION:-3.13}"
$STD uv python install "$UV_PY"
cd /opt/dispatcharr
PYPI_URL="https://pypi.org/simple"
mapfile -t EXTRA_INDEX_URLS < <(grep -E '^(--(extra-)?index-url|-i)\s' requirements.txt 2>/dev/null | awk '{print $2}' | sed 's#/*$##')
UV_INDEX_ARGS=(--index-url "$PYPI_URL" --index-strategy unsafe-best-match)
for u in "${EXTRA_INDEX_URLS[@]}"; do
[[ -n "$u" && "$u" != "$PYPI_URL" ]] && UV_INDEX_ARGS+=(--extra-index-url "$u")
done
if [[ -f requirements.txt ]]; then
$STD uv pip install --system "${UV_INDEX_ARGS[@]}" -r requirements.txt
fi
$STD uv pip install --system "${UV_INDEX_ARGS[@]}" gunicorn gevent celery daphne
ln -sf /usr/bin/ffmpeg /opt/dispatcharr/env/bin/ffmpeg
msg_ok "Python Requirements Installed"
msg_info "Building Frontend"
cd /opt/dispatcharr/frontend
$STD npm install --legacy-peer-deps
$STD npm run build
msg_ok "Built Frontend"
msg_info "Running Django Migrations"
cd /opt/dispatcharr
set -o allexport
source /etc/dispatcharr/dispatcharr.env
set +o allexport
$STD ./.venv/bin/python manage.py migrate --noinput
$STD ./.venv/bin/python manage.py collectstatic --noinput
msg_ok "Migrations Complete"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/dispatcharr.conf
server {
listen 9191;
location / {
include proxy_params;
proxy_pass http://127.0.0.1:5656;
}
location /static/ {
alias /opt/dispatcharr/static/;
}
location /assets/ {
alias /opt/dispatcharr/frontend/dist/assets/;
}
location /media/ {
alias /opt/dispatcharr/media/;
}
location /ws/ {
proxy_pass http://127.0.0.1:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
}
}
EOF
ln -sf /etc/nginx/sites-available/dispatcharr.conf /etc/nginx/sites-enabled/dispatcharr.conf
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl restart nginx
systemctl enable nginx
msg_ok "Configured Nginx"
msg_info "Creating systemd services"
cat <<EOF >/etc/systemd/system/dispatcharr.service
[Unit]
Description=Gunicorn for Dispatcharr
After=network.target postgresql.service redis-server.service
[Service]
WorkingDirectory=/opt/dispatcharr
RuntimeDirectory=dispatcharr
RuntimeDirectoryMode=0775
Environment="PATH=/opt/dispatcharr/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
EnvironmentFile=/etc/dispatcharr/dispatcharr.env
ExecStart=/opt/dispatcharr/env/bin/gunicorn \\
--workers=4 \\
--worker-class=gevent \\
--timeout=300 \\
--bind 0.0.0.0:5656 \
dispatcharr.wsgi:application
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-celery.service
[Unit]
Description=Celery Worker for Dispatcharr
After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
WorkingDirectory=/opt/dispatcharr
Environment="PATH=/opt/dispatcharr/env/bin"
EnvironmentFile=/etc/dispatcharr/dispatcharr.env
Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
ExecStart=/opt/dispatcharr/env/bin/celery -A dispatcharr worker -l info -c 4
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-celerybeat.service
[Unit]
Description=Celery Beat Scheduler for Dispatcharr
After=network.target redis-server.service
Requires=dispatcharr.service
[Service]
WorkingDirectory=/opt/dispatcharr
Environment="PATH=/opt/dispatcharr/env/bin"
EnvironmentFile=/etc/dispatcharr/dispatcharr.env
Environment="CELERY_BROKER_URL=redis://localhost:6379/0"
ExecStart=/opt/dispatcharr/env/bin/celery -A dispatcharr beat -l info
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/dispatcharr-daphne.service
[Unit]
Description=Daphne for Dispatcharr (ASGI)
After=network.target
Requires=dispatcharr.service
[Service]
WorkingDirectory=/opt/dispatcharr
Environment="PATH=/opt/dispatcharr/env/bin"
EnvironmentFile=/etc/dispatcharr/dispatcharr.env
ExecStart=/opt/dispatcharr/env/bin/daphne -b 0.0.0.0 -p 8001 dispatcharr.asgi:application
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now dispatcharr dispatcharr-celery dispatcharr-celerybeat dispatcharr-daphne
msg_ok "Started Dispatcharr Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

174
install/ente-install.sh Normal file
View File

@@ -0,0 +1,174 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/ente-io/ente
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
libsodium23 \
libsodium-dev \
pkg-config \
caddy \
gcc
msg_ok "Installed Dependencies"
PG_VERSION="17" setup_postgresql
setup_go
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "ente" "ente-io/ente" "tarball" "latest" "/opt/ente"
msg_info "Setting up PostgreSQL"
DB_NAME="ente_db"
DB_USER="ente"
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 "Ente Credentials"
echo "Database Name: $DB_NAME"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
} >>~/ente.creds
msg_ok "Set up PostgreSQL"
msg_info "Building Museum (server)"
cd /opt/ente/server
$STD corepack enable
$STD go mod tidy
export CGO_ENABLED=1
CGO_CFLAGS="$(pkg-config --cflags libsodium || true)"
CGO_LDFLAGS="$(pkg-config --libs libsodium || true)"
if [ -z "$CGO_CFLAGS" ]; then
CGO_CFLAGS="-I/usr/include"
fi
if [ -z "$CGO_LDFLAGS" ]; then
CGO_LDFLAGS="-lsodium"
fi
export CGO_CFLAGS
export CGO_LDFLAGS
$STD go build cmd/museum/main.go
msg_ok "Built Museum"
msg_info "Generating Secrets"
SECRET_ENC=$($STD go run tools/gen-random-keys/main.go | grep "encryption" | awk '{print $2}')
SECRET_HASH=$($STD go run tools/gen-random-keys/main.go | grep "hash" | awk '{print $2}')
SECRET_JWT=$($STD go run tools/gen-random-keys/main.go | grep "jwt" | awk '{print $2}')
msg_ok "Generated Secrets"
msg_info "Creating museum.yaml"
cat <<EOF >/opt/ente/server/museum.yaml
db:
host: 127.0.0.1
port: 5432
name: $DB_NAME
user: $DB_USER
password: $DB_PASS
s3:
are_local_buckets: true
use_path_style_urls: true
local-dev:
key: dummy
secret: dummy
endpoint: localhost:3200
region: eu-central-2
bucket: ente-dev
apps:
public-albums: http://localhost:3002
cast: http://localhost:3004
accounts: http://localhost:3001
key:
encryption: $SECRET_ENC
hash: $SECRET_HASH
jwt:
secret: $SECRET_JWT
EOF
msg_ok "Created museum.yaml"
msg_info "Building Web Applications"
cd /opt/ente/web
$STD yarn install
export NEXT_PUBLIC_ENTE_ENDPOINT=http://localhost:8080
export NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT=http://localhost:3002
$STD yarn build
$STD yarn build:accounts
$STD yarn build:auth
$STD yarn build:cast
mkdir -p /var/www/ente/apps
cp -r apps/photos/out /var/www/ente/apps/photos
cp -r apps/accounts/out /var/www/ente/apps/accounts
cp -r apps/auth/out /var/www/ente/apps/auth
cp -r apps/cast/out /var/www/ente/apps/cast
msg_ok "Built Web Applications"
msg_info "Creating Museum Service"
cat <<EOF >/etc/systemd/system/ente-museum.service
[Unit]
Description=Ente Museum Server
After=network.target postgresql.service
[Service]
WorkingDirectory=/opt/ente/server
ExecStart=/opt/ente/server/main -config /opt/ente/server/museum.yaml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now ente-museum
msg_ok "Created Museum Service"
msg_info "Configuring Caddy"
cat <<EOF >/etc/caddy/Caddyfile
:3000 {
root * /var/www/ente/apps/photos
file_server
try_files {path} {path}.html /index.html
}
:3001 {
root * /var/www/ente/apps/accounts
file_server
try_files {path} {path}.html /index.html
}
:3002 {
root * /var/www/ente/apps/photos
file_server
try_files {path} {path}.html /index.html
}
:3003 {
root * /var/www/ente/apps/auth
file_server
try_files {path} {path}.html /index.html
}
:3004 {
root * /var/www/ente/apps/cast
file_server
try_files {path} {path}.html /index.html
}
EOF
systemctl reload caddy
msg_ok "Configured Caddy"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

111
install/freepbx-install.sh Normal file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Arian Nasr (arian-nasr)
# Updated by: Javier Pastor (vsc55)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.freepbx.org/
INSTALL_URL="https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh"
INSTALL_PATH="/opt/sng_freepbx_debian_install.sh"
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
ONLY_OPENSOURCE="${ONLY_OPENSOURCE:-no}"
REMOVE_FIREWALL="${REMOVE_FIREWALL:-no}"
msg_ok "Remove Commercial modules is set to: $ONLY_OPENSOURCE"
msg_ok "Remove Firewall module is set to: $REMOVE_FIREWALL"
msg_info "Downloading FreePBX installation script..."
if curl -fsSL "$INSTALL_URL" -o "$INSTALL_PATH"; then
msg_ok "Download completed successfully"
else
curl_exit_code=$?
msg_error "Error downloading FreePBX installation script (curl exit code: $curl_exit_code)"
msg_error "Aborting!"
exit 1
fi
if [[ "$VERBOSE" == "yes" ]]; then
msg_info "Installing FreePBX (Verbose)\n"
else
msg_info "Installing FreePBX, be patient, this takes time..."
fi
$STD bash "$INSTALL_PATH"
if [[ $ONLY_OPENSOURCE == "yes" ]]; then
msg_info "Removing Commercial modules..."
end_count=0
max=5
count=0
while fwconsole ma list | awk '/Commercial/ {found=1} END {exit !found}'; do
count=$((count + 1))
while read -r module; do
msg_info "Removing module: $module"
if [[ "$REMOVE_FIREWALL" == "no" ]] && [[ "$module" == "sysadmin" ]]; then
msg_warn "Skipping sysadmin module removal, it is required for Firewall!"
continue
fi
code=0
$STD fwconsole ma -f remove $module || code=$?
if [[ $code -ne 0 ]]; then
msg_error "Module $module could not be removed - error code $code"
else
msg_ok "Module $module removed successfully"
fi
done < <(fwconsole ma list | awk '/Commercial/ {print $2}')
[[ $count -ge $max ]] && break
com_list=$(fwconsole ma list)
end_count=$(awk '/Commercial/ {count++} END {print count + 0}' <<< "$com_list")
awk '/Commercial/ {found=1} END {exit !found}' <<< "$com_list" || break
if [[ "$REMOVE_FIREWALL" == "no" ]] && \
[[ $end_count -eq 1 ]] && \
[[ $(awk '/Commercial/ {print $2}' <<< "$com_list") == "sysadmin" ]]; then
break
fi
msg_warn "Not all commercial modules could be removed, retrying (attempt $count of $max)..."
done
if [[ $REMOVE_FIREWALL == "yes" ]] && [[ $end_count -gt 0 ]]; then
msg_info "Removing Firewall module..."
if $STD fwconsole ma -f remove firewall; then
msg_ok "Firewall module removed successfully"
else
msg_error "Firewall module could not be removed, please check manually!"
fi
fi
if [[ $end_count -eq 0 ]]; then
msg_ok "All commercial modules removed successfully"
elif [[ $end_count -eq 1 ]] && [[ $REMOVE_FIREWALL == "no" ]] && [[ $(fwconsole ma list | awk '/Commercial/ {print $2}') == "sysadmin" ]]; then
msg_ok "Only sysadmin module left, which is required for Firewall, skipping removal"
else
msg_warn "Some commercial modules could not be removed, please check the web interface for removal manually!"
fi
msg_info "Reloading FreePBX..."
$STD fwconsole reload
msg_ok "FreePBX reloaded completely"
fi
msg_ok "Installed FreePBX finished"
motd_ssh
customize
msg_info "Cleaning up"
rm -f "$INSTALL_PATH"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -14,120 +14,55 @@ network_check
update_os
msg_info "Installing Dependencies (Patience)"
$STD apt-get install -y \
git automake build-essential xz-utils libtool ccache pkg-config \
libgtk-3-dev libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev \
libjpeg-dev libpng-dev libtiff-dev gfortran openexr libatlas-base-dev libssl-dev libtbb-dev \
libopenexr-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev gcc gfortran \
libopenblas-dev liblapack-dev libusb-1.0-0-dev jq moreutils tclsh libhdf5-dev libopenexr-dev nginx
$STD apt-get install -y {git,ca-certificates,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb-dev,libdc1394-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils}
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
$STD apt-get install -y \
python3 python3-dev python3-setuptools python3-distutils python3-pip python3-venv
$STD pip install --upgrade pip --break-system-packages
$STD apt-get install -y {python3,python3-dev,python3-setuptools,python3-distutils,python3-pip,python3-venv}
$STD pip install --upgrade pip
msg_ok "Setup Python3"
msg_info "Setup NGINX"
apt-get update
apt-get -y build-dep nginx
apt-get -y install wget build-essential ccache patch ca-certificates
update-ca-certificates -f
export PATH="/usr/lib/ccache:$PATH"
cd /tmp
wget -nv https://nginx.org/download/nginx-1.29.0.tar.gz
tar -xf nginx-1.29.0.tar.gz
cd nginx-1.29.0
mkdir /tmp/nginx-vod
wget -nv https://github.com/kaltura/nginx-vod-module/archive/refs/tags/1.31.tar.gz
tar -xf 1.31.tar.gz -C /tmp/nginx-vod --strip-components=1
sed -i 's/MAX_CLIPS (128)/MAX_CLIPS (1080)/g' /tmp/nginx-vod/vod/media_set.h
patch -d /tmp/nginx-vod -p1 <<'EOF'
--- a/vod/avc_hevc_parser.c
+++ b/vod/avc_hevc_parser.c
@@ -3,6 +3,9 @@
bool_t
avc_hevc_parser_rbsp_trailing_bits(bit_reader_state_t* reader)
{
+ // https://github.com/blakeblackshear/frigate/issues/4572
+ return TRUE;
+
uint32_t one_bit;
if (reader->stream.eof_reached)
EOF
# secure-token module
mkdir /tmp/nginx-secure-token
wget -nv https://github.com/kaltura/nginx-secure-token-module/archive/refs/tags/1.5.tar.gz
tar -xf 1.5.tar.gz -C /tmp/nginx-secure-token --strip-components=1
# ngx-devel-kit
mkdir /tmp/ngx-devel-kit
wget -nv https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.3.tar.gz
tar -xf v0.3.3.tar.gz -C /tmp/ngx-devel-kit --strip-components=1
# set-misc module
mkdir /tmp/nginx-set-misc
wget -nv https://github.com/openresty/set-misc-nginx-module/archive/refs/tags/v0.33.tar.gz
tar -xf v0.33.tar.gz -C /tmp/nginx-set-misc --strip-components=1
# configure & build
cd /tmp/nginx-1.29.0
./configure --prefix=/usr/local/nginx \
--with-file-aio \
--with-http_sub_module \
--with-http_ssl_module \
--with-http_auth_request_module \
--with-http_realip_module \
--with-threads \
--add-module=/tmp/ngx-devel-kit \
--add-module=/tmp/nginx-set-misc \
--add-module=/tmp/nginx-vod \
--add-module=/tmp/nginx-secure-token \
--with-cc-opt="-O3 -Wno-error=implicit-fallthrough"
make CC="ccache gcc" -j"$(nproc)"
make install
ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
# cleanup
rm -rf /tmp/nginx-1.29.0* /tmp/nginx-vod /tmp/nginx-secure-token /tmp/ngx-devel-kit /tmp/nginx-set-misc
msg_ok "NGINX with Custom Modules Built"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "go2rtc" "AlexxIT/go2rtc" "singlefile" "latest" "/usr/local/go2rtc/bin" "go2rtc_linux_amd64"
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "v0.16.0-beta4" "/opt/frigate"
fetch_and_deploy_gh_release "frigate" "blakeblackshear/frigate" "tarball" "latest" "/opt/frigate"
fetch_and_deploy_gh_release "libusb" "libusb/libusb" "tarball" "v1.0.29" "/opt/frigate/libusb"
msg_info "Setting Up Hardware Acceleration"
$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
if [[ "$CTTYPE" == "0" ]]; then
chgrp video /dev/dri
chmod 755 /dev/dri
chmod 660 /dev/dri/*
fi
msg_ok "Set Up Hardware Acceleration"
# msg_info "Setting Up Hardware Acceleration"
# $STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
# if [[ "$CTTYPE" == "0" ]]; then
# chgrp video /dev/dri
# chmod 755 /dev/dri
# chmod 660 /dev/dri/*
# fi
# msg_ok "Set Up Hardware Acceleration"
msg_info "Setting up Python venv"
msg_info "Setting up Python"
cd /opt/frigate
python3 -m venv venv
source venv/bin/activate
$STD pip install --upgrade pip wheel --break-system-packages
$STD pip install -r docker/main/requirements.txt --break-system-packages
$STD pip install -r docker/main/requirements-wheels.txt --break-system-packages
$STD pip install -r docker/main/requirements-ov.txt --break-system-packages
mkdir -p /opt/frigate/models
$STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt
cp -a /opt/frigate/docker/main/rootfs/. /
export TARGETARCH="amd64"
echo 'libc6 libraries/restart-without-asking boolean true' | debconf-set-selections
$STD apt update
$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg
$STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
$STD pip3 install -U /wheels/*.whl
ldconfig
$STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt
$STD /opt/frigate/.devcontainer/initialize.sh
$STD make version
msg_ok "Python venv ready"
msg_info "Building Web UI"
cd /opt/frigate/web
$STD npm install
$STD npm ci
$STD npm run build
cp -r /opt/frigate/web/dist/* /opt/frigate/web/
cp -r /opt/frigate/config/. /config
msg_ok "Web UI built"
msg_info "Writing default config"
sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
mkdir -p /opt/frigate/config
cat <<EOF >/opt/frigate/config/config.yml
mqtt:
@@ -147,11 +82,54 @@ cameras:
fps: 5
EOF
mkdir -p /config
ln -sf /opt/frigate/config/config.yml /config/config.yml
ln -sf /config/config.yml /opt/frigate/config/config.yml
if [[ "$CTTYPE" == "0" ]]; then
sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group
else
sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group
fi
echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
mkdir -p /media/frigate
wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4
cat <<'EOF' >/opt/frigate/frigate/version.py
VERSION = "0.16.0"
EOF
msg_ok "Config ready"
if grep -q -o -m1 -E 'avx[^ ]*' /proc/cpuinfo; then
msg_ok "AVX Support Detected"
msg_info "Installing Openvino Object Detection Model (Resilience)"
$STD pip install -r /opt/frigate/docker/main/requirements-ov.txt
cd /opt/frigate/models
export ENABLE_ANALYTICS=NO
$STD /usr/local/bin/omz_downloader --name ssdlite_mobilenet_v2 --num_attempts 2
$STD /usr/local/bin/omz_converter --name ssdlite_mobilenet_v2 --precision FP16 --mo /usr/local/bin/mo
cd /
cp -r /opt/frigate/models/public/ssdlite_mobilenet_v2 openvino-model
curl -fsSL "https://github.com/openvinotoolkit/open_model_zoo/raw/master/data/dataset_classes/coco_91cl_bkgr.txt" -o "openvino-model/coco_91cl_bkgr.txt"
sed -i 's/truck/car/g' openvino-model/coco_91cl_bkgr.txt
cat <<EOF >>/config/config.yml
detectors:
ov:
type: openvino
device: CPU
model:
path: /openvino-model/FP16/ssdlite_mobilenet_v2.xml
model:
width: 300
height: 300
input_tensor: nhwc
input_pixel_format: bgr
labelmap_path: /openvino-model/coco_91cl_bkgr.txt
EOF
msg_ok "Installed Openvino Object Detection Model"
else
cat <<EOF >>/config/config.yml
model:
path: /cpu_model.tflite
EOF
fi
msg_info "Building and Installing libUSB without udev"
wget -qO /tmp/libusb.zip https://github.com/libusb/libusb/archive/v1.0.29.zip
unzip -q /tmp/libusb.zip -d /tmp/
@@ -164,24 +142,35 @@ ldconfig
rm -rf /tmp/libusb.zip /tmp/libusb-1.0.29
msg_ok "Installed libUSB without udev"
# Coral Object Detection Models
msg_info "Installing Coral Object Detection Models"
msg_info "Installing Coral Object Detection Model (Patience)"
cd /opt/frigate
export CCACHE_DIR=/root/.ccache
export CCACHE_MAXSIZE=2G
# edgetpu / cpu Modelle
wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite
wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite
curl -fsSL "https://github.com/libusb/libusb/archive/v1.0.26.zip" -o "v1.0.26.zip"
$STD unzip v1.0.26.zip
rm v1.0.26.zip
cd libusb-1.0.26
$STD ./bootstrap.sh
$STD ./configure --disable-udev --enable-shared
$STD make -j $(nproc --all)
cd /opt/frigate/libusb-1.0.26/libusb
mkdir -p /usr/local/lib
$STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib'
mkdir -p /usr/local/include/libusb-1.0
$STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'
ldconfig
cd /
curl -fsSL "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite" -o "edgetpu_model.tflite"
curl -fsSL "https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite" -o "cpu_model.tflite"
cp /opt/frigate/labelmap.txt /labelmap.txt
# Audio-Modelle
wget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download
curl -fsSL "https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download" -o "yamnet-tflite-classification-tflite-v1.tar.gz"
tar xzf yamnet-tflite-classification-tflite-v1.tar.gz
rm -rf yamnet-tflite-classification-tflite-v1.tar.gz
mv 1.tflite cpu_audio_model.tflite
cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt
msg_ok "Installed Coral Object Detection Models"
mkdir -p /media/frigate
curl -fsSL "https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4" -o "/media/frigate/person-bicycle-car-detection.mp4"
msg_ok "Installed Coral Object Detection Model"
# ------------------------------------------------------------
# Tempio installieren
@@ -191,281 +180,107 @@ export TARGETARCH="amd64"
export DEBIAN_FRONTEND=noninteractive
echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
echo "libedgetpu1-max libedgetpu/install-confirm-max select true" | debconf-set-selections
/opt/frigate/docker/main/install_tempio.sh
$STD /opt/frigate/docker/main/install_tempio.sh
chmod +x /usr/local/tempio/bin/tempio
ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
msg_ok "Installed Tempio"
# ------------------------------------------------------------
# systemd Units
msg_info "Creating systemd service for go2rtc"
cat <<EOF >/etc/systemd/system/go2rtc.service
# msg_info "Copying model files"
# cp /opt/frigate/cpu_model.tflite /
# cp /opt/frigate/edgetpu_model.tflite /
# cp /opt/frigate/audio-labelmap.txt /
# cp /opt/frigate/labelmap.txt /
# msg_ok "Copied model files"
msg_info "Building Nginx with Custom Modules"
sed -i 's/if \[\[ "$VERSION_ID" == "12" \]\]; then/if [[ -f \/etc\/apt\/sources.list.d\/debian.sources ]]; then/' /opt/frigate/docker/main/build_nginx.sh
$STD /opt/frigate/docker/main/build_nginx.sh
sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
msg_ok "Built Nginx"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/create_directories.service
[Unit]
Description=go2rtc
After=network.target
Description=Create necessary directories for logs
[Service]
ExecStart=/usr/local/bin/go2rtc
Restart=always
RestartSec=2
User=root
StandardOutput=journal
StandardError=journal
Type=oneshot
ExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs'
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now go2rtc
msg_ok "go2rtc service enabled"
systemctl enable -q --now create_directories
sleep 3
cat <<EOF >/etc/systemd/system/go2rtc.service
[Unit]
Description=go2rtc service
After=network.target
After=create_directories.service
StartLimitIntervalSec=0
msg_info "Creating systemd service for Frigate"
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
Environment=DEFAULT_FFMPEG_VERSION=7.0
Environment=INCLUDED_FFMPEG_VERSIONS=5.0
ExecStartPre=+rm /dev/shm/logs/go2rtc/current
ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
StandardOutput=file:/dev/shm/logs/go2rtc/current
StandardError=file:/dev/shm/logs/go2rtc/current
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now go2rtc
sleep 3
cat <<EOF >/etc/systemd/system/frigate.service
[Unit]
Description=Frigate service
After=go2rtc.service network.target
After=go2rtc.service
After=create_directories.service
StartLimitIntervalSec=0
[Service]
WorkingDirectory=/opt/frigate
Environment="PATH=/opt/frigate/venv/bin"
ExecStart=/opt/frigate/venv/bin/python3 -u -m frigate
Type=simple
Restart=always
RestartSec=5
RestartSec=1
User=root
StandardOutput=journal
StandardError=journal
# Environment=PLUS_API_KEY=
Environment=DEFAULT_FFMPEG_VERSION=7.0
Environment=INCLUDED_FFMPEG_VERSIONS=5.0
ExecStartPre=+rm /dev/shm/logs/frigate/current
ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
StandardOutput=file:/dev/shm/logs/frigate/current
StandardError=file:/dev/shm/logs/frigate/current
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable -q --now frigate
msg_ok "Frigate service enabled"
sleep 3
cat <<EOF >/etc/systemd/system/nginx.service
[Unit]
Description=Nginx service
After=frigate.service
After=create_directories.service
StartLimitIntervalSec=0
# msg_info "Setup Frigate"
# ln -sf /usr/local/go2rtc/bin/go2rtc /usr/local/bin/go2rtc
# cd /opt/frigate
# $STD pip install -r /opt/frigate/docker/main/requirements.txt --break-system-packages
# $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt --break-system-packages
# $STD pip3 wheel --wheel-dir=/wheels -r /opt/frigate/docker/main/requirements-wheels.txt
# pip3 install -U /wheels/*.whl
# cp -a /opt/frigate/docker/main/rootfs/. /
# export TARGETARCH="amd64"
# export DEBIAN_FRONTEND=noninteractive
# echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections
# echo "libedgetpu1-max libedgetpu/install-confirm-max select true" | debconf-set-selections
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStartPre=+rm /dev/shm/logs/nginx/current
ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
StandardOutput=file:/dev/shm/logs/nginx/current
StandardError=file:/dev/shm/logs/nginx/current
# msg_info "Ensure /etc/apt/sources.list.d/debian.sources exists with deb-src"
# mkdir -p /etc/apt/sources.list.d
# cat >/etc/apt/sources.list.d/debian.sources <<'EOF'
# Types: deb deb-src
# URIs: http://deb.debian.org/debian
# Suites: bookworm
# Components: main
# Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
# EOF
# msg_ok "Stub /etc/apt/sources.list.d/debian.sources created"
# msg_info "Updating APT cache"
# $STD apt-get update
# msg_ok "APT cache updated"
# msg_info "Building Nginx with Custom Modules"
# $STD bash /opt/frigate/docker/main/build_nginx.sh
# sed -e '/s6-notifyoncheck/ s/^#*/#/' -i /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run
# ln -sf /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
# msg_ok "Built Nginx"
# msg_info "Cleanup stub debian.sources"
# rm -f /etc/apt/sources.list.d/debian.sources
# $STD apt-get update
# msg_ok "Removed stub and updated APT cache"
# $STD /opt/frigate/docker/main/install_deps.sh
# $STD apt update
# $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffmpeg /usr/local/bin/ffmpeg
# $STD ln -svf /usr/lib/btbn-ffmpeg/bin/ffprobe /usr/local/bin/ffprobe
# $STD pip3 install -U /wheels/*.whl
# ldconfig
# $STD pip3 install -r /opt/frigate/docker/main/requirements-dev.txt
# $STD /opt/frigate/.devcontainer/initialize.sh
# $STD make version
# cd /opt/frigate/web
# $STD npm install
# $STD npm run build
# cp -r /opt/frigate/web/dist/* /opt/frigate/web/
# cp -r /opt/frigate/config/. /config
# sed -i '/^s6-svc -O \.$/s/^/#/' /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run
# cat <<EOF >/config/config.yml
# mqtt:
# enabled: false
# cameras:
# test:
# ffmpeg:
# #hwaccel_args: preset-vaapi
# inputs:
# - path: /media/frigate/person-bicycle-car-detection.mp4
# input_args: -re -stream_loop -1 -fflags +genpts
# roles:
# - detect
# - rtmp
# detect:
# height: 1080
# width: 1920
# fps: 5
# EOF
# ln -sf /config/config.yml /opt/frigate/config/config.yml
# if [[ "$CTTYPE" == "0" ]]; then
# sed -i -e 's/^kvm:x:104:$/render:x:104:root,frigate/' -e 's/^render:x:105:root$/kvm:x:105:/' /etc/group
# else
# sed -i -e 's/^kvm:x:104:$/render:x:104:frigate/' -e 's/^render:x:105:$/kvm:x:105:/' /etc/group
# fi
# echo "tmpfs /tmp/cache tmpfs defaults 0 0" >>/etc/fstab
# msg_ok "Installed Frigate"
# # read -p "Semantic Search requires a dedicated GPU and at least 16GB RAM. Would you like to install it? (y/n): " semantic_choice
# # if [[ "$semantic_choice" == "y" ]]; then
# # msg_info "Configuring Semantic Search & AI Models"
# # mkdir -p /opt/frigate/models/semantic_search
# # curl -fsSL -o /opt/frigate/models/semantic_search/clip_model.pt https://huggingface.co/openai/clip-vit-base-patch32/resolve/main/pytorch_model.bin
# # msg_ok "Semantic Search Models Installed"
# # else
# # msg_ok "Skipped Semantic Search Setup"
# # fi
# msg_info "Building and Installing libUSB without udev"
# wget -qO /tmp/libusb.zip https://github.com/libusb/libusb/archive/v1.0.29.zip
# unzip -q /tmp/libusb.zip -d /tmp/
# cd /tmp/libusb-1.0.29
# ./bootstrap.sh
# ./configure --disable-udev --enable-shared
# make -j$(nproc --all)
# make install
# ldconfig
# rm -rf /tmp/libusb.zip /tmp/libusb-1.0.29
# msg_ok "Installed libUSB without udev"
# msg_info "Installing Coral Object Detection Model (Patience)"
# cd /opt/frigate
# export CCACHE_DIR=/root/.ccache
# export CCACHE_MAXSIZE=2G
# cd libusb
# $STD ./bootstrap.sh
# $STD ./configure --disable-udev --enable-shared
# $STD make -j $(nproc --all)
# cd /opt/frigate/libusb/libusb
# mkdir -p /usr/local/lib
# $STD /bin/bash ../libtool --mode=install /usr/bin/install -c libusb-1.0.la '/usr/local/lib'
# mkdir -p /usr/local/include/libusb-1.0
# $STD /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'
# ldconfig
# cd /
# wget -qO edgetpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite
# wget -qO cpu_model.tflite https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite
# cp /opt/frigate/labelmap.txt /labelmap.txt
# wget -qO yamnet-tflite-classification-tflite-v1.tar.gz https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download
# tar xzf yamnet-tflite-classification-tflite-v1.tar.gz
# rm -rf yamnet-tflite-classification-tflite-v1.tar.gz
# mv 1.tflite cpu_audio_model.tflite
# cp /opt/frigate/audio-labelmap.txt /audio-labelmap.txt
# mkdir -p /media/frigate
# wget -qO /media/frigate/person-bicycle-car-detection.mp4 https://github.com/intel-iot-devkit/sample-videos/raw/master/person-bicycle-car-detection.mp4
# msg_ok "Installed Coral Object Detection Model"
# msg_info "Installing Tempio"
# sed -i 's|/rootfs/usr/local|/usr/local|g' /opt/frigate/docker/main/install_tempio.sh
# TARGETARCH="amd64"
# $STD /opt/frigate/docker/main/install_tempio.sh
# chmod +x /usr/local/tempio/bin/tempio
# ln -sf /usr/local/tempio/bin/tempio /usr/local/bin/tempio
# msg_ok "Installed Tempio"
# msg_info "Creating Services"
# cat <<EOF >/etc/systemd/system/create_directories.service
# [Unit]
# Description=Create necessary directories for logs
# [Service]
# Type=oneshot
# ExecStart=/bin/bash -c '/bin/mkdir -p /dev/shm/logs/{frigate,go2rtc,nginx} && /bin/touch /dev/shm/logs/{frigate/current,go2rtc/current,nginx/current} && /bin/chmod -R 777 /dev/shm/logs'
# [Install]
# WantedBy=multi-user.target
# EOF
# systemctl enable -q --now create_directories
# sleep 3
# cat <<EOF >/etc/systemd/system/go2rtc.service
# [Unit]
# Description=go2rtc service
# After=network.target
# After=create_directories.service
# StartLimitIntervalSec=0
# [Service]
# Type=simple
# Restart=always
# RestartSec=1
# User=root
# ExecStartPre=+rm /dev/shm/logs/go2rtc/current
# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
# StandardOutput=file:/dev/shm/logs/go2rtc/current
# StandardError=file:/dev/shm/logs/go2rtc/current
# [Install]
# WantedBy=multi-user.target
# EOF
# systemctl enable -q --now go2rtc
# sleep 3
# cat <<EOF >/etc/systemd/system/frigate.service
# [Unit]
# Description=Frigate service
# After=go2rtc.service
# After=create_directories.service
# StartLimitIntervalSec=0
# [Service]
# Type=simple
# Restart=always
# RestartSec=1
# User=root
# # Environment=PLUS_API_KEY=
# ExecStartPre=+rm /dev/shm/logs/frigate/current
# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
# StandardOutput=file:/dev/shm/logs/frigate/current
# StandardError=file:/dev/shm/logs/frigate/current
# [Install]
# WantedBy=multi-user.target
# EOF
# systemctl enable -q --now frigate
# sleep 3
# cat <<EOF >/etc/systemd/system/nginx.service
# [Unit]
# Description=Nginx service
# After=frigate.service
# After=create_directories.service
# StartLimitIntervalSec=0
# [Service]
# Type=simple
# Restart=always
# RestartSec=1
# User=root
# ExecStartPre=+rm /dev/shm/logs/nginx/current
# ExecStart=/bin/bash -c "bash /opt/frigate/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run 2> >(/usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S ' >&2) | /usr/bin/ts '%%Y-%%m-%%d %%H:%%M:%%.S '"
# StandardOutput=file:/dev/shm/logs/nginx/current
# StandardError=file:/dev/shm/logs/nginx/current
# [Install]
# WantedBy=multi-user.target
# EOF
# systemctl enable -q --now nginx
# msg_ok "Configured Services"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now nginx
msg_ok "Configured Services"

View File

@@ -1,132 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (Canbiz)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/getmaxun/maxun
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
gcc \
libpq-dev \
libcurl4-openssl-dev \
libssl-dev
msg_ok "Installed Dependencies"
msg_info "Setup Python3"
$STD apt-get install -y \
python3 python3-dev python3-pip
$STD pip install --upgrade pip
msg_ok "Setup Python3"
setup_uv
PG_VERSION=16 setup_postgresql
msg_info "Setup Database"
DB_NAME=healthchecks_db
DB_USER=hc_user
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
SECRET_KEY="$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | cut -c1-32)"
$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 "healthchecks-Credentials"
echo "healthchecks Database User: $DB_USER"
echo "healthchecks Database Password: $DB_PASS"
echo "healthchecks Database Name: $DB_NAME"
} >>~/healthchecks.creds
msg_ok "Set up Database"
msg_info "Setup healthchecks"
fetch_and_deploy_gh_release "healthchecks" "healthchecks/healthchecks" "source"
cd /opt/healthchecks
mkdir -p /opt/healthchecks/static-collected/
$STD uv venv .venv
$STD source .venv/bin/activate
$STD uv pip install wheel
$STD uv pip install gunicorn
$STD uv pip install -r requirements.txt
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/healthchecks/.env
ALLOWED_HOSTS=localhost,127.0.0.1,${LOCAL_IP},healthchecks
DB=postgres
DB_HOST=localhost
DB_PORT=5432
DB_NAME=${DB_NAME}
DB_USER=${DB_USER}
DB_PASSWORD=${DB_PASS}
DB_CONN_MAX_AGE=0
DB_SSLMODE=prefer
DB_TARGET_SESSION_ATTRS=read-write
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost:5432/${DB_NAME}?sslmode=prefer
DEFAULT_FROM_EMAIL=healthchecks@example.org
EMAIL_HOST=localhost
EMAIL_HOST_PASSWORD=
EMAIL_HOST_USER=
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_USE_VERIFICATION=True
# Django & Healthchecks Konfiguration
SECRET_KEY=${SECRET_KEY}
DEBUG=True
SITE_ROOT=http://${LOCAL_IP}:8000
SITE_NAME=MyChecks
STATIC_ROOT=/opt/healthchecks/static-collected
EOF
$STD .venv/bin/python3 manage.py makemigrations
$STD .venv/bin/python3 manage.py migrate --noinput
$STD .venv/bin/python3 manage.py collectstatic --noinput
ADMIN_EMAIL="admin@helper-scripts.local"
ADMIN_PASSWORD="$DB_PASS"
cat <<EOF | $STD .venv/bin/python3 manage.py shell
from django.contrib.auth import get_user_model
User = get_user_model()
if not User.objects.filter(email="${ADMIN_EMAIL}").exists():
User.objects.create_superuser("${ADMIN_EMAIL}", "${ADMIN_EMAIL}", "${ADMIN_PASSWORD}")
EOF
msg_ok "Installed healthchecks"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/healthchecks.service
[Unit]
Description=Healthchecks Service
After=network.target postgresql.service
[Service]
WorkingDirectory=/opt/healthchecks/
EnvironmentFile=/opt/healthchecks/.env
ExecStart=/opt/healthchecks/.venv/bin/gunicorn hc.wsgi:application --bind 127.0.0.1:8000
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now healthchecks
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,94 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Mips2648
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://jeedom.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y \
lsb-release \
git
msg_ok "Dependencies installed"
DEFAULT_BRANCH="master"
REPO_URL="https://github.com/jeedom/core.git"
echo
while true; do
read -rp "${TAB3}Enter branch to use (master, beta, alpha...) (Default: ${DEFAULT_BRANCH}): " BRANCH
BRANCH="${BRANCH:-$DEFAULT_BRANCH}"
if git ls-remote --heads "$REPO_URL" "refs/heads/$BRANCH" | grep -q .; then
break
else
msg_error "Branch '$BRANCH' does not exist on remote. Please try again."
fi
done
msg_info "Downloading Jeedom installation script"
cd /tmp
wget -q https://raw.githubusercontent.com/jeedom/core/"${BRANCH}"/install/install.sh
chmod +x install.sh
msg_ok "Installation script downloaded"
msg_info "Install Jeedom main dependencies, please wait"
$STD ./install.sh -v "$BRANCH" -s 2
msg_ok "Installed Jeedom main dependencies"
msg_info "Install Database"
$STD ./install.sh -v "$BRANCH" -s 3
msg_ok "Database installed"
msg_info "Install Apache"
$STD ./install.sh -v "$BRANCH" -s 4
msg_ok "Apache installed"
msg_info "Install PHP and dependencies"
$STD ./install.sh -v "$BRANCH" -s 5
msg_ok "PHP installed"
msg_info "Download Jeedom core"
$STD ./install.sh -v "$BRANCH" -s 6
msg_ok "Download done"
msg_info "Database customisation"
$STD ./install.sh -v "$BRANCH" -s 7
msg_ok "Database customisation done"
msg_info "Jeedom customisation"
$STD ./install.sh -v "$BRANCH" -s 8
msg_ok "Jeedom customisation done"
msg_info "Configuring Jeedom"
$STD ./install.sh -v "$BRANCH" -s 9
msg_ok "Jeedom configured"
msg_info "Installing Jeedom"
$STD ./install.sh -v "$BRANCH" -s 10
msg_ok "Jeedom installed"
msg_info "Post installation"
$STD ./install.sh -v "$BRANCH" -s 11
msg_ok "Post installation done"
msg_info "Check installation"
$STD ./install.sh -v "$BRANCH" -s 12
msg_ok "Installation checked, everything is successfuly installed. A reboot is recommended."
motd_ssh
customize
msg_info "Cleaning up"
rm -rf /tmp/install.sh
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
PHP_VERSION=8.4 PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
PHP_VERSION="8.4" PHP_MODULE="mysql" PHP_APACHE="YES" PHP_FPM="YES" setup_php
setup_mariadb
msg_info "Setting up Database"
@@ -24,20 +24,18 @@ $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 "Leantime Credentials"
echo "Database User: $DB_USER"
echo "Database Password: $DB_PASS"
echo "Database Name: $DB_NAME"
} >>~/"$APPLICATION".creds
} >>~/leantime.creds
msg_ok "Set up Database"
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
msg_info "Setup ${APPLICATION}"
APACHE_LOG_DIR=/var/log/apache2
msg_info "Setup Leantime"
chown -R www-data:www-data "/opt/leantime"
chmod -R 750 "/opt/leantime"
cat <<EOF >/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
@@ -55,26 +53,21 @@ cat <<EOF >/etc/apache2/sites-enabled/000-default.conf
Require all granted
</Location>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
EOF
mv "/opt/leantime/config/sample.env" "/opt/leantime/config/.env"
sed -i -e "s|^LEAN_DB_DATABASE.*|LEAN_DB_DATABASE = '$DB_NAME'|" \
-e "s|^LEAN_DB_USER.*|LEAN_DB_USER = '$DB_USER'|" \
-e "s|^LEAN_DB_PASSWORD.*|LEAN_DB_PASSWORD = '$DB_PASS'|" \
-e "s|^LEAN_SESSION_PASSWORD.*|LEAN_SESSION_PASSWORD = '$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)'|" \
"/opt/leantime/config/.env"
a2enmod -q proxy_fcgi setenvif rewrite
a2enconf -q "php${PHP_VERSION}-fpm"
sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/${PHP_VERSION}/apache2/php.ini"
$STD a2enmod -q proxy_fcgi setenvif rewrite
$STD a2enconf -q "php8.4-fpm"
sed -i -e "s/^;extension.\(curl\|fileinfo\|gd\|intl\|ldap\|mbstring\|exif\|mysqli\|odbc\|openssl\|pdo_mysql\)/extension=\1/g" "/etc/php/8.4/apache2/php.ini"
systemctl restart apache2
msg_ok "Setup ${APPLICATION}"
msg_ok "Setup leantime"
motd_ssh
customize

View File

@@ -15,28 +15,28 @@ update_os
msg_info "Installing Dependencies"
$STD apt-get install -y \
lsb-release \
ca-certificates \
acl \
fping \
graphviz \
imagemagick \
mtr-tiny \
nginx \
nmap \
rrdtool \
snmp \
snmpd
lsb-release \
ca-certificates \
acl \
fping \
graphviz \
imagemagick \
mtr-tiny \
nginx \
nmap \
rrdtool \
snmp \
snmpd
msg_ok "Installed Dependencies"
PHP_VERSION=8.2 PHP_FPM=YES PHP_APACHE=NO PHP_MODULE="gmp,mysql,snmp" setup_php
PHP_VERSION="8.3" PHP_FPM="YES" PHP_MODULE="gmp,mysql,snmp" setup_php
setup_mariadb
setup_composer
setup_uv
PYTHON_VERSION="3.13" setup_uv
msg_info "Installing Python"
$STD apt-get install -y \
python3-{dotenv,pymysql,redis,setuptools,systemd,pip}
python3-{dotenv,pymysql,redis,setuptools,systemd,pip}
msg_ok "Installed Python"
msg_info "Configuring Database"
@@ -47,16 +47,17 @@ $STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE
$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 "LibreNMS-Credentials"
echo "LibreNMS Database User: $DB_USER"
echo "LibreNMS Database Password: $DB_PASS"
echo "LibreNMS Database Name: $DB_NAME"
echo "LibreNMS-Credentials"
echo "LibreNMS Database User: $DB_USER"
echo "LibreNMS Database Password: $DB_PASS"
echo "LibreNMS Database Name: $DB_NAME"
} >>~/librenms.creds
msg_ok "Configured Database"
msg_info "Setup Librenms"
fetch_and_deploy_gh_release "LibreNMS" "librenms/librenms"
msg_info "Configuring LibreNMS"
$STD useradd librenms -d /opt/librenms -M -r -s "$(which bash)"
fetch_and_deploy_gh_release "librenms/librenms"
setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/
cd /opt/librenms
@@ -72,7 +73,7 @@ chown -R librenms:librenms /opt/librenms
chmod 771 /opt/librenms
setfacl -d -m g::rwx /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
chmod -R ug=rwX /opt/librenms/bootstrap/cache /opt/librenms/storage /opt/librenms/logs /opt/librenms/rrd
msg_ok "Setup LibreNMS"
msg_ok "Configured LibreNMS"
msg_info "Configure MariaDB"
sed -i "/\[mysqld\]/a innodb_file_per_table=1\nlower_case_table_names=0" /etc/mysql/mariadb.conf.d/50-server.cnf
@@ -147,7 +148,6 @@ motd_ssh
customize
msg_info "Cleaning up"
rm -f $tmp_file
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,54 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: elvito
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/librespeed/speedtest
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get update
$STD apt-get install -y \
caddy \
php-fpm
msg_ok "Installed Dependencies"
msg_info "Installing librespeed"
temp_file=$(mktemp)
RELEASE=$(curl -fsSL https://api.github.com/repos/librespeed/speedtest/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
curl -fsSL "https://github.com/librespeed/speedtest/archive/refs/tags/${RELEASE}.zip" -o "$temp_file"
mkdir -p /opt/librespeed
mkdir -p /temp
unzip -q "$temp_file" -d /temp
cd /temp/speedtest-"${RELEASE}"
cp -u favicon.ico index.html speedtest.js speedtest_worker.js /opt/librespeed/
cp -ru backend results /opt/librespeed/
cat <<EOF >/etc/caddy/Caddyfile
:80 {
root * /opt/librespeed
file_server
php_fastcgi unix//run/php/php-fpm.sock
}
EOF
systemctl restart caddy
echo "${RELEASE}" >/opt/"${APP}_version.txt"
msg_ok "Installation completed"
motd_ssh
customize
msg_info "Cleaning up"
rm -rf /temp
rm -f "$temp_file"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,122 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2025 Community Scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/maxdorninger/MediaManager
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y yq
msg_ok "Installed dependencies"
NODE_VERSION="24" setup_nodejs
setup_uv
PG_VERSION="17" setup_postgresql
msg_info "Setting up PostgreSQL"
DB_NAME="mm_db"
DB_USER="mm_user"
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;"
$STD sudo -u postgres psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'utf8';"
{
echo "MediaManager Credentials"
echo "MediaManager Database User: $DB_USER"
echo "MediaManager Database Password: $DB_PASS"
echo "MediaManager Database Name: $DB_NAME"
} >>~/mediamanager.creds
msg_ok "Set up PostgreSQL"
fetch_and_deploy_gh_release "MediaManager" "maxdorninger/MediaManager" "tarball" "latest" "/opt/mediamanager"
msg_info "Configuring MediaManager"
MM_DIR="/opt/mm"
MEDIA_DIR="${MM_DIR}/media"
export CONFIG_DIR="${MM_DIR}/config"
export FRONTEND_FILES_DIR="${MM_DIR}/web/build"
export BASE_PATH=""
export PUBLIC_VERSION=""
export PUBLIC_API_URL="${BASE_PATH}/api/v1"
export BASE_PATH="${BASE_PATH}/web"
cd /opt/mediamanager/web
$STD npm ci
$STD npm run build
mkdir -p {"$MM_DIR"/web,"$MEDIA_DIR","$CONFIG_DIR"}
cp -r build "$FRONTEND_FILES_DIR"
export BASE_PATH=""
export VIRTUAL_ENV="${MM_DIR}/venv"
cd /opt/mediamanager
cp -r {media_manager,alembic*} "$MM_DIR"
$STD /usr/local/bin/uv venv "$VIRTUAL_ENV"
$STD /usr/local/bin/uv sync --locked --active
msg_ok "Configured MediaManager"
read -r -p "Enter the email address of your first admin user: " admin_email
if [[ "$admin_email" ]]; then
EMAIL="$admin_email"
fi
msg_info "Creating config and start script"
LOCAL_IP="$(hostname -I | awk '{print $1}')"
SECRET="$(openssl rand -hex 32)"
sed -e "s/localhost:8/$LOCAL_IP:8/g" \
-e "s|/data/|$MEDIA_DIR|g" \
-e 's/"db"/"localhost"/' \
-e "s/user = \"MediaManager\"/user = \"$DB_USER\"/" \
-e "s/password = \"MediaManager\"/password = \"$DB_PASS\"/" \
-e "s/dbname = \"MediaManager\"/dbname = \"$DB_NAME\"/" \
-e "/^token_secret/s/=.*/= \"$SECRET\"/" \
-e "s/admin@example.com/$EMAIL/" \
-e '/^admin_emails/s/, .*/]/' \
/opt/mediamanager/config.example.toml >"$CONFIG_DIR"/config.toml
mkdir -p "$MEDIA_DIR"/{images,tv,movies,torrents}
cat <<EOF >/opt/"$MM_DIR"/start.sh
#!/usr/bin/env bash
export CONFIG_DIR="$CONFIG_DIR"
export FRONTEND_FILES_DIR="$FRONTEND_FILES_DIR"
export BASE_PATH=""
cd /opt/"$MM_DIR"
source ./venv/bin/activate
/usr/local/bin/uv run alembic upgrade head
/usr/local/bin/uv run fastapi run ./media_manager/main.py --port 8000
EOF
chmod +x /opt/"$MM_DIR"/start.sh
msg_ok "Created config and start script"
msg_info "Creating service"
cat <<EOF >/etc/systemd/system/mediamanager.service
[Unit]
Description=MediaManager Backend Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/"$MM_DIR"
ExecStart=/usr/bin/bash start.sh
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now mediamanager
msg_ok "Created service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,171 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nginxproxymanager.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get update
$STD apt-get -y install \
ca-certificates \
apache2-utils \
logrotate \
build-essential \
jq \
git
msg_ok "Installed Dependencies"
NODE_VERSION="16" NODE_MODULE="yarn" setup_nodejs
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "nginxproxymanager" "NginxProxyManager/nginx-proxy-manager" "tarball" "latest" "/tmp/nginxproxymanager"
msg_info "Installing Python Dependencies"
$STD apt-get install -y \
python3 \
python3-dev \
python3-venv
msg_ok "Installed Python Dependencies"
msg_info "Setting up Certbot Environment"
$STD uv venv /opt/certbot
$STD uv pip install --python \
certbot \
certbot-dns-cloudflare \
certbot-dns-multi
msg_ok "Certbot Environment Ready"
msg_info "Installing Openresty"
VERSION="$(awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release)"
curl -fsSL "https://openresty.org/package/pubkey.gpg" | gpg --dearmor -o /etc/apt/trusted.gpg.d/openresty-archive-keyring.gpg
echo -e "deb http://openresty.org/package/debian $VERSION openresty" >/etc/apt/sources.list.d/openresty.list
$STD apt-get update
$STD apt-get -y install openresty
msg_ok "Installed Openresty"
msg_info "Setting up Environment"
ln -sf /usr/bin/python3 /usr/bin/python
ln -sf /opt/certbot/bin/certbot /usr/bin/certbot
ln -sf /usr/local/openresty/nginx/sbin/nginx /usr/sbin/nginx
ln -sf /usr/local/openresty/nginx/ /etc/nginx
sed -i 's+^daemon+#daemon+g' /tmp/nginxproxymanager/docker/rootfs/etc/nginx/nginx.conf
NGINX_CONFS=$(find "$(pwd)" -type f -name "*.conf")
for NGINX_CONF in $NGINX_CONFS; do
sed -i 's+include conf.d+include /etc/nginx/conf.d+g' "$NGINX_CONF"
done
mkdir -p /var/www/html /etc/nginx/logs
cd /tmp/nginxproxymanager
cp -r docker/rootfs/var/www/html/* /var/www/html/
cp -r docker/rootfs/etc/nginx/* /etc/nginx/
cp docker/rootfs/etc/letsencrypt.ini /etc/letsencrypt.ini
cp docker/rootfs/etc/logrotate.d/nginx-proxy-manager /etc/logrotate.d/nginx-proxy-manager
ln -sf /etc/nginx/nginx.conf /etc/nginx/conf/nginx.conf
rm -f /etc/nginx/conf.d/dev.conf
mkdir -p /tmp/nginx/body \
/run/nginx \
/data/nginx \
/data/custom_ssl \
/data/logs \
/data/access \
/data/nginx/default_host \
/data/nginx/default_www \
/data/nginx/proxy_host \
/data/nginx/redirection_host \
/data/nginx/stream \
/data/nginx/dead_host \
/data/nginx/temp \
/var/lib/nginx/cache/public \
/var/lib/nginx/cache/private \
/var/cache/nginx/proxy_temp
chmod -R 777 /var/cache/nginx
chown root /tmp/nginx
echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" {print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf);" >/etc/nginx/conf.d/include/resolvers.conf
if [ ! -f /data/nginx/dummycert.pem ] || [ ! -f /data/nginx/dummykey.pem ]; then
openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj "/O=Nginx Proxy Manager/OU=Dummy Certificate/CN=localhost" -keyout /data/nginx/dummykey.pem -out /data/nginx/dummycert.pem &>/dev/null
fi
mkdir -p /app/global /app/frontend/images
cd /tmp/nginxproxymanager
cp -r backend/* /app
cp -r global/* /app/global
msg_ok "Set up Environment"
msg_info "Building Frontend"
cd /tmp/nginxproxymanager/frontend
$STD yarn install --frozen-lockfile
$STD yarn build
cp -r dist/* /app/frontend
cp -r app-images/* /app/frontend/images
msg_ok "Built Frontend"
msg_info "Initializing Backend"
rm -rf /app/config/default.json
if [ ! -f /app/config/production.json ]; then
cat <<'EOF' >/app/config/production.json
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/data/database.sqlite"
}
}
}
}
EOF
fi
cd /app
$STD yarn install --production
msg_ok "Initialized Backend"
msg_info "Creating Service"
cat <<'EOF' >/lib/systemd/system/npm.service
[Unit]
Description=Nginx Proxy Manager
After=network.target
Wants=openresty.service
[Service]
Type=simple
Environment=NODE_ENV=production
Environment=NODE_OPTIONS=--openssl-legacy-provider
ExecStartPre=-mkdir -p /tmp/nginx/body /data/letsencrypt-acme-challenge
ExecStart=/usr/bin/node index.js --abort_on_uncaught_exception --max_old_space_size=1024
WorkingDirectory=/app
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
msg_ok "Created Service"
motd_ssh
customize
msg_info "Starting Services"
sed -i 's/user npm/user root/g; s/^pid/#pid/g' /usr/local/openresty/nginx/conf/nginx.conf
sed -r -i 's/^([[:space:]]*)su npm npm/\1#su npm npm/g;' /etc/logrotate.d/nginx-proxy-manager
systemctl enable -q --now openresty
systemctl enable -q --now npm
msg_ok "Started Services"
msg_info "Cleaning up"
rm -rf /tmp/*
systemctl restart openresty
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.proxmox.com/en/proxmox-backup-server
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
read -rp "${TAB3}Do you want to use the Enterprise repository (requires valid subscription key)? [y/N]: " USE_ENTERPRISE_REPO
msg_info "Installing Proxmox Backup Server"
curl -fsSL https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg |
gpg --dearmor -o /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
if [[ "$USE_ENTERPRISE_REPO" =~ ^([yY].*)$ ]]; then
echo "deb https://enterprise.proxmox.com/debian/pbs bookworm pbs-enterprise" >/etc/apt/sources.list.d/pbs-enterprise.list
msg_ok "Enterprise repository enabled. Make sure your subscription key is installed."
else
echo "deb http://download.proxmox.com/debian/pbs bookworm pbs-no-subscription" >>/etc/apt/sources.list
msg_ok "No-subscription repository enabled."
fi
$STD apt-get update
$STD apt-get install -y proxmox-backup-server
msg_ok "Installed Proxmox Backup Server"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: David Bennett (dbinit)
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://www.resilio.com/sync
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Setting up Resilio Sync Repository"
curl -fsSL "https://linux-packages.resilio.com/resilio-sync/key.asc" >/etc/apt/trusted.gpg.d/resilio-sync.asc
echo "deb [signed-by=/etc/apt/trusted.gpg.d/resilio-sync.asc] http://linux-packages.resilio.com/resilio-sync/deb resilio-sync non-free" >/etc/apt/sources.list.d/resilio-sync.list
$STD apt-get update
msg_ok "Resilio Sync Repository Setup"
msg_info "Installing Resilio Sync"
$STD apt-get install -y resilio-sync
sed -i "s/127.0.0.1:8888/0.0.0.0:8888/g" /etc/resilio-sync/config.json
systemctl enable -q resilio-sync
systemctl restart resilio-sync
msg_ok "Installed Resilio Sync"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

223
install/romm-install.sh Normal file
View File

@@ -0,0 +1,223 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: DevelopmentCats
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://romm.app
# Updated: 03/10/2025
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing dependencies"
$STD apt-get install -y \
acl \
build-essential \
libssl-dev \
libffi-dev \
python3-dev \
python3-pip \
python3-venv \
libmariadb3 \
libmariadb-dev \
libpq-dev \
redis-tools \
p7zip \
tzdata \
jq
msg_ok "Installed core dependencies"
PYTHON_VERSION="3.12" setup_uv
NODE_VERSION="22" NODE_MODULE="serve" setup_nodejs
setup_mariadb
msg_info "Configuring Database"
DB_NAME=romm
DB_USER=romm
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$STD mariadb -u root -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';"
$STD mariadb -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"
{
echo "RomM-Credentials"
echo "RomM Database User: $DB_USER"
echo "RomM Database Password: $DB_PASS"
echo "RomM Database Name: $DB_NAME"
} >~/romm.creds
chmod 600 ~/romm.creds
msg_ok "Configured Database"
msg_info "Creating romm user and directories"
id -u romm &>/dev/null || useradd -r -m -d /var/lib/romm -s /bin/bash romm
mkdir -p /opt/romm \
/var/lib/romm/config \
/var/lib/romm/resources \
/var/lib/romm/assets/{saves,states,screenshots} \
/var/lib/romm/library/roms/{gba,gbc,ps} \
/var/lib/romm/library/bios/{gba,ps}
chown -R romm:romm /opt/romm /var/lib/romm
msg_ok "Created romm user and directories"
msg_info "Configuring Database"
DB_NAME=romm
DB_USER=romm
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mariadb -u root -e "CREATE DATABASE $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
$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 "RomM-Credentials"
echo "RomM Database User: $DB_USER"
echo "RomM Database Password: $DB_PASS"
echo "RomM Database Name: $DB_NAME"
} >~/romm.creds
msg_ok "Configured Database"
fetch_and_deploy_gh_release "romm" "rommapp/romm"
msg_info "Creating environment file"
sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
systemctl restart redis-server
systemctl enable -q --now redis-server
AUTH_SECRET_KEY=$(openssl rand -hex 32)
cat >/opt/romm/.env <<EOF
ROMM_BASE_PATH=/var/lib/romm
WEB_CONCURRENCY=4
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=$DB_NAME
DB_USER=$DB_USER
DB_PASSWD=$DB_PASS
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
ROMM_AUTH_SECRET_KEY=$AUTH_SECRET_KEY
DISABLE_DOWNLOAD_ENDPOINT_AUTH=false
DISABLE_CSRF_PROTECTION=false
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true
RESCAN_ON_FILESYSTEM_CHANGE_DELAY=5
ENABLE_SCHEDULED_RESCAN=true
SCHEDULED_RESCAN_CRON=0 3 * * *
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB=true
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON=0 4 * * *
LOGLEVEL=INFO
EOF
chown romm:romm /opt/romm/.env
chmod 600 /opt/romm/.env
msg_ok "Created environment file"
msg_info "Installing backend"
cd /opt/romm
uv pip install --all-extras .
cd /opt/romm/backend
uv run alembic upgrade head
chown -R romm:romm /opt/romm
msg_ok "Installed backend"
msg_info "Installing frontend"
cd /opt/romm/frontend
npm install
npm run build
ln -sfn /var/lib/romm/resources /opt/romm/frontend/assets/romm/resources
ln -sfn /var/lib/romm/assets /opt/romm/frontend/assets/romm/assets
chown -R romm:romm /opt/romm
msg_ok "Installed frontend"
msg_info "Creating services"
cat >/etc/systemd/system/romm-backend.service <<EOF
[Unit]
Description=RomM Backend
After=network.target mariadb.service redis-server.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:5000
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/romm-frontend.service <<EOF
[Unit]
Description=RomM Frontend
After=network.target
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/frontend
ExecStart=$(which serve) -s dist -l 8080
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/romm-worker.service <<EOF
[Unit]
Description=RomM Worker
After=network.target mariadb.service redis-server.service romm-backend.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run python3 worker.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat >/etc/systemd/system/romm-scheduler.service <<EOF
[Unit]
Description=RomM Scheduler
After=network.target mariadb.service redis-server.service romm-backend.service
Requires=mariadb.service redis-server.service
[Service]
Type=simple
User=romm
WorkingDirectory=/opt/romm/backend
Environment="PYTHONPATH=/opt/romm"
ExecStart=/opt/romm/.venv/bin/uv run python3 scheduler.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now romm-backend romm-frontend romm-worker romm-scheduler
msg_ok "Created services"
# Install serve globally
su - ${ROMM_USER} -c "npm install -g serve"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt-get -y clean
msg_ok "Cleaned up"

48
install/stylus-install.sh Normal file
View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: luismco
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mmastrac/stylus
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "stylus" "mmastrac/stylus" "singlefile" "latest" "/usr/bin/" "*_linux_amd64"
msg_info "Configuring Stylus"
$STD stylus init /opt/stylus/
msg_ok "Configured Stylus"
msg_info "Creating service"
cat <<EOF >/etc/systemd/system/stylus.service
[Unit]
Description=Stylus Service
After=network.target
[Service]
Type=simple
ExecStart=stylus run /opt/stylus/
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now stylus
msg_ok "Created service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
$STD apt-get -y clean
msg_ok "Cleaned up"

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: EEJoshua
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://swizzin.ltd/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_warn "WARNING: This script will run an external installer from a third-party source (https://swizzin.ltd/)."
msg_warn "The following code is NOT maintained or audited by our repository."
msg_warn "If you have any doubts or concerns, please review the installer code before proceeding:"
msg_custom "${TAB3}${GATEWAY}${BGN}${CL}" "\e[1;34m" "→ https://s5n.sh"
echo
read -r -p "${TAB3}Do you want to continue? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
msg_error "Aborted by user. No changes have been made."
exit 10
fi
bash <(curl -sL s5n.sh)
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,59 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2025 Community Scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://tracktor.bytedge.in
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_nodejs
fetch_and_deploy_gh_release "tracktor" "javedh-dev/tracktor" "tarball" "latest" "/opt/tracktor"
msg_info "Configuring Tracktor"
cd /opt/tracktor
rm package-lock.json
$STD npm install
$STD npm run build
mkdir /opt/tracktor-data
HOST_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/opt/tracktor/app/server/.env
NODE_ENV=production
PUBLIC_DEMO_MODE=false
DB_PATH=/opt/tracktor-data/vehicles.db
PUBLIC_API_BASE_URL=http://$HOST_IP:3000
PORT=3000
EOF
msg_ok "Configured Tracktor"
msg_info "Creating service"
cat <<EOF >/etc/systemd/system/tracktor.service
[Unit]
Description=Tracktor Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/tracktor
EnvironmentFile=/opt/tracktor/app/server/.env
ExecStart=/usr/bin/npm start
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now tracktor
msg_ok "Created service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,263 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://traefik.io/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt-get install -y apt-transport-https
msg_ok "Installed Dependencies"
RELEASE=$(curl -fsSL https://api.github.com/repos/traefik/traefik/releases | grep -oP '"tag_name":\s*"v\K[\d.]+?(?=")' | sort -V | tail -n 1)
msg_info "Installing Traefik v${RELEASE}"
mkdir -p /etc/traefik/{conf.d,ssl,sites-available}
curl -fsSL "https://github.com/traefik/traefik/releases/download/v${RELEASE}/traefik_v${RELEASE}_linux_amd64.tar.gz" -o "traefik_v${RELEASE}_linux_amd64.tar.gz"
tar -C /tmp -xzf traefik*.tar.gz
mv /tmp/traefik /usr/bin/
rm -rf traefik*.tar.gz
echo "${RELEASE}" >/opt/${APPLICATION}_version.txt
msg_ok "Installed Traefik v${RELEASE}"
msg_info "Creating Traefik configuration"
cat <<EOF >/etc/traefik/traefik.yaml
providers:
file:
directory: /etc/traefik/conf.d/
watch: true
entryPoints:
web:
address: ':80'
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ':443'
http:
tls:
certResolver: letsencrypt
# Uncomment below if using cloudflare
/*
forwardedHeaders:
trustedIPs:
- 173.245.48.0/20
- 103.21.244.0/22
- 103.22.200.0/22
- 103.31.101.64/22
- 141.101.64.0/18
- 108.162.192.0/18
- 190.93.240.0/20
- 188.114.96.0/20
- 197.234.240.0/22
- 198.41.128.0/17
- 162.158.0.0/15
- 104.16.0.0/13
- 104.16.0.0/13
- 172.64.0.0/13
- 131.0.72.0/22
*/
asDefault: true
traefik:
address: ':8080'
certificatesResolvers:
letsencrypt:
acme:
email: "foo@bar.com"
storage: /etc/traefik/ssl/acme.json
tlsChallenge: {}
# Uncomment below if you are using self signed or no certificate
#serversTransport:
# insecureSkipVerify: true
api:
dashboard: true
insecure: true
log:
filePath: /var/log/traefik/traefik.log
format: json
level: INFO
accessLog:
filePath: /var/log/traefik/traefik-access.log
format: json
filters:
statusCodes:
- "200"
- "400-599"
retryAttempts: true
minDuration: "10ms"
bufferingSize: 0
fields:
headers:
defaultMode: drop
names:
User-Agent: keep
EOF
msg_ok "Created Traefik configuration"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/traefik.service
[Unit]
Description=Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience
[Service]
Type=notify
ExecStart=/usr/bin/traefik --configFile=/etc/traefik/traefik.yaml
Restart=on-failure
ExecReload=/bin/kill -USR1 \$MAINPID
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now traefik
msg_ok "Created Service"
msg_info "Creating site templates"
cat <<EOF >/etc/traefik/template.yaml.tpl
http:
routers:
${hostname}:
rule: Host(`${FQDN}`)
service: ${hostname}
tls:
certResolver: letsencrypt
services:
${hostname}:
loadbalancer:
servers:
- url: "${URL}"
EOF
msg_ok: "Template Created"
msg_info: "Creating Helper Scripts"
cat <<EOF >/usr/bin/addsite
#!/bin/bash
function setup_site() {
hostname="$(whiptail --inputbox "Enter the hostname of the Site" 8 78 --title "Hostname" 3>&1 1>&2 2>&3)"
exitstatus=$?
[[ "$exitstatus" = 1 ]] && return;
FQDN="$(whiptail --inputbox "Enter the FQDN of the Site" 8 78 --title "FQDN" 3>&1 1>&2 2>&3)"
exitstatus=$?
[[ "$exitstatus" = 1 ]] && return;
URL="$(whiptail --inputbox "Enter the URL of the Site (For example http://192.168.x.x:8080)" 8 78 --title "URL" 3>&1 1>&2 2>&3)"
exitstatus=$?
[[ "$exitstatus" = 1 ]] && return;
filename="/etc/traefik/sites-available/${hostname}.yaml"
export hostname FQDN URL
envsubst '${hostname} ${FQDN} ${URL}' < /etc/traefik/template.yaml.tpl > ${filename}
}
setup_site
EOF
cat <<EOF >/usr/bin/ensite
#!/bin/bash
function ensite() {
DIR="/etc/traefik/sites-available"
files=( "$DIR"/* )
opts=()
for f in "${files[@]}"; do
name="${f##*/}"
opts+=( "$name" "" )
done
choice=$(whiptail \
--title "Select an entry" \
--menu "Choose a site" \
20 60 12 \
"${opts[@]}" \
3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
ln -s $DIR/$choice /etc/traefik/conf.d
else
return
fi
}
ensite
EOF
cat <<EOF >/usr/bin/dissite
#!/bin/bash
function dissite() {
DIR="/etc/traefik/conf.d"
files=( "$DIR"/* )
opts=()
for f in "${files[@]}"; do
name="${f##*/}"
opts+=( "$name" "" )
done
choice=$(whiptail \
--title "Select an entry" \
--menu "Choose a site" \
20 60 12 \
"${opts[@]}" \
3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
rm $DIR/$choice
else
return
fi
}
dissite
EOF
cat <<EOF >/usr/bin/editsite
#!/bin/bash
function edit_site() {
DIR="/etc/traefik/sites-available"
files=( "$DIR"/* )
opts=()
for f in "${files[@]}"; do
name="${f##*/}"
opts+=( "$name" "" )
done
choice=$(whiptail \
--title "Select an entry" \
--menu "Choose a site" \
20 60 12 \
"${opts[@]}" \
3>&1 1>&2 2>&3)
if [ $? -eq 0 ]; then
nano $DIR/$choice
else
return
fi
}
edit_site
EOF
msg_ok "Helper Scripts Created"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

85
install/tunarr-install.sh Normal file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 tteck
# Author: chrisbenincasa
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://tunarr.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Setting Up Hardware Acceleration"
$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
if [[ "$CTTYPE" == "0" ]]; then
chgrp video /dev/dri
chmod 755 /dev/dri
chmod 660 /dev/dri/*
$STD adduser $(id -u -n) video
$STD adduser $(id -u -n) render
fi
msg_ok "Set Up Hardware Acceleration"
read -r -p "${TAB3}Do you need the intel-media-va-driver-non-free driver for HW encoding (Debian 12 only)? <y/N> " prompt
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
msg_info "Installing Intel Hardware Acceleration (non-free)"
cat <<EOF >/etc/apt/sources.list.d/non-free.list
deb http://deb.debian.org/debian bookworm non-free non-free-firmware
deb-src http://deb.debian.org/debian bookworm non-free non-free-firmware
deb http://deb.debian.org/debian-security bookworm-security non-free non-free-firmware
deb-src http://deb.debian.org/debian-security bookworm-security non-free non-free-firmware
deb http://deb.debian.org/debian bookworm-updates non-free non-free-firmware
deb-src http://deb.debian.org/debian bookworm-updates non-free non-free-firmware
EOF
$STD apt-get update
$STD apt-get -y install {intel-media-va-driver-non-free,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
else
msg_info "Installing Intel Hardware Acceleration"
$STD apt-get -y install {va-driver-all,ocl-icd-libopencl1,intel-opencl-icd,vainfo,intel-gpu-tools}
fi
msg_ok "Installed and Set Up Intel Hardware Acceleration"
fetch_and_deploy_gh_release "tunarr" "chrisbenincasa/tunarr" "singlefile" "latest" "/opt/tunarr" "*linux-x64"
fetch_and_deploy_gh_release "ersatztv-ffmpeg" "ErsatzTV/ErsatzTV-ffmpeg" "prebuild" "latest" "/opt/ErsatzTV-ffmpeg" "*-linux64-gpl-7.1.tar.xz"
msg_info "Set ErsatzTV-ffmpeg links"
chmod +x /opt/ErsatzTV-ffmpeg/bin/*
ln -sf /opt/ErsatzTV-ffmpeg/bin/ffmpeg /usr/bin/ffmpeg
ln -sf /opt/ErsatzTV-ffmpeg/bin/ffplay /usr/bin/ffplay
ln -sf /opt/ErsatzTV-ffmpeg/bin/ffprobe /usr/bin/ffprobe
msg_ok "ffmpeg links set"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/tunarr.service
[Unit]
Description=Tunarr Service
After=multi-user.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/tunarr
ExecStart=/opt/tunarr/tunarr
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now tunarr
msg_ok "Created Service"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

View File

@@ -1,63 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ), twingate-andrewb
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.twingate.com/docs/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
install -d -m 0700 /etc/twingate
access_token=""
refresh_token=""
network=""
while [[ -z "$access_token" ]]; do
read -rp "${TAB3}Please enter your access token: " access_token
done
while [[ -z "$refresh_token" ]]; do
read -rp "${TAB3}Please enter your refresh token: " refresh_token
done
while [[ -z "$network" ]]; do
read -rp "${TAB3}Please enter your network name: " network
done
msg_info "Setup Twingate Repository"
curl -fsSL "https://packages.twingate.com/apt/gpg.key" | gpg --dearmor -o /usr/share/keyrings/twingate-connector-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/twingate-connector-keyring.gpg] https://packages.twingate.com/apt/ /" > /etc/apt/sources.list.d/twingate.list
$STD apt-get update
msg_ok "Setup Twingate Repository"
msg_info "Setup Twingate Connector"
$STD apt-get install -y twingate-connector
msg_ok "Setup Twingate Connector"
msg_info "Writing config"
{
echo "TWINGATE_NETWORK=${network}"
echo "TWINGATE_ACCESS_TOKEN=${access_token}"
echo "TWINGATE_REFRESH_TOKEN=${refresh_token}"
echo "TWINGATE_LABEL_HOSTNAME=$(hostname)"
echo "TWINGATE_LABEL_DEPLOYED_BY=proxmox"
} > /etc/twingate/connector.conf
chmod 600 /etc/twingate/connector.conf
msg_ok "Config written"
msg_info "Starting Service"
systemctl enable -q --now twingate-connector
msg_ok "Service started"
motd_ssh
customize
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Done cleaning up"

View File

@@ -17,102 +17,6 @@ msg_info "Installing Dependencies"
$STD apt-get install -y jq
msg_ok "Installed Dependencies"
# echo "Getting aceberg/WatchYourLAN..."
# fetch_and_deploy_gh_release aceberg/WatchYourLAN
# echo "Got Version: $RELEASE"
# echo "Getting actualbudget/actual..."
# RELEASE=$(get_gh_release actualbudget/actual)
# echo "Got Version: $RELEASE"
# echo "Getting agl/jbig2enc..."
# RELEASE=$(get_gh_release agl/jbig2enc)
# echo "Got Version: $RELEASE"
# echo "Getting alexta69/metube..."
# RELEASE=$(get_gh_release alexta69/metube)
# echo "Got Version: $RELEASE"
# echo "Getting AlexxIT/go2rtc..."
# RELEASE=$(get_gh_release AlexxIT/go2rtc)
# echo "Got Version: $RELEASE"
# echo "Getting apache/tika..."
# RELEASE=$(get_gh_release apache/tika)
# echo "Got Version: $RELEASE"
# echo "Getting ArtifexSoftware/ghostpdl-downloads..."
# RELEASE=$(get_gh_release ArtifexSoftware/ghostpdl-downloads)
# echo "Got Version: $RELEASE"
# echo "Getting Athou/commafeed..."
# RELEASE=$(get_gh_release Athou/commafeed)
# echo "Got Version: $RELEASE"
# echo "Getting authelia/authelia..."
# RELEASE=$(get_gh_release authelia/authelia)
# echo "Got Version: $RELEASE"
# echo "Getting azukaar/Cosmos-Server..."
# RELEASE=$(get_gh_release azukaar/Cosmos-Server)
# echo "Got Version: $RELEASE"
# echo "Getting bastienwirtz/homer..."
# RELEASE=$(get_gh_release bastienwirtz/homer)
# echo "Got Version: $RELEASE"
# echo "Getting benjaminjonard/koillection..."
# RELEASE=$(get_gh_release benjaminjonard/koillection)
# echo "Got Version: $RELEASE"
# echo "Getting benzino77/tasmocompiler..."
# RELEASE=$(get_gh_release benzino77/tasmocompiler)
# echo "Got Version: $RELEASE"
# echo "Getting blakeblackshear/frigate..."
# RELEASE=$(get_gh_release blakeblackshear/frigate)
# echo "Got Version: $RELEASE"
# echo "Getting bluenviron/mediamtx..."
# RELEASE=$(get_gh_release bluenviron/mediamtx)
# echo "Got Version: $RELEASE"
# echo "Getting BookStackApp/BookStack..."
# RELEASE=$(get_gh_release BookStackApp/BookStack)
# echo "Got Version: $RELEASE"
# echo "Getting browserless/chrome..."
# RELEASE=$(get_gh_release browserless/chrome)
# echo "Got Version: $RELEASE"
# echo "Getting Bubka/2FAuth..."
# RELEASE=$(get_gh_release Bubka/2FAuth)
# echo "Got Version: $RELEASE"
# echo "Getting caddyserver/xcaddy..."
# RELEASE=$(get_gh_release caddyserver/xcaddy)
# echo "Got Version: $RELEASE"
# echo "Getting clusterzx/paperless-ai..."
# RELEASE=$(get_gh_release clusterzx/paperless-ai)
# echo "Got Version: $RELEASE"
# echo "Getting cockpit-project/cockpit..."
# RELEASE=$(get_gh_release cockpit-project/cockpit)
# echo "Got Version: $RELEASE"
# echo "Getting community-scripts/ProxmoxVE..."
# RELEASE=$(get_gh_release community-scripts/ProxmoxVE)
# echo "Got Version: $RELEASE"
# echo "Getting CorentinTh/it-tools..."
# RELEASE=$(get_gh_release CorentinTh/it-tools)
# echo "Got Version: $RELEASE"
# echo "Getting dani-garcia/bw_web_builds..."
# RELEASE=$(get_gh_release dani-garcia/bw_web_builds)
# echo "Got Version: $RELEASE"
motd_ssh
customize

View File

@@ -14,7 +14,7 @@ network_check
update_os
msg_info "Installing Dependencies"
setup_ffmpeg
$STD apt install -y ffmpeg
msg_ok "Installed Dependencies"
msg_info "Setting Up UHF Server Environment"
@@ -34,9 +34,8 @@ fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "lates
fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
msg_info "Creating Service"
service_path=""
cat <<EOF >/etc/systemd/system/uhf-server.service
echo "[Unit]
[Unit]
Description=UHF Server service
After=syslog.target network-online.target
[Service]
@@ -47,7 +46,7 @@ ExecStart=/opt/uhf-server/uhf-server
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now -q uhf-server.service
systemctl enable -q --now uhf-server
msg_ok "Created Service"
motd_ssh

View File

@@ -13,20 +13,36 @@ setting_up_container
network_check
update_os
PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Dependencies"
$STD apt-get install -y \
python3 python3-pip python3-venv \
python3-opencv jq \
libgl1-mesa-glx libglib2.0-0 \
libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \
gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-libav \
build-essential python3-dev python3-gi pkg-config libcairo2-dev gir1.2-glib-2.0 \
cmake gfortran libopenblas-dev liblapack-dev libgirepository1.0-dev
cmake gfortran libopenblas-dev liblapack-dev libgirepository1.0-dev git
msg_ok "Installed Dependencies"
PYTHON_VERSION="3.12" setup_uv
PG_VERSION="16" setup_postgresql
msg_info "Setting up PostgreSQL Database"
DB_NAME=viseron
DB_USER=viseron_usr
DB_PASS="$(openssl rand -base64 18 | 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 "Hanko-Credentials"
echo "Hanko Database User: $DB_USER"
echo "Hanko Database Password: $DB_PASS"
echo "Hanko Database Name: $DB_NAME"
} >>~/hanko.creds
msg_ok "Set up PostgreSQL Database"
# msg_info "Setting up Hardware Acceleration"
# if [[ "$CTTYPE" == "0" ]]; then
# chgrp video /dev/dri
@@ -35,21 +51,32 @@ msg_ok "Installed Dependencies"
# fi
# msg_ok "Hardware Acceleration Configured"
PYTHON_VERSION="3.12" setup_uv
fetch_and_deploy_gh_release "viseron" "roflcoopter/viseron" "tarball" "latest" "/opt/viseron"
msg_info "Setting up Viseron (Patience)"
cd /opt/viseron
uv venv .venv
$STD uv pip install --upgrade pip setuptools wheel
$STD uv pip install -r requirements.txt --python /opt/viseron/.venv/bin/python
ln -s /opt/viseron/.venv/bin/viseron /usr/local/bin/viseron
msg_ok "Setup Viseron"
msg_info "Setting up Python Environment"
uv venv --python "python3.12" /opt/viseron/.venv
uv pip install --python /opt/viseron/.venv/bin/python --upgrade pip setuptools wheel
msg_ok "Python Environment Setup"
msg_info "Creating Configuration Directory"
mkdir -p /config
mkdir -p /config/recordings
mkdir -p /config/logs
msg_ok "Created Configuration Directory"
msg_info "Setup Viseron (Patience)"
if ls /dev/nvidia* >/dev/null 2>&1; then
msg_info "GPU detected → Installing PyTorch with CUDA"
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python \
torch==2.8.0 torchvision==0.19.0 torchaudio==2.8.0
msg_ok "Installed Torch with CUDA"
else
msg_info "No GPU detected → Installing CPU-only PyTorch"
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python \
torch==2.8.0+cpu torchvision==0.19.0+cpu torchaudio==2.8.0+cpu \
--extra-index-url https://download.pytorch.org/whl/cpu
msg_ok "Installed Torch CPU-only"
fi
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -e /opt/viseron/.
UV_HTTP_TIMEOUT=600 uv pip install --python /opt/viseron/.venv/bin/python -r /opt/viseron/requirements.txt
mkdir -p /config/{recordings,snapshots,segments,event_clips,thumbnails}
for d in recordings snapshots segments event_clips thumbnails; do ln -s "/config/$d" "/$d" 2>/dev/null || true; done
msg_ok "Setup Viseron"
msg_info "Creating Default Configuration"
cat <<EOF >/config/viseron.yaml
@@ -103,6 +130,14 @@ motion_detection:
enabled: true
threshold: 25
sensitivity: 0.8
storage:
connection_string: postgresql://$DB_USER:$DB_PASS@localhost:5432/$DB_NAME
recordings: /recordings
snapshots: /snapshots
segments: /segments
event_clips: /event_clips
thumbnails: /thumbnails
EOF
msg_ok "Created Default Configuration"
@@ -117,7 +152,7 @@ Type=simple
User=root
WorkingDirectory=/opt/viseron
Environment=PATH=/opt/viseron/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/opt/viseron/.venv/bin/viseron --config /config/viseron.yaml
ExecStart=/opt/viseron/.venv/bin/python -m viseron --config /config/viseron.yaml
Restart=always
RestartSec=10