All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
Adds title, description, type, domain, and tags frontmatter to every doc for improved KB semantic search. The description field is prepended to every search chunk, and domain/type/tags enable filtered queries. Type values: context, guide, runbook, reference, troubleshooting Domain values match directory structure (networking, docker, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
355 lines
9.1 KiB
Markdown
355 lines
9.1 KiB
Markdown
---
|
|
title: "Proxmox Automation Examples"
|
|
description: "Working examples for Proxmox VM automation: cloud-init deployment, post-install scripting, bulk provisioning, Docker service deployment, VM template creation, and health check scripts."
|
|
type: reference
|
|
domain: vm-management
|
|
tags: [proxmox, automation, cloud-init, docker, templates, examples]
|
|
---
|
|
|
|
# Proxmox VM Automation - Complete Examples
|
|
|
|
Complete working examples for automated VM provisioning in Proxmox environments using cloud-init and post-installation scripts.
|
|
|
|
## Overview
|
|
|
|
This guide provides real-world examples for automating Ubuntu Server VM deployment with:
|
|
- SSH key-based authentication
|
|
- Docker environment setup
|
|
- Security hardening
|
|
- System updates and maintenance
|
|
|
|
## Example 1: Cloud-Init VM Creation
|
|
|
|
### Proxmox VM Setup
|
|
```bash
|
|
# Create VM with cloud-init support in Proxmox
|
|
# VM ID: 200, Name: homelab-docker-01, IP: 10.10.0.200
|
|
|
|
# 1. Create VM through Proxmox web interface or CLI
|
|
pvesh create /nodes/pve/qemu -vmid 200 -name homelab-docker-01 \
|
|
-memory 2048 -cores 2 -sockets 1 -cpu cputype=host \
|
|
-net0 virtio,bridge=vmbr0 \
|
|
-ide2 local:cloudinit \
|
|
-boot c -bootdisk scsi0 \
|
|
-scsi0 local-lvm:10 \
|
|
-ostype l26
|
|
```
|
|
|
|
### Cloud-Init Configuration
|
|
Use the complete `cloud-init-user-data.yaml` template:
|
|
|
|
```yaml
|
|
#cloud-config
|
|
hostname: homelab-docker-01
|
|
timezone: America/New_York
|
|
|
|
users:
|
|
- name: cal
|
|
groups: [sudo, docker]
|
|
shell: /bin/bash
|
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
|
ssh_authorized_keys:
|
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVVK02rOeeIw1e... homelab-cal@nobara-pc
|
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCPzqHDgdK9TlN4uzumBZKEOGt... emergency-homelab-cal@nobara-pc
|
|
|
|
ssh_pwauth: false
|
|
disable_root: true
|
|
package_update: true
|
|
package_upgrade: true
|
|
|
|
# Docker installation and configuration...
|
|
# (Full template available in scripts/vm-management/cloud-init-user-data.yaml)
|
|
```
|
|
|
|
### Deployment Process
|
|
1. **Create VM** with cloud-init drive attached
|
|
2. **Paste cloud-init config** into User Data field
|
|
3. **Set network** configuration (IP: 10.10.0.200/24, Gateway: 10.10.0.1)
|
|
4. **Start VM** - automatic provisioning begins
|
|
5. **Wait 3-5 minutes** for first boot provisioning
|
|
6. **Test connectivity**: `ssh cal@10.10.0.200`
|
|
|
|
## Example 2: Post-Installation Script
|
|
|
|
### Scenario: Existing VM Needs Provisioning
|
|
```bash
|
|
# VM already exists at 10.10.0.150 with password authentication
|
|
# Need to configure SSH keys, Docker, and security hardening
|
|
|
|
# Run the post-installation script
|
|
cd /mnt/NV2/Development/claude-home
|
|
./scripts/vm-management/vm-post-install.sh 10.10.0.150 cal
|
|
```
|
|
|
|
### Script Execution Flow
|
|
```
|
|
🔐 Starting VM provisioning for 10.10.0.150 as user cal
|
|
✅ System updates completed
|
|
✅ SSH key authentication successful
|
|
✅ SSH hardened (password authentication disabled)
|
|
✅ Docker and Docker Compose installed successfully
|
|
✅ User environment configured
|
|
🎉 VM provisioning completed successfully!
|
|
|
|
=== PROVISIONING SUMMARY ===
|
|
VM IP: 10.10.0.150
|
|
User: cal
|
|
Hostname: homelab-vm-03
|
|
Docker: Docker version 24.0.7, build afdd53b
|
|
```
|
|
|
|
## Example 3: Bulk VM Provisioning
|
|
|
|
### Multiple VM Deployment Script
|
|
```bash
|
|
#!/bin/bash
|
|
# Bulk VM provisioning for home lab expansion
|
|
# Creates and configures multiple VMs with sequential IPs
|
|
|
|
VM_BASE_ID=300
|
|
VM_BASE_IP="10.10.0"
|
|
VM_COUNT=3
|
|
|
|
for i in $(seq 1 $VM_COUNT); do
|
|
VM_ID=$((VM_BASE_ID + i))
|
|
VM_IP="${VM_BASE_IP}.$((200 + i))"
|
|
VM_NAME="homelab-worker-$(printf "%02d" $i)"
|
|
|
|
echo "Creating VM: $VM_NAME (ID: $VM_ID, IP: $VM_IP)"
|
|
|
|
# Create VM in Proxmox (adapt to your environment)
|
|
pvesh create /nodes/pve/qemu -vmid $VM_ID -name $VM_NAME \
|
|
-memory 2048 -cores 2 \
|
|
-net0 virtio,bridge=vmbr0 \
|
|
-ide2 local:cloudinit \
|
|
-scsi0 local-lvm:20
|
|
|
|
# Set cloud-init configuration
|
|
pvesh set /nodes/pve/qemu/$VM_ID/config \
|
|
-ipconfig0 ip=$VM_IP/24,gw=10.10.0.1 \
|
|
-nameserver 10.10.0.16 \
|
|
-user cal \
|
|
-sshkeys /path/to/encoded/ssh-keys
|
|
|
|
# Start VM
|
|
pvesh create /nodes/pve/qemu/$VM_ID/status/start
|
|
|
|
echo "VM $VM_NAME created and starting..."
|
|
sleep 30 # Wait for boot
|
|
done
|
|
|
|
echo "Bulk provisioning completed. VMs available at:"
|
|
for i in $(seq 1 $VM_COUNT); do
|
|
echo " homelab-worker-$(printf "%02d" $i): ${VM_BASE_IP}.$((200 + i))"
|
|
done
|
|
```
|
|
|
|
## Example 4: Docker Service Deployment
|
|
|
|
### Post-Provisioning Service Setup
|
|
After VM provisioning, deploy services using Docker Compose:
|
|
|
|
```bash
|
|
# Connect to newly provisioned VM
|
|
ssh cal@10.10.0.200
|
|
|
|
# Create service directory
|
|
mkdir -p ~/services/nginx-proxy
|
|
cd ~/services/nginx-proxy
|
|
|
|
# Create docker-compose.yml
|
|
cat > docker-compose.yml << 'EOF'
|
|
version: '3.8'
|
|
services:
|
|
nginx:
|
|
image: nginx:alpine
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./config:/etc/nginx/conf.d:ro
|
|
- ./ssl:/etc/nginx/ssl:ro
|
|
restart: unless-stopped
|
|
|
|
portainer:
|
|
image: portainer/portainer-ce:latest
|
|
ports:
|
|
- "9000:9000"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- portainer_data:/data
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
portainer_data:
|
|
EOF
|
|
|
|
# Deploy services
|
|
docker compose up -d
|
|
docker compose logs -f
|
|
```
|
|
|
|
## Example 5: VM Template Creation
|
|
|
|
### Creating Reusable VM Templates
|
|
```bash
|
|
# 1. Create and fully configure a base VM
|
|
./scripts/vm-management/vm-post-install.sh 10.10.0.199 cal
|
|
|
|
# 2. Clean up the VM for template use
|
|
ssh cal@10.10.0.199 '
|
|
# Clear bash history
|
|
history -c && history -w
|
|
|
|
# Clear logs
|
|
sudo truncate -s 0 /var/log/*log
|
|
sudo truncate -s 0 /var/log/syslog
|
|
|
|
# Clear SSH host keys (regenerated on first boot)
|
|
sudo rm -f /etc/ssh/ssh_host_*
|
|
|
|
# Clear machine ID
|
|
sudo truncate -s 0 /etc/machine-id
|
|
|
|
# Clear network configuration
|
|
sudo rm -f /etc/udev/rules.d/70-persistent-net.rules
|
|
|
|
# Shutdown
|
|
sudo shutdown -h now
|
|
'
|
|
|
|
# 3. Convert VM to template in Proxmox
|
|
pvesh create /nodes/pve/qemu/199/template
|
|
|
|
# 4. Clone template to create new VMs
|
|
pvesh create /nodes/pve/qemu/199/clone -newid 201 -name homelab-from-template
|
|
```
|
|
|
|
## Example 6: Monitoring and Verification
|
|
|
|
### Post-Deployment Health Checks
|
|
```bash
|
|
#!/bin/bash
|
|
# VM health check script
|
|
# Usage: ./vm-health-check.sh <vm-ip>
|
|
|
|
VM_IP="$1"
|
|
|
|
echo "🔍 VM Health Check: $VM_IP"
|
|
|
|
# Test SSH connectivity
|
|
if ssh -o ConnectTimeout=5 cal@$VM_IP 'echo "SSH OK"' >/dev/null 2>&1; then
|
|
echo "✅ SSH: Connected"
|
|
else
|
|
echo "❌ SSH: Failed"
|
|
exit 1
|
|
fi
|
|
|
|
# Check system info
|
|
INFO=$(ssh cal@$VM_IP '
|
|
echo "Hostname: $(hostname)"
|
|
echo "Uptime: $(uptime -p)"
|
|
echo "Memory: $(free -h | grep Mem | awk "{print \$3\"/\"\$2}")"
|
|
echo "Disk: $(df -h / | tail -1 | awk "{print \$3\"/\"\$2\" (\"\$5\" used)\"}")"
|
|
')
|
|
|
|
echo "$INFO"
|
|
|
|
# Test Docker
|
|
if ssh cal@$VM_IP 'docker --version && docker compose version' >/dev/null 2>&1; then
|
|
echo "✅ Docker: Installed and working"
|
|
else
|
|
echo "❌ Docker: Not working"
|
|
fi
|
|
|
|
# Test Docker permissions
|
|
if ssh cal@$VM_IP 'docker run --rm hello-world' >/dev/null 2>&1; then
|
|
echo "✅ Docker: User permissions OK"
|
|
else
|
|
echo "❌ Docker: User permissions issue"
|
|
fi
|
|
|
|
echo "🎉 Health check completed"
|
|
```
|
|
|
|
## Common Workflows
|
|
|
|
### 1. New Development Environment
|
|
```bash
|
|
# Create VM with cloud-init
|
|
# Wait for provisioning
|
|
# Deploy development stack
|
|
ssh cal@10.10.0.201 '
|
|
mkdir -p ~/dev
|
|
cd ~/dev
|
|
|
|
# Clone your project
|
|
git clone https://github.com/your-org/project.git
|
|
cd project
|
|
|
|
# Start development environment
|
|
docker compose -f docker-compose.dev.yml up -d
|
|
'
|
|
```
|
|
|
|
### 2. Service Migration
|
|
```bash
|
|
# Provision new VM
|
|
./scripts/vm-management/vm-post-install.sh 10.10.0.202 cal
|
|
|
|
# Copy service configuration from existing server
|
|
scp -r cal@10.10.0.124:~/services/app-name cal@10.10.0.202:~/services/
|
|
|
|
# Start service on new VM
|
|
ssh cal@10.10.0.202 'cd ~/services/app-name && docker compose up -d'
|
|
```
|
|
|
|
### 3. Testing Environment
|
|
```bash
|
|
# Quick test environment with cloud-init
|
|
# Use minimal resources: 1GB RAM, 1 CPU, 10GB disk
|
|
# Deploy test configuration
|
|
# Run automated tests
|
|
# Destroy when done
|
|
```
|
|
|
|
## Troubleshooting Examples
|
|
|
|
### VM Won't Start After Cloud-Init
|
|
```bash
|
|
# Check cloud-init logs
|
|
ssh cal@<vm-ip> 'sudo cloud-init status --long'
|
|
ssh cal@<vm-ip> 'sudo cat /var/log/cloud-init-output.log'
|
|
|
|
# Manual cloud-init re-run if needed
|
|
ssh cal@<vm-ip> 'sudo cloud-init clean && sudo cloud-init init'
|
|
```
|
|
|
|
### SSH Key Issues
|
|
```bash
|
|
# Verify keys are properly installed
|
|
ssh cal@<vm-ip> 'cat ~/.ssh/authorized_keys | wc -l' # Should show 2 keys
|
|
|
|
# Test specific key
|
|
ssh -i ~/.ssh/homelab_rsa cal@<vm-ip> 'echo "Primary key works"'
|
|
ssh -i ~/.ssh/emergency_homelab_rsa cal@<vm-ip> 'echo "Emergency key works"'
|
|
```
|
|
|
|
### Docker Permission Problems
|
|
```bash
|
|
# Check user groups
|
|
ssh cal@<vm-ip> 'groups' # Should include 'docker'
|
|
|
|
# Re-login to apply group membership
|
|
ssh cal@<vm-ip> 'newgrp docker'
|
|
|
|
# Test Docker access
|
|
ssh cal@<vm-ip> 'docker ps'
|
|
```
|
|
|
|
## Related Documentation
|
|
|
|
- **Scripts**: `scripts/vm-management/README.md` - Implementation details
|
|
- **Patterns**: `patterns/vm-management/README.md` - Architectural guidance
|
|
- **SSH Setup**: `examples/networking/ssh-homelab-setup.md` - Key management
|
|
- **Docker**: `examples/docker/` - Container deployment patterns |