claude-configs/skills/proxmox/scripts/create_docker_lxc_template.py
Cal Corum 8a1d15911f Initial commit: Claude Code configuration backup
Version control Claude Code configuration including:
- Global instructions (CLAUDE.md)
- User settings (settings.json)
- Custom agents (architect, designer, engineer, etc.)
- Custom skills (create-skill templates and workflows)

Excludes session data, secrets, cache, and temporary files per .gitignore.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 16:34:21 -06:00

251 lines
8.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Create Docker-Ready LXC Template
Creates a fully configured LXC template with Docker pre-installed and optimized
"""
import sys
import os
import time
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from proxmox_client import ProxmoxClient
def create_docker_lxc_template(
template_id: int = 9001,
template_name: str = "docker-lxc-template",
os_template: str = "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst",
memory: int = 2048,
cores: int = 2,
disk_size: int = 20,
storage: str = "local-lvm"
):
"""
Create a Docker-ready LXC template
Args:
template_id: Container ID for the template
template_name: Hostname for the template
os_template: Base OS template to use
memory: Memory allocation in MB
cores: CPU cores
disk_size: Root disk size in GB
storage: Storage pool to use
"""
client = ProxmoxClient()
print(f"🚀 Creating Docker-Ready LXC Template (ID: {template_id})")
print("=" * 60)
# Step 1: Check if template ID is available
print("\n📋 Step 1: Checking template ID availability...")
try:
existing = client.get_container(template_id)
print(f"❌ Container ID {template_id} already exists!")
print(f" Name: {existing.get('hostname', 'unknown')}")
response = input(" Delete existing container? (yes/no): ")
if response.lower() == 'yes':
print(f" Stopping container {template_id}...")
try:
client.stop_container(template_id)
time.sleep(5)
except:
pass
print(f" Deleting container {template_id}...")
upid = client.delete_container(template_id)
client.wait_for_task(upid, timeout=60)
print(" ✅ Container deleted")
else:
print(" Aborting...")
return False
except:
print(f"✅ Container ID {template_id} is available")
# Step 2: List available OS templates
print("\n📦 Step 2: Checking available OS templates...")
templates = client.list_container_templates()
template_found = False
for tmpl in templates:
if os_template in tmpl.get('volid', ''):
template_found = True
print(f"✅ Found OS template: {tmpl['volid']}")
break
if not template_found:
print(f"⚠️ OS template not found: {os_template}")
print(" Available templates:")
for tmpl in templates[:5]:
print(f" - {tmpl['volid']}")
print("\n Please download Ubuntu 22.04 template from Proxmox web UI:")
print(" Datacenter → <node> → local → CT Templates → Download from template")
return False
# Step 3: Create the container
print(f"\n🔨 Step 3: Creating LXC container...")
print(f" Hostname: {template_name}")
print(f" Memory: {memory}MB")
print(f" Cores: {cores}")
print(f" Disk: {disk_size}GB")
try:
upid = client.create_container(
vmid=template_id,
ostemplate=os_template,
hostname=template_name,
storage=storage,
memory=memory,
cores=cores,
rootfs=f"{storage}:{disk_size}",
net0="name=eth0,bridge=vmbr0,ip=dhcp",
nameserver="8.8.8.8",
searchdomain="localdomain",
password="temporary123", # Will be removed later
onboot=0,
unprivileged=0, # Privileged for Docker
features="nesting=1,keyctl=1" # Docker support
)
print(f" Task ID: {upid}")
print(" Waiting for container creation...")
if client.wait_for_task(upid, timeout=120):
print("✅ Container created successfully!")
else:
print("❌ Container creation failed or timed out")
return False
except Exception as e:
print(f"❌ Error creating container: {e}")
return False
# Step 4: Start the container
print("\n▶️ Step 4: Starting container...")
try:
upid = client.start_container(template_id)
if client.wait_for_task(upid, timeout=60):
print("✅ Container started")
time.sleep(10) # Wait for boot
else:
print("❌ Failed to start container")
return False
except Exception as e:
print(f"❌ Error starting container: {e}")
return False
# Step 5: Install Docker (via SSH or pct exec)
print("\n🐳 Step 5: Installing Docker...")
print(" You need to run these commands manually via:")
print(f" pct enter {template_id}")
print("\n Then run:")
print("""
# Update system
apt update && apt upgrade -y
# Install Docker
apt install -y docker.io docker-compose-plugin curl wget git vim htop
# Enable Docker service
systemctl enable docker
systemctl start docker
# Verify Docker
docker --version
docker run hello-world
# Clean up
apt clean
history -c
# Exit container
exit
""")
print("\n⏸️ Pausing for manual Docker installation...")
print(" Press ENTER after you've completed the Docker installation...")
input()
# Step 6: Stop the container
print("\n⏹️ Step 6: Stopping container...")
try:
upid = client.shutdown_container(template_id, timeout=60)
if client.wait_for_task(upid, timeout=90):
print("✅ Container stopped")
else:
print("⚠️ Graceful shutdown timed out, forcing stop...")
client.stop_container(template_id)
time.sleep(5)
except Exception as e:
print(f"⚠️ Error stopping container: {e}")
print(" Forcing stop...")
client.stop_container(template_id)
time.sleep(5)
# Step 7: Convert to template
print("\n📝 Step 7: Converting to template...")
print(" Run this command manually:")
print(f" pct template {template_id}")
print("\n Or via Proxmox web UI:")
print(f" Right-click container {template_id} → Convert to template")
print("\n" + "=" * 60)
print("🎉 Docker-Ready LXC Template Creation Guide Complete!")
print("\n📋 Summary:")
print(f" Template ID: {template_id}")
print(f" Hostname: {template_name}")
print(f" Resources: {memory}MB RAM, {cores} cores, {disk_size}GB disk")
print(f" Features: Docker pre-installed, nesting enabled, privileged")
print("\n🔄 Next Steps:")
print(" 1. Convert container to template (see above)")
print(" 2. Clone template for new Docker hosts:")
print(f" pct clone {template_id} <newid> --hostname <name> --full")
print(" 3. Configure network/storage for cloned containers")
print(" 4. Start and use!")
return True
def main():
"""Main entry point"""
import argparse
parser = argparse.ArgumentParser(description="Create Docker-ready LXC template")
parser.add_argument("--id", type=int, default=9001, help="Template container ID (default: 9001)")
parser.add_argument("--name", default="docker-lxc-template", help="Template hostname")
parser.add_argument("--memory", type=int, default=2048, help="Memory in MB (default: 2048)")
parser.add_argument("--cores", type=int, default=2, help="CPU cores (default: 2)")
parser.add_argument("--disk", type=int, default=20, help="Disk size in GB (default: 20)")
parser.add_argument("--storage", default="local-lvm", help="Storage pool (default: local-lvm)")
parser.add_argument("--template", default="local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst",
help="OS template path")
args = parser.parse_args()
try:
success = create_docker_lxc_template(
template_id=args.id,
template_name=args.name,
os_template=args.template,
memory=args.memory,
cores=args.cores,
disk_size=args.disk,
storage=args.storage
)
if success:
print("\n✅ Template creation process completed!")
sys.exit(0)
else:
print("\n❌ Template creation failed")
sys.exit(1)
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
main()