Add configuration and deployment guides to docs (#9591)

This commit is contained in:
CanbiZ
2025-12-02 14:34:14 +01:00
committed by GitHub
parent d079ac7d67
commit e53bb2d825
5 changed files with 1875 additions and 6 deletions

View File

@@ -0,0 +1,840 @@
# Configuration Reference
**Complete reference for all configuration variables and options in community-scripts for Proxmox VE.**
---
## Table of Contents
1. [Variable Naming Convention](#variable-naming-convention)
2. [Complete Variable Reference](#complete-variable-reference)
3. [Resource Configuration](#resource-configuration)
4. [Network Configuration](#network-configuration)
5. [IPv6 Configuration](#ipv6-configuration)
6. [SSH Configuration](#ssh-configuration)
7. [Container Features](#container-features)
8. [Storage Configuration](#storage-configuration)
9. [Security Settings](#security-settings)
10. [Advanced Options](#advanced-options)
11. [Quick Reference Table](#quick-reference-table)
---
## Variable Naming Convention
All configuration variables follow a consistent pattern:
```
var_<setting>=<value>
```
**Rules:**
- ✅ Always starts with `var_`
- ✅ Lowercase letters only
- ✅ Underscores for word separation
- ✅ No spaces around `=`
- ✅ Values can be quoted if needed
**Examples:**
```bash
# ✓ Correct
var_cpu=4
var_hostname=myserver
var_ssh_authorized_key=ssh-rsa AAAA...
# ✗ Wrong
CPU=4 # Missing var_ prefix
var_CPU=4 # Uppercase not allowed
var_cpu = 4 # Spaces around =
var-cpu=4 # Hyphens not allowed
```
---
## Complete Variable Reference
### var_unprivileged
**Type:** Boolean (0 or 1)
**Default:** `1` (unprivileged)
**Description:** Determines if container runs unprivileged (recommended) or privileged.
```bash
var_unprivileged=1 # Unprivileged (safer, recommended)
var_unprivileged=0 # Privileged (less secure, more features)
```
**When to use privileged (0):**
- Hardware access required
- Certain kernel modules needed
- Legacy applications
- Nested virtualization with full features
**Security Impact:**
- Unprivileged: Container root is mapped to unprivileged user on host
- Privileged: Container root = host root (security risk)
---
### var_cpu
**Type:** Integer
**Default:** Varies by app (usually 1-4)
**Range:** 1 to host CPU count
**Description:** Number of CPU cores allocated to container.
```bash
var_cpu=1 # Single core (minimal)
var_cpu=2 # Dual core (typical)
var_cpu=4 # Quad core (recommended for apps)
var_cpu=8 # High performance
```
**Best Practices:**
- Start with 2 cores for most applications
- Monitor usage with `pct exec <id> -- htop`
- Can be changed after creation
- Consider host CPU count (don't over-allocate)
---
### var_ram
**Type:** Integer (MB)
**Default:** Varies by app (usually 512-2048)
**Range:** 512 MB to host RAM
**Description:** Amount of RAM in megabytes.
```bash
var_ram=512 # 512 MB (minimal)
var_ram=1024 # 1 GB (typical)
var_ram=2048 # 2 GB (comfortable)
var_ram=4096 # 4 GB (recommended for databases)
var_ram=8192 # 8 GB (high memory apps)
```
**Conversion Guide:**
```
512 MB = 0.5 GB
1024 MB = 1 GB
2048 MB = 2 GB
4096 MB = 4 GB
8192 MB = 8 GB
16384 MB = 16 GB
```
**Best Practices:**
- Minimum 512 MB for basic Linux
- 1 GB for typical applications
- 2-4 GB for web servers, databases
- Monitor with `free -h` inside container
---
### var_disk
**Type:** Integer (GB)
**Default:** Varies by app (usually 2-8)
**Range:** 0.001 GB to storage capacity
**Description:** Root disk size in gigabytes.
```bash
var_disk=2 # 2 GB (minimal OS only)
var_disk=4 # 4 GB (typical)
var_disk=8 # 8 GB (comfortable)
var_disk=20 # 20 GB (recommended for apps)
var_disk=50 # 50 GB (large applications)
var_disk=100 # 100 GB (databases, media)
```
**Important Notes:**
- Can be expanded after creation (not reduced)
- Actual space depends on storage type
- Thin provisioning supported on most storage
- Plan for logs, data, updates
**Recommended Sizes by Use Case:**
```
Basic Linux container: 4 GB
Web server (Nginx/Apache): 8 GB
Application server: 10-20 GB
Database server: 20-50 GB
Docker host: 30-100 GB
Media server: 100+ GB
```
---
### var_hostname
**Type:** String
**Default:** Application name
**Max Length:** 63 characters
**Description:** Container hostname (FQDN format allowed).
```bash
var_hostname=myserver
var_hostname=pihole
var_hostname=docker-01
var_hostname=web.example.com
```
**Rules:**
- Lowercase letters, numbers, hyphens
- Cannot start or end with hyphen
- No underscores allowed
- No spaces
**Best Practices:**
```bash
# ✓ Good
var_hostname=web-server
var_hostname=db-primary
var_hostname=app.domain.com
# ✗ Avoid
var_hostname=Web_Server # Uppercase, underscore
var_hostname=-server # Starts with hyphen
var_hostname=my server # Contains space
```
---
### var_brg
**Type:** String
**Default:** `vmbr0`
**Description:** Network bridge interface.
```bash
var_brg=vmbr0 # Default Proxmox bridge
var_brg=vmbr1 # Custom bridge
var_brg=vmbr2 # Isolated network
```
**Common Setups:**
```
vmbr0 → Main network (LAN)
vmbr1 → Guest network
vmbr2 → DMZ
vmbr3 → Management
vmbr4 → Storage network
```
**Check available bridges:**
```bash
ip link show | grep vmbr
# or
brctl show
```
---
### var_net
**Type:** String
**Options:** `dhcp` or `static`
**Default:** `dhcp`
**Description:** IPv4 network configuration method.
```bash
var_net=dhcp # Automatic IP via DHCP
var_net=static # Manual IP configuration
```
**DHCP Mode:**
- Automatic IP assignment
- Easy setup
- Good for development
- Requires DHCP server on network
**Static Mode:**
- Fixed IP address
- Requires gateway configuration
- Better for servers
- Configure via advanced settings or after creation
---
### var_gateway
**Type:** IPv4 Address
**Default:** Auto-detected from host
**Description:** Network gateway IP address.
```bash
var_gateway=192.168.1.1
var_gateway=10.0.0.1
var_gateway=172.16.0.1
```
**Auto-detection:**
If not specified, system detects gateway from host:
```bash
ip route | grep default
```
**When to specify:**
- Multiple gateways available
- Custom routing setup
- Different network segment
---
### var_vlan
**Type:** Integer
**Range:** 1-4094
**Default:** None
**Description:** VLAN tag for network isolation.
```bash
var_vlan=10 # VLAN 10
var_vlan=100 # VLAN 100
var_vlan=200 # VLAN 200
```
**Common VLAN Schemes:**
```
VLAN 10 → Management
VLAN 20 → Servers
VLAN 30 → Desktops
VLAN 40 → Guest WiFi
VLAN 50 → IoT devices
VLAN 99 → DMZ
```
**Requirements:**
- Switch must support VLANs
- Proxmox bridge configured for VLAN aware
- Gateway on same VLAN
---
### var_mtu
**Type:** Integer
**Default:** `1500`
**Range:** 68-9000
**Description:** Maximum Transmission Unit size.
```bash
var_mtu=1500 # Standard Ethernet
var_mtu=1492 # PPPoE
var_mtu=9000 # Jumbo frames
```
**Common Values:**
```
1500 → Standard Ethernet (default)
1492 → PPPoE connections
1400 → Some VPN setups
9000 → Jumbo frames (10GbE networks)
```
**When to change:**
- Jumbo frames for performance on 10GbE
- PPPoE internet connections
- VPN tunnels with overhead
- Specific network requirements
---
### var_mac
**Type:** MAC Address
**Format:** `XX:XX:XX:XX:XX:XX`
**Default:** Auto-generated
**Description:** Container MAC address.
```bash
var_mac=02:00:00:00:00:01
var_mac=DE:AD:BE:EF:00:01
```
**When to specify:**
- MAC-based licensing
- Static DHCP reservations
- Network access control
- Cloning configurations
**Best Practices:**
- Use locally administered addresses (2nd bit set)
- Start with `02:`, `06:`, `0A:`, `0E:`
- Avoid vendor OUIs
- Document custom MACs
---
### var_ipv6_method
**Type:** String
**Options:** `auto`, `dhcp`, `static`, `none`, `disable`
**Default:** `none`
**Description:** IPv6 configuration method.
```bash
var_ipv6_method=auto # SLAAC (auto-configuration)
var_ipv6_method=dhcp # DHCPv6
var_ipv6_method=static # Manual configuration
var_ipv6_method=none # IPv6 enabled but not configured
var_ipv6_method=disable # IPv6 completely disabled
```
**Detailed Options:**
**auto (SLAAC)**
- Stateless Address Auto-Configuration
- Router advertisements
- No DHCPv6 server needed
- Recommended for most cases
**dhcp (DHCPv6)**
- Stateful configuration
- Requires DHCPv6 server
- More control over addressing
**static**
- Manual IPv6 address
- Manual gateway
- Full control
**none**
- IPv6 stack active
- No address configured
- Can configure later
**disable**
- IPv6 completely disabled at kernel level
- Use when IPv6 causes issues
- Sets `net.ipv6.conf.all.disable_ipv6=1`
---
### var_ns
**Type:** IP Address
**Default:** Auto (from host)
**Description:** DNS nameserver IP.
```bash
var_ns=8.8.8.8 # Google DNS
var_ns=1.1.1.1 # Cloudflare DNS
var_ns=9.9.9.9 # Quad9 DNS
var_ns=192.168.1.1 # Local DNS
```
**Common DNS Servers:**
```
8.8.8.8, 8.8.4.4 → Google Public DNS
1.1.1.1, 1.0.0.1 → Cloudflare DNS
9.9.9.9, 149.112.112.112 → Quad9 DNS
208.67.222.222 → OpenDNS
192.168.1.1 → Local router/Pi-hole
```
---
### var_ssh
**Type:** Boolean
**Options:** `yes` or `no`
**Default:** `no`
**Description:** Enable SSH server in container.
```bash
var_ssh=yes # SSH server enabled
var_ssh=no # SSH server disabled (console only)
```
**When enabled:**
- OpenSSH server installed
- Started on boot
- Port 22 open
- Root login allowed
**Security Considerations:**
- Disable if not needed
- Use SSH keys instead of passwords
- Consider non-standard port
- Firewall rules recommended
---
### var_ssh_authorized_key
**Type:** String (SSH public key)
**Default:** None
**Description:** SSH public key for root user.
```bash
var_ssh_authorized_key=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... user@host
var_ssh_authorized_key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
```
**Supported Key Types:**
- RSA (2048-4096 bits)
- Ed25519 (recommended)
- ECDSA
- DSA (deprecated)
**How to get your public key:**
```bash
cat ~/.ssh/id_rsa.pub
# or
cat ~/.ssh/id_ed25519.pub
```
**Multiple keys:**
Separate with newlines (in file) or use multiple deployments.
---
### var_pw
**Type:** String
**Default:** Empty (auto-login)
**Description:** Root password.
```bash
var_pw=SecurePassword123! # Set password
var_pw= # Auto-login (empty)
```
**Auto-login behavior:**
- No password required for console
- Automatic login on console access
- SSH still requires key if enabled
- Suitable for development
**Password best practices:**
- Minimum 12 characters
- Mix upper/lower/numbers/symbols
- Use password manager
- Rotate regularly
---
### var_nesting
**Type:** Boolean (0 or 1)
**Default:** `1`
**Description:** Allow nested containers (required for Docker).
```bash
var_nesting=1 # Nested containers allowed
var_nesting=0 # Nested containers disabled
```
**Required for:**
- Docker
- LXC inside LXC
- Systemd features
- Container orchestration
**Security Impact:**
- Slightly reduced isolation
- Required for container platforms
- Generally safe when unprivileged
---
### var_keyctl
**Type:** Boolean (0 or 1)
**Default:** `0`
**Description:** Enable keyctl system call.
```bash
var_keyctl=1 # Keyctl enabled
var_keyctl=0 # Keyctl disabled
```
**Required for:**
- Docker in some configurations
- Systemd keyring features
- Encryption key management
- Some authentication systems
---
### var_fuse
**Type:** Boolean (0 or 1)
**Default:** `0`
**Description:** Enable FUSE filesystem support.
```bash
var_fuse=1 # FUSE enabled
var_fuse=0 # FUSE disabled
```
**Required for:**
- sshfs
- AppImage
- Some backup tools
- User-space filesystems
---
### var_mknod
**Type:** Boolean (0 or 1)
**Default:** `0`
**Description:** Allow device node creation.
```bash
var_mknod=1 # Device nodes allowed
var_mknod=0 # Device nodes disabled
```
**Requires:**
- Kernel 5.3+
- Experimental feature
- Use with caution
---
### var_mount_fs
**Type:** String (comma-separated)
**Default:** Empty
**Description:** Allowed mountable filesystems.
```bash
var_mount_fs=nfs
var_mount_fs=nfs,cifs
var_mount_fs=ext4,xfs,nfs
```
**Common Options:**
```
nfs → NFS network shares
cifs → SMB/CIFS shares
ext4 → Ext4 filesystems
xfs → XFS filesystems
btrfs → Btrfs filesystems
```
---
### var_protection
**Type:** Boolean
**Options:** `yes` or `no`
**Default:** `no`
**Description:** Prevent accidental deletion.
```bash
var_protection=yes # Protected from deletion
var_protection=no # Can be deleted normally
```
**When protected:**
- Cannot delete via GUI
- Cannot delete via `pct destroy`
- Must disable protection first
- Good for production containers
---
### var_tags
**Type:** String (comma-separated)
**Default:** `community-script`
**Description:** Container tags for organization.
```bash
var_tags=production
var_tags=production,webserver
var_tags=dev,testing,temporary
```
**Best Practices:**
```bash
# Environment tags
var_tags=production
var_tags=development
var_tags=staging
# Function tags
var_tags=webserver,nginx
var_tags=database,postgresql
var_tags=cache,redis
# Project tags
var_tags=project-alpha,frontend
var_tags=customer-xyz,billing
# Combined
var_tags=production,webserver,project-alpha
```
---
### var_timezone
**Type:** String (TZ database format)
**Default:** Host timezone
**Description:** Container timezone.
```bash
var_timezone=Europe/Berlin
var_timezone=America/New_York
var_timezone=Asia/Tokyo
```
**Common Timezones:**
```
Europe/London
Europe/Berlin
Europe/Paris
America/New_York
America/Chicago
America/Los_Angeles
Asia/Tokyo
Asia/Singapore
Australia/Sydney
UTC
```
**List all timezones:**
```bash
timedatectl list-timezones
```
---
### var_verbose
**Type:** Boolean
**Options:** `yes` or `no`
**Default:** `no`
**Description:** Enable verbose output.
```bash
var_verbose=yes # Show all commands
var_verbose=no # Silent mode
```
**When enabled:**
- Shows all executed commands
- Displays detailed progress
- Useful for debugging
- More log output
---
### var_apt_cacher
**Type:** Boolean
**Options:** `yes` or `no`
**Default:** `no`
**Description:** Use APT caching proxy.
```bash
var_apt_cacher=yes
var_apt_cacher=no
```
**Benefits:**
- Faster package installs
- Reduced bandwidth
- Offline package cache
- Speeds up multiple containers
---
### var_apt_cacher_ip
**Type:** IP Address
**Default:** None
**Description:** APT cacher proxy IP.
```bash
var_apt_cacher=yes
var_apt_cacher_ip=192.168.1.100
```
**Setup apt-cacher-ng:**
```bash
apt install apt-cacher-ng
# Runs on port 3142
```
---
### var_container_storage
**Type:** String
**Default:** Auto-detected
**Description:** Storage for container.
```bash
var_container_storage=local
var_container_storage=local-zfs
var_container_storage=pve-storage
```
**List available storage:**
```bash
pvesm status
```
---
### var_template_storage
**Type:** String
**Default:** Auto-detected
**Description:** Storage for templates.
```bash
var_template_storage=local
var_template_storage=nfs-templates
```
---
## Quick Reference Table
| Variable | Type | Default | Example |
|----------|------|---------|---------|
| `var_unprivileged` | 0/1 | 1 | `var_unprivileged=1` |
| `var_cpu` | int | varies | `var_cpu=4` |
| `var_ram` | int (MB) | varies | `var_ram=4096` |
| `var_disk` | int (GB) | varies | `var_disk=20` |
| `var_hostname` | string | app name | `var_hostname=server` |
| `var_brg` | string | vmbr0 | `var_brg=vmbr1` |
| `var_net` | dhcp/static | dhcp | `var_net=dhcp` |
| `var_gateway` | IP | auto | `var_gateway=192.168.1.1` |
| `var_ipv6_method` | string | none | `var_ipv6_method=disable` |
| `var_vlan` | int | - | `var_vlan=100` |
| `var_mtu` | int | 1500 | `var_mtu=9000` |
| `var_mac` | MAC | auto | `var_mac=02:00:00:00:00:01` |
| `var_ns` | IP | auto | `var_ns=8.8.8.8` |
| `var_ssh` | yes/no | no | `var_ssh=yes` |
| `var_ssh_authorized_key` | string | - | `var_ssh_authorized_key=ssh-rsa...` |
| `var_pw` | string | empty | `var_pw=password` |
| `var_nesting` | 0/1 | 1 | `var_nesting=1` |
| `var_keyctl` | 0/1 | 0 | `var_keyctl=1` |
| `var_fuse` | 0/1 | 0 | `var_fuse=1` |
| `var_mknod` | 0/1 | 0 | `var_mknod=1` |
| `var_mount_fs` | string | - | `var_mount_fs=nfs,cifs` |
| `var_protection` | yes/no | no | `var_protection=yes` |
| `var_tags` | string | community-script | `var_tags=prod,web` |
| `var_timezone` | string | host TZ | `var_timezone=Europe/Berlin` |
| `var_verbose` | yes/no | no | `var_verbose=yes` |
| `var_apt_cacher` | yes/no | no | `var_apt_cacher=yes` |
| `var_apt_cacher_ip` | IP | - | `var_apt_cacher_ip=192.168.1.10` |
| `var_container_storage` | string | auto | `var_container_storage=local-zfs` |
| `var_template_storage` | string | auto | `var_template_storage=local` |
---
## See Also
- [Defaults System Guide](DEFAULTS_GUIDE.md)
- [Unattended Deployments](UNATTENDED_DEPLOYMENTS.md)
- [Security Best Practices](SECURITY_GUIDE.md)
- [Network Configuration](NETWORK_GUIDE.md)

View File

@@ -0,0 +1,748 @@
# Configuration & Defaults System - User Guide
> **Complete Guide to App Defaults and User Defaults**
>
> *Learn how to configure, save, and reuse your installation settings*
---
## Table of Contents
1. [Quick Start](#quick-start)
2. [Understanding the Defaults System](#understanding-the-defaults-system)
3. [Installation Modes](#installation-modes)
4. [How to Save Defaults](#how-to-save-defaults)
5. [How to Use Saved Defaults](#how-to-use-saved-defaults)
6. [Managing Your Defaults](#managing-your-defaults)
7. [Advanced Configuration](#advanced-configuration)
8. [Troubleshooting](#troubleshooting)
---
## Quick Start
### 30-Second Setup
```bash
# 1. Run any container installation script
bash pihole-install.sh
# 2. When prompted, select: "Advanced Settings"
# (This allows you to customize everything)
# 3. Answer all configuration questions
# 4. At the end, when asked "Save as App Defaults?"
# Select: YES
# 5. Done! Your settings are now saved
```
**Next Time**: Run the same script again, select **"App Defaults"** and your settings will be applied automatically!
---
## Understanding the Defaults System
### The Three-Tier System
Your installation settings are managed through three layers:
#### 🔷 **Tier 1: Built-in Defaults** (Fallback)
```
These are hardcoded in the scripts
Provide sensible defaults for each application
Example: PiHole uses 2 CPU cores by default
```
#### 🔶 **Tier 2: User Defaults** (Global)
```
Your personal global defaults
Applied to ALL container installations
Location: /usr/local/community-scripts/default.vars
Example: "I always want 4 CPU cores and 2GB RAM"
```
#### 🔴 **Tier 3: App Defaults** (Specific)
```
Application-specific saved settings
Only applied when installing that specific app
Location: /usr/local/community-scripts/defaults/<appname>.vars
Example: "Whenever I install PiHole, use these exact settings"
```
### Priority System
When installing a container, settings are applied in this order:
```
┌─────────────────────────────────────┐
│ 1. Environment Variables (HIGHEST) │ Set in shell: export var_cpu=8
│ (these override everything) │
├─────────────────────────────────────┤
│ 2. App Defaults │ From: defaults/pihole.vars
│ (app-specific saved settings) │
├─────────────────────────────────────┤
│ 3. User Defaults │ From: default.vars
│ (your global defaults) │
├─────────────────────────────────────┤
│ 4. Built-in Defaults (LOWEST) │ Hardcoded in script
│ (failsafe, always available) │
└─────────────────────────────────────┘
```
**In Plain English**:
- If you set an environment variable → it wins
- Otherwise, if you have app-specific defaults → use those
- Otherwise, if you have user defaults → use those
- Otherwise, use the hardcoded defaults
---
## Installation Modes
When you run any installation script, you'll be presented with a menu:
### Option 1⃣ : **Default Settings**
```
Quick installation with standard settings
├─ Best for: First-time users, quick deployments
├─ What happens:
│ 1. Script uses built-in defaults
│ 2. Container created immediately
│ 3. No questions asked
└─ Time: ~2 minutes
```
**When to use**: You want a standard installation, don't need customization
---
### Option 2⃣ : **Advanced Settings**
```
Full customization with 19 configuration steps
├─ Best for: Power users, custom requirements
├─ What happens:
│ 1. Script asks for EVERY setting
│ 2. You control: CPU, RAM, Disk, Network, SSH, etc.
│ 3. Shows summary before creating
│ 4. Offers to save as App Defaults
└─ Time: ~5-10 minutes
```
**When to use**: You want full control over the configuration
**Available Settings**:
- CPU cores, RAM amount, Disk size
- Container name, network settings
- SSH access, API access, Features
- Password, SSH keys, Tags
---
### Option 3⃣ : **User Defaults**
```
Use your saved global defaults
├─ Best for: Consistent deployments across many containers
├─ Requires: You've previously saved User Defaults
├─ What happens:
│ 1. Loads settings from: /usr/local/community-scripts/default.vars
│ 2. Shows you the loaded settings
│ 3. Creates container immediately
└─ Time: ~2 minutes
```
**When to use**: You have preferred defaults you want to use for every app
---
### Option 4⃣ : **App Defaults** (if available)
```
Use previously saved app-specific defaults
├─ Best for: Repeating the same configuration multiple times
├─ Requires: You've previously saved App Defaults for this app
├─ What happens:
│ 1. Loads settings from: /usr/local/community-scripts/defaults/<app>.vars
│ 2. Shows you the loaded settings
│ 3. Creates container immediately
└─ Time: ~2 minutes
```
**When to use**: You've installed this app before and want identical settings
---
### Option 5⃣ : **Settings Menu**
```
Manage your saved configurations
├─ Functions:
│ • View current settings
│ • Edit storage selections
│ • Manage defaults location
│ • See what's currently configured
└─ Time: ~1 minute
```
**When to use**: You want to review or modify saved settings
---
## How to Save Defaults
### Method 1: Save While Installing
This is the easiest way:
#### Step-by-Step: Create App Defaults
```bash
# 1. Run the installation script
bash pihole-install.sh
# 2. Choose installation mode
# ┌─────────────────────────┐
# │ Select installation mode:│
# │ 1) Default Settings │
# │ 2) Advanced Settings │
# │ 3) User Defaults │
# │ 4) App Defaults │
# │ 5) Settings Menu │
# └─────────────────────────┘
#
# Enter: 2 (Advanced Settings)
# 3. Answer all configuration questions
# • Container name? → my-pihole
# • CPU cores? → 4
# • RAM amount? → 2048
# • Disk size? → 20
# • SSH access? → yes
# ... (more options)
# 4. Review summary (shown before creation)
# ✓ Confirm to proceed
# 5. After creation completes, you'll see:
# ┌──────────────────────────────────┐
# │ Save as App Defaults for PiHole? │
# │ (Yes/No) │
# └──────────────────────────────────┘
#
# Select: Yes
# 6. Done! Settings saved to:
# /usr/local/community-scripts/defaults/pihole.vars
```
#### Step-by-Step: Create User Defaults
```bash
# Same as App Defaults, but:
# When you select "Advanced Settings"
# FIRST app you run with this selection will offer
# to save as "User Defaults" additionally
# This saves to: /usr/local/community-scripts/default.vars
```
---
### Method 2: Manual File Creation
For advanced users who want to create defaults without running installation:
```bash
# Create User Defaults manually
sudo tee /usr/local/community-scripts/default.vars > /dev/null << 'EOF'
# Global User Defaults
var_cpu=4
var_ram=2048
var_disk=20
var_unprivileged=1
var_brg=vmbr0
var_gateway=192.168.1.1
var_timezone=Europe/Berlin
var_ssh=yes
var_container_storage=local
var_template_storage=local
EOF
# Create App Defaults manually
sudo tee /usr/local/community-scripts/defaults/pihole.vars > /dev/null << 'EOF'
# App-specific defaults for PiHole
var_unprivileged=1
var_cpu=2
var_ram=1024
var_disk=10
var_brg=vmbr0
var_gateway=192.168.1.1
var_hostname=pihole
var_container_storage=local
var_template_storage=local
EOF
```
---
### Method 3: Using Environment Variables
Set defaults via environment before running:
```bash
# Set as environment variables
export var_cpu=4
export var_ram=2048
export var_disk=20
export var_hostname=my-container
# Run installation
bash pihole-install.sh
# These settings will be used
# (Can still be overridden by saved defaults)
```
---
## How to Use Saved Defaults
### Using User Defaults
```bash
# 1. Run any installation script
bash pihole-install.sh
# 2. When asked for mode, select:
# Option: 3 (User Defaults)
# 3. Your settings from default.vars are applied
# 4. Container created with your saved settings
```
### Using App Defaults
```bash
# 1. Run the app you configured before
bash pihole-install.sh
# 2. When asked for mode, select:
# Option: 4 (App Defaults)
# 3. Your settings from defaults/pihole.vars are applied
# 4. Container created with exact same settings
```
### Overriding Saved Defaults
```bash
# Even if you have defaults saved,
# you can override them with environment variables
export var_cpu=8 # Override saved defaults
export var_hostname=custom-name
bash pihole-install.sh
# Installation will use these values instead of saved defaults
```
---
## Managing Your Defaults
### View Your Settings
#### View User Defaults
```bash
cat /usr/local/community-scripts/default.vars
```
#### View App Defaults
```bash
cat /usr/local/community-scripts/defaults/pihole.vars
```
#### List All Saved App Defaults
```bash
ls -la /usr/local/community-scripts/defaults/
```
### Edit Your Settings
#### Edit User Defaults
```bash
sudo nano /usr/local/community-scripts/default.vars
```
#### Edit App Defaults
```bash
sudo nano /usr/local/community-scripts/defaults/pihole.vars
```
### Update Existing Defaults
```bash
# Run installation again with your app
bash pihole-install.sh
# Select: Advanced Settings
# Make desired changes
# At end, when asked to save:
# "Defaults already exist, Update?"
# Select: Yes
# Your saved defaults are updated
```
### Delete Defaults
#### Delete User Defaults
```bash
sudo rm /usr/local/community-scripts/default.vars
```
#### Delete App Defaults
```bash
sudo rm /usr/local/community-scripts/defaults/pihole.vars
```
#### Delete All App Defaults
```bash
sudo rm /usr/local/community-scripts/defaults/*
```
---
## Advanced Configuration
### Available Variables
All configurable variables start with `var_`:
#### Resource Allocation
```bash
var_cpu=4 # CPU cores
var_ram=2048 # RAM in MB
var_disk=20 # Disk in GB
var_unprivileged=1 # 0=privileged, 1=unprivileged
```
#### Network
```bash
var_brg=vmbr0 # Bridge interface
var_net=veth # Network driver
var_gateway=192.168.1.1 # Default gateway
var_mtu=1500 # MTU size
var_vlan=100 # VLAN ID
```
#### System
```bash
var_hostname=pihole # Container name
var_timezone=Europe/Berlin # Timezone
var_pw=SecurePass123 # Root password
var_tags=dns,pihole # Tags for organization
var_verbose=yes # Enable verbose output
```
#### Security & Access
```bash
var_ssh=yes # Enable SSH
var_ssh_authorized_key="ssh-rsa AA..." # SSH public key
var_protection=1 # Enable protection flag
```
#### Features
```bash
var_fuse=1 # FUSE filesystem support
var_tun=1 # TUN device support
var_nesting=1 # Nesting (Docker in LXC)
var_keyctl=1 # Keyctl syscall
var_mknod=1 # Device node creation
```
#### Storage
```bash
var_container_storage=local # Where to store container
var_template_storage=local # Where to store templates
```
### Example Configuration Files
#### Gaming Server Defaults
```bash
# High performance for gaming containers
var_cpu=8
var_ram=4096
var_disk=50
var_unprivileged=0
var_fuse=1
var_nesting=1
var_tags=gaming
```
#### Development Server
```bash
# Development with Docker support
var_cpu=4
var_ram=2048
var_disk=30
var_unprivileged=1
var_nesting=1
var_ssh=yes
var_tags=development
```
#### IoT/Monitoring
```bash
# Low-resource, always-on containers
var_cpu=2
var_ram=512
var_disk=10
var_unprivileged=1
var_nesting=0
var_fuse=0
var_tun=0
var_tags=iot,monitoring
```
---
## Troubleshooting
### "App Defaults not available" Message
**Problem**: You want to use App Defaults, but option says they're not available
**Solution**:
1. You haven't created App Defaults yet for this app
2. Run the app with "Advanced Settings"
3. When finished, save as App Defaults
4. Next time, App Defaults will be available
---
### "Settings not being applied"
**Problem**: You saved defaults, but they're not being used
**Checklist**:
```bash
# 1. Verify files exist
ls -la /usr/local/community-scripts/default.vars
ls -la /usr/local/community-scripts/defaults/<app>.vars
# 2. Check file permissions (should be readable)
stat /usr/local/community-scripts/default.vars
# 3. Verify correct mode selected
# (Make sure you selected "User Defaults" or "App Defaults")
# 4. Check for environment variable override
env | grep var_
# If you have var_* set in environment,
# those override your saved defaults
```
---
### "Cannot write to defaults location"
**Problem**: Permission denied when saving defaults
**Solution**:
```bash
# Create the defaults directory if missing
sudo mkdir -p /usr/local/community-scripts/defaults
# Fix permissions
sudo chmod 755 /usr/local/community-scripts
sudo chmod 755 /usr/local/community-scripts/defaults
# Make sure you're running as root
sudo bash pihole-install.sh
```
---
### "Defaults directory doesn't exist"
**Problem**: Script can't find where to save defaults
**Solution**:
```bash
# Create the directory
sudo mkdir -p /usr/local/community-scripts/defaults
# Verify
ls -la /usr/local/community-scripts/
```
---
### Settings seem random or wrong
**Problem**: Container gets different settings than expected
**Possible Causes & Solutions**:
```bash
# 1. Check if environment variables are set
env | grep var_
# If you see var_* entries, those override your defaults
# Clear them: unset var_cpu var_ram (etc)
# 2. Verify correct defaults are in files
cat /usr/local/community-scripts/default.vars
cat /usr/local/community-scripts/defaults/pihole.vars
# 3. Check which mode you actually selected
# (Script output shows which defaults were applied)
# 4. Check Proxmox logs for errors
sudo journalctl -u pve-daemon -n 50
```
---
### "Variable not recognized"
**Problem**: You set a variable that doesn't work
**Solution**:
Only certain variables are allowed (security whitelist):
```
Allowed variables (starting with var_):
✓ var_cpu, var_ram, var_disk, var_unprivileged
✓ var_brg, var_gateway, var_mtu, var_vlan, var_net
✓ var_hostname, var_pw, var_timezone
✓ var_ssh, var_ssh_authorized_key
✓ var_fuse, var_tun, var_nesting, var_keyctl
✓ var_container_storage, var_template_storage
✓ var_tags, var_verbose
✓ var_apt_cacher, var_apt_cacher_ip
✓ var_protection, var_mount_fs
✗ Other variables are NOT supported
```
---
## Best Practices
### ✅ Do's
✓ Use **App Defaults** when you want app-specific settings
✓ Use **User Defaults** for your global preferences
✓ Edit defaults files directly with `nano` (safe)
✓ Keep separate App Defaults for each app
✓ Back up your defaults regularly
✓ Use environment variables for temporary overrides
### ❌ Don'ts
✗ Don't use `source` on defaults files (security risk)
✗ Don't put sensitive passwords in defaults (use SSH keys)
✗ Don't modify defaults while installation is running
✗ Don't delete defaults.d while containers are being created
✗ Don't use special characters without escaping
---
## Quick Reference
### Defaults Locations
| Type | Location | Example |
|------|----------|---------|
| User Defaults | `/usr/local/community-scripts/default.vars` | Global settings |
| App Defaults | `/usr/local/community-scripts/defaults/<app>.vars` | PiHole-specific |
| Backup Dir | `/usr/local/community-scripts/defaults/` | All app defaults |
### File Format
```bash
# Comments start with #
var_name=value
# No spaces around =
var_cpu=4
var_cpu = 4
# String values don't need quotes
var_hostname=mycontainer
var_hostname='mycontainer'
# Values with spaces need quotes
var_tags="docker,production,testing"
var_tags=docker,production,testing
```
### Command Reference
```bash
# View defaults
cat /usr/local/community-scripts/default.vars
# Edit defaults
sudo nano /usr/local/community-scripts/default.vars
# List all app defaults
ls /usr/local/community-scripts/defaults/
# Backup your defaults
cp -r /usr/local/community-scripts/defaults/ ~/defaults-backup/
# Set temporary override
export var_cpu=8
bash pihole-install.sh
# Create custom defaults
sudo tee /usr/local/community-scripts/defaults/custom.vars << 'EOF'
var_cpu=4
var_ram=2048
EOF
```
---
## Getting Help
### Need More Information?
- 📖 [Main Documentation](../../docs/)
- 🐛 [Report Issues](https://github.com/community-scripts/ProxmoxVE/issues)
- 💬 [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)
### Useful Commands
```bash
# Check what variables are available
grep "var_" /path/to/app-install.sh | head -20
# Verify defaults syntax
cat /usr/local/community-scripts/default.vars
# Monitor installation with defaults
bash pihole-install.sh 2>&1 | tee installation.log
```
---
## Document Information
| Field | Value |
|-------|-------|
| Version | 1.0 |
| Last Updated | November 28, 2025 |
| Status | Current |
| License | MIT |
---
**Happy configuring! 🚀**

58
docs/guides/README.md Normal file
View File

@@ -0,0 +1,58 @@
# Configuration & Deployment Guides
This directory contains comprehensive guides for configuring and deploying Proxmox VE containers using community-scripts.
## 📚 Available Guides
### [Configuration Reference](CONFIGURATION_REFERENCE.md)
Complete reference for all configuration options, environment variables, and advanced settings available in the build system.
**Topics covered:**
- Container specifications (CPU, RAM, Disk)
- Network configuration (IPv4/IPv6, VLAN, MTU)
- Storage selection and management
- Privilege modes and features
- OS selection and versions
### [Defaults System Guide](DEFAULTS_SYSTEM_GUIDE.md)
Understanding and customizing default settings for container deployments.
**Topics covered:**
- Default system settings
- Per-script overrides
- Custom defaults configuration
- Environment variable precedence
### [Unattended Deployments](UNATTENDED_DEPLOYMENTS.md)
Automating container deployments without user interaction.
**Topics covered:**
- Environment variable configuration
- Batch deployments
- CI/CD integration
- Scripted installations
- Pre-configured templates
## 🔗 Related Documentation
- **[CT Scripts Guide](../ct/)** - Container script structure and usage
- **[Install Scripts Guide](../install/)** - Installation script internals
- **[API Documentation](../api/)** - API integration and endpoints
- **[Build Functions](../misc/build.func/)** - Build system functions reference
- **[Tools Functions](../misc/tools.func/)** - Utility functions reference
## 💡 Quick Start
For most users, start with the **Unattended Deployments** guide to learn how to automate your container setups.
For advanced configuration options, refer to the **Configuration Reference**.
## 🤝 Contributing
If you'd like to improve these guides or add new ones, please see our [Contribution Guide](../contribution/).

View File

@@ -0,0 +1,963 @@
# Unattended Deployments Guide
Complete guide for automated, zero-interaction container deployments using community-scripts for Proxmox VE.
---
## 🎯 What You'll Learn
This comprehensive guide covers:
- ✅ Complete automation of container deployments
- ✅ Zero-interaction installations
- ✅ Batch deployments (multiple containers)
- ✅ Infrastructure as Code (Ansible, Terraform)
- ✅ CI/CD pipeline integration
- ✅ Error handling and rollback strategies
- ✅ Production-ready deployment scripts
- ✅ Security best practices
---
## Table of Contents
1. [Overview](#overview)
2. [Prerequisites](#prerequisites)
3. [Deployment Methods](#deployment-methods)
4. [Single Container Deployment](#single-container-deployment)
5. [Batch Deployments](#batch-deployments)
6. [Infrastructure as Code](#infrastructure-as-code)
7. [CI/CD Integration](#cicd-integration)
8. [Error Handling](#error-handling)
9. [Security Considerations](#security-considerations)
---
## Overview
Unattended deployments allow you to:
- ✅ Deploy containers without manual interaction
- ✅ Automate infrastructure provisioning
- ✅ Integrate with CI/CD pipelines
- ✅ Maintain consistent configurations
- ✅ Scale deployments across multiple nodes
---
## Prerequisites
### 1. Proxmox VE Access
```bash
# Verify you have root access
whoami # Should return: root
# Check Proxmox version (8.0+ or 9.0-9.1 required)
pveversion
```
### 2. Network Connectivity
```bash
# Test GitHub access
curl -I https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh
# Test internet connectivity
ping -c 1 1.1.1.1
```
### 3. Storage Available
```bash
# List available storage
pvesm status
# Check free space
df -h
```
---
## Deployment Methods
### Method Comparison
| Method | Use Case | Complexity | Flexibility |
|--------|----------|------------|-------------|
| **Environment Variables** | Quick one-offs | Low | High |
| **App Defaults** | Repeat deployments | Low | Medium |
| **Shell Scripts** | Batch operations | Medium | High |
| **Ansible** | Infrastructure as Code | High | Very High |
| **Terraform** | Cloud-native IaC | High | Very High |
---
## Single Container Deployment
### Basic Unattended Deployment
**Simplest form:**
```bash
var_hostname=myserver bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/debian.sh)"
```
### Complete Configuration Example
```bash
#!/bin/bash
# deploy-single.sh - Deploy a single container with full configuration
var_unprivileged=1 \
var_cpu=4 \
var_ram=4096 \
var_disk=30 \
var_hostname=production-app \
var_brg=vmbr0 \
var_net=dhcp \
var_ipv6_method=none \
var_ssh=yes \
var_ssh_authorized_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... admin@workstation" \
var_nesting=1 \
var_tags=production,automated \
var_protection=yes \
var_verbose=no \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"
echo "✓ Container deployed successfully"
```
### Using App Defaults
**Step 1: Create defaults once (interactive)**
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/pihole.sh)"
# Select "Advanced Settings" → Configure → Save as "App Defaults"
```
**Step 2: Deploy unattended (uses saved defaults)**
```bash
#!/bin/bash
# deploy-with-defaults.sh
# App defaults are loaded automatically
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/pihole.sh)"
# Script will use /usr/local/community-scripts/defaults/pihole.vars
```
---
## Batch Deployments
### Deploy Multiple Containers
#### Simple Loop
```bash
#!/bin/bash
# batch-deploy-simple.sh
apps=("debian" "ubuntu" "alpine")
for app in "${apps[@]}"; do
echo "Deploying $app..."
var_hostname="$app-container" \
var_cpu=2 \
var_ram=2048 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)"
echo "$app deployed"
sleep 5 # Wait between deployments
done
```
#### Advanced with Configuration Array
```bash
#!/bin/bash
# batch-deploy-advanced.sh - Deploy multiple containers with individual configs
declare -A CONTAINERS=(
["pihole"]="2:1024:8:vmbr0:dns,network"
["homeassistant"]="4:4096:20:vmbr0:automation,ha"
["docker"]="6:8192:50:vmbr1:containers,docker"
["nginx"]="2:2048:10:vmbr0:webserver,proxy"
)
for app in "${!CONTAINERS[@]}"; do
# Parse configuration
IFS=':' read -r cpu ram disk bridge tags <<< "${CONTAINERS[$app]}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Deploying: $app"
echo " CPU: $cpu cores"
echo " RAM: $ram MB"
echo " Disk: $disk GB"
echo " Bridge: $bridge"
echo " Tags: $tags"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Deploy container
var_unprivileged=1 \
var_cpu="$cpu" \
var_ram="$ram" \
var_disk="$disk" \
var_hostname="$app" \
var_brg="$bridge" \
var_net=dhcp \
var_ipv6_method=none \
var_ssh=yes \
var_tags="$tags,automated" \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" 2>&1 | tee "deploy-${app}.log"
if [ $? -eq 0 ]; then
echo "$app deployed successfully"
else
echo "$app deployment failed - check deploy-${app}.log"
fi
sleep 5
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Batch deployment complete!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
```
#### Parallel Deployment
```bash
#!/bin/bash
# parallel-deploy.sh - Deploy multiple containers in parallel
deploy_container() {
local app="$1"
local cpu="$2"
local ram="$3"
local disk="$4"
echo "[$app] Starting deployment..."
var_cpu="$cpu" \
var_ram="$ram" \
var_disk="$disk" \
var_hostname="$app" \
var_net=dhcp \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)" \
&> "deploy-${app}.log"
echo "[$app] ✓ Completed"
}
# Export function for parallel execution
export -f deploy_container
# Deploy in parallel (max 3 at a time)
parallel -j 3 deploy_container ::: \
"debian 2 2048 10" \
"ubuntu 2 2048 10" \
"alpine 1 1024 5" \
"pihole 2 1024 8" \
"docker 4 4096 30"
echo "All deployments complete!"
```
---
## Infrastructure as Code
### Ansible Playbook
#### Basic Playbook
```yaml
---
# playbook-proxmox.yml
- name: Deploy ProxmoxVED Containers
hosts: proxmox_hosts
become: yes
tasks:
- name: Deploy Debian Container
shell: |
var_unprivileged=1 \
var_cpu=2 \
var_ram=2048 \
var_disk=10 \
var_hostname=debian-{{ inventory_hostname }} \
var_net=dhcp \
var_ssh=yes \
var_tags=ansible,automated \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"
args:
executable: /bin/bash
register: deploy_result
- name: Display deployment result
debug:
var: deploy_result.stdout_lines
```
#### Advanced Playbook with Variables
```yaml
---
# advanced-playbook.yml
- name: Deploy Multiple Container Types
hosts: proxmox
vars:
containers:
- name: pihole
cpu: 2
ram: 1024
disk: 8
tags: "dns,network"
- name: homeassistant
cpu: 4
ram: 4096
disk: 20
tags: "automation,ha"
- name: docker
cpu: 6
ram: 8192
disk: 50
tags: "containers,docker"
ssh_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
tasks:
- name: Ensure community-scripts directory exists
file:
path: /usr/local/community-scripts/defaults
state: directory
mode: '0755'
- name: Deploy containers
shell: |
var_unprivileged=1 \
var_cpu={{ item.cpu }} \
var_ram={{ item.ram }} \
var_disk={{ item.disk }} \
var_hostname={{ item.name }} \
var_brg=vmbr0 \
var_net=dhcp \
var_ipv6_method=none \
var_ssh=yes \
var_ssh_authorized_key="{{ ssh_key }}" \
var_tags="{{ item.tags }},ansible" \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/{{ item.name }}.sh)"
args:
executable: /bin/bash
loop: "{{ containers }}"
register: deployment_results
- name: Wait for containers to be ready
wait_for:
timeout: 60
- name: Report deployment status
debug:
msg: "Deployed {{ item.item.name }} - Status: {{ 'Success' if item.rc == 0 else 'Failed' }}"
loop: "{{ deployment_results.results }}"
```
Run with:
```bash
ansible-playbook -i inventory.ini advanced-playbook.yml
```
### Terraform Integration
```hcl
# main.tf - Deploy containers via Terraform
terraform {
required_providers {
proxmox = {
source = "telmate/proxmox"
version = "2.9.14"
}
}
}
provider "proxmox" {
pm_api_url = "https://proxmox.example.com:8006/api2/json"
pm_api_token_id = "terraform@pam!terraform"
pm_api_token_secret = var.proxmox_token
}
resource "null_resource" "deploy_container" {
for_each = var.containers
provisioner "remote-exec" {
inline = [
"var_unprivileged=1",
"var_cpu=${each.value.cpu}",
"var_ram=${each.value.ram}",
"var_disk=${each.value.disk}",
"var_hostname=${each.key}",
"var_net=dhcp",
"bash -c \"$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${each.value.template}.sh)\""
]
connection {
type = "ssh"
host = var.proxmox_host
user = "root"
private_key = file("~/.ssh/id_rsa")
}
}
}
variable "containers" {
type = map(object({
template = string
cpu = number
ram = number
disk = number
}))
default = {
"pihole" = {
template = "pihole"
cpu = 2
ram = 1024
disk = 8
}
"homeassistant" = {
template = "homeassistant"
cpu = 4
ram = 4096
disk = 20
}
}
}
```
---
## CI/CD Integration
### GitHub Actions
```yaml
# .github/workflows/deploy-container.yml
name: Deploy Container to Proxmox
on:
push:
branches: [main]
workflow_dispatch:
inputs:
container_type:
description: 'Container type to deploy'
required: true
type: choice
options:
- debian
- ubuntu
- docker
- pihole
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Proxmox
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.PROXMOX_HOST }}
username: root
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
var_unprivileged=1 \
var_cpu=4 \
var_ram=4096 \
var_disk=30 \
var_hostname=${{ github.event.inputs.container_type }}-ci \
var_net=dhcp \
var_ssh=yes \
var_tags=ci-cd,automated \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${{ github.event.inputs.container_type }}.sh)"
- name: Notify deployment status
if: success()
run: echo "✓ Container deployed successfully"
```
### GitLab CI
```yaml
# .gitlab-ci.yml
stages:
- deploy
deploy_container:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client curl bash
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $PROXMOX_HOST >> ~/.ssh/known_hosts
script:
- |
ssh root@$PROXMOX_HOST << 'EOF'
var_unprivileged=1 \
var_cpu=4 \
var_ram=4096 \
var_disk=30 \
var_hostname=gitlab-ci-container \
var_net=dhcp \
var_tags=gitlab-ci,automated \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"
EOF
only:
- main
when: manual
```
---
## Error Handling
### Deployment Verification Script
```bash
#!/bin/bash
# deploy-with-verification.sh
APP="debian"
HOSTNAME="production-server"
MAX_RETRIES=3
RETRY_COUNT=0
deploy_container() {
echo "Attempting deployment (Try $((RETRY_COUNT + 1))/$MAX_RETRIES)..."
var_unprivileged=1 \
var_cpu=4 \
var_ram=4096 \
var_disk=30 \
var_hostname="$HOSTNAME" \
var_net=dhcp \
var_ssh=yes \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)" 2>&1 | tee deploy.log
return ${PIPESTATUS[0]}
}
verify_deployment() {
echo "Verifying deployment..."
# Check if container exists
if ! pct list | grep -q "$HOSTNAME"; then
echo "✗ Container not found in pct list"
return 1
fi
# Check if container is running
CTID=$(pct list | grep "$HOSTNAME" | awk '{print $1}')
STATUS=$(pct status "$CTID" | awk '{print $2}')
if [ "$STATUS" != "running" ]; then
echo "✗ Container not running (Status: $STATUS)"
return 1
fi
# Check network connectivity
if ! pct exec "$CTID" -- ping -c 1 1.1.1.1 &>/dev/null; then
echo "⚠ Warning: No internet connectivity"
fi
echo "✓ Deployment verified successfully"
echo " Container ID: $CTID"
echo " Status: $STATUS"
echo " IP: $(pct exec "$CTID" -- hostname -I)"
return 0
}
# Main deployment loop with retry
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
if deploy_container; then
if verify_deployment; then
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✓ Deployment successful!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 0
else
echo "✗ Deployment verification failed"
fi
else
echo "✗ Deployment failed"
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
echo "Retrying in 10 seconds..."
sleep 10
fi
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✗ Deployment failed after $MAX_RETRIES attempts"
echo "Check deploy.log for details"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 1
```
### Rollback on Failure
```bash
#!/bin/bash
# deploy-with-rollback.sh
APP="debian"
HOSTNAME="test-server"
SNAPSHOT_NAME="pre-deployment"
# Take snapshot of existing container (if exists)
backup_existing() {
EXISTING_CTID=$(pct list | grep "$HOSTNAME" | awk '{print $1}')
if [ -n "$EXISTING_CTID" ]; then
echo "Creating snapshot of existing container..."
pct snapshot "$EXISTING_CTID" "$SNAPSHOT_NAME" --description "Pre-deployment backup"
return 0
fi
return 1
}
# Deploy new container
deploy() {
var_hostname="$HOSTNAME" \
var_cpu=4 \
var_ram=4096 \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)"
return $?
}
# Rollback to snapshot
rollback() {
local ctid="$1"
echo "Rolling back to snapshot..."
pct rollback "$ctid" "$SNAPSHOT_NAME"
pct delsnapshot "$ctid" "$SNAPSHOT_NAME"
}
# Main execution
backup_existing
HAD_BACKUP=$?
if deploy; then
echo "✓ Deployment successful"
[ $HAD_BACKUP -eq 0 ] && echo "You can remove the snapshot with: pct delsnapshot <CTID> $SNAPSHOT_NAME"
else
echo "✗ Deployment failed"
if [ $HAD_BACKUP -eq 0 ]; then
read -p "Rollback to previous version? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rollback "$EXISTING_CTID"
echo "✓ Rolled back successfully"
fi
fi
exit 1
fi
```
---
## Security Considerations
### Secure Deployment Script
```bash
#!/bin/bash
# secure-deploy.sh - Production-ready secure deployment
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Configuration
readonly APP="debian"
readonly HOSTNAME="secure-server"
readonly SSH_KEY_PATH="/root/.ssh/id_rsa.pub"
readonly LOG_FILE="/var/log/container-deployments.log"
# Logging function
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
# Validate prerequisites
validate_environment() {
log "Validating environment..."
# Check if running as root
if [ "$EUID" -ne 0 ]; then
log "ERROR: Must run as root"
exit 1
fi
# Check SSH key exists
if [ ! -f "$SSH_KEY_PATH" ]; then
log "ERROR: SSH key not found at $SSH_KEY_PATH"
exit 1
fi
# Check internet connectivity
if ! curl -s --max-time 5 https://github.com &>/dev/null; then
log "ERROR: No internet connectivity"
exit 1
fi
log "✓ Environment validated"
}
# Secure deployment
deploy_secure() {
log "Starting secure deployment for $HOSTNAME..."
SSH_KEY=$(cat "$SSH_KEY_PATH")
var_unprivileged=1 \
var_cpu=4 \
var_ram=4096 \
var_disk=30 \
var_hostname="$HOSTNAME" \
var_brg=vmbr0 \
var_net=dhcp \
var_ipv6_method=disable \
var_ssh=yes \
var_ssh_authorized_key="$SSH_KEY" \
var_nesting=0 \
var_keyctl=0 \
var_fuse=0 \
var_protection=yes \
var_tags=production,secure,automated \
var_verbose=no \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${APP}.sh)" 2>&1 | tee -a "$LOG_FILE"
if [ ${PIPESTATUS[0]} -eq 0 ]; then
log "✓ Deployment successful"
return 0
else
log "✗ Deployment failed"
return 1
fi
}
# Main execution
main() {
validate_environment
if deploy_secure; then
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log "Secure deployment completed successfully"
log "Container: $HOSTNAME"
log "Features: Unprivileged, SSH-only, Protected"
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 0
else
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log "Deployment failed - check logs at $LOG_FILE"
log "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
exit 1
fi
}
main "$@"
```
### SSH Key Management
```bash
#!/bin/bash
# deploy-with-ssh-keys.sh - Secure SSH key deployment
# Load SSH keys from multiple sources
load_ssh_keys() {
local keys=()
# Personal key
if [ -f ~/.ssh/id_rsa.pub ]; then
keys+=("$(cat ~/.ssh/id_rsa.pub)")
fi
# Team keys
if [ -f /etc/ssh/authorized_keys.d/team ]; then
while IFS= read -r key; do
[ -n "$key" ] && keys+=("$key")
done < /etc/ssh/authorized_keys.d/team
fi
# Join keys with newline
printf "%s\n" "${keys[@]}"
}
# Deploy with multiple SSH keys
SSH_KEYS=$(load_ssh_keys)
var_ssh=yes \
var_ssh_authorized_key="$SSH_KEYS" \
var_hostname=multi-key-server \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/debian.sh)"
```
---
## Complete Production Example
```bash
#!/bin/bash
# production-deploy.sh - Complete production deployment system
set -euo pipefail
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Configuration
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_DIR="/var/log/proxmox-deployments"
readonly CONFIG_FILE="$SCRIPT_DIR/deployment-config.json"
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Functions
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
setup_logging() {
mkdir -p "$LOG_DIR"
exec 1> >(tee -a "$LOG_DIR/deployment-$(date +%Y%m%d-%H%M%S).log")
exec 2>&1
}
log_info() { echo "[INFO] $(date +'%H:%M:%S') - $*"; }
log_error() { echo "[ERROR] $(date +'%H:%M:%S') - $*" >&2; }
log_success() { echo "[SUCCESS] $(date +'%H:%M:%S') - $*"; }
validate_prerequisites() {
log_info "Validating prerequisites..."
[ "$EUID" -eq 0 ] || { log_error "Must run as root"; exit 1; }
command -v jq >/dev/null 2>&1 || { log_error "jq not installed"; exit 1; }
command -v curl >/dev/null 2>&1 || { log_error "curl not installed"; exit 1; }
log_success "Prerequisites validated"
}
deploy_from_config() {
local config_file="$1"
if [ ! -f "$config_file" ]; then
log_error "Config file not found: $config_file"
return 1
fi
local container_count
container_count=$(jq '.containers | length' "$config_file")
log_info "Deploying $container_count containers from config..."
for i in $(seq 0 $((container_count - 1))); do
local name cpu ram disk app tags
name=$(jq -r ".containers[$i].name" "$config_file")
cpu=$(jq -r ".containers[$i].cpu" "$config_file")
ram=$(jq -r ".containers[$i].ram" "$config_file")
disk=$(jq -r ".containers[$i].disk" "$config_file")
app=$(jq -r ".containers[$i].app" "$config_file")
tags=$(jq -r ".containers[$i].tags" "$config_file")
log_info "Deploying container: $name ($app)"
var_unprivileged=1 \
var_cpu="$cpu" \
var_ram="$ram" \
var_disk="$disk" \
var_hostname="$name" \
var_net=dhcp \
var_ssh=yes \
var_tags="$tags,automated" \
var_protection=yes \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/ct/${app}.sh)"
if [ $? -eq 0 ]; then
log_success "Deployed: $name"
else
log_error "Failed to deploy: $name"
fi
sleep 5
done
}
generate_report() {
log_info "Generating deployment report..."
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "DEPLOYMENT REPORT"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Time: $(date)"
echo ""
pct list
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
}
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Main
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
main() {
setup_logging
log_info "Starting production deployment system"
validate_prerequisites
deploy_from_config "$CONFIG_FILE"
generate_report
log_success "Production deployment complete"
}
main "$@"
```
**Example config file (deployment-config.json):**
```json
{
"containers": [
{
"name": "pihole",
"app": "pihole",
"cpu": 2,
"ram": 1024,
"disk": 8,
"tags": "dns,network,production"
},
{
"name": "homeassistant",
"app": "homeassistant",
"cpu": 4,
"ram": 4096,
"disk": 20,
"tags": "automation,ha,production"
},
{
"name": "docker-host",
"app": "docker",
"cpu": 8,
"ram": 16384,
"disk": 100,
"tags": "containers,docker,production"
}
]
}
```
---
## See Also
- [Defaults System Guide](DEFAULTS_GUIDE.md)
- [Configuration Reference](CONFIGURATION_REFERENCE.md)
- [Security Best Practices](SECURITY_GUIDE.md)
- [Network Configuration](NETWORK_GUIDE.md)