Transform your Linux workstation into a powerful, automated virtual datacenter where you can deploy, break, and rebuild VMs effortlessly. tux2lab automates provisioning, manages the complete VM lifecycle, and provides a flexible environment for learning, testing, and experimenting with Linux-based technologies.
Plenty of open-source alternatives may exist; this project was built out of the sheer fun of creating something from scratch and sharing it with anyone who has similar interests.
Architecturally, tux2lab is orchestrated by JBOBS, Just a Bunch Of Bash Scripts. No frameworks, no extra languages. Just Bash doing what Bash does best.
Warning
This project is intended for testing, development, and experimentation purposes only.
- Automated VM provisioning via PXE boot & golden images
- Dynamic DNS management for your local domain
- Complete VM lifecycle management: deploy, resize, snapshot, destroy
- Multi-distribution support across Red Hat, Debian, and SUSE families
- Dual-stack networking (IPv4 + IPv6) with per-VM stack mode selection
- TCP load balancer management (nginx stream)
- Containerized infrastructure: lab services in a single rootful Podman container (~60 MB)
tux2lab runs on your Linux workstation (the KVM host) and creates a private
virtual network (labbr0 bridge, 10.28.28.0/22 + IPv6 ULA fd28:2808:2020:3000::/64) with a
tux2lab-engine container that provides the lab services on the gateway IP (10.28.28.1):
| Service | Software | Purpose | Runs In |
|---|---|---|---|
| DNS | BIND (named) | Local domain resolution | Container |
| DHCP | Kea (v4 + v6) | Automatic IP assignment | Container |
| PXE/TFTP | tftp-hpa + iPXE | Network boot for OS installs | Container |
| NTP | chrony | Time synchronization | Container |
| HTTP/HTTPS | nginx | Boot ISO & kickstart serving | Container |
| IPv6 RA | radvd | Router advertisements | Container |
| NFS | nfs-server | Shared storage | Host |
Note
NFS is the one service that runs on the KVM host rather than in the container. The kernel NFS server cannot export host-side ISO submounts from inside a container because of mount namespace isolation.
All lab services except NFS run inside a single rootful Podman container (tux2lab-engine)
based on Alpine Linux 3.21 (~60 MB). The container uses --network=host to bind directly to the
lab bridge interface, providing seamless network access for all guest VMs.
| Feature | Detail |
|---|---|
| Image | ghcr.io/muthukumar-subramaniam/tux2lab-engine:2.1.1 |
| Runtime | Podman (rootful, --network=host --privileged) |
| Persistence | All state in /tux2lab-data/ (bind-mounted into container) |
| Lifecycle | Start, stop, and rebuild lab services, including host-side NFS |
| Resources | Minimal, shares host kernel, no VM overhead |
| Family | Distribution | Versions | Method |
|---|---|---|---|
| Red Hat | AlmaLinux, Rocky, Oracle Linux, CentOS Stream | 10, 9, 8 | Kickstart |
| RHEL | 10, 9, 8 | Kickstart (subscription-manager) | |
| Debian | Ubuntu LTS | 26.04, 24.04, 22.04 | Cloud-init autoinstall |
| Debian | 13, 12, 11 | Preseed (netboot) | |
| SUSE | openSUSE Leap | 16.0 | Agama |
| Microsoft | Azure Linux | 3.0 | Unattended installer |
Distros are set up automatically when needed. Running
tux2lab distro setupmanually is optional (useful for pre-staging ISOs or managing disk space).
These are the minimum recommended values. Adjust based on your workload.
Guest VMs (each): 2 GiB RAM · 2 vCPUs · 30 GiB disk
KVM Host: RHEL-based, Ubuntu, or openSUSE (hardware virtualization required). Podman must be available (installed automatically by setup).
Download the latest release tarball:
sudo mkdir -p /tux2lab
sudo chown "${USER}:$(id -g)" /tux2lab
curl -sSL https://github.com/Muthukumar-Subramaniam/tux2lab/releases/latest/download/tux2lab.tar.gz \
| tar -xzv -C /tux2labFor developers and contributors, clone from the repository:
sudo mkdir -p /tux2lab
sudo chown "${USER}:$(id -g)" /tux2lab
git clone https://github.com/Muthukumar-Subramaniam/tux2lab.git /tux2lab/tux2lab/setup/setup-host.shThis script:
- Installs QEMU/KVM, libvirt, Podman, jq, and all dependencies (supports
apt,dnf,zypper) - Grants passwordless sudo to the current user
- Creates the
labbr0bridge network with dual-stack addressing and IPv4 NAT - Sets up the
/tux2lab-data/data directory - Installs the
tux2labCLI and bash completion
tux2lab deployThe interactive wizard handles:
- Admin password setup
- SSH key and SSL certificate generation (cert trusted by host)
- Service configuration generation (DNS, DHCP, NTP, HTTP, TFTP, NFS)
- Container image pull and startup
- Host DNS, SSH, and SSL trust configuration
The hostname is fixed to tux2lab-engine and the domain is automatically set to <your-username>.internal.
tux2lab healthDistros are prepared automatically when you build a golden image or install a VM. Use these commands to pre-stage ISOs or check status.
Check the readiness of every supported distribution and version:
tux2lab distro listPre-stage a specific distribution (downloads and mounts its ISO):
tux2lab distro setup almalinux -v 10Azure Linux 3 uses its native unattended installer and can be staged the same way:
tux2lab distro setup azure-linux -v 3.0Running distro list again shows it is now PXE-ready:
tux2lab distro listGolden images let you deploy VMs in seconds instead of running a full PXE install.
List existing golden images (none yet on a fresh install):
tux2lab golden-image listBuild a golden image for a distribution:
tux2lab golden-image build almalinux -v 10List again to confirm the image is available:
tux2lab golden-image listdistro list now shows AlmaLinux 10 as both PXE-ready and having a golden image:
tux2lab distro list# From golden image (default, fast disk clone)
tux2lab vm install -H testvm1 -d almalinux -v 10# Multiple VMs at once
tux2lab vm install -H testvm2,testvm3,testvm4 -d almalinux -v 10Most commands accept
-H testvm1,testvm2,testvm3for multi-VM operations.
tux2lab distro list List distributions and setup status
tux2lab distro setup Prepare a distro for PXE provisioning
tux2lab distro cleanup Remove a distro's PXE setup
tux2lab golden-image build Build a reusable base image via PXE
tux2lab golden-image rebuild Rebuild (or build if none exists)
tux2lab golden-image list List available golden images
tux2lab golden-image cleanup Remove golden image(s)
tux2lab vm install Deploy VM(s) [--via-golden (default) | --via-pxe]
tux2lab vm reimage Reinstall VM(s) [--via-golden (default) | --via-pxe]
tux2lab vm list List all VMs and their status
tux2lab vm info Detailed VM information (all VMs)
tux2lab vm info -H <hostname> Detailed VM information (specific VM)
tux2lab vm validate Validate post-install config (all running VMs)
tux2lab vm validate -H <hostname> Validate specific VM(s)
tux2lab vm console -H <hostname> Attach to serial console (Ctrl+] to exit)
tux2lab vm start -H <hostname> Power on
tux2lab vm stop -H <hostname> Force power off
tux2lab vm shutdown -H <hostname> Graceful shutdown via ACPI
tux2lab vm reboot -H <hostname> Graceful reboot
tux2lab vm restart -H <hostname> Hard reset (power cycle)
tux2lab vm remove -H <hostname> Delete VM and all its data
tux2lab vm resize -H <hostname> Resize memory, CPU, or root disk
tux2lab vm disk-add -H <hostname> Add a new storage disk
tux2lab vm disk-resize -H <hostname> Resize an additional disk
tux2lab vm disk-attach -H <hostname> Re-attach a previously detached disk
tux2lab vm disk-detach -H <hostname> Detach a disk (preserved in storage)
tux2lab vm disk-delete Permanently delete detached disk(s)
tux2lab vm nic-add -H <hostname> Add a network interface
tux2lab vm nic-remove -H <hostname> Remove a network interface
Snapshot creation and reversion are offline operations and require the VM to be shut off.
tux2lab vm snapshot-create -H <hostname> Create an offline snapshot
tux2lab vm snapshot-list -H <hostname> List snapshots
tux2lab vm snapshot-info -H <hostname> Show snapshot details
tux2lab vm snapshot-revert -H <hostname> Revert to a snapshot
tux2lab vm snapshot-delete -H <hostname> Delete a snapshot
tux2lab start Start lab infrastructure (container)
tux2lab stop Stop lab infrastructure and shut down all VMs
tux2lab enable Enable lab infrastructure auto-start on boot
tux2lab disable Disable lab infrastructure auto-start on boot
tux2lab health Check all lab service health
tux2lab deploy Deploy the lab environment (one-time setup)
tux2lab rebuild Regenerate configs and recreate container
tux2lab rebuild --pull-image Also pull latest container image from registry
tux2lab destroy Permanently destroy the entire lab environment
tux2lab info Show lab deployment details
tux2lab credentials Manage lab credentials (password, SSH keys, cert)
tux2lab logflush Clear all service log files
tux2lab dns [options] Manage DNS records via dnsbinder
tux2lab lb create Create a TCP load balancer
tux2lab lb delete Delete a load balancer
tux2lab lb update Update backends, ports, or algorithm
tux2lab lb list List all configured load balancers
tux2lab lb status Check health of load balancers
tux2lab lb restore Re-apply secondary IPs from registry
tux2lab ipv6-route enable Add IPv6 route to lab network
tux2lab ipv6-route disable Remove IPv6 route
tux2lab ipv6-route check Check IPv6 connectivity and route status
tux2lab ipv6-route auto Auto-configure based on host IPv6 connectivity
tux2lab ipv6-route status Show current IPv6 route status
tux2lab version Show version information
Use tux2lab --help or tux2lab <command> --help for detailed usage.
Tab completion is available after installation.
These tools run on the KVM host and power the provisioning pipeline:
| Tool | Purpose |
|---|---|
| dnsbinder | Manages BIND DNS zone records with automatic A/AAAA/CNAME/PTR creation and deletion as VMs are created or destroyed |
| ksmanager | Orchestrates OS provisioning: generates kickstart/cloud-init/preseed/Agama configs, manages iPXE boot entries, DHCP reservations, and golden image workflows |
| lbmanager | Manages nginx TCP stream load balancers: creates VIPs, configures backends, manages DNS records |
| prepare-distro-for-ksmanager | Downloads boot ISOs, registers distributions with ksmanager for PXE provisioning |
tux2lab/
├── container/ Container image (Containerfile + entrypoint.sh)
├── setup/ Host setup and lab deployment scripts
│ ├── setup-host.sh Prepare KVM host (packages, bridge, podman)
│ ├── deploy-lab.sh Deploy lab (configs, container, DNS, health)
│ └── generate-service-configs.sh Generate all service configs from JSON
├── qemu-kvm-manage/ KVM host scripts (VM management)
│ └── scripts-to-manage-vms/ CLI dispatcher and all tux2lab subcommands
├── ksmanager/ Kickstart/cloud-init templates and ksmanager
├── named-manage/ DNS zone management (dnsbinder)
├── lb-manage/ TCP load balancer management (lbmanager)
├── common-utils/ Shared utilities (color output, disk tools)
├── shared-functions/ Host-side helpers (NFS, bridge firewall, container run)
└── vendor/ Vendored virt-manager (no system package needed)
| Path | Purpose |
|---|---|
/tux2lab/ |
Project source (scripts, templates) |
/tux2lab-data/ |
Persistent data volume (mounted into container) |
/tux2lab-data/lab-config/ |
lab_environment.json, SSH keys, SSL certs |
/tux2lab-data/named/ |
DNS zone files and named.conf |
/tux2lab-data/kea/ |
DHCP config and lease database |
/tux2lab-data/nginx/ |
Nginx config |
/tux2lab-data/tftpboot/ |
iPXE boot files |
/tux2lab-data/vms/ |
VM disk images |
/tux2lab-data/golden-images-disk-store/ |
Golden image disks |
This is one of the things I use my own lab for. Three control planes and four
workers, with the control plane endpoint and workload publishing served by
tux2lab lb.
The infrastructure is provisioned and managed by tux2lab. The Kubernetes deployment itself is done with install-k8s-on-linux, a companion Ansible playbook for kubeadm-based clusters.
- Found a bug? Have ideas? Open an issue on GitHub.
- Pull requests are welcome, whether to improve automation, add distros, or enhance docs.
This project is open source and licensed under the GNU General Public License v3.0.
Built for the home lab community.












