mirror of
https://github.com/community-scripts/ProxmoxVED.git
synced 2026-02-24 21:47:26 +00:00
Restructure and relocate documentation files
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.
This commit is contained in:
646
docs/install/DETAILED_GUIDE.md
Normal file
646
docs/install/DETAILED_GUIDE.md
Normal file
@@ -0,0 +1,646 @@
|
||||
# 🛠️ **Application Installation Scripts (install/AppName-install.sh)**
|
||||
|
||||
**Modern Guide to Writing In-Container Installation Scripts**
|
||||
|
||||
> **Updated**: December 2025
|
||||
> **Context**: Integrated with tools.func, error_handler.func, and install.func
|
||||
> **Examples Used**: `/install/pihole-install.sh`, `/install/mealie-install.sh`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Execution Context](#execution-context)
|
||||
- [File Structure](#file-structure)
|
||||
- [Complete Script Template](#complete-script-template)
|
||||
- [Installation Phases](#installation-phases)
|
||||
- [Function Reference](#function-reference)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Real Examples](#real-examples)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Contribution Checklist](#contribution-checklist)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
### Purpose
|
||||
|
||||
Installation scripts (`install/AppName-install.sh`) **run inside the LXC container** and are responsible for:
|
||||
|
||||
1. Setting up the container OS (updates, packages)
|
||||
2. Installing application dependencies
|
||||
3. Downloading and configuring the application
|
||||
4. Setting up services and systemd units
|
||||
5. Creating version tracking files for updates
|
||||
6. Generating credentials/configurations
|
||||
7. Final cleanup and validation
|
||||
|
||||
### Execution Flow
|
||||
|
||||
```
|
||||
ct/AppName.sh (Proxmox Host)
|
||||
↓
|
||||
build_container()
|
||||
↓
|
||||
pct exec CTID bash -c "$(cat install/AppName-install.sh)"
|
||||
↓
|
||||
install/AppName-install.sh (Inside Container)
|
||||
↓
|
||||
Container Ready with App Installed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Context
|
||||
|
||||
### Environment Variables Available
|
||||
|
||||
```bash
|
||||
# From Proxmox/Container
|
||||
CTID # Container ID (100, 101, etc.)
|
||||
PCT_OSTYPE # OS type (alpine, debian, ubuntu)
|
||||
HOSTNAME # Container hostname
|
||||
|
||||
# From build.func
|
||||
FUNCTIONS_FILE_PATH # Bash functions library (core.func + tools.func)
|
||||
VERBOSE # Verbose mode (yes/no)
|
||||
STD # Standard redirection variable (silent/empty)
|
||||
|
||||
# From install.func
|
||||
APP # Application name
|
||||
NSAPP # Normalized app name (lowercase, no spaces)
|
||||
METHOD # Installation method (ct/install)
|
||||
RANDOM_UUID # Session UUID for telemetry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
### Minimal install/AppName-install.sh Template
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash # [1] Shebang
|
||||
|
||||
# [2] Copyright/Metadata
|
||||
# Copyright (c) 2021-2025 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT
|
||||
# Source: https://example.com
|
||||
|
||||
# [3] Load functions
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
# [4] Installation steps
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y package1 package2
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
# [5] Final setup
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Script Template
|
||||
|
||||
### Phase 1: Header & Initialization
|
||||
|
||||
```bash
|
||||
#!/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/application/repo
|
||||
|
||||
# Load all available functions (from core.func + tools.func)
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
# Initialize environment
|
||||
color # Setup ANSI colors and icons
|
||||
verb_ip6 # Configure IPv6 (if needed)
|
||||
catch_errors # Setup error traps
|
||||
setting_up_container # Verify OS is ready
|
||||
network_check # Verify internet connectivity
|
||||
update_os # Update packages (apk/apt)
|
||||
```
|
||||
|
||||
### Phase 2: Dependency Installation
|
||||
|
||||
```bash
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
nano \
|
||||
build-essential \
|
||||
libssl-dev \
|
||||
python3-dev
|
||||
msg_ok "Installed Dependencies"
|
||||
```
|
||||
|
||||
### Phase 3: Tool Setup (Using tools.func)
|
||||
|
||||
```bash
|
||||
# Setup specific tool versions
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PHP_VERSION="8.4" setup_php
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
```
|
||||
|
||||
### Phase 4: Application Download & Setup
|
||||
|
||||
```bash
|
||||
# Download 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)}')
|
||||
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz"
|
||||
cd /opt
|
||||
tar -xzf app-${RELEASE}.tar.gz
|
||||
rm -f app-${RELEASE}.tar.gz
|
||||
```
|
||||
|
||||
### Phase 5: Configuration Files
|
||||
|
||||
```bash
|
||||
# Using cat << EOF (multiline)
|
||||
cat <<'EOF' >/etc/nginx/sites-available/appname
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /opt/appname/public;
|
||||
index index.php index.html;
|
||||
}
|
||||
EOF
|
||||
|
||||
# Using sed for replacements
|
||||
sed -i -e "s|^DB_HOST=.*|DB_HOST=localhost|" \
|
||||
-e "s|^DB_USER=.*|DB_USER=appuser|" \
|
||||
/opt/appname/.env
|
||||
```
|
||||
|
||||
### Phase 6: Database Setup (If Needed)
|
||||
|
||||
```bash
|
||||
msg_info "Setting up Database"
|
||||
|
||||
DB_NAME="appname_db"
|
||||
DB_USER="appuser"
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
|
||||
# For MySQL/MariaDB
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE ${DB_NAME};
|
||||
CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||||
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
msg_ok "Database setup complete"
|
||||
```
|
||||
|
||||
### Phase 7: Permission & Ownership
|
||||
|
||||
```bash
|
||||
msg_info "Setting permissions"
|
||||
|
||||
# Web applications typically run as www-data
|
||||
chown -R www-data:www-data /opt/appname
|
||||
chmod -R 755 /opt/appname
|
||||
chmod -R 644 /opt/appname/*
|
||||
chmod 755 /opt/appname/*/.*
|
||||
|
||||
msg_ok "Permissions set"
|
||||
```
|
||||
|
||||
### Phase 8: Service Configuration
|
||||
|
||||
```bash
|
||||
# Enable systemd service
|
||||
systemctl enable -q --now appname
|
||||
|
||||
# Or for OpenRC (Alpine)
|
||||
rc-service appname start
|
||||
rc-update add appname default
|
||||
|
||||
# Verify service is running
|
||||
if systemctl is-active --quiet appname; then
|
||||
msg_ok "Service running successfully"
|
||||
else
|
||||
msg_error "Service failed to start"
|
||||
journalctl -u appname -n 20
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Phase 9: Version Tracking
|
||||
|
||||
```bash
|
||||
# Essential for update detection
|
||||
echo "${RELEASE}" > /opt/${APP}_version.txt
|
||||
|
||||
# Or with additional metadata
|
||||
cat > /opt/${APP}_version.txt <<EOF
|
||||
Version: ${RELEASE}
|
||||
InstallDate: $(date)
|
||||
InstallMethod: ${METHOD}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Phase 10: Final Setup & Cleanup
|
||||
|
||||
```bash
|
||||
# Display MOTD and enable autologin
|
||||
motd_ssh
|
||||
|
||||
# Final customization
|
||||
customize
|
||||
|
||||
# Clean up package manager cache
|
||||
msg_info "Cleaning up"
|
||||
apt-get -y autoremove
|
||||
apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
||||
|
||||
# Or for Alpine
|
||||
apk cache clean
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# System cleanup
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation Phases
|
||||
|
||||
### Phase 1: Container OS Setup
|
||||
- Network interface brought up and configured
|
||||
- Internet connectivity verified
|
||||
- Package lists updated
|
||||
- All OS packages upgraded to latest versions
|
||||
|
||||
### Phase 2: Base Dependencies
|
||||
```bash
|
||||
msg_info "Installing Base Dependencies"
|
||||
$STD apt-get install -y \
|
||||
curl wget git nano build-essential
|
||||
msg_ok "Installed Base Dependencies"
|
||||
```
|
||||
|
||||
### Phase 3: Tool Installation
|
||||
```bash
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PHP_VERSION="8.4" setup_php
|
||||
```
|
||||
|
||||
### Phase 4: Application Setup
|
||||
```bash
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app.tar.gz"
|
||||
```
|
||||
|
||||
### Phase 5: Configuration
|
||||
Application-specific configuration files and environment setup
|
||||
|
||||
### Phase 6: Service Registration
|
||||
Enable and verify systemd services are running
|
||||
|
||||
---
|
||||
|
||||
## Function Reference
|
||||
|
||||
### Core Messaging Functions
|
||||
|
||||
#### `msg_info(message)`
|
||||
|
||||
Displays an info message with spinner animation
|
||||
|
||||
```bash
|
||||
msg_info "Installing application"
|
||||
# Output: ⏳ Installing application (with spinning animation)
|
||||
```
|
||||
|
||||
#### `msg_ok(message)`
|
||||
|
||||
Displays success message with checkmark
|
||||
|
||||
```bash
|
||||
msg_ok "Installation completed"
|
||||
# Output: ✔️ Installation completed
|
||||
```
|
||||
|
||||
#### `msg_error(message)`
|
||||
|
||||
Displays error message and exits
|
||||
|
||||
```bash
|
||||
msg_error "Installation failed"
|
||||
# Output: ✖️ Installation failed
|
||||
```
|
||||
|
||||
### Package Management
|
||||
|
||||
#### `$STD` Variable
|
||||
|
||||
Controls output verbosity
|
||||
|
||||
```bash
|
||||
# Silent mode (respects VERBOSE setting)
|
||||
$STD apt-get install -y nginx
|
||||
```
|
||||
|
||||
#### `update_os()`
|
||||
|
||||
Updates OS packages
|
||||
|
||||
```bash
|
||||
update_os
|
||||
# Runs: apt update && apt upgrade
|
||||
```
|
||||
|
||||
### Tool Installation Functions
|
||||
|
||||
#### `setup_nodejs()`
|
||||
|
||||
Installs Node.js with optional global modules
|
||||
|
||||
```bash
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
NODE_VERSION="22" NODE_MODULE="yarn,@vue/cli" setup_nodejs
|
||||
```
|
||||
|
||||
#### `setup_php()`
|
||||
|
||||
Installs PHP with optional extensions
|
||||
|
||||
```bash
|
||||
PHP_VERSION="8.4" PHP_MODULE="bcmath,curl,gd,intl,redis" setup_php
|
||||
```
|
||||
|
||||
#### Other Tools
|
||||
|
||||
```bash
|
||||
setup_mariadb # MariaDB database
|
||||
setup_mysql # MySQL database
|
||||
setup_postgresql # PostgreSQL
|
||||
setup_docker # Docker Engine
|
||||
setup_composer # PHP Composer
|
||||
setup_python # Python 3
|
||||
setup_ruby # Ruby
|
||||
setup_rust # Rust
|
||||
```
|
||||
|
||||
### Cleanup Functions
|
||||
|
||||
#### `cleanup_lxc()`
|
||||
|
||||
Comprehensive container cleanup
|
||||
|
||||
- Removes package manager caches
|
||||
- Cleans temporary files
|
||||
- Clears language package caches
|
||||
- Removes systemd journal logs
|
||||
|
||||
```bash
|
||||
cleanup_lxc
|
||||
# Output: ⏳ Cleaning up
|
||||
# ✔️ Cleaned
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
|
||||
1. **Always Use $STD for Commands**
|
||||
```bash
|
||||
# ✅ Good: Respects VERBOSE setting
|
||||
$STD apt-get install -y nginx
|
||||
```
|
||||
|
||||
2. **Generate Random Passwords Safely**
|
||||
```bash
|
||||
# ✅ Good: Alphanumeric only
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
```
|
||||
|
||||
3. **Check Command Success**
|
||||
```bash
|
||||
# ✅ Good: Verify success
|
||||
if ! wget -q "https://example.com/file.tar.gz"; then
|
||||
msg_error "Download failed"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
4. **Set Proper Permissions**
|
||||
```bash
|
||||
# ✅ Good: Explicit permissions
|
||||
chown -R www-data:www-data /opt/appname
|
||||
chmod -R 755 /opt/appname
|
||||
```
|
||||
|
||||
5. **Save Version for Update Checks**
|
||||
```bash
|
||||
# ✅ Good: Version tracked
|
||||
echo "${RELEASE}" > /opt/${APP}_version.txt
|
||||
```
|
||||
|
||||
6. **Handle Alpine vs Debian Differences**
|
||||
```bash
|
||||
# ✅ Good: Detect OS
|
||||
if grep -qi 'alpine' /etc/os-release; then
|
||||
apk add package
|
||||
else
|
||||
apt-get install -y package
|
||||
fi
|
||||
```
|
||||
|
||||
### ❌ DON'T:
|
||||
|
||||
1. **Hardcode Versions**
|
||||
```bash
|
||||
# ❌ Bad: Won't auto-update
|
||||
wget https://example.com/app-1.2.3.tar.gz
|
||||
```
|
||||
|
||||
2. **Use Root Without Password**
|
||||
```bash
|
||||
# ❌ Bad: Security risk
|
||||
mysql -u root
|
||||
```
|
||||
|
||||
3. **Forget Error Handling**
|
||||
```bash
|
||||
# ❌ Bad: Silent failures
|
||||
wget https://example.com/file
|
||||
tar -xzf file
|
||||
```
|
||||
|
||||
4. **Leave Temporary Files**
|
||||
```bash
|
||||
# ✅ Always cleanup
|
||||
rm -rf /opt/app-${RELEASE}.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real Examples
|
||||
|
||||
### Example 1: Node.js Application
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
color
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Node.js"
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
msg_ok "Node.js installed"
|
||||
|
||||
msg_info "Installing Application"
|
||||
cd /opt
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app.tar.gz"
|
||||
tar -xzf app.tar.gz
|
||||
echo "${RELEASE}" > /opt/app_version.txt
|
||||
msg_ok "Application installed"
|
||||
|
||||
systemctl enable --now app
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### Example 2: PHP Application with Database
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
color
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
PHP_VERSION="8.4" PHP_MODULE="bcmath,curl,pdo_mysql" setup_php
|
||||
MARIADB_VERSION="11.4" setup_mariadb
|
||||
|
||||
# Database setup
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE appdb;
|
||||
CREATE USER 'appuser'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||||
GRANT ALL ON appdb.* TO 'appuser'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
# App installation
|
||||
cd /opt
|
||||
wget -q https://github.com/user/repo/releases/latest/download/app.tar.gz
|
||||
tar -xzf app.tar.gz
|
||||
|
||||
# Configuration
|
||||
cat > /opt/app/.env <<EOF
|
||||
DB_HOST=localhost
|
||||
DB_NAME=appdb
|
||||
DB_USER=appuser
|
||||
DB_PASS=${DB_PASS}
|
||||
EOF
|
||||
|
||||
chown -R www-data:www-data /opt/app
|
||||
systemctl enable --now php-fpm
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Installation Hangs
|
||||
|
||||
**Check internet connectivity**:
|
||||
```bash
|
||||
ping -c 1 8.8.8.8
|
||||
```
|
||||
|
||||
**Enable verbose mode**:
|
||||
```bash
|
||||
# In ct/AppName.sh, before running
|
||||
VERBOSE="yes" bash install/AppName-install.sh
|
||||
```
|
||||
|
||||
### Package Not Found
|
||||
|
||||
**Update package lists**:
|
||||
```bash
|
||||
apt update
|
||||
apt-cache search package_name
|
||||
```
|
||||
|
||||
### Service Won't Start
|
||||
|
||||
**Check logs**:
|
||||
```bash
|
||||
journalctl -u appname -n 50
|
||||
systemctl status appname
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contribution Checklist
|
||||
|
||||
Before submitting a PR:
|
||||
|
||||
### Structure
|
||||
- [ ] Shebang is `#!/usr/bin/env bash`
|
||||
- [ ] Loads functions from `$FUNCTIONS_FILE_PATH`
|
||||
- [ ] Copyright header with author
|
||||
- [ ] Clear phase comments
|
||||
|
||||
### Installation
|
||||
- [ ] `setting_up_container` called early
|
||||
- [ ] `network_check` before downloads
|
||||
- [ ] `update_os` before package installation
|
||||
- [ ] All errors checked properly
|
||||
|
||||
### Functions
|
||||
- [ ] Uses `msg_info/msg_ok/msg_error` for status
|
||||
- [ ] Uses `$STD` for command output silencing
|
||||
- [ ] Version saved to `/opt/${APP}_version.txt`
|
||||
- [ ] Proper permissions set
|
||||
|
||||
### Cleanup
|
||||
- [ ] `motd_ssh` called for final setup
|
||||
- [ ] `customize` called for options
|
||||
- [ ] `cleanup_lxc` called at end
|
||||
|
||||
### Testing
|
||||
- [ ] Tested with default settings
|
||||
- [ ] Tested with advanced (19-step) mode
|
||||
- [ ] Service starts and runs correctly
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Compatibility**: ProxmoxVED with install.func v3+
|
||||
Reference in New Issue
Block a user