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

5.7 KiB

Using Templates as Base for Multiple LXC Deployments

Overview

Yes, you can absolutely use a template (created by all-templates.sh or any official Proxmox template) as a base for deploying multiple LXC containers. There are two main approaches:

This is the most common approach - use the official Proxmox template directly for each deployment.

How It Works

  1. Download template once (if not already available):

    pveam download local debian-12-standard_12.2-1_amd64.tar.zst
    
  2. Deploy multiple containers from the same template:

    # Container 1
    pct create 100 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
      --hostname container1 --memory 2048 --cores 2
    
    # Container 2
    pct create 101 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
      --hostname container2 --memory 2048 --cores 2
    
    # Container 3
    pct create 102 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
      --hostname container3 --memory 4096 --cores 4
    

Advantages

  • Fast deployments (template is reused)
  • Clean slate for each container
  • Official templates are maintained and updated
  • Less storage overhead (linked clones possible)

Example from Codebase

Looking at smom-dbis-138-proxmox/scripts/deployment/deploy-services.sh, this approach is used:

pct create "$vmid" \
    "${CONTAINER_OS_TEMPLATE:-local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst}" \
    --storage "${PROXMOX_STORAGE:-local-lvm}" \
    --hostname "$hostname" \
    --memory "$memory" \
    --cores "$cores" \
    --rootfs "${PROXMOX_STORAGE:-local-lvm}:${disk}" \
    --net0 "$network_config"

Approach 2: Create Custom Template from Base Container

If you need a pre-configured base with specific packages or configurations.

Workflow

  1. Create a base container using all-templates.sh:

    bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/all-templates.sh)"
    # Select: debian-12-standard
    
  2. Customize the base container:

    # Enter the container
    pct enter <CTID>
    
    # Install common packages, configure settings, etc.
    apt update && apt upgrade -y
    apt install -y curl wget git vim htop
    
    # Configure base settings
    # ... your customizations ...
    
    # Exit container
    exit
    
  3. Stop the container:

    pct stop <CTID>
    
  4. Convert container to template:

    pct template <CTID>
    
  5. Deploy multiple containers from your custom template:

    # Use the template (it's now at local:vztmpl/vm-<CTID>.tar.gz)
    pct create 200 local:vztmpl/vm-<CTID>.tar.gz \
      --hostname app1 --memory 2048
    
    pct create 201 local:vztmpl/vm-<CTID>.tar.gz \
      --hostname app2 --memory 2048
    

Advantages

  • Pre-configured with your common packages
  • Faster deployment (less setup per container)
  • Consistent base configuration
  • Custom applications/tools pre-installed

Considerations

  • ⚠️ Template becomes static (won't get OS updates automatically)
  • ⚠️ Requires maintenance if you need to update base packages
  • ⚠️ Larger template size (includes your customizations)

Approach 3: Clone Existing Container

For quick duplication of an existing container:

# Clone container 100 to new container 200
pct clone 100 200 --hostname new-container

This creates a linked clone (space-efficient) or full clone depending on storage capabilities.

Based on the codebase patterns, here's the recommended approach:

For Standard Deployments

Use official templates directly - This is what most scripts in the codebase do:

# Set your base template
CONTAINER_OS_TEMPLATE="local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst"

# Deploy multiple containers with different configurations
for i in {1..5}; do
  pct create $((100+i)) "$CONTAINER_OS_TEMPLATE" \
    --hostname "app-$i" \
    --memory 2048 \
    --cores 2 \
    --rootfs local-lvm:20 \
    --net0 name=eth0,bridge=vmbr0,ip=dhcp
done

For Pre-Configured Bases

If you need a customized base:

  1. Create one container from all-templates.sh
  2. Customize it with common packages/configurations
  3. Convert to template: pct template <CTID>
  4. Use that template for all future deployments

Example: Batch Deployment Script

Here's a script that deploys multiple containers from a base template:

#!/bin/bash
# deploy-multiple-containers.sh

BASE_TEMPLATE="${CONTAINER_OS_TEMPLATE:-local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst}"
START_CTID=100

declare -A CONTAINERS=(
  ["web1"]="2048:2:20"
  ["web2"]="2048:2:20"
  ["db1"]="4096:4:50"
  ["app1"]="2048:2:30"
)

for hostname in "${!CONTAINERS[@]}"; do
  IFS=':' read -r memory cores disk <<< "${CONTAINERS[$hostname]}"
  CTID=$((START_CTID++))
  
  echo "Creating $hostname (CTID: $CTID)..."
  pct create $CTID "$BASE_TEMPLATE" \
    --hostname "$hostname" \
    --memory "$memory" \
    --cores "$cores" \
    --rootfs local-lvm:"$disk" \
    --net0 name=eth0,bridge=vmbr0,ip=dhcp \
    --unprivileged 1 \
    --features nesting=1,keyctl=1
  
  pct start $CTID
  echo "✓ $hostname created and started"
done

Summary

  • Yes, templates can be the base for all LXC deployments
  • Official templates (from all-templates.sh) are best for standard deployments
  • Custom templates (from pct template) are best for pre-configured bases
  • Cloning (pct clone) is best for quick duplication

The codebase already uses this pattern extensively - templates are reused for multiple container deployments, making it efficient and consistent.