VirtualBox: How to Configure an Ubuntu 20.04 Virtual Machine for Web Development

When developing for the web we need a local development environment. The simplest way to create a local virtual server for web development is probably to use Oracle VirtualBox. Then you could have as many web dev servers on different virtual machines as you need.

It’s very important to set up your virtual machines properly right from the start. Or you could get a lot of misconfiguration or performance problems. Which could make work a nightmare.

We’ll set up virtual machines with Ubuntu 20.04 on Oracle VirtualBox here. I normally use VirtualBox on Mac and Windows computers. So I am considering installation and configuration here both on computers running Windows 10 and macOS Catalina.

And we’ll consider how to configure the virtual machines for the best performance.

I hope it will be useful to web developers, webmasters, or any enthusiasts who need to use VirtualBox for web development.

1. Install Oracle VirtualBox and an Ubuntu 20.04 Virtual Machine

The installation process is pretty straightforward. So, I’ll describe it very briefly.

If setting up a virtual machine is too elementary for you, please skip to section 2. Configure the Network. This is where some interesting stuff begins.

First, you need to install the Oracle VirtualBox. Personally I’ve installed version 6.1.2 which is available from the older builds on the VirtualBox official site since I had some performance problems with version 6.1.12 (version 6.1.12 was the latest version at the time of this article writing).

The installation of Oracle VirtualBox is pretty straightforward. You will have an exe-file for Windows on a dmg-file for macOS. Just run the installer and follow the instructions.

When the VirtualBox software has been installed, you’ll need to create a new virtual machine. It’s a little bit less evident. So let’s consider it.

I’ll show it for a Mac computer. But for Windows, it is the same.

To create a virtual machine, run the Oracle VirtualBox and click the button VirtualBox Button New New:

Create a Virtual Machine (macOS)
Create a Virtual Machine

In a window that opens enter the virtual machine name, select the operating system, and click Continue:

Enter the Virtual Machine Name (macOS)
Enter the Virtual Machine Name

On the next screen set the RAM for the virtual machine. The default is 1GB. I usually set it to 4GB. But it depends on how much memory you have on the host machine and how much you are ready to spare. In any case, you’ll be able to increase or decrease the virtual machine RAM after the virtual machine has been created.

Set RAM for Virtual Machine (macOS)
Set RAM for Virtual Machine

Then you’ll need need to choose the Create the virtual hard disk now option which is the default:

Virtual Hard Disk (macOS)
Virtual Hard Disk

Next, you’ll be asked to choose the virtual disk file type. I keep it at the default setting which is VDI:

Choose Hard Disk File Type (macOS)
Choose Hard Disk File Type

Next, I always choose the hard disk to be Dynamically allocated. It allows me to set the disk size to some bigger value e.g. 100GB. But initially, the disk will be small (so the virtual machine will not take a lot of space on the host machine hard disk right away). And additional space will be allocated when necessary.

Choose Dynamically Allocated Disk (macOS)
Choose Dynamically Allocated Disk

And finally, set the virtual hard disk file size. Since I always use a dynamically allocated disk (which means it will be small at first and will grow when necessary), I usually set the size to some bigger value, e.g. 100GB. You never know how much additional space you’ll need. So I find it convenient to set the disk size big enough.

Set the Virtual Hard Disk File Size (macOS)
Set the Virtual Hard Disk File Size

Now we need to install the Ubuntu operating system. So, you need to download the Ubuntu 20.04 Server iso image. You can do it here (or just Google for “ubuntu server download”).

After we have downloaded the iso image, select your newly created virtual machine in the left panel and click the button VirtualBox Settings Button Settings:

Select Your VM and Click the Button Settings (macOS)
Select Your VM and Click the Button Settings

In the window that opens select the tab Storage and add the iso file to the virtual machine optical drive:

Add iso File to VM Optical Drive (macOS)
Add iso File to VM Optical Drive

Also, make sure that it is set for the virtual machine to boot from the CD-ROM first. It is done on the tab System of the same Settings window and this is the default boot sequence.

Now when you VirtualBox Button Start start your virtual machine, the Ubuntu 20.04 installation from the virtual CD-ROM will start.

The Ubuntu installation process is step by step and pretty straightforward. So I am not describing it here.

After Ubuntu has been installed, you need to install packages you’ll need for web development. The easiest way is probably to use Docker. In this way, you can easily experiment with e.g. different versions of PHP, MySQL, etc. by running different docker containers for them. E.g. installing WordPress with XDebug in a docker container is described in this article.

2. Configure the Network

There are 2 ways to configure the network for a Linux virtual machine:

  1. using the VirtualBox Bridged network adapter
  2. using 2 adapters at once: NAT adapter (for the VirtualBox to access the Internet) and Host-only adapter (for you to access the VM locally by SSH, HTTP, etc.)

Each of these 2 ways has its own cons and pros (described in the sections below).

You need to choose one of these 2 ways (not both of them). To proceed with the bridged network adapter configuration, continue to section 2.1. To proceed with NAT + Host-only adapters configuration, go to section 2.2.

2.1 Configure the Network on a Bridged Adapter

In this case, your VM will look and behave like a separate computer in your local network. It will have a separate from your host machine IP address. And it will be accessible in your local network (not just from your host machines but from other computers as well) by this IP address.

There’re Pros and Cons for this method:

Pros:

  1. Simpler to configure
    You need only 1 network adapter. And you do not need additional VirtualBox configurations (like having a NAT network or adding a Host-only adapter – like in section 2.2)
  2. VM is accessible from anywhere on your local network by the VM IP address.
    So your server could be easily shown e.g. to your co-workers.

Cons:

  1. Requires a router (yes, physical device). No router? See section 2.2.
  2. VM is accessible from anywhere on your local network
    So, anyone on your local network could try to access it (and maybe it’s not what you want).
  3. VM takes a separate (from your host machine) IP address on your local network
    So you could need to talk to your system administrator or warn your colleagues or they could try to acquire the same IP and you would get some IP conflicts.

2.1.1 Configure the Bridged Adapter for the Virtual Machine

Your VM with a bridged adapter will appear as a separate computer in your local network.

Let’s configure it.

Turn off your virtual machine if it is on.

MacOS: For your VM go to VirtualBox Settings Button Settings > Network and set the Adapter 1 to the Bridged Adapter:

Virtual Machine Bridged Adapter Configuration
Virtual Machine Bridged Adapter Configuration

The default Adapter Type would be Intel Pro/1000 Mt Desktop. You can leave it as is. I have set it to Paravirtualized Network (virtio-net) hoping for some performance improvement.

Windows: For your VM go to VirtualBox Settings Button Settings > Network and set the Adapter 1 to the Bridged Adapter:

Virtual Machine Bridged Adapter Configuration (Windows)
Virtual Machine Bridged Adapter Configuration

2.1.2 Set a Static IP for the Ubuntu Virtual Machine

Let’s set the static IP address for our Ubuntu 20.04 Virtual Machine.

In my case, I have configured (in my router settings) my local network to use the subnet 192.168.1.0/24 with my router having IP address 192.168.1.1. My host machine has the static IP 192.168.1.50. And I’ve decided to set the static IP address 192.168.1.98 for my Ubuntu 20.04 VM.

Log in to your Virtual Machine. In the Ubuntu 20.04 console run:

cd /etc/netplan/
sudo nano 00-installer-config.yaml

The initial file contents will be:

# This is the network config written by 'subiquity'
network:
  ethernets:
    enp0s3:
      dhcp4: true
  version: 2

For the static IP 192.168.1.98 change the file contents to:

network:
  ethernets:
    enp0s3:
      dhcp4: false
      addresses: [192.168.1.98/24]
      gateway4: 192.168.1.1
      nameservers:
         addresses: [8.8.8.8, 8.8.8.4]
  version: 2

I used Google DNS servers here: 8.8.8.8, 8.8.8.4. You can use any DNS servers you wish instead of course.

Now to apply the changes, run:

sudo netplan apply

2.1.3 Add the Static IP to the File hosts on the Host Machine

At this stage, we can access our virtual machine by its IP address 192.168.1.98 only. To be able to access our virtual machine from our host machine by some hostname (domain name), we need to add this name to the file hosts. This file is called the same (hosts) on Mac, under Windows, and under Linux.

MacOS: On Mac we can edit the hosts file like this:

sudo nano /etc/hosts

Add the following line to the file:

192.168.1.98    mytestsite.com

and save the file.

On the previous versions on MacOS I also had to flush Mac’s DNS cache like this:

sudo killall -HUP mDNSResponder

but on MacOS Catalina it does not seem to be required any longer.

Now if you e.g. run an HTTP server on your VM, you would be able to access it from the browser prompt by your domain name – in our case mytestsite.com.

Please note that on your host machine the domain name mytestsite.com will always resolve to 192.168.1.98 now. So if mytestsite.com really exists on the Internet, you will be accessing 192.168.1.98 instead.

Windows: If your host machine is under Windows, then (if Windows is installed by the default path) your hosts file could be found by the following path: c:\Windows\System32\drivers\etc\hosts

You will add the same (as for the macOS) line to the file:

192.168.1.98    mytestsite.com

And then you will need to run

ipconfig /flushdns

from the Windows terminal to flush the DNS cache under Windows.

Linux: Under Linux, the file hosts is normally located in the directory /etc. So you edit it like:

sudo nano /etc/hosts

and add the same line as in the examples above:

192.168.1.98    mytestsite.com

2.2 Configure the Network on NAT + Host-only Adapters

We are using 2 network Adapters in this case:

  1. NAT adapter – for our Virtual Machine to access the Internet
  2. Host-only adapter – for us to access the VM locally by SSH, HTTP, etc.

In this case, our VM will be available by its IP address from our host machine only. It will not be available from other computers on our local network. It does not require a router at all. It does not consume a separate IP on the local network.

There’re Pros and Cons for this method:

Pros:

  1. No router required
  2. VM is not accessible from other computers
    It does not take an additional IP address in your local network. It can not be accessed from other computers (if it’s what you want).

Cons:

  1. A little bit more difficult to configure
    You need to configure 2 network adapters.

2.2.1 Add a NAT Network

MacOS: Open the VirtualBox Preferences menu (keyboard shortcut: ⌘,):

VirtualBox Preferences Menu (macOS)
VirtualBox Preferences Menu

In the window that opens add the NAT network:

NAT Network Added (macOS)
NAT Network Added

In my case the NAT network has been added with the following settings:

NAT Network Settings Example (macOS)
NAT Network Settings Example

Please notice that this is a completely new network. E.g. my network (where the host machine is located) is 192.168.1.0/24. But this new NAT network is 10.0.2.0/24. It is a completely different network of course.

Windows: In the Oracle VirtualBox window click File > Preferences:

VirtualBox Preferences Menu (MS Windows)
VirtualBox Preferences Menu

In the window that opens add the NAT network and click the OK button:

NAT Network Added (MS Windows)
NAT Network Added

In my case the NAT network has had the following parameters:

NAT Network Settings Example (MS Windows)
NAT Network Settings Example

2.2.2 Add a Host Network

MacOS: With VirtualBox window in focus in the menu at the top of the screen click File > Host Network Manager...

Main Menu: File > Host Network Manager... (macOS)
Main Menu: File > Host Network Manager…

In the window that opens add a host network:

Host Network Added (macOS)
Host Network Added

In my case, the network created for me was 192.168.56.1/24. Please notice that it is quite different from the network where my host machine is located (my physical router network) which is 192.168.1.0/24.

Windows: Click File > Host Network Manager...

Main Menu: File > Host Network Manager... (Windows)
Main Menu: File > Host Network Manager…

Add the host network:

Host Network Added (Windows)
Host Network Added

2.2.3 Configure the NAT Adapter for the Virtual Machine

Turn off your virtual machine if it is on.

MacOS: With your VM selected go to VirtualBox Settings Button Settings > Network and set the Adapter 1 to the NAT Adapter:

Virtual Machine NAT Adapter Configuration (macOS)
Virtual Machine NAT Adapter Configuration

Windows: With your VM selected go to VirtualBox Settings Button Settings > Network and set the Adapter 1 to the NAT Adapter:

Virtual Machine NAT Adapter Configuration (Windows)
Virtual Machine NAT Adapter Configuration

2.2.4 Configure the Host-only Adapter for the Virtual Machine

Turn off your virtual machine if it is on.

MacOS: With your VM selected go to VirtualBox Settings Button Settings > Network and set the Adapter 2 to the Host-only Adapter:

Virtual Machine Host-only Adapter Configuration (macOS)
Virtual Machine Host-only Adapter Configuration

Choose the network name from the Name drop-down.

Windows: With your VM selected go to VirtualBox Settings Button Settings > Network and set the Adapter 2 to the Host-only Adapter:

Virtual Machine Host-only Adapter Configuration (Windows)
Virtual Machine Host-only Adapter Configuration

2.2.5 Set a Static IP for the Ubuntu Virtual Machine

Since the host network is 192.168.56.1/24 (see section 2.2.2), we must set the static IP of our virtual machine in this network. Let’s configure it as 192.168.56.2.

Log in to your Virtual Machine and run in the Ubuntu 20.04 console:

cd /etc/netplan/
sudo nano 00-installer-config.yaml

For the static IP 192.168.56.2 change the file contents to this:

network:
  ethernets:
    enp0s3:
      dhcp4: true
    enp0s8:
      dhcp4: false
      addresses: [192.168.56.2/24]
  version: 2

Here we’ve configured the network interface enp0s3 for the NAT network (the IP of the VM in this network is obtained via DHCP) and the network interface enp0s8 for the host-only network (where we’ve configured the static IP address 192.168.56.2 for the VM).

2.2.6 Add the Static IP to the File hosts on the Host Machine

In our case, the VM will be accessible from on host machine by the IP address 192.168.56.2. The VM can be accessed by this IP from the host machine only (where we run the VirtualBox). We can’t access the VM from any other computer on our local network.

To be able to access the VM not only by the IP address but also by a hostname (domain name) from our host machine, we need to add the hostname to the file hosts on the host machine:

192.168.1.98    mytestsite.com

How to add this line to the file hosts under macOS, Windows and Linux is described in section 2.1.3 above.

Additional reading for section 2.2: you could also check this article on how to configure a web-development environment for a Debian VM using NAT + Host-only adapters.

3. Add Guest Additions to the Ubuntu Virtual Machine

3.1 Install Required Packages on the Ubuntu Virtual Machine

Login to your Ubuntu 20.04 virtual machine terminal. First you need to update all Ubuntu packages:

sudo apt update & apt upgrade -y

Now run:

sudo apt install linux-headers-$(uname -r) dkms build-essential

Technically dkms is not required for the Guest Additions to work. But if you do not install the package, the Guest Additions would stop working after the next VM kernel update. So it is better to install this package right away (it must be installed before installing guest additions).

Now you need the file VBoxGuestAdditions.iso of the same version as the version of your VirtualBox. In my case it is VirtualBox 6.1.2 (I had some performance problems with 6.1.12 so I installed 6.1.2 instead). You can locate the file VBoxGuestAdditions.iso on the computer where your VirtualBox has been installed:

3.2 Locate VBoxGuestAdditions.iso on your computer

MacOS: Go to your Applications directory, locate the file VirtualBox, right-click on it, select Show Package Contents:

Locate VBoxGuestAdditions.iso on Mac: Step 1
Locate VBoxGuestAdditions.iso on Mac: Step 1

This will open the package contents. There under Contents > MacOS locate the file VBoxGuestAdditions.iso:

Locate VBoxGuestAdditions.iso on Mac: Step 2
Locate VBoxGuestAdditions.iso on Mac: Step 2

Copy the file VBoxGuestAdditions.iso to any directory on your computer.

Windows: The file VBoxGuestAdditions.iso could be found in the directory where the VirtualBox is installed. By default it is: c:\Program Files\Oracle\VirtualBox\

Just right-click on the VirtualBox desktop shortcut and see the installation path for the VirtualBox on your computer:

VirtualBox Desktop Shortcut Right-Clicked
VirtualBox Desktop Shortcut Right-Clicked

The file VBoxGuestAdditions.iso will be in the same folder as VirtualBox.exe.

3.3 Install Guest Additions on the Ubuntu Virtual Machine

Turn off your VM if it is on.

macOS: In the VirtualBox interface for your VM go to VirtualBox Settings Button Settings > Storage. Add the disk file VBoxGuestAdditions.iso to your VM Optical Drive:

VBoxGuestAdditions.iso in the VM Optical Drive
VBoxGuestAdditions.iso in the VM Optical Drive (macOS)

Windows: The same as for Mac, for your VM go to VirtualBox Settings Button Settings > Storage. Add the disk file VBoxGuestAdditions.iso to your VM Optical Drive:

VBoxGuestAdditions.iso in the VM Optical Drive (Windows)
VBoxGuestAdditions.iso in the VM Optical Drive (Windows)

You do not need to boot from this optical drive.

Turn your VM on.

Now mount this optical drive to some directory on the Ubuntu VM. In the Ubuntu terminal run (I am mounting to the subdirectory cdrom of the current Ubuntu user home directory – you can mount to any other directory of course):

cd
mkdir cdrom
sudo mount /dev/cdrom cdrom

You’ll get the message “WARNING: device write-protected, mounted read-only.”. It’s OK of course – a CD-ROM is supposed to be read-only.

Now run:

cd cdrom
sudo ./VBoxLinuxAdditions.run

In the end, you’ll get the message “VirtualBox Guest Additions: Running kernel modules will not be replaced until the system is restarted”. So reboot the VM for the changes to take effect:

reboot

Please also check the 4.1 Introduction to Guest Additions section of the VirtualBox documentation.

3.4 Check that the Guest Additions have been installed successfully

To check the Guest Additions have been really installed, run this command from the VM console:

lsmod | grep vbo

If the Guest Additions have been installed successfully, you will see vboxguest in the results. E.g. in my case the result looked like this:

Check that VM Guest Additions were installed
Check that VM Guest Additions were installed

Also you could check this reply and this Youtube video.

4. Additional Performance Improvements

What we’ve done so far should make your VM work without performance problems already. At least this how it worked for me.

But if you wish to improve the virtual machine disk performance a little bit, you could try the approach described in this article.

What is proposed in that article is to go to VirtualBox Settings Button Settings > Storage, select the Controller: SATA and check the checkbox Host I/O Cache:

macOS:

Host I/O Cache
Host I/O Cache (macOS)

Windows:

Host I/O Cache
Host I/O Cache (Windows)

5. Deploy Your Website Locally

Probably the simplest way to deploy your web site for development locally is to use Docker. Please see this article on how to do that for a WordPress site. The article describes how to set a development environment with Docker for a WordPress site. And how to add XDebug to the docker image (which would certainly be useful for development).

Or you could set LAMP and deploy a web site locally in the traditional way. This process is pretty straightforward and out of the scope of this article.

Conclusion

Why have I written all this in the first place? I’ve been using Oracle VirtualBox for web development for many years. But recently I’ve started getting performance problems with my virtual machines. And the more recent versions of the VirtualBox I used, the worse everything worked. I’ve ended up with some of my web pages sometimes loading instantly but sometimes after 10 seconds delay. The work has become intolerable.

The worst performance problems were on virtual machines where I used Docker containers.

At that time I was on VirtualBox 6.1.12, the host machine was running macOS Catalina, my virtual machines were on Ubuntu 20.04 and the VirtualBox Guest Additions were not installed.

So I’ve decided to dig into VirtualBox configuration more carefully. Downgrading from VirtualBox 6.1.12 to 6.1.2, using 2 network adapters (NAT + Host-only), and especially installing VirtualBox Guest Additions solved the performance problems for me. Virtual machines with the Bridged Adapter also have started to work much better with Guest Additions installed and on VirtualBox 6.1.2.

So, it’s very important to configure your virtual machine properly right from the start 🙂

I hope you’ve enjoyed the article.

If you have any questions or comments, I would be very glad if you posted them below.

All my articles are always work in progress. So, if you have anything to say, please do not hesitate to do it. Your comments will be highly appreciated.

Thanks for reading to the end!

Leave a Reply

Your email address will not be published. Required fields are marked *