Skip to content

Instantly share code, notes, and snippets.

@azazar
Created April 18, 2026 16:22
Show Gist options
  • Select an option

  • Save azazar/9330b766a10e0fba50d901cf829395a3 to your computer and use it in GitHub Desktop.

Select an option

Save azazar/9330b766a10e0fba50d901cf829395a3 to your computer and use it in GitHub Desktop.
Quickly create a temporary LXC Debian VM for small experiments
#!/bin/bash
set -euo pipefail
NAME="${1:-test-vm}"
PASSWORD="${2:-password}"
export LXD_DIR="${LXD_DIR:-/var/lib/lxd}"
command -v lxc >/dev/null || { echo "Missing command: lxc" >&2; exit 1; }
[ -S "$LXD_DIR/unix.socket" ] || { echo "Missing LXD socket: $LXD_DIR/unix.socket" >&2; exit 1; }
USER_DATA=$(cat <<EOF
#cloud-config
hostname: $NAME
create_hostname_file: true
packages:
- openssh-server
chpasswd:
list: |
root:$PASSWORD
user:$PASSWORD
expire: false
ssh_pwauth: true
users:
- default
- name: user
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: false
runcmd:
- systemctl enable ssh || true
- systemctl restart ssh || true
EOF
)
echo "Creating $NAME"
sudo lxc info "$NAME" >/dev/null 2>&1 && sudo lxc delete -f "$NAME" || true
sudo lxc launch images:debian/13/cloud "$NAME" --ephemeral --config=user.user-data="$USER_DATA" >/dev/null
for _ in $(seq 1 60); do
STATUS="$(sudo lxc exec "$NAME" -- cloud-init status 2>/dev/null || true)"
[ "$STATUS" = "status: done" ] && break
sleep 2
done
IP="$(sudo lxc list "$NAME" -c 4 --format csv | head -n1)"
echo "Status: ${STATUS:-unknown}"
echo "Instance: $NAME"
echo "IP: ${IP:-not available}"
echo "Login: user/$PASSWORD"
echo "Shell: sudo lxc exec $NAME -- bash"
echo "SSH: ssh user@${IP:-<ip>}"
echo "Remove: instance is ephemeral and will be deleted when stopped; force remove: sudo lxc delete -f $NAME"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment