Ubuntu-vm-bootstrap

Featured Post Image - Ubuntu-vm-bootstrap

Every new Ubuntu VM on the XCP-ng pool needed the same post-install housekeeping — updates, timezone, NTP, guest tools, a few baseline packages — done by hand, every time. Instead of repeating that checklist again, I put together a bash script that does it in one pass and only touches the system when told to.

https://github.com/tobiastillstam/Ubuntu-vm-bootstrap

Post-install housekeeping for a freshly installed Ubuntu VM. Detects current state and reports it; only changes anything when --fix is given (always previewable via --dry-run).

Built for XCP-ng guests first, but it also detects and handles KVM/Proxmox, VMware, Hyper-V, and VirtualBox. Interactive with a terminal attached (a yes/no + confirm-the-default wizard), flag-driven and silent otherwise — including a straight curl | bash pipe.

curl -fsSL https://raw.githubusercontent.com/tobiastillstam/Ubuntu-vm-bootstrap/main/ubuntu-vm-bootstrap.sh | sudo bash

Features

  • Audit-first — a plain run only reports what it would do. Nothing changes until --fix is given, and --dry-run previews either way.
  • Core housekeeping — full apt update/full-upgrade/autoremove/autoclean, timezone + NTP via systemd-timesyncd, and a set of baseline CLI packages (curl, git, jq, htop, tmux, and the rest).
  • Hypervisor-aware guest tools — auto-detects the hypervisor via systemd-detect-virt and installs the matching guest tools, or takes an override with --hypervisor.
  • Interactive wizard or fully unattended — asks its way through the settings when a terminal is attached; runs silently under --yes, automation, or a piped install.
  • Opt-in SSH hardening (--harden) — key-only SSH (root login and password auth disabled), plus UFW with an OpenSSH allow rule. Refuses to lock out password auth if no authorized_keys is found, unless forced.
  • Opt-in swap, unattended-upgrades, and Zabbix Agent2 — each behind its own flag (--swap, --unattended-upgrades, --zabbix), with the generated Zabbix PSK printed once and never written to a log.
  • Idempotent — safe to run again on the same VM. Verified live on Ubuntu 26.04 LTS on XCP-ng across audit, dry-run, a full --fix with every optional category, and a second pass to confirm nothing changes twice.