Google the phrase ‘VirtualBox set up’ or similar and you’ll find plenty of guides that will instruct you on the install of a Virtual Machine (VM) with the network adapter set to either NAT or Bridged. While these options work fine, as a web developer you are quick to realise their limitations. So what does a web developer need from their VM networking set up? Simple:
- To simply and consistently connect to the guest VM from the host, and
- To connect to the Internet, remote servers and web applications from the guest VM with the same ease as the host.
Once a VM has been installed, the first goal can be expanded into some real world use cases:
- To immediately be able to SSH into the guest machine from a terminal to configure the environment.
- To connect to another port on the guest VM via an SSH tunnel, i.e. to administer MySQL from a GUI client.
- To request web sites running in the VM through the host’s web browser on the HTTP and HTTPS ports.
- To be able to connect to any other port which maybe required. For example, my VMs run Zend Server so I need to connect over HTTPS on port 10082.
- To be able to connect to the guest VM regardless of my location or the network I’m connected to.
- To set this up once and not have to worry about a guest VM having different IP addresses every now and again.
As for the second goal, the following use cases should be met:
- To immediately be able to connect to the Internet and perform system updates and software installs from the guest VM.
- To be able to piggy back on a host’s private VPN connection.
- To have exactly the same ACL rules as the host when connecting to remote servers or services.
So which network adapter satisfies all of the above use cases? NAT or bridged?
The NAT option for the network adapter achieves all of the use cases for network access (goal 2) but once the VM is launched you cannot immediately connect to it via SSH or any other port. You can discover the IP address attached to the network adapter and try but it won’t work. It’s strange since VMWare fusion gets this spot on. So how is a connection established? The answer lies with port mapping.
For each port you want to connect to on the guest VM, lets say port 22, you have to map an unused port on your host, say port 2222 and then bind the two together (see http://mydebian.blogdns.org/?p=148 or http://blogs.sitepoint.com/build-your-own-dev-server-with-virtualbox/ for two different approaches on how to do this). You may have to do this at least three times, again with port 80 and 443. This now means that you have to specify the alternate connection port when connecting over SSH and HTTP. This might not be such a pain but if like me you have some older web sites and when browsing through them via the mapped port 8080 the site itself redirects using a Fully Qualified Domain Name (FQDN), i.e. switching to port 443 (HTTPS), then it all goes horribly wrong. It’s the correct behaviour when browsing on the staging and production sites but not for our host where it needs to redirect to our mapped port of 4430.
A bridged network option will have the guest VM ask for an IP address to use on the network. The IP address that is allocated to the VM will allow you to make straightforward connections to the guest VM. Just as you would expect. No port mapping. This would meet most of the use cases for the first goal However, the allocated address may be dynamic. If so, this IP address will expire after the lease period and the VM maybe given a different one each time. This becomes a real annoyance if you have to keep changing the host’s host file for a hostname to IP mapping.
If this is a home network you maybe able to create a binding between the VM’s Mac address and a reserved IP address so it has a static IP. This will help prevent changes to the hosts file but if you need to connect to another network, such as a company, hotel or conference, then it’s back to maintaining the hosts file again.
Being connected to a different network may also present difficulties with port access to the guest VM if that network has a security policy in place. You may have access to HTTP and HTTPS but what about SSH? You may also have to accept some usage policy over HTTP to actually do anything, which is annoying if your VM has no GUI.
Of course, the real kicker with the bridged network option lies on the dependancy of being connected to a network. No network access means no connection to the guest VM and your websites won’t load from the host’s browser. Beware of trains, planes and automobiles!
As for the second goal, the guest VM will have it’s own IP address and as such when the guest connects to anything on the network it will most likely inherit a default set of privileges. If like myself, your host machine has additional privileges on some networks, for example, a home and work network, you may need to grant these to your guest VM, ensuring a static IP if needed. This maybe OK if you have one or two VMs and no need to add more but with many VMs this additional setup becomes more of a chore. Clearly the NAT option wins in this regard.
So where does this leave us? Both options by themselves do not meet all of the use cases laid out at the beginning of this post. So what’s the solution? The answer is to set two network adapters. One must be set to NAT to achieve seamless network access from the guest. Whilst, the other must be set to Host to allow a direct connection to the guest via a static IP. No network connection required.
Now go fourth and enjoy a pleasing Web development VM experience with VirtualBox