Vagrant is so popular among developers and DevOps engineers, because they can be able to continue using existing development tools (E.g. editors, browsers, debuggers, etc.) on their local system. For example, the developers can sync the files from a guest machine to local system, use their favourite editor to edit those files and finally sync them back to the guest machine. Similarly, if they have created a web application on the VM, they can access and test that application from their local system's web browser. In this guide, we will see how to configure networking in Vagrant to provide access to guest machine from the local host system.
Configure Networking In Vagrant
Vagrant offers the following three network options:
- Port forwarding
- Private network (host-only network)
- Public network (bridged network)
1. Configure port forwarding
By default, we can access Vagrant VMs via ssh using
vagrant ssh command. When we access a VM via SSH, Vagrant forwards port 22 from the guest machine to an open port in the host machine. This is called port forwarding. Vagrant automatically handles this port forwarding process without any user intervention. You can also forward a specific port of your choice. For example, if you forwarded port 80 in the guest machine to port 8080 on the host machine, you can then access the webserver by navigating to http://localhost:8080 on your host machine.
The port forwarding can be configured in the "Vagrantfile". Go to your Vagrant project directory and open Vagrantfile in your favourite editor.
Find the following line:
Vagrant.configure("2") do |config| [...] # config.vm.network "forwarded_port", guest: 80, host: 8080 end
Uncomment it and define what ports to forward where. In this example, I am forwarding port 80 in the guest to port 8080 in the host.
Vagrant.configure("2") do |config| [...] config.vm.network "forwarded_port", guest: 80, host: 8080 end
Now restart the Vagrant machine with the updated Vagrantfile:
$ vagrant reload --provision
You will see the port forwarding is configured in the output:
==> default: Halting domain… ==> default: Starting domain. ==> default: Waiting for domain to get an IP address… ==> default: Waiting for SSH to become available… ==> default: Creating shared folders metadata… ==> default: Forwarding ports… ==> default: 80 (guest) => 8080 (host) (adapter eth0) ==> default: Rsyncing folder: /home/sk/myvagrants/ => /vagrant
You can also destroy the VM and re-run it with updated Vagrantfile:
$ vagrant destroy <VM-name>
$ vagrant up
Now SSH in to the guest machine with command:
$ vagrant ssh
Install Apache webserver in it. If the VM is Deb-based, run:
$ sudo apt install apache2
If it is RHEL-based system, run this:
$ sudo yum install httpd
Start Apache service:
$ sudo systemctl enable --now httpd
Now open the web browser in your host system and navigate to http://localhost:8080 address from your browser. You will see the Apache test page on your browser.
Even though we access the web server with URL http://localhost:8080 in the host system, it is not served from the local webserver. The actual website (i.e. Apache test page) is being served from the guest virtual machine and all actual network data is being sent to the guest.
1.1. What if the port 8080 is being used by another application?
In our previous example, we forwarded the port 80 from guest to port 8080 in host. In other words, the traffic sent to port 8080 is actually forwarded to port 80 on the guest machine. What if some other application is currently using the port 8080? Port collision happens when running multiple VMs. You may unknowingly forward an already used port. No worries! Vagrant has built-in support for detecting port collisions. If the port is already being used by another application, Vagrant will report it in the output, so you can either free up the port or use another port.
Vagrant is also smart-enough to find and correct port collision automatically. If it find a port is collided with another port, it will auto-correct it by using any other unused port for you.
To enable auto-correction, add an extra option
auto_correct: true in the port forwarding definition in your Vagrantfile.
config.vm.network "forwarded_port", guest: 80, host: 8080, auto_correct: true
By default, Vagrant will choose auto-correction port between port 2200 and port 2250 range. You can also choose your own custom range by defining the following line in the Vagrantfile like below.
config.vm.usable_port_range = (2200..2250)
Restart the Vagrant machine to take effect the changes:
1.2. Change network protocol
By default, Vagrant uses TCP protocol for port forwarding. You can, however, use UDP protocol if you want to forward UDP packets.
To use UDP port, add the following definition in your Vagrantfile:
config.vm.network "forwarded_port", guest: 80, host: 8080,
Restart Vagrant VM to apply the changes.
2. Configure private network
In private or host-only networking, a network connection is created between the host system and the VMs on the host system. The private network is created using a virtual network adapter that is visible to the host operating system. The other systems on the network can't communicate with the VMs. All network operations are allowed within the host system.
The private network can also function as DHCP server and has its own subnet. Each VM in the private network will get a IP address from this IP space. So, we can access the VMs directly using the IP from the host system.
To configure private or host-only networking in Vagrant with static IP address, open the Vagrantfile, find the following line and uncomment it.
config.vm.network "private_network", ip: "192.168.121.60"
Here, 192.168.121.60 is the IP address of the VM. Replace this with your own IP.
Restart the VM to take effect the changes.
If you want to set IP address automatically from DHCP, modify the private network definition like below:
config.vm.network "private_network", type: "dhcp"
A random IP address will be assigned to the VM. In order to find the IP of a VM, you need to SSH into it using
vagrant ssh command and then find its ip address with
3. Configure public network
In public or bridged networking, all the VMs will be in same network as your host machine. Each VM will receive its own IP address from a DHCP server (if available in the local network). So all VMs will act like just another physical system on the network and they can communicate with any system in the network.
To configure public or bridged networking, edit Vagrantfile, find the following line and uncomment it:
Save and close the file. Restart the VM to apply the changes. The VM will automatically get an IP address.
If you want to set a static IP, just modify the network definition like below:
config.vm.network "public_network", ip: "192.168.121.61"
4. Set hostname
You can define hostname using the
config.vm.hostname setting in the Vagrantfile.
Edit Vagrantfile in your preferred editor and add/modify the following line:
config.vm.hostname = "myhost.ostechnix.example"
Save and close the file. The above definition will add
myhost.ostechnix.example line in
Restart Vagrant VM to take effect the changes.
Verify if the hostname is changed:
[[email protected] ~]$ hostname -f myhost.osechnix.example
You can also directly check the contents of the
$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.1.1 myhost.osechnix.example myhost
5. Enable multiple network options
Each network option has its own upside and downside. For some reason, you might want to configure all network options to a single VM. If so, Vagrant has the ability to enable multiple network options. All you have to do is just define the network options one by one in the Vagrantfile like below:
config.vm.hostname = "myhost.ostechnix.example" config.vm.network "forwarded_port", guest: 80, host: 8080, auto_correct: true config.vm.network "private_network", ip: "192.168.121.60"
When you create a new VM with this Vagrantfile, vagrant will create a VM with following network details:
- set hostname as myhost.ostechnix.example
- configure port forwarding
- configure a private with static IP 192.168.121.60
In addition to configuring multiple types of networks, we can also define multiple networks as well. For example, you can define multiple host-only network with different IP address like below.
config.vm.network "private_network", ip: "192.168.121.60" config.vm.network "private_network", ip: "192.168.121.61"
Hope this helps. At this stage, you might have get the basic idea about Vagrant networking types and how to configure networking in Vagrant from command line. There is more to learn. I recommend you to look into official Vagrant documentation for more detailed configuration.