If you want to build a flexible and inexpensive homelab and don't want to invest money in an additional server for the time being, then I can only recommend you to use a combination of Oracle Virtualbox and HashiCorp Vagrant. Both tools run under Windows, Linux and also MacOS (Intel). In my case I installed it on my Windows 10 machine. And no you don't need to have a Killer gaming PC with many CPU cores and lots of RAM. You can start really small on a dual core CPU with 4GB RAM. Virtualbox is a hypervisor with which you can run virtual machines. Vagrant on the other hand is a tool that makes the deployment of these virtual machines much easier, because you can deploy virtual machines images, so called Vagrant Boxes, from HashiCorps catalog by using a single file and one command. You can also use another tool from Hashicorp called Packer to create Vagrant Boxes from your own virtual machines.

Installation

First download the following two programs and install them one after the other.

Once you have installed both programs, we will install an additional Vagrant plugin called vagrant-hostmanager. This can be very useful if you don't have a real DNS server on your home network. The plugin can create static host entries on deployed VMs and even on your local machine. For this simply open a cmd or PowerShell and enter:

vagrant plugin install vagrant-hostmanager

BTW, you can list all installed plugins using:

vagrant plugin list

and there is a ton of additional plugins that you can install.

How to use Vagrant

Once you have completed all the steps and downloaded my example Vagrant files from Github, let's start with a very simple deployment of just one CentOS 7 Linux VM. By default Vagrant will always look for a file called "Vagrantfile" in the current directory. It will even climb up the directory tree to find this file. And be careful, it is case-sensitive. In this file you define which Vagrant Box to download / deploy and various other options like the provider (hypervisor) that you want to use. Vagrant supports many different hypervisors. The Vagrant Boxes are also tagged by which hypervisors are supported. In our case we will use the Vagrantfile from the the single_virtbox directory.

cd single_virtbox
vagrant up

Vagrant will now download the CentOS 7 Vagrant Box and deploy it in Virtualbox. Additionally it will execute the script "myscript.sh" from the scripts folder. You can now use the VM just as any other VM.

BTW once you Vagrant has downloaded a Vagrant Box it will not download it again, unless we tell it to do so by running:

cd single_virtbox
vagrant up

The first deployment will take a little longer, because the box has to be downloaded. Further deployments will be much faster since the already downloaded box will be used. In my case it only takes 10 seconds to deploy the CentOS 7 box. Isn't this awesome?!?!

There is also a vagrant command to ssh (log in) to your virtual machine.

vagrant ssh

Once logged in let's have a look at the network interfaces and assigned IPs

ip -o a

Example

[vagrant@centos7 ~]$ ip -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
1: lo    inet6 ::1/128 scope host \       valid_lft forever preferred_lft forever
2: eth0    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0\       valid_lft 85766sec preferred_lft 85766sec
2: eth0    inet6 fe80::5054:ff:fe4d:77d3/64 scope link \       valid_lft forever preferred_lft forever
3: eth1    inet 192.168.2.85/24 brd 192.168.2.255 scope global noprefixroute dynamic eth1\       valid_lft 85766sec preferred_lft 85766sec
3: eth1    inet6 fe80::a00:27ff:fedb:1e7c/64 scope link \       valid_lft forever preferred_lft forever

As we can see we have two interfaces eth0 and eth1 configured. By default the VM will only have one interface, in this case eth0, configured on the virtualbox internal network. This interface has a dynamic IP assigned. Vagrant uses this network to interact with the VM using a local user called "vagrant". BTW, the default password of this user is also "vagrant". The other interface eth1, is configured on the public virtualbox interface by the following line in the Vagrantfile:

config.vm.network "public_network"

In my case this allows me to access the VM from other machines on my local network. I have just as most of the people at home a router that establishes my internet connection and assigns IP addresses via DHCP to all devices on my local network. And therefore it also assigned an IP to the public interface on this VM. You can also assign static IPs but we will look into this later. There is also some very detailed and good information on the Vagrant website.

And if you think this is cool, then check out my other example file that will deploy multiple virtual machines.

cd multi_virtbox
vagrant up

This will deploy a CentOS 8 Stream and a Ubuntu 20.04 VM. In case you only want to deploy a single box from your Vagrantfile, you can do so by specifying the box name.

vagrant up vm1

If you want to ssh to one of the VMs you have to specify the name:

vagrant ssh vm1

The VMs now have static IPs assigned and they have different resources for RAM and an additional disk assigned:

[vagrant@vm1 ~]$ sudo fdisk -l
Disk /dev/sda: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xf07c3c50

Device     Boot Start      End  Sectors Size Id Type
/dev/sda1  *     2048 20971519 20969472  10G 83 Linux


Disk /dev/sdb: 19.5 GiB, 20971520000 bytes, 40960000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Make sure to read the comments in my Vagrantfiles for more information. From now on you can easily deploy multiple virtual machines using Vagrant and build even more complex test or even production environments within minutes.

Vagrant Cheatsheet


You can list all downloaded Vagrant Boxes by using

vagrant box list

You can even create snapshots of your VM

vagrant snapshot save initial_snap

List all snapshots

vagrant snapshot list

Restore a snapshot

vagrant snapshot restore initial_snap

Delete a VM called centos7

vagrant destroy centos7