Replaced Headscale (too buggy in 0.28.x — random node drops) with direct WireGuard hub-and-spoke + full mesh. 7 Proxmox VMs across 3 hosts form a K3s v1.34.6 cluster: 3 control-plane/etcd nodes, 4 workers. Running services: postgres, mariadb, ghost (x3), forgejo, authentik. All unpinned services use local-path StorageClass. Databases pinned to pve-worker and adder-worker with local PVs. Includes VM provisioning scripts (create-debian-template.sh, clone-vm.sh), K3s manifests for all services, and full deployment docs in k3s/README.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
78 lines
2.8 KiB
Bash
78 lines
2.8 KiB
Bash
#!/bin/bash
|
|
# create-debian-template.sh
|
|
# Creates a Debian Trixie Cloud-Init VM template on Proxmox.
|
|
#
|
|
# Usage:
|
|
# ./create-debian-template.sh <VMID> <n> [STORAGE] [BRIDGE]
|
|
#
|
|
# Examples:
|
|
# ./create-debian-template.sh 9000 debian-trixie-template
|
|
# ./create-debian-template.sh 9000 debian-trixie-template local-lvm vmbr1
|
|
#
|
|
# Defaults:
|
|
# STORAGE = local-lvm
|
|
# BRIDGE = vmbr1
|
|
|
|
set -euo pipefail
|
|
|
|
VMID="${1:?Usage: $0 <VMID> <n> [STORAGE] [BRIDGE]}"
|
|
NAME="${2:?Usage: $0 <VMID> <n> [STORAGE] [BRIDGE]}"
|
|
STORAGE="${3:-local-lvm}"
|
|
BRIDGE="${4:-vmbr1}"
|
|
|
|
IMAGE="debian-13-genericcloud-amd64.qcow2"
|
|
IMAGE_URL="https://cloud.debian.org/images/cloud/trixie/latest/${IMAGE}"
|
|
TMPDIR="/tmp"
|
|
|
|
echo "==> Downloading Debian Trixie cloud image..."
|
|
wget -q --show-progress -O "${TMPDIR}/${IMAGE}" "${IMAGE_URL}"
|
|
|
|
echo "==> Installing libguestfs-tools if needed..."
|
|
apt-get install -y libguestfs-tools > /dev/null
|
|
|
|
echo "==> Customizing image (installing base tools + Tailscale repo)..."
|
|
virt-customize -a "${TMPDIR}/${IMAGE}" \
|
|
--install qemu-guest-agent,curl,wget,nano,rsync,htop,tmux,emacs-nox,nfs-common \
|
|
--run-command 'curl -fsSL https://pkgs.tailscale.com/stable/debian/trixie.noarmor.gpg -o /usr/share/keyrings/tailscale-archive-keyring.gpg' \
|
|
--run-command 'echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/debian trixie main" > /etc/apt/sources.list.d/tailscale.list' \
|
|
--run-command 'apt-get update -qq' \
|
|
--install tailscale \
|
|
--run-command 'truncate -s 0 /etc/machine-id' \
|
|
--run-command 'rm -f /etc/ssh/ssh_host_*' \
|
|
--quiet
|
|
|
|
echo "==> Creating VM ${VMID} (${NAME})..."
|
|
qm create "${VMID}" \
|
|
--name "${NAME}" \
|
|
--memory 2048 \
|
|
--cores 2 \
|
|
--net0 "virtio,bridge=${BRIDGE}" \
|
|
--ostype l26
|
|
|
|
echo "==> Importing disk to ${STORAGE}..."
|
|
qm importdisk "${VMID}" "${TMPDIR}/${IMAGE}" "${STORAGE}"
|
|
|
|
echo "==> Configuring VM..."
|
|
qm set "${VMID}" --scsihw virtio-scsi-pci --scsi0 "${STORAGE}:vm-${VMID}-disk-0"
|
|
qm set "${VMID}" --boot c --bootdisk scsi0
|
|
qm set "${VMID}" --ide2 "${STORAGE}:cloudinit"
|
|
qm set "${VMID}" --vga std
|
|
qm set "${VMID}" --agent enabled=1
|
|
PUBKEY_FILE=$(mktemp)
|
|
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJq4fOOrPQKYAq5olwKWAXKGO5zv/rujveyTORxMrDp root@pve" > "${PUBKEY_FILE}"
|
|
qm set "${VMID}" --ciuser samantha --cipassword "changeme" --sshkeys "${PUBKEY_FILE}"
|
|
rm -f "${PUBKEY_FILE}"
|
|
qm set "${VMID}" --ipconfig0 ip=dhcp
|
|
|
|
echo "==> Converting to template..."
|
|
qm template "${VMID}"
|
|
|
|
echo "==> Cleaning up..."
|
|
rm -f "${TMPDIR}/${IMAGE}"
|
|
|
|
echo ""
|
|
echo "Done. Template ${VMID} (${NAME}) created."
|
|
echo "Clone with: ./clone-vm.sh ${VMID} <NEW_VMID> <NEW_NAME> [CORES] [MEMORY_MB] [DISK_SIZE]"
|
|
echo ""
|
|
echo "After cloning, join the Headscale mesh:"
|
|
echo " tailscale up --login-server <headscale_server> --authkey mkey:..."
|