Removed outdated documentation files from docs/. Added new detailed guides to ct/ and install/ directories. Updated README.md to reflect new navigation, learning paths, and documentation structure. Relocated system guides and technical references to settings/ and install/ subdirectories for improved organization.
11 KiB
🚀 Application Container Scripts (ct/AppName.sh)
Modern Guide to Creating LXC Container Installation Scripts
Updated: December 2025 Context: Fully integrated with build.func, advanced_settings wizard, and defaults system Example Used:
/ct/pihole.sh,/ct/docker.sh
📋 Table of Contents
- Overview
- Architecture & Flow
- File Structure
- Complete Script Template
- Function Reference
- Advanced Features
- Real Examples
- Troubleshooting
- Contribution Checklist
Overview
Purpose
Container scripts (ct/AppName.sh) are entry points for creating LXC containers with specific applications pre-installed. They:
- Define container defaults (CPU, RAM, disk, OS)
- Call the main build orchestrator (
build.func) - Implement application-specific update mechanisms
- Provide user-facing success messages
Execution Context
Proxmox Host
↓
ct/AppName.sh sourced (runs as root on host)
↓
build.func: Creates LXC container + runs install script inside
↓
install/AppName-install.sh (runs inside container)
↓
Container ready with app installed
Key Integration Points
- build.func - Main orchestrator (container creation, storage, variable management)
- install.func - Container-specific setup (OS update, package management)
- tools.func - Tool installation helpers (repositories, GitHub releases)
- core.func - UI/messaging functions (colors, spinners, validation)
- error_handler.func - Error handling and signal management
Architecture & Flow
Container Creation Flow
START: bash ct/pihole.sh
↓
[1] Set APP, var_*, defaults
↓
[2] header_info() → Display ASCII art
↓
[3] variables() → Parse arguments & load build.func
↓
[4] color() → Setup ANSI codes
↓
[5] catch_errors() → Setup trap handlers
↓
[6] install_script() → Show mode menu (5 options)
↓
├─ INSTALL_MODE="0" (Default)
├─ INSTALL_MODE="1" (Advanced - 19-step wizard)
├─ INSTALL_MODE="2" (User Defaults)
├─ INSTALL_MODE="3" (App Defaults)
└─ INSTALL_MODE="4" (Settings Menu)
↓
[7] advanced_settings() → Collect user configuration (if mode=1)
↓
[8] start() → Confirm or re-edit settings
↓
[9] build_container() → Create LXC + execute install script
↓
[10] description() → Set container description
↓
[11] SUCCESS → Display access URL
↓
END
Default Values Precedence
Priority 1 (Highest): Environment Variables (var_cpu, var_ram, etc.)
Priority 2: App-Specific Defaults (/defaults/AppName.vars)
Priority 3: User Global Defaults (/default.vars)
Priority 4 (Lowest): Built-in Defaults (in build.func)
File Structure
Minimal ct/AppName.sh Template
#!/usr/bin/env bash # [1] Shebang
# [2] Copyright/License
source <(curl -s .../misc/build.func) # [3] Import functions
# [4] APP metadata
APP="AppName" # [5] Default values
var_tags="tag1;tag2"
var_cpu="2"
var_ram="2048"
...
header_info "$APP" # [6] Display header
variables # [7] Process arguments
color # [8] Setup colors
catch_errors # [9] Setup error handling
function update_script() { ... } # [10] Update function (optional)
start # [11] Launch container creation
build_container
description
msg_ok "Completed Successfully!\n"
Complete Script Template
1. File Header & Imports
#!/usr/bin/env bash
# Copyright (c) 2021-2025 community-scripts ORG
# Author: YourUsername
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
# Source: https://github.com/example/project
# Import main orchestrator
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
⚠️ IMPORTANT: Before opening a PR, change URL to
community-scriptsrepo!
2. Application Metadata
# Application Configuration
APP="ApplicationName"
var_tags="tag1;tag2;tag3" # Max 3-4 tags, no spaces, semicolon-separated
# Container Resources
var_cpu="2" # CPU cores
var_ram="2048" # RAM in MB
var_disk="10" # Disk in GB
# Container Type & OS
var_os="debian" # Options: alpine, debian, ubuntu
var_version="12" # Alpine: 3.20+, Debian: 11-13, Ubuntu: 20.04+
var_unprivileged="1" # 1=unprivileged (secure), 0=privileged (rarely needed)
Variable Naming Convention:
- Variables exposed to user:
var_*(e.g.,var_cpu,var_hostname,var_ssh) - Internal variables: lowercase (e.g.,
container_id,app_version)
3. Display & Initialization
# Display header ASCII art
header_info "$APP"
# Process command-line arguments and load configuration
variables
# Setup ANSI color codes and formatting
color
# Initialize error handling (trap ERR, EXIT, INT, TERM)
catch_errors
4. Update Function (Highly Recommended)
function update_script() {
header_info
# Always start with these checks
check_container_storage
check_container_resources
# Verify app is installed
if [[ ! -d /opt/appname ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
# Get latest version from GitHub
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
# Compare with saved version
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
msg_info "Updating ${APP} to v${RELEASE}"
# Backup user data
cp -r /opt/appname /opt/appname-backup
# Perform update
cd /opt
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz"
tar -xzf app-${RELEASE}.tar.gz
# Restore user data
cp /opt/appname-backup/config/* /opt/appname/config/
# Cleanup
rm -rf app-${RELEASE}.tar.gz /opt/appname-backup
# Save new version
echo "${RELEASE}" > /opt/${APP}_version.txt
msg_ok "Updated ${APP} to v${RELEASE}"
else
msg_ok "No update required. ${APP} is already at v${RELEASE}."
fi
exit
}
5. Script Launch
# Start the container creation workflow
start
# Build the container with selected configuration
build_container
# Set container description/notes in Proxmox UI
description
# Display success message
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
Function Reference
Core Functions (From build.func)
variables()
Purpose: Initialize container variables, load user arguments, setup orchestration
Triggered by: Called automatically at script start
Behavior:
- Parse command-line arguments (if any)
- Generate random UUID for session tracking
- Load container storage from Proxmox
- Initialize application-specific defaults
- Setup SSH/environment configuration
start()
Purpose: Launch the container creation menu with 5 installation modes
Menu Options:
1. Default Installation (Quick setup, predefined settings)
2. Advanced Installation (19-step wizard with full control)
3. User Defaults (Load ~/.community-scripts/default.vars)
4. App Defaults (Load /defaults/AppName.vars)
5. Settings Menu (Interactive mode selection)
build_container()
Purpose: Main orchestrator for LXC container creation
Operations:
- Validates all variables
- Creates LXC container via
pct create - Executes
install/AppName-install.shinside container - Monitors installation progress
- Handles errors and rollback on failure
description()
Purpose: Set container description/notes visible in Proxmox UI
Advanced Features
1. Custom Configuration Menus
If your app has additional setup beyond standard vars:
custom_app_settings() {
CONFIGURE_DB=$(whiptail --title "Database Setup" \
--yesno "Would you like to configure a custom database?" 8 60)
if [[ $? -eq 0 ]]; then
DB_HOST=$(whiptail --inputbox "Database Host:" 8 60 3>&1 1>&2 2>&3)
DB_PORT=$(whiptail --inputbox "Database Port:" 8 60 "3306" 3>&1 1>&2 2>&3)
fi
}
custom_app_settings
2. Update Function Patterns
Save installed version for update checks
3. Health Check Functions
Add custom validation:
function health_check() {
header_info
if [[ ! -d /opt/appname ]]; then
msg_error "Application not found!"
exit 1
fi
if ! systemctl is-active --quiet appname; then
msg_error "Application service not running"
exit 1
fi
msg_ok "Health check passed"
}
Real Examples
Example 1: Simple Web App (Debian-based)
#!/usr/bin/env bash
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func)
APP="Homarr"
var_tags="dashboard;homepage"
var_cpu="2"
var_ram="1024"
var_disk="5"
var_os="debian"
var_version="12"
var_unprivileged="1"
header_info "$APP"
variables
color
catch_errors
function update_script() {
# Update logic here
}
start
build_container
description
msg_ok "Completed Successfully!\n"
Troubleshooting
Container Creation Fails
Symptom: pct create exits with error code 209
Solution:
# Check existing containers
pct list | grep CTID
# Remove conflicting container
pct destroy CTID
# Retry ct/AppName.sh
Update Function Doesn't Detect New Version
Debug:
# Check version file
cat /opt/AppName_version.txt
# Test GitHub API
curl -fsSL https://api.github.com/repos/user/repo/releases/latest | grep tag_name
Contribution Checklist
Before submitting a PR:
Script Structure
- Shebang is
#!/usr/bin/env bash - Imports
build.funcfrom community-scripts repo - Copyright header with author and source URL
- APP variable matches filename
var_tagsare semicolon-separated (no spaces)
Default Values
var_cpuset appropriately (2-4 for most apps)var_ramset appropriately (1024-4096 MB minimum)var_disksufficient for app + data (5-20 GB)var_osis realistic
Functions
update_script()implemented- Update function checks if app installed
- Proper error handling with
msg_error
Testing
- Script tested with default installation
- Script tested with advanced (19-step) installation
- Update function tested on existing installation
Best Practices
✅ DO:
- Use meaningful defaults
- Implement version tracking
- Handle edge cases
- Use proper messaging with msg_info/msg_ok/msg_error
❌ DON'T:
- Hardcode versions
- Use custom color codes (use built-in variables)
- Forget error handling
- Leave temporary files
Last Updated: December 2025 Compatibility: ProxmoxVED with build.func v3+