Virtualization

Run Rocky Linux 10 VM using Vagrant on KVM / VirtualBox / VMware

Rocky Linux is the community-driven successor to CentOS, built from RHEL sources. It gives you the same enterprise-grade stability without the licensing costs, making it a solid choice for development VMs and test environments. Vagrant makes spinning up and tearing down Rocky Linux VMs fast and repeatable across different hypervisors.

This guide covers running Rocky Linux 10 VMs with Vagrant using the official rockylinux/10 box from Vagrant Cloud. We cover VirtualBox, libvirt/KVM, and VMware Desktop providers, along with shell provisioning and multi-machine Vagrantfile examples.

Prerequisites

Step 1: Add the Rocky Linux 10 Vagrant Box

The official rockylinux/10 box on Vagrant Cloud supports libvirt, VirtualBox, and VMware Desktop providers on both amd64 and arm64 architectures. Download the box for your preferred provider.

For libvirt/KVM:

vagrant box add rockylinux/10 --provider=libvirt

For VirtualBox:

vagrant box add rockylinux/10 --provider=virtualbox

For VMware Desktop:

vagrant box add rockylinux/10 --provider=vmware_desktop

Verify the box was downloaded:

$ vagrant box list
rockylinux/10   (libvirt, 0.0.0)

Step 2: Create a Vagrantfile for Rocky Linux 10

Create a project directory and initialize the Vagrantfile.

mkdir -p ~/vagrant/rocky10 && cd ~/vagrant/rocky10

Create the Vagrantfile:

vim Vagrantfile

Vagrantfile for libvirt/KVM

If you use Vagrant with libvirt as your provider, use this configuration:

# -*- mode: ruby -*-
# vi: set ft=ruby :

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/10"
  config.vm.hostname = "rocky10"
  config.vm.box_check_update = false

  # Private network for host-only access
  config.vm.network "private_network", ip: "192.168.56.10"

  config.vm.provider :libvirt do |v|
    v.memory = 2048
    v.cpus = 2
  end
end

Vagrantfile for VirtualBox

For VirtualBox, the configuration is slightly different. You can set VirtualBox as your default Vagrant provider if you use it regularly:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/10"
  config.vm.hostname = "rocky10"
  config.vm.box_check_update = false

  # Private network for host-only access
  config.vm.network "private_network", ip: "192.168.56.10"

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false
    vb.memory = "2048"
    vb.cpus = 2
    vb.name = "rocky10"
  end
end

Vagrantfile for VMware Desktop

VMware Desktop (Workstation or Fusion) requires the Vagrant VMware plugin:

vagrant plugin install vagrant-vmware-desktop

Then use this Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/10"
  config.vm.hostname = "rocky10"
  config.vm.box_check_update = false

  config.vm.provider "vmware_desktop" do |v|
    v.vmx["memsize"] = "2048"
    v.vmx["numvcpus"] = "2"
  end
end

Step 3: Start the Rocky Linux 10 VM

From the project directory containing the Vagrantfile, bring up the VM:

vagrant up

Sample output for the libvirt provider:

$ vagrant up
Bringing machine 'default' up with 'libvirt' provider...
==> default: Uploading base box image as volume into libvirt storage...
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings...
==> default:  -- Name:              rocky10_default
==> default:  -- Domain type:       kvm
==> default:  -- Cpus:              2
==> default:  -- Memory:            2048M
==> default:  -- Base box:          rockylinux/10
==> default:  -- Storage pool:      default
==> default: Creating shared folders metadata...
==> default: Starting domain.
==> default: Waiting for domain to get an IP address...
==> default: Waiting for SSH to become available...
    default: Vagrant insecure key detected. Vagrant will automatically replace
    default: this with a newly generated keypair for better security.
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Setting hostname...
==> default: Configuring and enabling network interfaces...

Step 4: Connect to the VM

SSH into the running VM:

vagrant ssh

Verify the OS release:

$ cat /etc/os-release
NAME="Rocky Linux"
VERSION="10.0 (Pelican)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="10.0"
PLATFORM_ID="platform:el10"
PRETTY_NAME="Rocky Linux 10.0 (Pelican)"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:rocky:rocky:10::baseos"
HOME_URL="https://rockylinux.org/"
VENDOR_NAME="RESF"
VENDOR_URL="https://resf.org/"

$ cat /etc/redhat-release
Rocky Linux release 10.0 (Pelican)

Type exit to disconnect from the VM.

Step 5: Vagrantfile with Shell Provisioning

Vagrant supports provisioning scripts that run automatically when the VM is first created. This saves time when you need the same packages installed every time you spin up a new VM.

Here is a Vagrantfile that installs common development tools and enables the firewall on first boot:

# -*- mode: ruby -*-
# vi: set ft=ruby :

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/10"
  config.vm.hostname = "rocky10-dev"
  config.vm.box_check_update = false

  config.vm.network "private_network", ip: "192.168.56.10"

  # Forward port 8080 on guest to 8080 on host
  config.vm.network "forwarded_port", guest: 8080, host: 8080

  config.vm.provider :libvirt do |v|
    v.memory = 2048
    v.cpus = 2
  end

  # Shell provisioning - runs on first 'vagrant up'
  config.vm.provision "shell", inline: <<-SHELL
    dnf update -y
    dnf install -y vim git curl wget tar unzip net-tools bind-utils
    systemctl enable --now firewalld
    echo "Provisioning complete"
  SHELL
end

To re-run the provisioning script on an existing VM without destroying it:

vagrant provision

Step 6: Multi-Machine Vagrantfile

Vagrant can manage multiple VMs from a single Vagrantfile. This is useful for testing clustered setups, client-server architectures, or replication scenarios. The following example creates three Rocky Linux 10 VMs on a shared private network:

# -*- mode: ruby -*-
# vi: set ft=ruby :

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'

NODES = [
  { name: "node1", ip: "192.168.56.11", memory: 2048, cpus: 2 },
  { name: "node2", ip: "192.168.56.12", memory: 2048, cpus: 2 },
  { name: "node3", ip: "192.168.56.13", memory: 1024, cpus: 1 },
]

Vagrant.configure("2") do |config|
  config.vm.box = "rockylinux/10"
  config.vm.box_check_update = false

  NODES.each do |node|
    config.vm.define node[:name] do |n|
      n.vm.hostname = node[:name]
      n.vm.network "private_network", ip: node[:ip]

      n.vm.provider :libvirt do |v|
        v.memory = node[:memory]
        v.cpus = node[:cpus]
      end

      n.vm.provision "shell", inline: <<-SHELL
        dnf install -y vim net-tools
        echo "#{node[:ip]}  #{node[:name]}" >> /etc/hosts
      SHELL
    end
  end
end

Bring up all three VMs at once:

vagrant up

Or start a specific node:

vagrant up node1

SSH into a specific node by name:

vagrant ssh node2

Common Vagrant Commands Reference

Here are the commands you will use regularly when working with Vagrant VMs:

CommandDescription
vagrant upCreate and start the VM
vagrant sshSSH into the running VM
vagrant haltGracefully shut down the VM
vagrant reloadRestart the VM and reload the Vagrantfile
vagrant suspendSave the VM state and stop it
vagrant resumeResume a suspended VM
vagrant provisionRe-run provisioning scripts
vagrant destroyStop and delete the VM
vagrant statusShow the current VM status
vagrant box listList all downloaded Vagrant boxes

To stop the VM without deleting it:

vagrant halt

To save the current VM state so you can resume later from exactly the same point:

vagrant suspend

When you are done and want to remove the VM entirely:

vagrant destroy -f

Conclusion

We set up Rocky Linux 10 VMs using Vagrant with libvirt/KVM, VirtualBox, and VMware Desktop providers, including shell provisioning and multi-machine configurations. Vagrant makes it straightforward to create reproducible development and test environments that you can share across your team using a single Vagrantfile.

For production-like environments, consider adding synced folders for code sharing, configuring bridged networking for full network access, and using Ansible or Puppet provisioners instead of shell scripts for complex setups.

Related Articles

AlmaLinux Install Odoo EPR 17 on Rocky, Alma, CentOS, RHEL 9|8 RHEl How To Install Jira on Rocky Linux 9 Server Debian Install OpenNebula LXC Node on Debian 13 / Debian 12 AlmaLinux Install iRedMail on Rocky Linux 10 / AlmaLinux 10

Press ESC to close