echo6-docs/vault/runbooks/proxmox-create-ubuntu-vm.md

297 lines
9.9 KiB
Markdown
Raw Normal View History

auto: docs sync 2026-06-18T18:00:10+00:00 Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
2026-06-18 18:00:10 +00:00
---
title: Proxmox — Create Ubuntu VM (Cloud-Init)
type: runbook
tags:
- proxmox
aliases: []
related:
- [[ct-runbook]]
- [[environment]]
- [[proxmox-onboard-node]]
- [[headscale-onboard-node]]
- [[pi-nas-omv-runbook]]
updated: 2026-07-11
auto: docs sync 2026-06-18T18:00:10+00:00 Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
2026-06-18 18:00:10 +00:00
---
# Proxmox — Create Ubuntu VM (Cloud-Init)
Automated VM creation using Ubuntu cloud images. No interactive installer needed.
## Prerequisites
- SSH access to the target Proxmox host (directly or via jump box)
- Headscale running on edge2 CT 107 with a valid preauth key
- Target Proxmox host has sufficient resources (check with `pvesm status`, `free -h`, `nproc`)
## Variables — Prompt the User
**Before executing any steps, prompt the user for ALL of the following values.** Present them one group at a time. Suggest defaults in parentheses where noted. Do not proceed until all values are confirmed.
### Group 1 — Identity
Prompt for these first:
- **VM name** — hostname for the VM (e.g., `cortex`)
- **Proxmox host** — which node to create it on? (e.g., `toc`, `data`, `utility`)
### Group 2 — Networking
Once identity is set, prompt:
- **VMID** — 150-199 range per convention. Suggest next available by checking `qm list` on the host.
- **Static IP** — suggest matching VMID (e.g., VMID 150 → 192.168.1.150). Verify it's not already in use.
- **Gateway** — (default: `192.168.1.1`)
### Group 3 — Resources
Prompt for hardware allocation. Check host resources first (`nproc`, `free -h`, `pvesm status`) and suggest reasonable values:
- **CPU cores/threads** — how many to allocate?
- **RAM (MB)** — how much?
- **Disk (GB)** — how large?
### Group 4 — Features
Prompt yes/no for each:
- **GPU passthrough?** — if yes, detect PCI address automatically via `lspci -nn | grep -i nvidia` on the host. Requires IOMMU+VFIO already configured.
- **Install Docker?**
- **Install NVIDIA drivers?** — only relevant if GPU passthrough is yes.
- **Install Node.js?** — for Claude Code.
- **Register with Tailscale?** — if yes, Tailscale hostname defaults to VM name.
### Summary
After collecting all values, present a summary table and ask for confirmation before executing.
## Step 1 — Download Ubuntu Cloud Image
Check if image already exists on the host. Only download if missing.
```bash
ssh root@$PVE_HOST 'ls /var/lib/vz/template/iso/noble-server-cloudimg-amd64.img 2>/dev/null \
|| wget -P /var/lib/vz/template/iso/ \
https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img'
```
## Step 2 — Create VM
```bash
ssh root@$PVE_HOST "qm create $VMID \
--name $VM_NAME \
--memory $RAM_MB \
--cores $CORES \
--cpu cputype=host \
--scsihw virtio-scsi-single \
--net0 virtio,bridge=vmbr0 \
--ostype l26 \
--bios ovmf \
--efidisk0 local-lvm:1 \
--machine q35 \
--agent enabled=1 \
--onboot 1"
```
## Step 3 — Import Cloud Image as Disk
```bash
ssh root@$PVE_HOST "qm importdisk $VMID /var/lib/vz/template/iso/noble-server-cloudimg-amd64.img local-lvm"
# Attach the imported disk (disk name is vm-$VMID-disk-1)
ssh root@$PVE_HOST "qm set $VMID --scsi0 local-lvm:vm-${VMID}-disk-1,iothread=1,discard=on"
# Resize
ssh root@$PVE_HOST "qm resize $VMID scsi0 ${DISK_GB}G"
```
## Step 4 — Configure Cloud-Init
```bash
# Add cloud-init drive
ssh root@$PVE_HOST "qm set $VMID --ide2 local-lvm:cloudinit"
# Ensure SSH keys exist on the Proxmox host
# If not, pull from another node:
ssh root@$PVE_HOST 'test -f /root/.ssh/authorized_keys || echo "ERROR: No SSH keys on host"'
# Configure cloud-init
ssh root@$PVE_HOST "qm set $VMID \
--ciuser zvx \
--cipassword temp-change-me \
--ipconfig0 ip=${VM_IP}/24,gw=${GATEWAY} \
--nameserver 1.1.1.1 \
--searchdomain echo6.co \
--sshkeys /root/.ssh/authorized_keys \
--boot order=scsi0"
```
### Alternative: Use standard Echo6 cloud-init snippet
If the snippet is already on the node (deployed by `echo6-onboard-node.sh`), you can use it instead of the manual `--ciuser`/`--cipassword` config above. This pre-installs sshpass, curl, git, htop, and other standard packages via cloud-init:
```bash
ssh root@$PVE_HOST "qm set $VMID --cicustom \"user=local:snippets/echo6-base-userdata.yml\""
```
**Note:** You still need `--ipconfig0`, `--nameserver`, `--searchdomain`, `--sshkeys`, and `--boot` from the block above. The snippet only covers packages and `manage_etc_hosts`.
## Step 5 — GPU Passthrough (if enabled)
Skip if `GPU_PASSTHROUGH=no`.
Requires IOMMU and VFIO already configured on the Proxmox host. Verify first:
```bash
ssh root@$PVE_HOST 'dmesg | grep -i "IOMMU enabled"'
ssh root@$PVE_HOST "lspci -nnk -s $GPU_PCI_ADDR | grep 'Kernel driver in use: vfio-pci'"
```
If both check out:
```bash
ssh root@$PVE_HOST "qm set $VMID --hostpci0 ${GPU_PCI_ADDR},pcie=1,x-vga=0"
```
If VFIO is NOT configured, stop and follow the IOMMU/VFIO setup procedure before continuing.
## Step 6 — Start VM and Wait for Boot
```bash
ssh root@$PVE_HOST "qm config $VMID"
ssh root@$PVE_HOST "qm start $VMID"
echo "Waiting for VM to boot and run cloud-init..."
sleep 60
until ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no zvx@$VM_IP 'hostname' 2>/dev/null; do
echo "Still waiting..."
sleep 15
done
```
If the VM doesn't come up after 3 minutes, check the console via Proxmox web UI or:
```bash
ssh root@$PVE_HOST "qm terminal $VMID"
```
## Step 7 — Base System Setup
```bash
ssh zvx@$VM_IP 'sudo apt-get update && sudo apt-get install -y \
sshpass curl wget git htop iotop tmux vim \
rsync tree jq unzip \
net-tools dnsutils \
python3 python3-pip python3-venv \
sudo'
```
## Step 8 — Enable Password Authentication
Ubuntu cloud images default to key-only SSH via a drop-in config. Enable password auth since all machines are behind VPN/local network.
```bash
# Fix the cloud-init drop-in that disables password auth
ssh zvx@$VM_IP 'echo "PasswordAuthentication yes" | sudo tee /etc/ssh/sshd_config.d/60-cloudimg-settings.conf'
# Also set in main config for completeness
ssh zvx@$VM_IP 'sudo sed -i "s/^#*PasswordAuthentication.*/PasswordAuthentication yes/" /etc/ssh/sshd_config'
ssh zvx@$VM_IP 'sudo sed -i "s/^#*KbdInteractiveAuthentication.*/KbdInteractiveAuthentication yes/" /etc/ssh/sshd_config'
ssh zvx@$VM_IP 'sudo systemctl restart ssh'
# Change the default password immediately
ssh zvx@$VM_IP 'passwd'
```
**Important:** Password authentication is the default for Echo6 infrastructure. All machines are protected by VPN (Headscale/Tailscale) and local network — key-only auth creates unnecessary friction for multi-machine access.
## Step 9 — NVIDIA Drivers (if GPU passthrough)
Skip if `INSTALL_NVIDIA=no`.
```bash
ssh zvx@$VM_IP 'lspci | grep -i nvidia'
# Install driver
ssh zvx@$VM_IP 'sudo apt-get update && sudo apt-get install -y nvidia-driver-550'
ssh zvx@$VM_IP 'sudo reboot'
sleep 60
until ssh -o ConnectTimeout=5 zvx@$VM_IP 'hostname' 2>/dev/null; do
echo "Waiting for reboot..."
sleep 15
done
ssh zvx@$VM_IP 'nvidia-smi'
```
Verify: `nvidia-smi` should show the GPU name, driver version, and VRAM.
## Step 10 — Docker (if enabled)
Skip if `INSTALL_DOCKER=no`.
```bash
ssh zvx@$VM_IP 'curl -fsSL https://get.docker.com | sh'
ssh zvx@$VM_IP 'sudo usermod -aG docker zvx'
```
### NVIDIA Container Toolkit (only if GPU + Docker)
```bash
ssh zvx@$VM_IP 'curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && \
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed "s#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g" | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list'
ssh zvx@$VM_IP 'sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit'
ssh zvx@$VM_IP 'sudo nvidia-ctk runtime configure --runtime=docker'
ssh zvx@$VM_IP 'sudo systemctl restart docker'
# Test
ssh zvx@$VM_IP 'docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu24.04 nvidia-smi'
```
## Step 11 — Node.js (if enabled)
Skip if `INSTALL_NODEJS=no`.
```bash
ssh zvx@$VM_IP 'curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash - && \
sudo apt-get install -y nodejs'
```
## Step 12 — Tailscale Registration
Generate a preauth key on edge2 CT 107 first:
```bash
ssh edge2 "sudo pct exec 107 -- docker exec headscale headscale preauthkeys create --user echo6 --reusable --expiration 72h"
```
Then register the VM:
```bash
ssh zvx@$VM_IP 'curl -fsSL https://tailscale.com/install.sh | sh'
ssh zvx@$VM_IP 'sudo systemctl enable tailscaled && sudo systemctl start tailscaled'
ssh zvx@$VM_IP "sudo tailscale up --login-server https://vpn.echo6.co --auth-key <KEY> --hostname $TAILSCALE_HOSTNAME"
# Verify
ssh zvx@$VM_IP 'tailscale status'
ssh edge2 "sudo pct exec 107 -- docker exec headscale headscale nodes list"
```
## Step 13 — Final Verification
```bash
ssh zvx@$VM_IP "
echo '=== Hostname ===' && hostname
echo '=== IP ===' && ip -4 addr show | grep 'inet 192'
echo '=== Kernel ===' && uname -r
echo '=== GPU ===' && (nvidia-smi --query-gpu=name,driver_version,memory.total --format=csv,noheader 2>/dev/null || echo 'No GPU')
echo '=== Docker ===' && (docker --version 2>/dev/null || echo 'Not installed')
echo '=== Docker GPU ===' && (docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu24.04 nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null || echo 'N/A')
echo '=== Tailscale ===' && tailscale status
echo '=== Node.js ===' && (node --version 2>/dev/null || echo 'Not installed')
echo '=== Python ===' && python3 --version
echo '=== Disk ===' && df -h /
"
ssh edge2 "sudo pct exec 107 -- docker exec headscale headscale nodes list"
```
## Post-Creation
1. Update `/home/zvx/projects/.ref/docs/hardware/environment.md` with the new VM's IP and Tailscale IP
auto: docs sync 2026-06-18T18:00:10+00:00 Files changed: .gitignore CLAUDE.md credentials engine/.embcache.json engine/changelog.md engine/config.yaml engine/lib/__pycache__/agent.cpython-312.pyc engine/lib/agent.py engine/lib/lint.py engine/lint-report.md engine/sweep-full.log engine/sweep.sh vault/.obsidian/graph.json vault/.obsidian/workspace.json vault/INDEX.md vault/archive/projects/mmud/last-ember-chronicle.html vault/archive/projects/mmud/last-ember-howto.html vault/archive/projects/mmud/last-ember.html vault/archive/projects/mmud/mmud-phase5-prompt.md vault/archive/projects/mmud/mmud-phase6-prompt.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/01-update-planned.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/02-npc-nodes.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/03-darkcragg.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/04-dcrg-node.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/05-phase5.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/06-phase6.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/README.md vault/archive/projects/mmud/mmud-prompts/mmud-prompts/mmud-project.md vault/docs/hardware/environment.md vault/docs/hardware/ip-allocation.md vault/docs/matrix/archivist.md vault/docs/matrix/matrix_host.md vault/docs/matrix/mautrix_signal.md vault/docs/matrix/synapse.md vault/docs/matrix/synapse_retention_discovery.md vault/docs/navi/cc-rules.md vault/docs/navi/deployment.md vault/docs/navi/themes.md vault/docs/services/ots-setup.md vault/docs/services/services.md vault/docs/services/usenet.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/geo-tools.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/notes/ia-download-queue.md vault/plans/vaultwarden-plan.md vault/projects/advbbs-project.md vault/projects/argus.md vault/projects/deploy-livesync.md vault/projects/matrix-synapse-deployment.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/ct-runbook.md vault/runbooks/edge2-access-reference.md vault/runbooks/expose-service-contabo.md vault/runbooks/expose-service-edge2.md vault/runbooks/expose-service-home.md vault/runbooks/headscale-onboard-node.md vault/runbooks/ia-cli-reference.md vault/runbooks/ia-download-mirror.md vault/runbooks/idahomesh-bridge-setup.md vault/runbooks/idahomesh-vpn-device-setup.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshmonitor-password-reset.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/nordvpn-lxc.md vault/runbooks/peertube-remote-runner.md vault/runbooks/pg-backup.md vault/runbooks/pi-nas-omv-runbook.md vault/runbooks/pipeline-patterns.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/proxmox-onboard-node.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md vault/session-resume/SESSION-HANDOFF-meshai-test.md
2026-06-18 18:00:10 +00:00
2. Update `/home/zvx/projects/.ref/docs/services/services.md` once [[services]] are deployed
3. Remove the cloud image ISO if disk space is tight: `ssh root@$PVE_HOST 'rm /var/lib/vz/template/iso/noble-server-cloudimg-amd64.img'`