Files
proxmox/docs/11-references/SCRIPT_REVIEW.md

18 KiB

ProxmoxVE Scripts - Comprehensive Review

Executive Summary

This document provides a comprehensive review of the ProxmoxVE Helper-Scripts repository structure, script construction patterns, and contribution guidelines. The repository contains community-driven automation scripts for Proxmox VE container and VM management.

Repository: https://github.com/community-scripts/ProxmoxVE
License: MIT
Main Language: Shell (89.9%), TypeScript (9.6%)


Repository Structure

Core Directories

ProxmoxVE/
├── ct/              # Container scripts (LXC) - 300+ scripts
├── vm/              # Virtual machine scripts - 15+ scripts
├── install/         # Installation scripts (run inside containers)
├── misc/            # Function libraries (.func files)
├── api/             # API-related scripts
├── tools/            # Utility tools
├── turnkey/         # TurnKey Linux templates
├── frontend/        # Frontend/web interface
└── docs/            # Comprehensive documentation

Function Libraries (misc/)

File Purpose
build.func Main orchestrator for container creation
install.func Container OS setup and package management
tools.func Tool installation helpers (Node.js, Python, etc.)
core.func UI/messaging, validation, system checks
error_handler.func Error handling and signal management
api.func API interaction functions
alpine-install.func Alpine Linux specific functions
alpine-tools.func Alpine-specific tool setup
cloud-init.func Cloud-init configuration for VMs

Script Construction Patterns

1. Container Scripts (ct/AppName.sh)

Purpose: Entry point for creating LXC containers with pre-installed applications.

Standard Structure

#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: YourUsername
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://application-source-url.com

# Application Configuration
APP="ApplicationName"
var_tags="tag1;tag2"          # Max 3-4 tags, semicolon-separated
var_cpu="2"                   # CPU cores
var_ram="2048"                # RAM in MB
var_disk="10"                 # Disk in GB
var_os="debian"               # OS: alpine, debian, ubuntu
var_version="12"              # OS version
var_unprivileged="1"          # 1=unprivileged (secure), 0=privileged

# Initialization
header_info "$APP"
variables
color
catch_errors

# Optional: Update function
function update_script() {
    header_info
    check_container_storage
    check_container_resources
    if [[ ! -f /path/to/installation ]]; then
        msg_error "No ${APP} Installation Found!"
        exit
    fi
    # Update logic here
    exit
}

# Main execution
start
build_container
description
msg_ok "Completed Successfully!\n"

Key Components

  1. Shebang: #!/usr/bin/env bash
  2. Function Library Import: Sources build.func via curl
  3. Application Metadata: APP name, tags, resource defaults
  4. Variable Naming: All user-configurable variables use var_* prefix
  5. Initialization Sequence: header_info → variables → color → catch_errors
  6. Update Function: Optional but recommended for application updates
  7. Main Flow: start → build_container → description → success message

Variable Precedence (Highest to Lowest)

  1. Environment Variables (set before script execution)
  2. App-Specific Defaults (/usr/local/community-scripts/defaults/<app>.vars)
  3. User Global Defaults (/usr/local/community-scripts/default.vars)
  4. Built-in Defaults (hardcoded in script)

Installation Modes

  • Mode 0: Default install (uses built-in defaults)
  • Mode 1: Advanced install (19-step interactive wizard)
  • Mode 2: User defaults (loads from global default.vars)
  • Mode 3: App defaults (loads from app-specific .vars)
  • Mode 4: Settings menu (manage defaults)

2. Installation Scripts (install/AppName-install.sh)

Purpose: Run inside the LXC container to install and configure the application.

Standard Structure

#!/usr/bin/env bash

# Copyright (c) 2021-2025 community-scripts ORG
# Author: YourUsername
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://application-source-url.com

# Import Functions and Setup
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

# Phase 1: Dependencies
msg_info "Installing Dependencies"
$STD apt-get install -y \
  curl \
  sudo \
  mc \
  package1 \
  package2
msg_ok "Installed Dependencies"

# Phase 2: Tool Setup (if needed)
NODE_VERSION="22" setup_nodejs
PHP_VERSION="8.4" setup_php

# Phase 3: Application Download & Setup
msg_info "Setting up ${APP}"
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
  grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
# Download and extract application
echo "${RELEASE}" >/opt/${APP}_version.txt
msg_ok "Setup ${APP}"

# Phase 4: Configuration
msg_info "Configuring ${APP}"
# Create config files, systemd services, etc.

# Phase 5: Service Setup
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/${APP}.service
[Unit]
Description=${APP} Service
After=network.target

[Service]
ExecStart=/path/to/start/command
Restart=always

[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now ${APP}.service
msg_ok "Created Service"

# Phase 6: Finalization
motd_ssh
customize

# Phase 7: Cleanup
msg_info "Cleaning up"
rm -f /tmp/temp-files
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"

Installation Phases

  1. Initialization: Load functions, setup environment, verify OS
  2. Dependencies: Install required packages (curl, sudo, mc are core)
  3. Tool Setup: Install runtime tools (Node.js, Python, PHP, etc.)
  4. Application: Download, extract, and setup application
  5. Configuration: Create config files, environment variables
  6. Services: Setup systemd services, enable on boot
  7. Finalization: MOTD, SSH setup, customization
  8. Cleanup: Remove temporary files, clean package cache

Available Environment Variables

  • CTID: Container ID
  • PCT_OSTYPE: OS type (alpine, debian, ubuntu)
  • HOSTNAME: Container hostname
  • FUNCTIONS_FILE_PATH: Bash functions library
  • VERBOSE: Verbose mode flag
  • STD: Standard redirection (for silent execution)
  • APP: Application name
  • NSAPP: Normalized app name

Function Library Architecture

build.func - Main Orchestrator

Key Functions:

  • variables(): Parse command-line arguments, initialize variables
  • install_script(): Display mode menu, route to appropriate workflow
  • base_settings(): Apply built-in defaults to all var_* variables
  • advanced_settings(): 19-step interactive wizard for configuration
  • load_vars_file(): Safely load variables from .vars files (NO source/eval)
  • default_var_settings(): Load user global defaults
  • get_app_defaults_path(): Get path to app-specific defaults
  • maybe_offer_save_app_defaults(): Offer to save current settings
  • build_container(): Create LXC container and execute install script
  • start(): Confirm settings or allow re-editing

Security Features:

  • Whitelist validation for variable names
  • Value sanitization (blocks command injection)
  • Safe file parsing (no source or eval)
  • Path traversal protection

core.func - Foundation Functions

Key Functions:

  • pve_check(): Verify Proxmox VE version (8.0-8.9, 9.0+)
  • arch_check(): Ensure AMD64 architecture
  • shell_check(): Validate Bash shell
  • root_check(): Ensure root privileges
  • msg_info(), msg_ok(), msg_error(), msg_warn(): Colored messages
  • spinner(): Animated progress indicator
  • silent(): Execute commands with error handling
  • color(): Setup ANSI color codes

install.func - Container Setup

Key Functions:

  • setting_up_container(): Verify container OS is ready
  • network_check(): Verify internet connectivity
  • update_os(): Update packages (apk/apt)
  • motd_ssh(): Setup MOTD and SSH configuration
  • customize(): Apply container customizations
  • cleanup_lxc(): Final cleanup operations

tools.func - Tool Installation

Key Functions:

  • setup_nodejs(): Install Node.js (specify version)
  • setup_php(): Install PHP (specify version)
  • setup_uv(): Install Python uv package manager
  • setup_docker(): Install Docker
  • setup_compose(): Install Docker Compose
  • install_from_github(): Download and install from GitHub releases

Configuration System

Defaults File Format

Location: /usr/local/community-scripts/default.vars (global)
App-Specific: /usr/local/community-scripts/defaults/<app>.vars

Format:

# Comments and blank lines are ignored
# Format: var_name=value (no spaces around =)

var_cpu=4
var_ram=2048
var_disk=20
var_hostname=mycontainer
var_brg=vmbr0
var_gateway=192.168.1.1
var_timezone=Europe/Berlin

Security Constraints:

  • Max file size: 64 KB
  • Max line length: 1024 bytes
  • Max variables: 100
  • Variable names must match: var_[a-z_]+
  • Values sanitized (blocks $(), backticks, ;, &, etc.)

Variable Whitelist

Only these variables can be configured:

  • 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

Coding Standards

Script Requirements

  1. Shebang: Always use #!/usr/bin/env bash
  2. Copyright Header: Include copyright, author, license, source URL
  3. Error Handling: Use catch_errors and proper error messages
  4. Message Functions: Use msg_info(), msg_ok(), msg_error(), msg_warn()
  5. Silent Execution: Use $STD prefix for commands (handles verbose mode)
  6. Variable Naming: User variables use var_* prefix
  7. Comments: Document complex logic, explain non-obvious decisions
  8. Indentation: Use 2 spaces (not tabs)
  9. Quoting: Quote all variables: "$variable" not $variable

Best Practices

  • Always test scripts before submitting PR
  • Use templates: Start from ct/example.sh or install/example-install.sh
  • Follow naming: AppName.sh and AppName-install.sh
  • Version tracking: Create /opt/${APP}_version.txt for updates
  • Backup before update: Always backup before updating in update_script()
  • Cleanup: Remove temporary files and clean package cache
  • Documentation: Update docs if adding new features

Common Patterns

Version Detection

RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
  grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')

Database Setup

DB_NAME="appname_db"
DB_USER="appuser"
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
$STD mysql -u root -e "CREATE DATABASE $DB_NAME;"
$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');"
$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;"

Systemd Service

cat <<EOF >/etc/systemd/system/${APP}.service
[Unit]
Description=${APP} Service
After=network.target

[Service]
ExecStart=/path/to/command
Restart=always
User=appuser

[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now ${APP}.service

Configuration File

cat <<'EOF' >/path/to/config
# Configuration content
KEY=value
EOF

Contribution Workflow

1. Fork and Setup

# Fork on GitHub, then clone
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
cd ProxmoxVE

# Auto-configure fork
bash docs/contribution/setup-fork.sh

# Create feature branch
git checkout -b feature/my-awesome-app

2. Development

# For testing, change URLs in build.func, install.func, and ct/AppName.sh
# Change: https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main
# To: https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/refs/heads/BRANCH

# Create scripts from templates
cp ct/example.sh ct/myapp.sh
cp install/example-install.sh install/myapp-install.sh

# Test your script
bash ct/myapp.sh

3. Before PR

# Sync with upstream
git fetch upstream
git rebase upstream/main

# Change URLs back to community-scripts
# Remove any test/debug code
# Ensure all standards are met

# Commit (DO NOT commit build.func or install.func changes)
git add ct/myapp.sh install/myapp-install.sh
git commit -m "feat: add MyApp"
git push origin feature/my-awesome-app

4. Pull Request

  • Only include: ct/AppName.sh, install/AppName-install.sh, json/AppName.json (if applicable)
  • Clear title: feat: add ApplicationName
  • Description: Explain what the app does, any special requirements
  • Tested: Confirm script was tested on Proxmox VE

Documentation Structure

Main Documentation

  • docs/README.md: Documentation overview
  • docs/TECHNICAL_REFERENCE.md: Architecture deep-dive
  • docs/EXIT_CODES.md: Exit codes reference
  • docs/DEV_MODE.md: Debugging guide

Script-Specific Guides

  • docs/ct/DETAILED_GUIDE.md: Complete container script reference
  • docs/install/DETAILED_GUIDE.md: Complete installation script reference
  • docs/vm/README.md: VM script guide
  • docs/tools/README.md: Tools guide

Function Library Docs

Each .func file has comprehensive documentation:

  • README.md: Overview and quick reference
  • FUNCTIONS_REFERENCE.md: Complete function reference
  • USAGE_EXAMPLES.md: Practical examples
  • INTEGRATION.md: Integration patterns
  • FLOWCHART.md: Visual execution flows

Contribution Guides

  • docs/contribution/README.md: Main contribution guide
  • docs/contribution/CONTRIBUTING.md: Coding standards
  • docs/contribution/CODE-AUDIT.md: Code review checklist
  • docs/contribution/FORK_SETUP.md: Fork setup instructions
  • docs/contribution/templates_ct/: Container script templates
  • docs/contribution/templates_install/: Installation script templates

Security Model

Threat Mitigation

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

  1. Input Validation: Only whitelisted variables allowed
  2. Safe File Parsing: Manual parsing, no code execution
  3. Value Sanitization: Blocks dangerous patterns ($(), ` `, ;, &, <()
  4. Whitelisting: Strict variable name validation
  5. Path Restrictions: Configuration files in controlled directory

Key Features

1. Flexible Configuration

  • 5 Installation Modes: Default, Advanced, User Defaults, App Defaults, Settings
  • Variable Precedence: Environment → App Defaults → User Defaults → Built-ins
  • 19-Step Wizard: Comprehensive interactive configuration
  • Settings Persistence: Save configurations for reuse

2. Advanced Settings Wizard

The advanced settings wizard covers:

  1. CPU cores
  2. RAM allocation
  3. Disk size
  4. Container name
  5. Password
  6. Network bridge
  7. IP address
  8. Gateway
  9. DNS servers
  10. VLAN tag
  11. MTU
  12. MAC address
  13. Container storage
  14. Template storage
  15. Unprivileged/Privileged
  16. Protection
  17. SSH keys
  18. Tags
  19. Features (FUSE, TUN, etc.)

3. Update Mechanism

Each container script can include an update_script() function that:

  • Checks if installation exists
  • Detects new version
  • Creates backup
  • Stops services
  • Updates application
  • Restarts services
  • Cleans up

4. Error Handling

  • Comprehensive error messages with explanations
  • Silent execution with detailed logging
  • Signal handling (ERR, EXIT, INT, TERM)
  • Graceful failure with cleanup

Testing Checklist

Before submitting a PR:

  • Script follows template structure
  • All required functions called (header_info, variables, color, catch_errors)
  • Error handling implemented
  • Messages use proper functions (msg_info, msg_ok, msg_error)
  • Silent execution uses $STD prefix
  • Variables properly quoted
  • Version tracking implemented (if applicable)
  • Update function implemented (if applicable)
  • Tested on Proxmox VE 8.4+ or 9.0+
  • No hardcoded values
  • Documentation updated (if needed)
  • URLs point to community-scripts (not fork)

Common Issues and Solutions

Issue: Script fails with "command not found"

Solution: Ensure dependencies are installed in install script, use $STD prefix

Issue: Container created but app not working

Solution: Check install script logs, verify all services are enabled and started

Issue: Update function not working

Solution: Ensure version file exists, check version detection logic, verify backup creation

Issue: Variables not loading from defaults

Solution: Check variable names match whitelist, verify file format (no spaces around =)

Issue: Script works locally but fails in PR

Solution: Ensure URLs point to community-scripts repo, not your fork


Resources


Conclusion

The ProxmoxVE Helper-Scripts repository provides a well-structured, secure, and maintainable framework for automating Proxmox VE container and VM deployments. The modular architecture, comprehensive documentation, and strict coding standards ensure consistency and quality across all contributions.

Key strengths:

  • Modular Design: Reusable function libraries
  • Security First: Multiple layers of input validation and sanitization
  • Flexible Configuration: Multiple installation modes and defaults system
  • Comprehensive Documentation: Extensive guides and references
  • Community Driven: Active maintenance and contribution process

Review completed: $(date) Repository version: Latest main branch Documentation version: December 2025