Compare commits

...

26 Commits

Author SHA1 Message Date
11cbf1b986 Update install/speedtest-tracker-install.sh
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2025-12-11 08:22:14 +01:00
7a1e71af62 Update install/speedtest-tracker-install.sh
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2025-12-11 08:22:04 +01:00
e3a201db02 Apply suggestion from @tremor021 2025-12-09 15:51:30 +01:00
721ed4ad1a Update Speedtest Tracker installation script for local IP 2025-12-09 15:12:10 +01:00
bf6fdb43d9 Update date_created and logo in JSON file 2025-12-09 15:10:33 +01:00
5cc1eae0d2 Update speedtest-tracker.sh 2025-12-09 15:09:02 +01:00
1c175eb012 Add speedtest-tracker (ct) 2025-12-09 13:52:19 +00:00
f6f131efab Update CHANGELOG.md (#9800)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 13:22:50 +00:00
e4d5ce221b fixed grammar on one of the alerts (#9799) 2025-12-09 14:22:23 +01:00
4e182bd5b9 Update versions.json (#9797)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 13:06:31 +01:00
12a7ecd85d Update .app files (#9795)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-12-09 10:08:03 +01:00
b658959c7b Update CHANGELOG.md (#9796)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 09:07:33 +00:00
5eb9d2bcdf Add dokploy (ct) (#9793)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2025-12-09 10:07:04 +01:00
7d37743981 Update CHANGELOG.md (#9794)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 09:05:57 +00:00
b0e7cdfe13 Coolify (#9792)
* Add coolify (ct)

* Update logo URL to use WebP format

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2025-12-09 10:05:36 +01:00
31c19bed09 Update CHANGELOG.md (#9788)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 00:13:26 +00:00
bff0650d72 Update versions.json (#9787)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-09 01:13:01 +01:00
d9b05882a3 Update CHANGELOG.md (#9782)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-08 18:36:34 +00:00
31dbf2554c Tandoor: Remove postgres17-contrib package (#9781)
* Remove contrib

* Update

* Update

* Upda
2025-12-08 19:36:06 +01:00
f95cc5a7ad Update CHANGELOG.md (#9775)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-08 13:20:30 +00:00
3fb9d02f36 fix: always show SSH access dialog in advanced settings (#9765)
- SSH access dialog is now always displayed regardless of password or SSH keys
- Added step indicator to SSH settings dialogs for consistency
- configure_ssh_settings() now accepts optional step_info parameter
- Updated documentation for SSH configuration functions

Fixes #9753
2025-12-08 14:20:05 +01:00
a748be9a1f Update CHANGELOG.md (#9774)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-08 12:52:51 +00:00
4d4ced6b63 feat: Add var_gpu flag for GPU passthrough configuration (#9764)
* feat: Add var_gpu flag for GPU passthrough configuration

Changes:
- Add var_gpu variable to CT scripts for explicit GPU control
- Remove hardcoded GPU_APPS list - GPU detection now uses var_gpu flag
- Add var_gpu to VAR_WHITELIST for persistence in default.vars and app.vars
- Add GPU Passthrough option (Step 19) to advanced_settings wizard (now 20 steps)
- Update documentation

Apps with var_gpu=yes (GPU enabled by default):
- Media: jellyfin, plex, emby, channels, ersatztv, tunarr
- Transcoding: tdarr, unmanic, fileflows
- AI/ML: ollama, openwebui
- NVR: frigate, immich

Usage:
- Disable GPU: var_gpu=no bash -c '$(curl -fsSL ...jellyfin.sh)'
- Enable GPU: var_gpu=yes bash -c '$(curl -fsSL ...debian.sh)'
- Via default.vars: echo 'var_gpu=yes' >> /usr/local/community-scripts/default.vars
- Via advanced settings wizard (Step 19)

* fix: tput rmcup timing, GPU line indentation, echo_default GPU display

* style: add GPU icon variable for consistent formatting
2025-12-08 13:52:30 +01:00
a5d017c83b Update versions.json (#9773)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-08 13:06:10 +01:00
5378d822f8 Update CHANGELOG.md (#9772)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-08 10:38:33 +00:00
243cb34d47 tandoor instead of trandoor (#9771) 2025-12-08 11:38:08 +01:00
35 changed files with 1364 additions and 390 deletions

View File

@ -10,8 +10,37 @@
> [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2025-12-09
### 🆕 New Scripts
- Dokploy ([#9793](https://github.com/community-scripts/ProxmoxVE/pull/9793))
- Coolify ([#9792](https://github.com/community-scripts/ProxmoxVE/pull/9792))
### 📚 Documentation
- fixed grammar on alert that pops up when you copy the curl command [@Sarthak-Sidhant](https://github.com/Sarthak-Sidhant) ([#9799](https://github.com/community-scripts/ProxmoxVE/pull/9799))
## 2025-12-08
### 🚀 Updated Scripts
- typo: tandoor instead of trandoor [@Neonize](https://github.com/Neonize) ([#9771](https://github.com/community-scripts/ProxmoxVE/pull/9771))
- #### 🐞 Bug Fixes
- Tandoor: Remove postgres17-contrib package [@tremor021](https://github.com/tremor021) ([#9781](https://github.com/community-scripts/ProxmoxVE/pull/9781))
- #### ✨ New Features
- feat: Add var_gpu flag for GPU passthrough configuration [@MickLesk](https://github.com/MickLesk) ([#9764](https://github.com/community-scripts/ProxmoxVE/pull/9764))
### 💾 Core
- #### 🐞 Bug Fixes
- fix: always show SSH access dialog in advanced settings [@MickLesk](https://github.com/MickLesk) ([#9765](https://github.com/community-scripts/ProxmoxVE/pull/9765))
## 2025-12-07
### 🚀 Updated Scripts

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-0}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
@ -38,4 +39,4 @@ description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8089${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8089${CL}"

46
ct/coolify.sh Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://coolify.io/
APP="Coolify"
var_tags="${var_tags:-docker;paas}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-30}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /data/coolify ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating Coolify"
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
msg_ok "Updated Coolify"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"

46
ct/dokploy.sh Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://dokploy.com/
APP="Dokploy"
var_tags="${var_tags:-docker;paas}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /etc/dokploy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating Dokploy"
$STD bash <(curl -sSL https://dokploy.com/install.sh)
msg_ok "Updated Dokploy"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-8}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-5}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-20}"
var_os="${var_os:-debian}"
var_version="${var_version:-11}"
var_unprivileged="${var_unprivileged:-0}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
@ -38,4 +39,4 @@ description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5000${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5000${CL}"

6
ct/headers/coolify Normal file
View File

@ -0,0 +1,6 @@
______ ___ ____
/ ____/___ ____ / (_) __/_ __
/ / / __ \/ __ \/ / / /_/ / / /
/ /___/ /_/ / /_/ / / / __/ /_/ /
\____/\____/\____/_/_/_/ \__, /
/____/

6
ct/headers/dokploy Normal file
View File

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

View File

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

View File

@ -13,6 +13,7 @@ var_ram="${var_ram:-4096}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-16}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -12,6 +12,7 @@ var_ram="${var_ram:-4096}"
var_disk="${var_disk:-35}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-25}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-8}"
var_os="${var_os:-ubuntu}"
var_version="${var_version:-24.04}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables
@ -23,8 +24,8 @@ function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]] \
&& [[ ! -f /etc/apt/sources.list.d/plexmediaserver.sources ]]; then
if [[ ! -f /etc/apt/sources.list.d/plexmediaserver.list ]] &&
[[ ! -f /etc/apt/sources.list.d/plexmediaserver.sources ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

83
ct/speedtest-tracker.sh Normal file
View File

@ -0,0 +1,83 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: AlphaLawless
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/alexjustesen/speedtest-tracker
APP="Speedtest-Tracker"
var_tags="${var_tags:-monitoring}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/speedtest-tracker ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "speedtest-tracker" "alexjustesen/speedtest-tracker"; then
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="common,sqlite3,redis" setup_php
setup_composer
NODE_VERSION="22" setup_nodejs
msg_info "Stopping Service"
systemctl stop speedtest-tracker
msg_ok "Stopped Service"
msg_info "Updating Speedtest CLI"
$STD apt update
$STD apt --only-upgrade install -y speedtest
msg_ok "Updated Speedtest CLI"
msg_info "Creating Backup"
cp -r /opt/speedtest-tracker /opt/speedtest-tracker-backup
msg_ok "Backup Created"
fetch_and_deploy_gh_release "speedtest-tracker" "alexjustesen/speedtest-tracker" "tarball" "latest" "/opt/speedtest-tracker"
msg_info "Updating Speedtest Tracker"
cp -r /opt/speedtest-tracker-backup/.env /opt/speedtest-tracker/.env
cd /opt/speedtest-tracker
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --optimize-autoloader --no-dev
$STD npm ci
$STD npm run build
$STD php artisan migrate --force
$STD php artisan config:clear
$STD php artisan cache:clear
$STD php artisan view:clear
chown -R www-data:www-data /opt/speedtest-tracker
chmod -R 755 /opt/speedtest-tracker/storage
chmod -R 755 /opt/speedtest-tracker/bootstrap/cache
msg_ok "Updated Speedtest Tracker"
msg_info "Starting Service"
systemctl start speedtest-tracker
msg_ok "Started Service"
msg_ok "Updated successfully"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"

View File

@ -55,7 +55,7 @@ function update_script() {
cd /opt/tandoor/vue3
$STD yarn install
$STD yarn build
TANDOOR_VERSION="$(curl -fsSL https://api.github.com/repos/TandoorRecipes/recipes/releases/latest | jq -r .tag_name)"
TANDOOR_VERSION=$(get_latest_github_release "TandoorRecipes/recipes")
cat <<EOF >/opt/tandoor/cookbook/version_info.py
TANDOOR_VERSION = "$TANDOOR_VERSION"
TANDOOR_REF = "bare-metal"
@ -65,7 +65,7 @@ EOF
$STD /opt/tandoor/.venv/bin/python manage.py migrate
$STD /opt/tandoor/.venv/bin/python manage.py collectstatic --no-input
rm -rf /opt/tandoor.bak
msg_ok "Updated Trandoor"
msg_ok "Updated Tandoor"
msg_info "Starting Service"
systemctl start tandoor

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-5}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -13,6 +13,7 @@ var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-0}"
var_gpu="${var_gpu:-yes}"
header_info "$APP"
variables

View File

@ -1,8 +1,8 @@
# Technical Reference: Configuration System Architecture
> **For Developers and Advanced Users**
>
> *Deep dive into how the defaults and configuration system works*
>
> _Deep dive into how the defaults and configuration system works_
---
@ -123,13 +123,13 @@ VAR_VALUE := [^\n]* # Any printable characters except newline
**Constraints**:
| Constraint | Value |
|-----------|-------|
| Max file size | 64 KB |
| Max line length | 1024 bytes |
| Max variables | 100 |
| Allowed var names | `var_[a-z_]+` |
| Value validation | Whitelist + Sanitization |
| Constraint | Value |
| ----------------- | ------------------------ |
| Max file size | 64 KB |
| Max line length | 1024 bytes |
| Max variables | 100 |
| Allowed var names | `var_[a-z_]+` |
| Value validation | Whitelist + Sanitization |
**Example Valid File**:
@ -206,21 +206,24 @@ var_tags=dns,pihole
**Purpose**: Safely load variables from .vars files without using `source` or `eval`
**Signature**:
```bash
load_vars_file(filepath)
```
**Parameters**:
| Param | Type | Required | Example |
|-------|------|----------|---------|
| filepath | String | Yes | `/usr/local/community-scripts/default.vars` |
| Param | Type | Required | Example |
| -------- | ------ | -------- | ------------------------------------------- |
| filepath | String | Yes | `/usr/local/community-scripts/default.vars` |
**Returns**:
- `0` on success
- `1` on error (file missing, parse error, etc.)
**Environment Side Effects**:
- Sets all parsed `var_*` variables as shell variables
- Does NOT unset variables if file missing (safe)
- Does NOT affect other variables
@ -230,25 +233,25 @@ load_vars_file(filepath)
```bash
load_vars_file() {
local file="$1"
# File must exist
[ -f "$file" ] || return 0
# Parse line by line (not with source/eval)
local line key val
while IFS='=' read -r key val || [ -n "$key" ]; do
# Skip comments and empty lines
[[ "$key" =~ ^[[:space:]]*# ]] && continue
[[ -z "$key" ]] && continue
# Validate key is in whitelist
_is_whitelisted_key "$key" || continue
# Sanitize and export value
val="$(_sanitize_value "$val")"
[ $? -eq 0 ] && export "$key=$val"
done < "$file"
return 0
}
```
@ -281,6 +284,7 @@ echo "Allocating ${var_ram} MB RAM"
**Purpose**: Get the full path for app-specific defaults file
**Signature**:
```bash
get_app_defaults_path()
```
@ -288,6 +292,7 @@ get_app_defaults_path()
**Parameters**: None
**Returns**:
- String: Full path to app defaults file
**Implementation**:
@ -322,6 +327,7 @@ load_vars_file "$(get_app_defaults_path)"
**Purpose**: Load and display user global defaults
**Signature**:
```bash
default_var_settings()
```
@ -329,6 +335,7 @@ default_var_settings()
**Parameters**: None
**Returns**:
- `0` on success
- `1` on error
@ -337,15 +344,15 @@ default_var_settings()
```
1. Find default.vars location
(usually /usr/local/community-scripts/default.vars)
2. Create if missing
3. Load variables from file
4. Map var_verbose → VERBOSE variable
5. Call base_settings (apply to container config)
6. Call echo_default (display summary)
```
@ -354,20 +361,20 @@ default_var_settings()
```bash
default_var_settings() {
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_gpu
var_gateway var_hostname var_ipv6_method var_mac var_mtu
var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged
var_verbose var_vlan var_ssh var_ssh_authorized_key
var_container_storage var_template_storage
)
# Ensure file exists
_ensure_default_vars
# Find and load
local dv="$(_find_default_vars)"
load_vars_file "$dv"
# Map verbose flag
if [[ -n "${var_verbose:-}" ]]; then
case "${var_verbose,,}" in
@ -375,7 +382,7 @@ default_var_settings() {
*) VERBOSE="${var_verbose}" ;;
esac
fi
# Apply and display
base_settings "$VERBOSE"
echo_default
@ -389,6 +396,7 @@ default_var_settings() {
**Purpose**: Offer to save current settings as app-specific defaults
**Signature**:
```bash
maybe_offer_save_app_defaults()
```
@ -413,10 +421,10 @@ maybe_offer_save_app_defaults()
```bash
maybe_offer_save_app_defaults() {
local app_vars_path="$(get_app_defaults_path)"
# Build current settings from memory
local new_tmp="$(_build_current_app_vars_tmp)"
# Check if already exists
if [ -f "$app_vars_path" ]; then
# Show diff and ask: Update? Keep? View Diff?
@ -438,29 +446,31 @@ maybe_offer_save_app_defaults() {
**Purpose**: Remove dangerous characters/patterns from configuration values
**Signature**:
```bash
_sanitize_value(value)
```
**Parameters**:
| Param | Type | Required |
|-------|------|----------|
| value | String | Yes |
| Param | Type | Required |
| ----- | ------ | -------- |
| value | String | Yes |
**Returns**:
- `0` (success) + sanitized value on stdout
- `1` (failure) + nothing if dangerous
**Dangerous Patterns**:
| Pattern | Threat | Example |
|---------|--------|---------|
| `$(...)` | Command substitution | `$(rm -rf /)` |
| `` ` ` `` | Command substitution | `` `whoami` `` |
| `;` | Command separator | `value; rm -rf /` |
| `&` | Background execution | `value & malicious` |
| `<(` | Process substitution | `<(cat /etc/passwd)` |
| Pattern | Threat | Example |
| --------- | -------------------- | -------------------- |
| `$(...)` | Command substitution | `$(rm -rf /)` |
| `` ` ` `` | Command substitution | `` `whoami` `` |
| `;` | Command separator | `value; rm -rf /` |
| `&` | Background execution | `value & malicious` |
| `<(` | Process substitution | `<(cat /etc/passwd)` |
**Implementation**:
@ -501,17 +511,19 @@ fi
**Purpose**: Check if variable name is in allowed whitelist
**Signature**:
```bash
_is_whitelisted_key(key)
```
**Parameters**:
| Param | Type | Required | Example |
|-------|------|----------|---------|
| key | String | Yes | `var_cpu` |
| Param | Type | Required | Example |
| ----- | ------ | -------- | --------- |
| key | String | Yes | `var_cpu` |
**Returns**:
- `0` if key is whitelisted
- `1` if key is NOT whitelisted
@ -573,6 +585,7 @@ Step 4: Use BUILT-IN DEFAULTS
### Precedence Examples
**Example 1: Environment Variable Wins**
```bash
# Shell environment has highest priority
$ export var_cpu=16
@ -583,6 +596,7 @@ $ bash pihole-install.sh
```
**Example 2: App Defaults Override User Defaults**
```bash
# User Defaults: var_cpu=4
# App Defaults: var_cpu=2
@ -593,6 +607,7 @@ $ bash pihole-install.sh
```
**Example 3: All Defaults Missing (Built-ins Used)**
```bash
# No environment variables set
# No app defaults file
@ -611,21 +626,21 @@ $ bash pihole-install.sh
base_settings() {
# Priority 1: Environment variables (already set if export used)
CT_TYPE=${var_unprivileged:-"1"} # Use existing or default
# Priority 2: Load app defaults (may override above)
if [ -f "$(get_app_defaults_path)" ]; then
load_vars_file "$(get_app_defaults_path)"
fi
# Priority 3: Load user defaults
if [ -f "/usr/local/community-scripts/default.vars" ]; then
load_vars_file "/usr/local/community-scripts/default.vars"
fi
# Priority 4: Apply built-in defaults (lowest)
CORE_COUNT=${var_cpu:-"${APP_CPU_DEFAULT:-2}"}
RAM_SIZE=${var_ram:-"${APP_RAM_DEFAULT:-1024}"}
# Result: var_cpu has been set through precedence chain
}
```
@ -734,14 +749,14 @@ CONTAINER CREATION STARTED
### Threat Model
| Threat | Mitigation |
|--------|-----------|
| **Arbitrary Code Execution** | No `source` or `eval`; manual parsing only |
| **Variable Injection** | Whitelist of allowed variable names |
| **Command Substitution** | `_sanitize_value()` blocks `$()`, backticks, etc. |
| **Path Traversal** | Files locked to `/usr/local/community-scripts/` |
| **Permission Escalation** | Files created with restricted permissions |
| **Information Disclosure** | Sensitive variables not logged |
| Threat | Mitigation |
| ---------------------------- | ------------------------------------------------- |
| **Arbitrary Code Execution** | No `source` or `eval`; manual parsing only |
| **Variable Injection** | Whitelist of allowed variable names |
| **Command Substitution** | `_sanitize_value()` blocks `$()`, backticks, etc. |
| **Path Traversal** | Files locked to `/usr/local/community-scripts/` |
| **Permission Escalation** | Files created with restricted permissions |
| **Information Disclosure** | Sensitive variables not logged |
### Security Controls
@ -798,6 +813,7 @@ fi
### Module: `build.func`
**Load Order** (in actual scripts):
1. `#!/usr/bin/env bash` - Shebang
2. `source /dev/stdin <<<$(curl ... api.func)` - API functions
3. `source /dev/stdin <<<$(curl ... build.func)` - Build functions
@ -832,17 +848,17 @@ fi
# Section 6: Installation Flow
- install_script() # Main entry point
- advanced_settings() # 19-step wizard
- advanced_settings() # 20-step wizard
```
### Regex Patterns Used
| Pattern | Purpose | Example Match |
|---------|---------|---|
| `^[0-9]+([.][0-9]+)?$` | Integer validation | `4`, `192.168` |
| `^var_[a-z_]+$` | Variable name | `var_cpu`, `var_ssh` |
| `*'$('*` | Command substitution | `$(whoami)` |
| `*\`*` | Backtick substitution | `` `cat /etc/passwd` `` |
| Pattern | Purpose | Example Match |
| ---------------------- | --------------------- | ----------------------- |
| `^[0-9]+([.][0-9]+)?$` | Integer validation | `4`, `192.168` |
| `^var_[a-z_]+$` | Variable name | `var_cpu`, `var_ssh` |
| `*'$('*` | Command substitution | `$(whoami)` |
| `*\`\*` | Backtick substitution | `` `cat /etc/passwd` `` |
---
@ -869,12 +885,12 @@ fi
### Function Mapping
| Old | New | Location |
|-----|-----|----------|
| `read_config()` | `load_vars_file()` | build.func |
| `write_config()` | `_build_current_app_vars_tmp()` | build.func |
| None | `maybe_offer_save_app_defaults()` | build.func |
| None | `get_app_defaults_path()` | build.func |
| Old | New | Location |
| ---------------- | --------------------------------- | ---------- |
| `read_config()` | `load_vars_file()` | build.func |
| `write_config()` | `_build_current_app_vars_tmp()` | build.func |
| None | `maybe_offer_save_app_defaults()` | build.func |
| None | `get_app_defaults_path()` | build.func |
---

View File

@ -8,103 +8,123 @@ This document provides a comprehensive reference of all environment variables us
### Core Container Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `APP` | Application name (e.g., "plex", "nextcloud") | - | Environment | Throughout |
| `NSAPP` | Namespace application name | `$APP` | Environment | Throughout |
| `CTID` | Container ID | - | Environment | Container creation |
| `CT_TYPE` | Container type ("install" or "update") | "install" | Environment | Entry point |
| `CT_NAME` | Container name | `$APP` | Environment | Container creation |
| Variable | Description | Default | Set In | Used In |
| --------- | -------------------------------------------- | --------- | ----------- | ------------------ |
| `APP` | Application name (e.g., "plex", "nextcloud") | - | Environment | Throughout |
| `NSAPP` | Namespace application name | `$APP` | Environment | Throughout |
| `CTID` | Container ID | - | Environment | Container creation |
| `CT_TYPE` | Container type ("install" or "update") | "install" | Environment | Entry point |
| `CT_NAME` | Container name | `$APP` | Environment | Container creation |
### Operating System Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `var_os` | Operating system selection | "debian" | base_settings() | OS selection |
| `var_version` | OS version | "12" | base_settings() | Template selection |
| `var_template` | Template name | Auto-generated | base_settings() | Template download |
| Variable | Description | Default | Set In | Used In |
| -------------- | -------------------------- | -------------- | --------------- | ------------------ |
| `var_os` | Operating system selection | "debian" | base_settings() | OS selection |
| `var_version` | OS version | "12" | base_settings() | Template selection |
| `var_template` | Template name | Auto-generated | base_settings() | Template download |
### Resource Configuration Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `var_cpu` | CPU cores | "2" | base_settings() | Container creation |
| `var_ram` | RAM in MB | "2048" | base_settings() | Container creation |
| `var_disk` | Disk size in GB | "8" | base_settings() | Container creation |
| `DISK_SIZE` | Disk size (alternative) | `$var_disk` | Environment | Container creation |
| `CORE_COUNT` | CPU cores (alternative) | `$var_cpu` | Environment | Container creation |
| `RAM_SIZE` | RAM size (alternative) | `$var_ram` | Environment | Container creation |
| Variable | Description | Default | Set In | Used In |
| ------------ | ----------------------- | ----------- | --------------- | ------------------ |
| `var_cpu` | CPU cores | "2" | base_settings() | Container creation |
| `var_ram` | RAM in MB | "2048" | base_settings() | Container creation |
| `var_disk` | Disk size in GB | "8" | base_settings() | Container creation |
| `DISK_SIZE` | Disk size (alternative) | `$var_disk` | Environment | Container creation |
| `CORE_COUNT` | CPU cores (alternative) | `$var_cpu` | Environment | Container creation |
| `RAM_SIZE` | RAM size (alternative) | `$var_ram` | Environment | Container creation |
### Network Configuration Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `var_net` | Network interface | "vmbr0" | base_settings() | Network config |
| `var_bridge` | Bridge interface | "vmbr0" | base_settings() | Network config |
| `var_gateway` | Gateway IP | "192.168.1.1" | base_settings() | Network config |
| `var_ip` | Container IP address | - | User input | Network config |
| `var_ipv6` | IPv6 address | - | User input | Network config |
| `var_vlan` | VLAN ID | - | User input | Network config |
| `var_mtu` | MTU size | "1500" | base_settings() | Network config |
| `var_mac` | MAC address | Auto-generated | base_settings() | Network config |
| `NET` | Network interface (alternative) | `$var_net` | Environment | Network config |
| `BRG` | Bridge interface (alternative) | `$var_bridge` | Environment | Network config |
| `GATE` | Gateway IP (alternative) | `$var_gateway` | Environment | Network config |
| `IPV6_METHOD` | IPv6 configuration method | "none" | Environment | Network config |
| `VLAN` | VLAN ID (alternative) | `$var_vlan` | Environment | Network config |
| `MTU` | MTU size (alternative) | `$var_mtu` | Environment | Network config |
| `MAC` | MAC address (alternative) | `$var_mac` | Environment | Network config |
| Variable | Description | Default | Set In | Used In |
| ------------- | ------------------------------- | -------------- | --------------- | -------------- |
| `var_net` | Network interface | "vmbr0" | base_settings() | Network config |
| `var_bridge` | Bridge interface | "vmbr0" | base_settings() | Network config |
| `var_gateway` | Gateway IP | "192.168.1.1" | base_settings() | Network config |
| `var_ip` | Container IP address | - | User input | Network config |
| `var_ipv6` | IPv6 address | - | User input | Network config |
| `var_vlan` | VLAN ID | - | User input | Network config |
| `var_mtu` | MTU size | "1500" | base_settings() | Network config |
| `var_mac` | MAC address | Auto-generated | base_settings() | Network config |
| `NET` | Network interface (alternative) | `$var_net` | Environment | Network config |
| `BRG` | Bridge interface (alternative) | `$var_bridge` | Environment | Network config |
| `GATE` | Gateway IP (alternative) | `$var_gateway` | Environment | Network config |
| `IPV6_METHOD` | IPv6 configuration method | "none" | Environment | Network config |
| `VLAN` | VLAN ID (alternative) | `$var_vlan` | Environment | Network config |
| `MTU` | MTU size (alternative) | `$var_mtu` | Environment | Network config |
| `MAC` | MAC address (alternative) | `$var_mac` | Environment | Network config |
### Storage Configuration Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `var_template_storage` | Storage for templates | - | select_storage() | Template storage |
| `var_container_storage` | Storage for container disks | - | select_storage() | Container storage |
| `TEMPLATE_STORAGE` | Template storage (alternative) | `$var_template_storage` | Environment | Template storage |
| `CONTAINER_STORAGE` | Container storage (alternative) | `$var_container_storage` | Environment | Container storage |
| Variable | Description | Default | Set In | Used In |
| ----------------------- | ------------------------------- | ------------------------ | ---------------- | ----------------- |
| `var_template_storage` | Storage for templates | - | select_storage() | Template storage |
| `var_container_storage` | Storage for container disks | - | select_storage() | Container storage |
| `TEMPLATE_STORAGE` | Template storage (alternative) | `$var_template_storage` | Environment | Template storage |
| `CONTAINER_STORAGE` | Container storage (alternative) | `$var_container_storage` | Environment | Container storage |
### Feature Flags
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `ENABLE_FUSE` | Enable FUSE support | "true" | base_settings() | Container features |
| `ENABLE_TUN` | Enable TUN/TAP support | "true" | base_settings() | Container features |
| `ENABLE_KEYCTL` | Enable keyctl support | "true" | base_settings() | Container features |
| `ENABLE_MOUNT` | Enable mount support | "true" | base_settings() | Container features |
| `ENABLE_NESTING` | Enable nesting support | "false" | base_settings() | Container features |
| `ENABLE_PRIVILEGED` | Enable privileged mode | "false" | base_settings() | Container features |
| `ENABLE_UNPRIVILEGED` | Enable unprivileged mode | "true" | base_settings() | Container features |
| `VERBOSE` | Enable verbose output | "false" | Environment | Logging |
| `SSH` | Enable SSH key provisioning | "true" | base_settings() | SSH setup |
| Variable | Description | Default | Set In | Used In |
| --------------------- | --------------------------- | ------- | --------------- | ------------------ |
| `ENABLE_FUSE` | Enable FUSE support | "true" | base_settings() | Container features |
| `ENABLE_TUN` | Enable TUN/TAP support | "true" | base_settings() | Container features |
| `ENABLE_KEYCTL` | Enable keyctl support | "true" | base_settings() | Container features |
| `ENABLE_MOUNT` | Enable mount support | "true" | base_settings() | Container features |
| `ENABLE_NESTING` | Enable nesting support | "false" | base_settings() | Container features |
| `ENABLE_PRIVILEGED` | Enable privileged mode | "false" | base_settings() | Container features |
| `ENABLE_UNPRIVILEGED` | Enable unprivileged mode | "true" | base_settings() | Container features |
| `VERBOSE` | Enable verbose output | "false" | Environment | Logging |
| `SSH` | Enable SSH key provisioning | "true" | base_settings() | SSH setup |
### GPU Passthrough Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `GPU_APPS` | List of apps that support GPU | - | Environment | GPU detection |
| `var_gpu` | GPU selection | - | User input | GPU passthrough |
| `var_gpu_type` | GPU type (intel/amd/nvidia) | - | detect_gpu_devices() | GPU passthrough |
| `var_gpu_devices` | GPU device list | - | detect_gpu_devices() | GPU passthrough |
| Variable | Description | Default | Set In | Used In |
| ------------ | ------------------------------- | ------- | ------------------------------------------- | ------------------ |
| `var_gpu` | Enable GPU passthrough | "no" | CT script / Environment / Advanced Settings | GPU passthrough |
| `ENABLE_GPU` | GPU passthrough flag (internal) | "no" | Advanced Settings | Container creation |
**Note**: GPU passthrough is controlled via `var_gpu`. Apps that benefit from GPU acceleration (media servers, AI/ML, transcoding) have `var_gpu=yes` as default in their CT scripts.
**Apps with GPU enabled by default**:
- Media: jellyfin, plex, emby, channels, ersatztv, tunarr, immich
- Transcoding: tdarr, unmanic, fileflows
- AI/ML: ollama, openwebui
- NVR: frigate
**Usage Examples**:
```bash
# Disable GPU for a specific installation
var_gpu=no bash -c "$(curl -fsSL https://...jellyfin.sh)"
# Enable GPU for apps without default GPU support
var_gpu=yes bash -c "$(curl -fsSL https://...debian.sh)"
# Set in default.vars for all apps
echo "var_gpu=yes" >> /usr/local/community-scripts/default.vars
```
### API and Diagnostics Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `DIAGNOSTICS` | Enable diagnostics mode | "false" | Environment | Diagnostics |
| `METHOD` | Installation method | "install" | Environment | Installation flow |
| `RANDOM_UUID` | Random UUID for tracking | - | Environment | Logging |
| `API_TOKEN` | Proxmox API token | - | Environment | API calls |
| `API_USER` | Proxmox API user | - | Environment | API calls |
| Variable | Description | Default | Set In | Used In |
| ------------- | ------------------------ | --------- | ----------- | ----------------- |
| `DIAGNOSTICS` | Enable diagnostics mode | "false" | Environment | Diagnostics |
| `METHOD` | Installation method | "install" | Environment | Installation flow |
| `RANDOM_UUID` | Random UUID for tracking | - | Environment | Logging |
| `API_TOKEN` | Proxmox API token | - | Environment | API calls |
| `API_USER` | Proxmox API user | - | Environment | API calls |
### Settings Persistence Variables
| Variable | Description | Default | Set In | Used In |
|----------|-------------|---------|---------|---------|
| `SAVE_DEFAULTS` | Save settings as defaults | "false" | User input | Settings persistence |
| `SAVE_APP_DEFAULTS` | Save app-specific defaults | "false" | User input | Settings persistence |
| `DEFAULT_VARS_FILE` | Path to default.vars | "/usr/local/community-scripts/default.vars" | Environment | Settings persistence |
| `APP_DEFAULTS_FILE` | Path to app.vars | "/usr/local/community-scripts/defaults/$APP.vars" | Environment | Settings persistence |
| Variable | Description | Default | Set In | Used In |
| ------------------- | -------------------------- | ------------------------------------------------- | ----------- | -------------------- |
| `SAVE_DEFAULTS` | Save settings as defaults | "false" | User input | Settings persistence |
| `SAVE_APP_DEFAULTS` | Save app-specific defaults | "false" | User input | Settings persistence |
| `DEFAULT_VARS_FILE` | Path to default.vars | "/usr/local/community-scripts/default.vars" | Environment | Settings persistence |
| `APP_DEFAULTS_FILE` | Path to app.vars | "/usr/local/community-scripts/defaults/$APP.vars" | Environment | Settings persistence |
## Variable Precedence Chain
@ -152,6 +172,7 @@ export SSH="true"
## Environment Variable Usage Patterns
### 1. Container Creation
```bash
# Basic container creation
export APP="nextcloud"
@ -170,6 +191,7 @@ export var_container_storage="local"
```
### 2. GPU Passthrough
```bash
# Enable GPU passthrough
export GPU_APPS="plex,jellyfin,emby"
@ -178,6 +200,7 @@ export ENABLE_PRIVILEGED="true"
```
### 3. Advanced Network Configuration
```bash
# VLAN and IPv6 configuration
export var_vlan="100"
@ -187,6 +210,7 @@ export var_mtu="9000"
```
### 4. Storage Configuration
```bash
# Custom storage locations
export var_template_storage="nfs-storage"
@ -206,6 +230,7 @@ The script validates variables at several points:
## Common Variable Combinations
### Development Container
```bash
export APP="dev-container"
export CTID="200"
@ -220,6 +245,7 @@ export ENABLE_PRIVILEGED="true"
```
### Media Server with GPU
```bash
export APP="plex"
export CTID="300"
@ -235,6 +261,7 @@ export ENABLE_PRIVILEGED="true"
```
### Lightweight Service
```bash
export APP="nginx"
export CTID="400"

View File

@ -9,30 +9,35 @@ This document provides a comprehensive reference of all functions in `build.func
### Initialization Functions
#### `start()`
**Purpose**: Main entry point when build.func is sourced or executed
**Parameters**: None
**Returns**: None
**Side Effects**:
- Detects execution context (Proxmox host vs container)
- Captures hard environment variables
- Sets CT_TYPE based on context
- Routes to appropriate workflow (install_script or update_script)
**Dependencies**: None
**Environment Variables Used**: `CT_TYPE`, `APP`, `CTID`
**Dependencies**: None
**Environment Variables Used**: `CT_TYPE`, `APP`, `CTID`
#### `variables()`
**Purpose**: Load and resolve all configuration variables using precedence chain
**Parameters**: None
**Returns**: None
**Side Effects**:
- Loads app-specific .vars file
- Loads global default.vars file
- Applies variable precedence chain
- Sets all configuration variables
**Dependencies**: `base_settings()`
**Environment Variables Used**: All configuration variables
**Dependencies**: `base_settings()`
**Environment Variables Used**: All configuration variables
#### `base_settings()`
**Purpose**: Set built-in default values for all configuration variables
**Parameters**: None
**Returns**: None
@ -43,28 +48,33 @@ This document provides a comprehensive reference of all functions in `build.func
### UI and Menu Functions
#### `install_script()`
**Purpose**: Main installation workflow coordinator
**Parameters**: None
**Returns**: None
**Side Effects**:
- Displays installation mode selection menu
- Coordinates the entire installation process
- Handles user interaction and validation
**Dependencies**: `variables()`, `build_container()`, `default_var_settings()`
**Environment Variables Used**: `APP`, `CTID`, `var_hostname`
**Dependencies**: `variables()`, `build_container()`, `default_var_settings()`
**Environment Variables Used**: `APP`, `CTID`, `var_hostname`
#### `advanced_settings()`
**Purpose**: Provide advanced configuration options via whiptail menus
**Parameters**: None
**Returns**: None
**Side Effects**:
- Displays whiptail menus for configuration
- Updates configuration variables based on user input
- Validates user selections
**Dependencies**: `select_storage()`, `detect_gpu_devices()`
**Environment Variables Used**: All configuration variables
**Dependencies**: `select_storage()`, `detect_gpu_devices()`
**Environment Variables Used**: All configuration variables
#### `settings_menu()`
**Purpose**: Display and handle settings configuration menu
**Parameters**: None
**Returns**: None
@ -75,58 +85,68 @@ This document provides a comprehensive reference of all functions in `build.func
### Storage Functions
#### `select_storage()`
**Purpose**: Handle storage selection for templates and containers
**Parameters**: None
**Returns**: None
**Side Effects**:
- Resolves storage preselection
- Prompts user for storage selection if needed
- Validates storage availability
- Sets var_template_storage and var_container_storage
**Dependencies**: `resolve_storage_preselect()`, `choose_and_set_storage_for_file()`
**Environment Variables Used**: `var_template_storage`, `var_container_storage`, `TEMPLATE_STORAGE`, `CONTAINER_STORAGE`
**Dependencies**: `resolve_storage_preselect()`, `choose_and_set_storage_for_file()`
**Environment Variables Used**: `var_template_storage`, `var_container_storage`, `TEMPLATE_STORAGE`, `CONTAINER_STORAGE`
#### `resolve_storage_preselect()`
**Purpose**: Resolve preselected storage options
**Parameters**:
- `storage_type`: Type of storage (template or container)
**Returns**: Storage name if valid, empty if invalid
**Side Effects**: Validates storage availability
**Dependencies**: None
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
**Returns**: Storage name if valid, empty if invalid
**Side Effects**: Validates storage availability
**Dependencies**: None
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
#### `choose_and_set_storage_for_file()`
**Purpose**: Interactive storage selection via whiptail
**Parameters**:
- `storage_type`: Type of storage (template or container)
- `content_type`: Content type (vztmpl or rootdir)
**Returns**: None
**Side Effects**:
**Returns**: None
**Side Effects**:
- Displays whiptail menu
- Updates storage variables
- Validates selection
**Dependencies**: None
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
**Dependencies**: None
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
### Container Creation Functions
#### `build_container()`
**Purpose**: Validate settings and prepare container creation
**Parameters**: None
**Returns**: None
**Side Effects**:
- Validates all configuration
- Checks for conflicts
- Prepares container configuration
- Calls create_lxc_container()
**Dependencies**: `create_lxc_container()`
**Environment Variables Used**: All configuration variables
**Dependencies**: `create_lxc_container()`
**Environment Variables Used**: All configuration variables
#### `create_lxc_container()`
**Purpose**: Create the actual LXC container
**Parameters**: None
**Returns**: None
**Side Effects**:
- Creates LXC container with basic configuration
- Configures network settings
- Sets up storage and mount points
@ -134,108 +154,176 @@ This document provides a comprehensive reference of all functions in `build.func
- Sets resource limits
- Configures startup options
- Starts container
**Dependencies**: `configure_gpu_passthrough()`, `fix_gpu_gids()`
**Environment Variables Used**: All configuration variables
**Dependencies**: `configure_gpu_passthrough()`, `fix_gpu_gids()`
**Environment Variables Used**: All configuration variables
### GPU and Hardware Functions
#### `detect_gpu_devices()`
**Purpose**: Detect available GPU hardware on the system
**Parameters**: None
**Returns**: None
**Side Effects**:
- Scans for Intel, AMD, and NVIDIA GPUs
- Updates var_gpu_type and var_gpu_devices
- Determines GPU capabilities
**Dependencies**: None
**Environment Variables Used**: `var_gpu_type`, `var_gpu_devices`, `GPU_APPS`
**Dependencies**: None
**Environment Variables Used**: `var_gpu_type`, `var_gpu_devices`, `GPU_APPS`
#### `configure_gpu_passthrough()`
**Purpose**: Configure GPU passthrough for the container
**Parameters**: None
**Returns**: None
**Side Effects**:
- Adds GPU device entries to container config
- Configures proper device permissions
- Sets up device mapping
- Updates /etc/pve/lxc/<ctid>.conf
**Dependencies**: `detect_gpu_devices()`
**Environment Variables Used**: `var_gpu`, `var_gpu_type`, `var_gpu_devices`, `CTID`
**Dependencies**: `detect_gpu_devices()`
**Environment Variables Used**: `var_gpu`, `var_gpu_type`, `var_gpu_devices`, `CTID`
#### `fix_gpu_gids()`
**Purpose**: Fix GPU group IDs after container creation
**Parameters**: None
**Returns**: None
**Side Effects**:
- Updates GPU group IDs in container
- Ensures proper GPU access permissions
- Configures video and render groups
**Dependencies**: `configure_gpu_passthrough()`
**Environment Variables Used**: `CTID`, `var_gpu_type`
**Dependencies**: `configure_gpu_passthrough()`
**Environment Variables Used**: `CTID`, `var_gpu_type`
### SSH Configuration Functions
#### `configure_ssh_settings()`
**Purpose**: Interactive SSH key and access configuration wizard
**Parameters**:
- `step_info` (optional): Step indicator string (e.g., "Step 17/19") for consistent dialog headers
**Returns**: None
**Side Effects**:
- Creates temporary file for SSH keys
- Discovers and presents available SSH keys from host
- Allows manual key entry or folder/glob scanning
- Sets `SSH` variable to "yes" or "no" based on user selection
- Sets `SSH_AUTHORIZED_KEY` if manual key provided
- Populates `SSH_KEYS_FILE` with selected keys
**Dependencies**: `ssh_discover_default_files()`, `ssh_build_choices_from_files()`
**Environment Variables Used**: `SSH`, `SSH_AUTHORIZED_KEY`, `SSH_KEYS_FILE`
**SSH Key Source Options**:
1. `found` - Select from auto-detected host keys
2. `manual` - Paste a single public key
3. `folder` - Scan custom folder or glob pattern
4. `none` - No SSH keys
**Note**: The "Enable root SSH access?" dialog is always shown, regardless of whether SSH keys or password are configured. This ensures users can always enable SSH access even with automatic login.
#### `ssh_discover_default_files()`
**Purpose**: Discover SSH public key files on the host system
**Parameters**: None
**Returns**: Array of discovered key file paths
**Side Effects**: Scans common SSH key locations
**Dependencies**: None
**Environment Variables Used**: `var_ssh_import_glob`
#### `ssh_build_choices_from_files()`
**Purpose**: Build whiptail checklist choices from SSH key files
**Parameters**:
- Array of file paths to process
**Returns**: None
**Side Effects**:
- Sets `CHOICES` array for whiptail checklist
- Sets `COUNT` variable with number of keys found
- Creates `MAPFILE` for key tag to content mapping
**Dependencies**: None
**Environment Variables Used**: `CHOICES`, `COUNT`, `MAPFILE`
### Settings Persistence Functions
#### `default_var_settings()`
**Purpose**: Offer to save current settings as defaults
**Parameters**: None
**Returns**: None
**Side Effects**:
- Prompts user to save settings
- Saves to default.vars file
- Saves to app-specific .vars file
**Dependencies**: `maybe_offer_save_app_defaults()`
**Environment Variables Used**: All configuration variables
**Dependencies**: `maybe_offer_save_app_defaults()`
**Environment Variables Used**: All configuration variables
#### `maybe_offer_save_app_defaults()`
**Purpose**: Offer to save app-specific defaults
**Parameters**: None
**Returns**: None
**Side Effects**:
- Prompts user to save app-specific settings
- Saves to app.vars file
- Updates app-specific configuration
**Dependencies**: None
**Environment Variables Used**: `APP`, `SAVE_APP_DEFAULTS`
**Dependencies**: None
**Environment Variables Used**: `APP`, `SAVE_APP_DEFAULTS`
### Utility Functions
#### `validate_settings()`
**Purpose**: Validate all configuration settings
**Parameters**: None
**Returns**: 0 if valid, 1 if invalid
**Side Effects**:
- Checks for configuration conflicts
- Validates resource limits
- Validates network configuration
- Validates storage configuration
**Dependencies**: None
**Environment Variables Used**: All configuration variables
**Dependencies**: None
**Environment Variables Used**: All configuration variables
#### `check_conflicts()`
**Purpose**: Check for configuration conflicts
**Parameters**: None
**Returns**: 0 if no conflicts, 1 if conflicts found
**Side Effects**:
- Checks for conflicting settings
- Validates resource allocation
- Checks network configuration
**Dependencies**: None
**Environment Variables Used**: All configuration variables
**Dependencies**: None
**Environment Variables Used**: All configuration variables
#### `cleanup_on_error()`
**Purpose**: Clean up resources on error
**Parameters**: None
**Returns**: None
**Side Effects**:
- Removes partially created containers
- Cleans up temporary files
- Resets configuration
**Dependencies**: None
**Environment Variables Used**: `CTID`
**Dependencies**: None
**Environment Variables Used**: `CTID`
## Function Call Flow
### Main Installation Flow
```
start()
├── variables()
@ -259,6 +347,7 @@ start()
```
### Error Handling Flow
```
Error Detection
├── validate_settings()
@ -271,24 +360,29 @@ Error Detection
## Function Dependencies
### Core Dependencies
- `start()``install_script()``build_container()``create_lxc_container()`
- `variables()``base_settings()`
- `advanced_settings()``select_storage()``detect_gpu_devices()`
### Storage Dependencies
- `select_storage()``resolve_storage_preselect()`
- `select_storage()``choose_and_set_storage_for_file()`
### GPU Dependencies
- `configure_gpu_passthrough()``detect_gpu_devices()`
- `fix_gpu_gids()``configure_gpu_passthrough()`
### Settings Dependencies
- `default_var_settings()``maybe_offer_save_app_defaults()`
## Function Usage Examples
### Basic Container Creation
```bash
# Set required variables
export APP="plex"
@ -304,6 +398,7 @@ start() # Entry point
```
### Advanced Configuration
```bash
# Set advanced variables
export var_os="debian"
@ -319,6 +414,7 @@ advanced_settings() # Interactive configuration
```
### GPU Passthrough
```bash
# Enable GPU passthrough
export GPU_APPS="plex"
@ -331,6 +427,7 @@ fix_gpu_gids() # Fix permissions
```
### Settings Persistence
```bash
# Save settings as defaults
export SAVE_DEFAULTS="true"
@ -344,15 +441,18 @@ maybe_offer_save_app_defaults() # Save app defaults
## Function Error Handling
### Validation Functions
- `validate_settings()`: Returns 0 for valid, 1 for invalid
- `check_conflicts()`: Returns 0 for no conflicts, 1 for conflicts
### Error Recovery
- `cleanup_on_error()`: Cleans up on any error
- Error codes are propagated up the call stack
- Critical errors cause script termination
### Error Types
1. **Configuration Errors**: Invalid settings or conflicts
2. **Resource Errors**: Insufficient resources or conflicts
3. **Network Errors**: Invalid network configuration

View File

@ -0,0 +1,52 @@
{
"name": "Coolify",
"slug": "coolify",
"categories": [
6
],
"date_created": "2025-12-09",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://coolify.io/docs",
"config_path": "/data/coolify",
"website": "https://coolify.io/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/coolify.webp",
"description": "Coolify is an open-source & self-hostable alternative to Heroku, Netlify, and Vercel. It helps you manage your servers, applications, and databases on your own hardware with Docker. Deploy any application from Git repositories, Docker images, or use pre-built templates.",
"install_methods": [
{
"type": "default",
"script": "ct/coolify.sh",
"resources": {
"cpu": 2,
"ram": 4096,
"hdd": 30,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Initial setup will be done via the web interface on first access.",
"type": "info"
},
{
"text": "Coolify has built-in auto-updates. You can configure update frequency in Settings.",
"type": "info"
},
{
"text": "Coolify requires SSH access to manage deployments. SSH is enabled automatically.",
"type": "info"
},
{
"text": "This container uses Docker-in-Docker (nesting) for application deployments.",
"type": "warning"
}
]
}

View File

@ -0,0 +1,48 @@
{
"name": "Dokploy",
"slug": "dokploy",
"categories": [
6
],
"date_created": "2025-12-09",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 3000,
"documentation": "https://docs.dokploy.com/",
"config_path": "/etc/dokploy",
"website": "https://dokploy.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/png/dokploy.png",
"description": "Dokploy is a free, self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases. Built with Docker and Traefik, it offers features like automatic SSL, Docker Compose support, database backups, and a real-time monitoring dashboard.",
"install_methods": [
{
"type": "default",
"script": "ct/dokploy.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 10,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Initial setup will be done via the web interface on first access.",
"type": "info"
},
{
"text": "Dokploy has built-in auto-updates via the web interface.",
"type": "info"
},
{
"text": "This container uses Docker-in-Docker (nesting) for application deployments.",
"type": "warning"
}
]
}

View File

@ -0,0 +1,35 @@
{
"name": "Speedtest-Tracker",
"slug": "speedtest-tracker",
"categories": [
4
],
"date_created": "2025-12-09",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.speedtest-tracker.dev/",
"website": "https://github.com/alexjustesen/speedtest-tracker",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/speedtest-tracker.webp",
"config_path": "/opt/speedtest-tracker/.env",
"description": "Speedtest Tracker is a self-hosted application that runs scheduled speed tests using the Ookla Speedtest CLI and saves the results to a database for historical tracking and visualization.",
"install_methods": [
{
"type": "default",
"script": "ct/speedtest-tracker.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 4,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "admin@example.com",
"password": "password"
},
"notes": []
}

View File

@ -1,4 +1,214 @@
[
{
"name": "fuma-nama/fumadocs",
"version": "fumadocs-typescript@4.0.14",
"date": "2025-12-09T11:11:49Z"
},
{
"name": "documenso/documenso",
"version": "v2.2.6",
"date": "2025-12-09T10:11:01Z"
},
{
"name": "Infisical/infisical",
"version": "v0.154.5",
"date": "2025-12-09T09:02:17Z"
},
{
"name": "mayanayza/netvisor",
"version": "v0.11.4",
"date": "2025-12-09T06:28:33Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.425",
"date": "2025-12-09T05:59:35Z"
},
{
"name": "mongodb/mongo",
"version": "r7.0.27-rc0",
"date": "2025-12-09T04:34:48Z"
},
{
"name": "ollama/ollama",
"version": "v0.13.2",
"date": "2025-12-08T05:49:52Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.80.9.dev1",
"date": "2025-12-09T01:38:18Z"
},
{
"name": "jeedom/core",
"version": "4.5",
"date": "2025-12-09T00:27:10Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "alexta69/metube",
"version": "2025.12.09",
"date": "2025-12-09T00:16:11Z"
},
{
"name": "Dispatcharr/Dispatcharr",
"version": "v0.14.0",
"date": "2025-12-09T00:04:09Z"
},
{
"name": "metabase/metabase",
"version": "v0.57.x",
"date": "2025-12-08T23:18:26Z"
},
{
"name": "seerr-team/seerr",
"version": "preview-test-fix-subscriptions",
"date": "2025-12-08T23:15:30Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.7",
"date": "2025-12-01T08:14:11Z"
},
{
"name": "sabnzbd/sabnzbd",
"version": "4.5.5",
"date": "2025-10-24T11:12:22Z"
},
{
"name": "home-assistant/core",
"version": "2025.12.2",
"date": "2025-12-08T21:36:42Z"
},
{
"name": "fosrl/pangolin",
"version": "1.13.0-rc.0",
"date": "2025-12-08T21:17:44Z"
},
{
"name": "Dokploy/dokploy",
"version": "v0.26.0",
"date": "2025-12-08T20:44:09Z"
},
{
"name": "hansmi/prometheus-paperless-exporter",
"version": "v0.0.9",
"date": "2025-12-08T20:37:45Z"
},
{
"name": "influxdata/telegraf",
"version": "v1.37.0",
"date": "2025-12-08T20:36:16Z"
},
{
"name": "pommee/goaway",
"version": "v0.62.23",
"date": "2025-12-08T20:30:54Z"
},
{
"name": "TuroYT/snowshare",
"version": "v1.1.2",
"date": "2025-12-08T20:29:51Z"
},
{
"name": "coollabsio/coolify",
"version": "v4.0.0-beta.453",
"date": "2025-12-08T20:23:48Z"
},
{
"name": "n8n-io/n8n",
"version": "n8n@1.123.4",
"date": "2025-12-08T13:30:40Z"
},
{
"name": "homarr-labs/homarr",
"version": "v1.45.3",
"date": "2025-12-08T16:11:16Z"
},
{
"name": "joaovitoriasilva/endurain",
"version": "v0.16.0-RC2",
"date": "2025-12-08T15:54:38Z"
},
{
"name": "AdguardTeam/AdGuardHome",
"version": "v0.107.71",
"date": "2025-12-08T14:34:55Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v0.22.18",
"date": "2025-12-08T14:26:24Z"
},
{
"name": "openobserve/openobserve",
"version": "v0.30.0-rc1",
"date": "2025-12-08T13:29:14Z"
},
{
"name": "wavelog/wavelog",
"version": "2.2.1",
"date": "2025-12-08T12:01:34Z"
},
{
"name": "fccview/jotty",
"version": "1.12.1",
"date": "2025-12-08T11:59:19Z"
},
{
"name": "ventoy/Ventoy",
"version": "v1.1.08",
"date": "2025-12-08T10:13:51Z"
},
{
"name": "zitadel/zitadel",
"version": "v4.7.1",
"date": "2025-12-08T10:05:21Z"
},
{
"name": "meilisearch/meilisearch",
"version": "latest",
"date": "2025-12-08T09:36:54Z"
},
{
"name": "WGDashboard/WGDashboard",
"version": "v4.3.0.2",
"date": "2025-12-08T09:01:37Z"
},
{
"name": "mattermost/mattermost",
"version": "v10.11.8",
"date": "2025-11-21T17:06:07Z"
},
{
"name": "nzbgetcom/nzbget",
"version": "v25.4",
"date": "2025-10-09T10:27:01Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.9",
"date": "2025-11-28T20:36:20Z"
},
{
"name": "maxdorninger/MediaManager",
"version": "v1.10.0",
"date": "2025-12-07T23:41:51Z"
},
{
"name": "nickheyer/discopanel",
"version": "v1.0.12-dev",
"date": "2025-12-07T22:56:11Z"
},
{
"name": "Part-DB/Part-DB-server",
"version": "v2.3.0",
@ -9,61 +219,31 @@
"version": "v6.11.1",
"date": "2025-12-07T19:19:08Z"
},
{
"name": "firefly-iii/firefly-iii",
"version": "v6.4.9",
"date": "2025-11-28T20:36:20Z"
},
{
"name": "seerr-team/seerr",
"version": "preview-test-fix-subscriptions",
"date": "2025-12-07T14:31:55Z"
},
{
"name": "bluenviron/mediamtx",
"version": "v1.15.5",
"date": "2025-12-07T12:24:21Z"
},
{
"name": "morpheus65535/bazarr",
"version": "v1.5.3",
"date": "2025-09-20T12:12:33Z"
"name": "livebook-dev/livebook",
"version": "v0.18.1",
"date": "2025-12-07T11:35:51Z"
},
{
"name": "Jackett/Jackett",
"version": "v0.24.415",
"date": "2025-12-07T05:56:32Z"
},
{
"name": "BerriAI/litellm",
"version": "v1.80.8.rc.1",
"date": "2025-12-07T01:36:40Z"
"name": "ghostfolio/ghostfolio",
"version": "2.222.0",
"date": "2025-12-07T09:09:47Z"
},
{
"name": "umami-software/umami",
"version": "v2.20.1",
"date": "2025-12-07T01:14:23Z"
},
{
"name": "steveiliop56/tinyauth",
"version": "v4.1.0",
"date": "2025-11-23T12:13:34Z"
},
{
"name": "jeedom/core",
"version": "4.5",
"date": "2025-12-07T00:27:06Z"
},
{
"name": "sysadminsmedia/homebox",
"version": "v0.22.0-rc.2",
"date": "2025-12-06T21:24:28Z"
},
{
"name": "keycloak/keycloak",
"version": "26.4.7",
"date": "2025-12-01T08:14:11Z"
},
{
"name": "Koenkk/zigbee2mqtt",
"version": "2.7.1",
@ -90,9 +270,9 @@
"date": "2025-12-06T14:31:36Z"
},
{
"name": "fuma-nama/fumadocs",
"version": "fumadocs-openapi@10.1.1",
"date": "2025-12-06T11:27:58Z"
"name": "prometheus/blackbox_exporter",
"version": "v0.28.0",
"date": "2025-12-06T13:32:18Z"
},
{
"name": "YunoHost/yunohost",
@ -124,35 +304,15 @@
"version": "v13.1.3",
"date": "2025-12-06T04:40:09Z"
},
{
"name": "ollama/ollama",
"version": "v0.13.2-rc1",
"date": "2025-12-04T23:19:06Z"
},
{
"name": "Stirling-Tools/Stirling-PDF",
"version": "v2.1.1",
"date": "2025-12-05T23:48:08Z"
},
{
"name": "chrisbenincasa/tunarr",
"version": "v0.23.0-alpha.30",
"date": "2025-12-05T21:23:38Z"
},
{
"name": "home-assistant/core",
"version": "2025.12.1",
"date": "2025-12-05T21:10:31Z"
},
{
"name": "n8n-io/n8n",
"version": "n8n@1.122.5",
"date": "2025-12-04T14:09:39Z"
},
{
"name": "homarr-labs/homarr",
"version": "v1.45.2",
"date": "2025-12-05T19:17:09Z"
"name": "HydroshieldMKII/Guardian",
"version": "v1.3.1",
"date": "2025-12-05T19:12:48Z"
},
{
"name": "booklore-app/booklore",
@ -164,6 +324,11 @@
"version": "v1.92.1",
"date": "2025-12-05T15:53:22Z"
},
{
"name": "community-scripts/ProxmoxVE-Local",
"version": "v0.5.2",
"date": "2025-12-05T15:13:46Z"
},
{
"name": "FlowiseAI/Flowise",
"version": "flowise@3.0.12",
@ -190,20 +355,15 @@
"date": "2025-12-05T09:58:17Z"
},
{
"name": "alexta69/metube",
"version": "2025.12.05",
"date": "2025-12-05T09:45:02Z"
"name": "alam00000/bentopdf",
"version": "v1.10.5",
"date": "2025-12-05T09:28:50Z"
},
{
"name": "esphome/esphome",
"version": "2025.11.4",
"date": "2025-12-05T03:54:58Z"
},
{
"name": "documenso/documenso",
"version": "v2.2.4",
"date": "2025-12-05T01:23:23Z"
},
{
"name": "transmission/transmission",
"version": "4.0.1-beta.1",
@ -224,16 +384,16 @@
"version": "v1.30.20",
"date": "2025-12-04T18:17:47Z"
},
{
"name": "AdguardTeam/AdGuardHome",
"version": "v0.107.70",
"date": "2025-12-03T16:12:15Z"
},
{
"name": "wazuh/wazuh",
"version": "coverity-w49-4.14.2",
"date": "2025-12-02T14:01:48Z"
},
{
"name": "valkey-io/valkey",
"version": "8.1.5",
"date": "2025-12-04T15:26:01Z"
},
{
"name": "crowdsecurity/crowdsec",
"version": "v1.7.4",
@ -244,6 +404,11 @@
"version": "v0.34.2",
"date": "2025-12-04T13:08:18Z"
},
{
"name": "qdrant/qdrant",
"version": "v1.16.2",
"date": "2025-12-04T11:03:49Z"
},
{
"name": "glpi-project/glpi",
"version": "11.0.4",
@ -299,11 +464,6 @@
"version": "v25.11.5",
"date": "2025-12-03T14:51:03Z"
},
{
"name": "meilisearch/meilisearch",
"version": "latest",
"date": "2025-12-03T14:19:01Z"
},
{
"name": "Graylog2/graylog2-server",
"version": "6.2.10",
@ -320,14 +480,9 @@
"date": "2025-12-03T06:48:38Z"
},
{
"name": "mattermost/mattermost",
"version": "v10.11.8",
"date": "2025-11-21T17:06:07Z"
},
{
"name": "openobserve/openobserve",
"version": "v0.20.2",
"date": "2025-12-03T02:20:57Z"
"name": "comfyanonymous/ComfyUI",
"version": "v0.3.77",
"date": "2025-12-03T05:02:09Z"
},
{
"name": "hyperion-project/hyperion.ng",
@ -389,11 +544,6 @@
"version": "jenkins-2.540",
"date": "2025-12-02T16:56:49Z"
},
{
"name": "nzbgetcom/nzbget",
"version": "v25.4",
"date": "2025-10-09T10:27:01Z"
},
{
"name": "docker/compose",
"version": "v5.0.0",
@ -439,6 +589,11 @@
"version": "v0.16.0",
"date": "2025-12-01T21:35:19Z"
},
{
"name": "martabal/qbittorrent-exporter",
"version": "v1.13.0",
"date": "2025-12-01T21:06:38Z"
},
{
"name": "slskd/slskd",
"version": "0.24.1",
@ -464,6 +619,11 @@
"version": "0.211.0",
"date": "2025-12-01T11:22:11Z"
},
{
"name": "opencloud-eu/opencloud",
"version": "v4.0.0",
"date": "2025-12-01T09:33:08Z"
},
{
"name": "cockpit-project/cockpit",
"version": "310.6",
@ -519,11 +679,6 @@
"version": "v11.8.2",
"date": "2025-11-30T08:39:28Z"
},
{
"name": "pommee/goaway",
"version": "v0.62.20",
"date": "2025-11-30T06:51:31Z"
},
{
"name": "MediaBrowser/Emby.Releases",
"version": "4.9.1.90",
@ -649,6 +804,11 @@
"version": "v0.25.3",
"date": "2025-11-25T15:40:41Z"
},
{
"name": "LimeSurvey/LimeSurvey",
"version": "6.16.0+251120",
"date": "2025-11-25T14:21:59Z"
},
{
"name": "TandoorRecipes/recipes",
"version": "2.3.6",
@ -679,16 +839,16 @@
"version": "v1.18.0",
"date": "2025-11-23T17:42:53Z"
},
{
"name": "wavelog/wavelog",
"version": "2.2",
"date": "2025-11-23T17:32:38Z"
},
{
"name": "crafty-controller/crafty-4",
"version": "v4.6.1",
"date": "2025-11-23T16:42:50Z"
},
{
"name": "dedicatedcode/reitti",
"version": "v2.5.0",
"date": "2025-11-23T12:49:50Z"
},
{
"name": "go-gitea/gitea",
"version": "v1.25.2",
@ -724,11 +884,6 @@
"version": "5.2.4",
"date": "2025-11-21T10:25:05Z"
},
{
"name": "sabnzbd/sabnzbd",
"version": "4.5.5",
"date": "2025-10-24T11:12:22Z"
},
{
"name": "MariaDB/server",
"version": "mariadb-12.1.2",
@ -799,6 +954,11 @@
"version": "v7.5.0",
"date": "2025-11-19T08:36:29Z"
},
{
"name": "PatchMon/PatchMon",
"version": "v1.3.6",
"date": "2025-11-18T22:01:02Z"
},
{
"name": "redis/redis",
"version": "8.4.0",
@ -809,6 +969,11 @@
"version": "v2.13.5",
"date": "2025-11-18T11:47:48Z"
},
{
"name": "Hosteroid/domain-monitor",
"version": "v1.1.1",
"date": "2025-11-18T11:32:30Z"
},
{
"name": "PCJones/UmlautAdaptarr",
"version": "v0.7.5",
@ -820,9 +985,14 @@
"date": "2025-11-18T05:51:46Z"
},
{
"name": "influxdata/telegraf",
"version": "v1.36.4",
"date": "2025-11-17T17:15:29Z"
"name": "passbolt/passbolt_api",
"version": "v5.7.2",
"date": "2025-11-17T15:17:55Z"
},
{
"name": "librenms/librenms",
"version": "25.11.0",
"date": "2025-11-17T13:29:57Z"
},
{
"name": "rabbitmq/rabbitmq-server",
@ -870,9 +1040,9 @@
"date": "2025-11-15T04:36:48Z"
},
{
"name": "zitadel/zitadel",
"version": "v4.7.0",
"date": "2025-11-14T09:45:13Z"
"name": "Lissy93/domain-locker",
"version": "v0.1.2",
"date": "2025-11-14T22:08:23Z"
},
{
"name": "runtipi/runtipi",
@ -889,6 +1059,11 @@
"version": "v1.0.25",
"date": "2025-11-12T16:57:54Z"
},
{
"name": "jason5ng32/MyIP",
"version": "v5.1.0",
"date": "2025-11-12T10:44:24Z"
},
{
"name": "moghtech/komodo",
"version": "v1.19.5",
@ -944,6 +1119,11 @@
"version": "v4.52.0",
"date": "2025-11-06T22:39:26Z"
},
{
"name": "deuxfleurs-org/garage",
"version": "v1.99.3-internal",
"date": "2025-11-06T17:27:21Z"
},
{
"name": "Notifiarr/notifiarr",
"version": "v0.9.1",
@ -969,6 +1149,11 @@
"version": "1.5.0",
"date": "2025-11-05T11:10:20Z"
},
{
"name": "SonarSource/sonarqube",
"version": "25.11.0.114957",
"date": "2025-11-05T10:26:59Z"
},
{
"name": "nicolargo/glances",
"version": "v4.4.1",
@ -999,16 +1184,16 @@
"version": "v3.0.9",
"date": "2025-11-04T07:28:45Z"
},
{
"name": "maxdorninger/MediaManager",
"version": "v1.9.1",
"date": "2025-11-02T21:14:50Z"
},
{
"name": "motioneye-project/motioneye",
"version": "0.42.1",
"date": "2020-06-07T07:27:04Z"
},
{
"name": "wanetty/upgopher",
"version": "v1.12.0",
"date": "2025-11-01T14:32:38Z"
},
{
"name": "zabbix/zabbix",
"version": "7.4.5",
@ -1024,16 +1209,16 @@
"version": "v1.10.1",
"date": "2025-10-31T08:25:57Z"
},
{
"name": "mongodb/mongo",
"version": "r7.0.26",
"date": "2025-10-30T18:44:14Z"
},
{
"name": "sassanix/Warracker",
"version": "1.0.2",
"date": "2025-10-30T18:23:23Z"
},
{
"name": "LogicLabs-OU/OpenArchiver",
"version": "v0.4.0",
"date": "2025-10-30T16:35:23Z"
},
{
"name": "homebridge/homebridge",
"version": "v1.11.1",
@ -1054,6 +1239,11 @@
"version": "v3.0.0-beta.2",
"date": "2025-10-28T10:16:29Z"
},
{
"name": "bakito/adguardhome-sync",
"version": "v0.8.2",
"date": "2025-10-24T17:13:47Z"
},
{
"name": "drakkan/sftpgo",
"version": "v2.7.0",
@ -1064,6 +1254,11 @@
"version": "v0.8.8.3",
"date": "2025-10-23T12:31:49Z"
},
{
"name": "miniflux/v2",
"version": "2.2.14",
"date": "2025-10-23T02:12:05Z"
},
{
"name": "louislam/uptime-kuma",
"version": "2.0.2",
@ -1119,6 +1314,11 @@
"version": "v1.5.9",
"date": "2025-10-06T08:34:01Z"
},
{
"name": "donetick/donetick",
"version": "v0.1.64",
"date": "2025-10-03T05:18:24Z"
},
{
"name": "MagicMirrorOrg/MagicMirror",
"version": "v2.33.0",
@ -1164,6 +1364,11 @@
"version": "v0.17.0",
"date": "2025-09-19T22:23:28Z"
},
{
"name": "Flomp/wanderer",
"version": "v0.18.3",
"date": "2025-09-19T16:16:11Z"
},
{
"name": "docmost/docmost",
"version": "v0.23.2",
@ -1179,11 +1384,6 @@
"version": "v0.23.0",
"date": "2025-09-17T10:15:51Z"
},
{
"name": "WGDashboard/WGDashboard",
"version": "v4.3.0.1",
"date": "2025-09-17T08:50:39Z"
},
{
"name": "Checkmk/checkmk",
"version": "v2.4.0p12",
@ -1204,6 +1404,11 @@
"version": "v0.8.1",
"date": "2025-09-14T06:45:23Z"
},
{
"name": "ThePhaseless/Byparr",
"version": "v2.0.1",
"date": "2025-09-11T20:29:38Z"
},
{
"name": "zerotier/ZeroTierOne",
"version": "1.16.0",
@ -1249,11 +1454,6 @@
"version": "0.6.25",
"date": "2025-08-24T08:51:55Z"
},
{
"name": "ventoy/Ventoy",
"version": "v1.1.07",
"date": "2025-08-18T16:13:54Z"
},
{
"name": "lldap/lldap",
"version": "v0.6.2",
@ -1309,6 +1509,11 @@
"version": "1.34.3",
"date": "2025-07-30T09:10:59Z"
},
{
"name": "eko/pihole-exporter",
"version": "v1.2.0",
"date": "2025-07-29T19:15:37Z"
},
{
"name": "caddyserver/xcaddy",
"version": "v0.4.5",
@ -1364,11 +1569,6 @@
"version": "v1.13.0",
"date": "2025-05-25T20:21:13Z"
},
{
"name": "hansmi/prometheus-paperless-exporter",
"version": "v0.0.8",
"date": "2025-05-18T11:37:31Z"
},
{
"name": "stackblitz-labs/bolt.diy",
"version": "1.0.0",
@ -1384,6 +1584,11 @@
"version": "2025-05-07-r1",
"date": "2025-05-07T12:18:42Z"
},
{
"name": "CyferShepard/Jellystat",
"version": "1.1.6",
"date": "2025-05-01T17:11:00Z"
},
{
"name": "dotnetfactory/fluid-calendar",
"version": "v1.4.0",
@ -1543,10 +1748,5 @@
"name": "thelounge/thelounge-deb",
"version": "v4.4.3",
"date": "2024-04-06T12:24:35Z"
},
{
"name": "deepch/RTSPtoWeb",
"version": "v2.4.3",
"date": "2023-03-29T12:05:02Z"
}
]

View File

@ -34,7 +34,7 @@ export default function CodeCopyButton({
localStorage.setItem("warning", "1");
setTimeout(() => {
toast.error(
"Be careful when copying scripts from the internet. Always remember check the source!",
"Be careful when copying scripts from the internet. Always remember to check the source!",
{ duration: 8000 },
);
}, 500);

View File

@ -0,0 +1,39 @@
#!/bin/bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://coolify.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 install -y \
git \
openssl
msg_ok "Installed Dependencies"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://coolify.io/)."
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://cdn.coollabs.io/coolify/install.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
msg_info "Installing Coolify (Patience - this installs Docker and pulls containers)"
$STD bash <(curl -fsSL https://cdn.coollabs.io/coolify/install.sh)
msg_ok "Installed Coolify"
motd_ssh
customize
cleanup_lxc

View File

@ -0,0 +1,39 @@
#!/bin/bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://dokploy.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 \
git \
openssl
msg_ok "Installed Dependencies"
msg_warn "WARNING: This script will run an external installer from a third-party source (https://dokploy.com/)."
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://dokploy.com/install.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
msg_info "Installing Dokploy (Patience - this installs Docker and pulls containers)"
$STD bash <(curl -sSL https://dokploy.com/install.sh)
msg_ok "Installed Dokploy"
motd_ssh
customize
cleanup_lxc

View File

@ -0,0 +1,162 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: AlphaLawless
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/alexjustesen/speedtest-tracker
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
nginx \
sqlite3
msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="common,sqlite3,redis" setup_php
setup_composer
NODE_VERSION="22" setup_nodejs
import_local_ip
fetch_and_deploy_gh_release "speedtest-tracker" "alexjustesen/speedtest-tracker" "tarball" "latest" "/opt/speedtest-tracker"
msg_info "Installing Speedtest CLI"
setup_deb822_repo \
"speedtest-cli" \
"https://packagecloud.io/ookla/speedtest-cli/gpgkey" \
"https://packagecloud.io/ookla/speedtest-cli/debian" \
"$(get_os_info codename)" \
"main"
$STD apt install -y speedtest
msg_ok "Installed Speedtest CLI"
msg_info "Configuring PHP-FPM runtime directory"
mkdir -p /etc/systemd/system/php8.4-fpm.service.d/
cat <<EOF >/etc/systemd/system/php8.4-fpm.service.d/override.conf
[Service]
RuntimeDirectory=php
RuntimeDirectoryMode=0755
EOF
msg_ok "Configured PHP-FPM runtime directory"
msg_info "Setting up Speedtest Tracker"
cd /opt/speedtest-tracker
APP_KEY=$(php -r "echo bin2hex(random_bytes(16));")
TIMEZONE=$(timedatectl | grep "Time zone" | awk '{print $3}')
cat <<EOF >/opt/speedtest-tracker/.env
APP_NAME="Speedtest Tracker"
APP_ENV=production
APP_TIMEZONE=${TIMEZONE}
APP_KEY=base64:$(echo -n $APP_KEY | base64)
APP_DEBUG=false
APP_URL=http://${LOCAL_IP}
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=sqlite
DB_DATABASE=/opt/speedtest-tracker/database/database.sqlite
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
SPEEDTEST_SCHEDULE="0 */6 * * *"
SPEEDTEST_SERVERS=
PRUNE_RESULTS_OLDER_THAN=0
DISPLAY_TIMEZONE=${TIMEZONE}
EOF
mkdir -p /opt/speedtest-tracker/database
touch /opt/speedtest-tracker/database/database.sqlite
export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --optimize-autoloader --no-dev
$STD npm ci
$STD npm run build
$STD php artisan key:generate --force
$STD php artisan migrate --force --seed
$STD php artisan config:clear
$STD php artisan cache:clear
$STD php artisan view:clear
chown -R www-data:www-data /opt/speedtest-tracker
chmod -R 755 /opt/speedtest-tracker/storage
chmod -R 755 /opt/speedtest-tracker/bootstrap/cache
msg_ok "Set up Speedtest Tracker"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/speedtest-tracker.service
[Unit]
Description=Speedtest Tracker Queue Worker
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /opt/speedtest-tracker/artisan queue:work --sleep=3 --tries=3 --max-time=3600
WorkingDirectory=/opt/speedtest-tracker
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now speedtest-tracker
msg_ok "Created Service"
msg_info "Setting up Scheduler"
cat <<EOF >/etc/cron.d/speedtest-tracker
* * * * * www-data cd /opt/speedtest-tracker && php artisan schedule:run >> /dev/null 2>&1
EOF
msg_ok "Set up Scheduler"
msg_info "Configuring Nginx"
cat <<EOF >/etc/nginx/sites-available/speedtest-tracker
server {
listen 80;
server_name _;
root /opt/speedtest-tracker/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
ln -sf /etc/nginx/sites-available/speedtest-tracker /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
systemctl reload nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc

View File

@ -32,28 +32,10 @@ msg_ok "Installed Dependencies"
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "tandoor" "TandoorRecipes/recipes" "tarball" "latest" "/opt/tandoor"
PG_VERSION="17" PG_MODULES="contrib" setup_postgresql
PG_VERSION="17" setup_postgresql
PYTHON_VERSION="3.13" setup_uv
msg_info "Set up PostgreSQL Database"
DB_NAME=db_recipes
DB_USER=tandoor
PG_DB_USER="tandoor" PG_DB_NAME="db_recipes" PG_DB_EXTENSIONS="unaccent,pg_trgm" setup_postgresql_db
SECRET_KEY=$(openssl rand -base64 45 | sed 's/\//\\\//g')
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 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'"
$STD sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS unaccent;"
$STD sudo -u postgres psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS pg_trgm;"
{
echo "Tandoor-Credentials"
echo "Tandoor Database Name: $DB_NAME"
echo "Tandoor Database User: $DB_USER"
echo "Tandoor Database Password: $DB_PASS"
} >>~/tandoor.creds
msg_ok "Set up PostgreSQL Database"
msg_info "Setup Tandoor"
mkdir -p /opt/tandoor/{config,api,mediafiles,staticfiles}
@ -69,16 +51,16 @@ TZ=Europe/Berlin
DB_ENGINE=django.db.backends.postgresql
POSTGRES_HOST=localhost
POSTGRES_DB=$DB_NAME
POSTGRES_DB=$PG_DB_NAME
POSTGRES_PORT=5432
POSTGRES_USER=$DB_USER
POSTGRES_PASSWORD=$DB_PASS
POSTGRES_USER=$PG_DB_USER
POSTGRES_PASSWORD=$PG_DB_PASS
STATIC_URL=/staticfiles/
MEDIA_URL=/media/
EOF
TANDOOR_VERSION="$(curl -s https://api.github.com/repos/TandoorRecipes/recipes/releases/latest | jq -r .tag_name)"
TANDOOR_VERSION=$(get_latest_github_release "TandoorRecipes/recipes")
cat <<EOF >/opt/tandoor/cookbook/version_info.py
TANDOOR_VERSION = "$TANDOOR_VERSION"
TANDOOR_REF = "bare-metal"

View File

@ -453,7 +453,7 @@ load_vars_file() {
# Allowed var_* keys
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_keyctl
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_gpu var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
@ -505,7 +505,7 @@ default_var_settings() {
# Allowed var_* keys (alphabetically sorted)
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
local VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_keyctl
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_gpu var_keyctl
var_gateway var_hostname var_ipv6_method var_mac var_mknod var_mount_fs var_mtu
var_net var_nesting var_ns var_protection var_pw var_ram var_tags var_timezone var_tun var_unprivileged
var_verbose var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
@ -667,7 +667,7 @@ get_app_defaults_path() {
if ! declare -p VAR_WHITELIST >/dev/null 2>&1; then
# Note: Removed var_ctid (can only exist once), var_ipv6_static (static IPs are unique)
declare -ag VAR_WHITELIST=(
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_gpu
var_gateway var_hostname var_ipv6_method var_mac var_mtu
var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged
var_verbose var_vlan var_ssh var_ssh_authorized_key var_container_storage var_template_storage
@ -1011,7 +1011,7 @@ advanced_settings() {
# Initialize defaults
TAGS="community-script;${var_tags:-}"
local STEP=1
local MAX_STEP=19
local MAX_STEP=20
# Store values for back navigation
local _ct_type="${CT_TYPE:-1}"
@ -1036,6 +1036,7 @@ advanced_settings() {
local _vlan=""
local _tags="$TAGS"
local _enable_fuse="no"
local _enable_gpu="${var_gpu:-no}"
local _verbose="no"
local _enable_keyctl="0"
local _enable_mknod="0"
@ -1491,7 +1492,7 @@ advanced_settings() {
# STEP 17: SSH Settings
# ═══════════════════════════════════════════════════════════════════════════
17)
configure_ssh_settings
configure_ssh_settings "Step $STEP/$MAX_STEP"
# configure_ssh_settings handles its own flow, always advance
((STEP++))
;;
@ -1527,9 +1528,33 @@ advanced_settings() {
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 19: Confirmation
# STEP 19: GPU Passthrough
# ═══════════════════════════════════════════════════════════════════════════
19)
local gpu_default="OFF"
[[ "$_enable_gpu" == "yes" ]] && gpu_default="ON"
if whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "GPU PASSTHROUGH" \
--ok-button "Next" --cancel-button "Back" \
--defaultno \
--yesno "\nEnable GPU Passthrough?\n\nAutomatically detects and passes through available GPUs\n(Intel/AMD/NVIDIA) for hardware acceleration.\n\nRecommended for: Media servers, AI/ML, Transcoding" 14 62; then
_enable_gpu="yes"
else
if [ $? -eq 1 ]; then
_enable_gpu="no"
else
((STEP--))
continue
fi
fi
((STEP++))
;;
# ═══════════════════════════════════════════════════════════════════════════
# STEP 20: Confirmation
# ═══════════════════════════════════════════════════════════════════════════
20)
# Build summary
local ct_type_desc="Unprivileged"
[[ "$_ct_type" == "0" ]] && ct_type_desc="Privileged"
@ -1550,12 +1575,13 @@ Network:
Options:
FUSE: $_enable_fuse
GPU Passthrough: $_enable_gpu
Verbose: $_verbose"
if whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \
--title "CONFIRM SETTINGS" \
--ok-button "Create LXC" --cancel-button "Back" \
--yesno "$summary\n\nCreate ${APP} LXC with these settings?" 26 58; then
--yesno "$summary\n\nCreate ${APP} LXC with these settings?" 28 58; then
((STEP++))
else
((STEP--))
@ -1582,8 +1608,12 @@ Options:
IPV6_GATE="$_ipv6_gate"
TAGS="$_tags"
ENABLE_FUSE="$_enable_fuse"
ENABLE_GPU="$_enable_gpu"
VERBOSE="$_verbose"
# Update var_gpu based on user choice (for is_gpu_app function)
var_gpu="$_enable_gpu"
# Format optional values
[[ -n "$_mtu" ]] && MTU=",mtu=$_mtu" || MTU=""
[[ -n "$_sd" ]] && SD="-searchdomain=$_sd" || SD=""
@ -1600,6 +1630,10 @@ Options:
export UDHCPC_FIX
export SSH_KEYS_FILE
# Exit alternate screen buffer before showing summary (so output remains visible)
tput rmcup 2>/dev/null || true
trap - RETURN
# Display final summary
echo -e "\n${INFO}${BOLD}${DGN}PVE Version ${PVEVERSION} (Kernel: ${KERNEL_VERSION})${CL}"
echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}$var_os${CL}"
@ -1614,6 +1648,7 @@ Options:
echo -e "${NETWORK}${BOLD}${DGN}IPv4: ${BGN}$NET${CL}"
echo -e "${NETWORK}${BOLD}${DGN}IPv6: ${BGN}$IPV6_METHOD${CL}"
echo -e "${FUSE}${BOLD}${DGN}FUSE Support: ${BGN}$ENABLE_FUSE${CL}"
echo -e "${GPU}${BOLD}${DGN}GPU Passthrough: ${BGN}$ENABLE_GPU${CL}"
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}$VERBOSE${CL}"
echo -e "${CREATING}${BOLD}${RD}Creating a ${APP} LXC using the above advanced settings${CL}"
}
@ -1736,6 +1771,9 @@ echo_default() {
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE} GB${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE} MiB${CL}"
if [[ -n "${var_gpu:-}" && "${var_gpu}" == "yes" ]]; then
echo -e "${GPU}${BOLD}${DGN}GPU Passthrough: ${BGN}Enabled${CL}"
fi
if [ "$VERBOSE" == "yes" ]; then
echo -e "${SEARCH}${BOLD}${DGN}Verbose Mode: ${BGN}Enabled${CL}"
fi
@ -2076,6 +2114,10 @@ ssh_discover_default_files() {
}
configure_ssh_settings() {
local step_info="${1:-}"
local backtitle="Proxmox VE Helper Scripts"
[[ -n "$step_info" ]] && backtitle="Proxmox VE Helper Scripts [${step_info}]"
SSH_KEYS_FILE="$(mktemp)"
: >"$SSH_KEYS_FILE"
@ -2085,14 +2127,14 @@ configure_ssh_settings() {
local ssh_key_mode
if [[ "$default_key_count" -gt 0 ]]; then
ssh_key_mode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
"Provision SSH keys for root:" 14 72 4 \
"found" "Select from detected keys (${default_key_count})" \
"manual" "Paste a single public key" \
"folder" "Scan another folder (path or glob)" \
"none" "No keys" 3>&1 1>&2 2>&3) || exit_script
else
ssh_key_mode=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SSH KEY SOURCE" --menu \
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
"No host keys detected; choose manual/none:" 12 72 2 \
"manual" "Paste a single public key" \
"none" "No keys" 3>&1 1>&2 2>&3) || exit_script
@ -2101,7 +2143,7 @@ configure_ssh_settings() {
case "$ssh_key_mode" in
found)
local selection
selection=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT HOST KEYS" \
selection=$(whiptail --backtitle "$backtitle" --title "SELECT HOST KEYS" \
--checklist "Select one or more keys to import:" 20 140 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
for tag in $selection; do
tag="${tag%\"}"
@ -2112,13 +2154,13 @@ configure_ssh_settings() {
done
;;
manual)
SSH_AUTHORIZED_KEY="$(whiptail --backtitle "Proxmox VE Helper Scripts" \
SSH_AUTHORIZED_KEY="$(whiptail --backtitle "$backtitle" \
--inputbox "Paste one SSH public key line (ssh-ed25519/ssh-rsa/...)" 10 72 --title "SSH Public Key" 3>&1 1>&2 2>&3)"
[[ -n "$SSH_AUTHORIZED_KEY" ]] && printf '%s\n' "$SSH_AUTHORIZED_KEY" >>"$SSH_KEYS_FILE"
;;
folder)
local glob_path
glob_path=$(whiptail --backtitle "Proxmox VE Helper Scripts" \
glob_path=$(whiptail --backtitle "$backtitle" \
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub)" 10 72 --title "Scan Folder/Glob" 3>&1 1>&2 2>&3)
if [[ -n "$glob_path" ]]; then
shopt -s nullglob
@ -2128,7 +2170,7 @@ configure_ssh_settings() {
ssh_build_choices_from_files "${_scan_files[@]}"
if [[ "$COUNT" -gt 0 ]]; then
local folder_selection
folder_selection=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT FOLDER KEYS" \
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
--checklist "Select key(s) to import:" 20 78 10 "${CHOICES[@]}" 3>&1 1>&2 2>&3) || exit_script
for tag in $folder_selection; do
tag="${tag%\"}"
@ -2138,10 +2180,10 @@ configure_ssh_settings() {
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$SSH_KEYS_FILE"
done
else
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox "No keys found in: $glob_path" 8 60
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
fi
else
whiptail --backtitle "Proxmox VE Helper Scripts" --msgbox "Path/glob returned no files." 8 60
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
fi
fi
;;
@ -2155,12 +2197,9 @@ configure_ssh_settings() {
printf '\n' >>"$SSH_KEYS_FILE"
fi
if [[ -s "$SSH_KEYS_FILE" || "$PW" == -password* ]]; then
if (whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH ACCESS" --yesno "Enable root SSH access?" 10 58); then
SSH="yes"
else
SSH="no"
fi
# Always show SSH access dialog - user should be able to enable SSH even without keys
if (whiptail --backtitle "$backtitle" --defaultno --title "SSH ACCESS" --yesno "Enable root SSH access?" 10 58); then
SSH="yes"
else
SSH="no"
fi
@ -2387,21 +2426,15 @@ build_container() {
# GPU/USB PASSTHROUGH CONFIGURATION
# ============================================================================
# List of applications that benefit from GPU acceleration
GPU_APPS=(
"immich" "channels" "emby" "ersatztv" "frigate"
"jellyfin" "plex" "scrypted" "tdarr" "unmanic"
"ollama" "fileflows" "open-webui" "tunarr"
"handbrake" "sunshine" "moonlight" "kodi" "stremio"
"viseron"
)
# Check if app needs GPU
# Check if GPU passthrough is enabled
# Returns true only if var_gpu is explicitly set to "yes"
# Can be set via:
# - Environment variable: var_gpu=yes bash -c "..."
# - CT script default: var_gpu="${var_gpu:-no}"
# - Advanced settings wizard
# - App defaults file: /usr/local/community-scripts/defaults/<app>.vars
is_gpu_app() {
local app="${1,,}"
for gpu_app in "${GPU_APPS[@]}"; do
[[ "$app" == "${gpu_app,,}" ]] && return 0
done
[[ "${var_gpu:-no}" == "yes" ]] && return 0
return 1
}
@ -2491,8 +2524,13 @@ EOF
# Configure GPU passthrough
configure_gpu_passthrough() {
# Skip if not a GPU app and not privileged
if [[ "$CT_TYPE" != "0" ]] && ! is_gpu_app "$APP"; then
# Skip if:
# GPU passthrough is enabled when var_gpu="yes":
# - Set via environment variable: var_gpu=yes bash -c "..."
# - Set in CT script: var_gpu="${var_gpu:-no}"
# - Enabled in advanced_settings wizard
# - Configured in app defaults file
if ! is_gpu_app "$APP"; then
return 0
fi

View File

@ -123,6 +123,7 @@ icons() {
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
FUSE="${TAB}🗂️${TAB}${CL}"
GPU="${TAB}🎮${TAB}${CL}"
HOURGLASS="${TAB}${TAB}"
}