Setting up Ubuntu on VirtualBox (Windows) and Why

I have been collecting valuable tricks and techniques over the years developing for the web. On this blog, I hope to share them with the world (and myself, for future reference), so I figure my first post should be getting started with Virtual Machines (VMs). Then, I can run the gamut of getting WordPress and Ghost up and running, and eventually maybe I'll give away some code secrets. There are a million posts about setting up VirtualBox, but this one is specifically for the purpose of setting up a development server.

A VM is a little machine within your machine. I use it to run Ubuntu, so that I can get full access to the wonders of the Linux command line. After years of trying to use Windows and WAMP, things became a little bit too complicated using Git and SSH'ing through the Windows command prompt, installing Ruby and Node, SVN -- I can go on. Then, I had to do it all over again on other (Linux flavor) servers. Windows is Windows, and I see it as a GUI-based OS. I use it for gaming, listening to music, emailing, office, and the things the rest of the world uses it for. However, when it came to doing real power-user tasks, I found that most real-world scenarios involve Linux, so instead of learning how to do it on Windows and then learning how to do it again on Linux (because it's kind of my job to know), I decided to use Ubuntu for the techie stuff.

I experimented with dual-booting. It was OK. When I was done watching Mall Cop, I could restart my laptop, boot into Ubuntu Server, and be ready to go. But I want to be able to access my server's PHP and other files from Windows and see the result while watching movies.

I use VirtualBox because it was the first VM manager I tried, and it worked. It didn't come without its complications. For example, I cannot copy and paste to my virtual machine without using SSH because I'm using a barebones server. That's a big issue, but one I haven't quite figured out. If this is too big of an issue, you might want to install the desktop version instead -- just know it will run a bit slower. Prepare to spend an hour or two (with my help!) getting everything set up. Sometimes, this guide might produce errors because of the many dependencies that this setup requires. Let me know, and maybe I'll be able to revise this guide with more information.

Enough background, let's get started!

For this guide, I am using the following configuration. Some older version of VirtualBox are not compatible with Windows 10, but hopefully future versions will be fine. I'm using 64-bit, so hopefully all of this works if you are using a 32-bit device (just be sure to download the 32-bit versions of everything!)

Windows 10 (x64)
VirtualBox 5.0.10 r104061
Ubuntu Server 14.04.3 LTS Trusty Tahr (x64)

First download Ubuntu. While it's downloading, Download and install VirtualBox, then download and install the VirtualBox Extension Pack. When your Ubuntu download is complete, open VirtualBox. Go to Preferences -> Network and add a NAT network with the default settings. Under Host-only Networks, edit the settings of your Host-Only Adapter, make sure it is 192.168.56.1, then switch over to "DHCP Server" and uncheck the box to disable it. Click "New" in the top left. Name your server, type: Linux, version: Ubuntu (64-bit). I have 8GB ram, so I usually give it 1024MB (1GB). Create a virtual hard disk (VDI). Since I'm on a solid state drive and for the purposes of this tutorial, I'll be using a fixed size disk. My actual server is dynamically allocated though, because it occasionally needs more space and was created before switching to an SSD.

Once it completes, select your new server and click "Settings". Go to Storage, click "Controller: IDE", and under Attributes click the disc -> "choose optical disk file". Find the Ubuntu ISO you just downloaded. If you're on a solid state drive, click the first Controller: SATA, and under attributes check Solid-State Drive.

Now, go under Network and make sure Adapter 1 has "Enable Network Adapter" checked, attached to NAT. After that, we're ready to get started! Click Start, and the VM should automatically boot from the ISO we added to the first IDE controller. Go through selecting language, etc, and the VM will load the additional components needed to install Ubuntu. I leave all of these options up to you -- I just run the defaults. Eventually, you will come to the Partition disk option. I am not using LVM for this particular instance, but it can come in handy, especially if you chose a Dynamically Allocated Disk at the beginning. Learn more about it here. I leave everything else default, and don't install any software -- we'll do that next!

Once your server restarts, it'll boot into Ubuntu and we'll be able to...

Install VirtualBox Guest Additions

Since we have NAT enabled, we should be able to access the internet from Ubuntu. You'll obviously need an internet connection for this next part. Let's update our repos and install guest additions. If you're on Ubuntu Desktop, open a Terminal now (and never close it!). Using 14.04.3, installing VBox Guest Additions was (thank golly) as simple as:

sudo apt-get update
sudo apt-get install virtualbox-guest-x11

As of this moment, you should have the capacity to share copy and paste between Ubuntu and Windows if you are on Ubuntu Desktop by clicking "Devices -> Shared Clipboard -> Bidirectional" in the VBox window. However, it doesn't help Ubuntu Server users, because we're using the basic terminal which has no mouse support. I never figured out the copy-paste situation. You can try installing GPM for a mouse-cursor, install Gnome or use X11... but every time I try it, it bothers me and I remove it. If anybody knows how to get a mouseable, copy-and-pasteable terminal without installing an entire desktop, feel free to let me know and I'll add it to the guide!

Configure a Host-only Network

Now, we have to add a Network Adapter to Ubuntu to provide a host-only interface, and connect it with our host's host-only network adapter. This allows us to ping "192.168.56.2" from the host, and reach the guest. Which means, eventually, we will be able to point domains to it in our HOSTS file, and reach our server files.

In VirtualBox, go to Preferences -> Network and add a NAT network with the default settings (if it isn't there already). Under Host-only Networks, edit the settings of your Host-Only Adapter, make sure it is 192.168.56.1, then switch over to "DHCP Server" and uncheck the box to disable it because we'll configure static IP addresses in a minute.

In your VM, we'll edit the network interfaces file.

sudo nano /etc/network/interfaces

In this file, you should see an eth0 and a loopback adapter. Update this file to look like this:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

# Host Only Config
auto eth1
iface eth1 inet static
address 192.168.56.2
netmask 255.255.255.0

When you're done, restart your VM. Now your Windows Host-only adapter will have the IP address 192.168.56.1, your VM will have the IP address 192.168.56.2 and, in Windows, you should be able to ping 192.168.56.2 in a Command Prompt. If you receive messages like "Reply from 192.168.56.2", everything is working!

Add shared folders between Windows and Ubuntu

The coolest part of this setup is the ability to fully utilize Ubuntu, while being able to edit server files on Windows. I highly recommending using a separate partition, or even better a separate drive, to host your server files, so that Ubuntu has no chance of corrupting your Windows partition. This works for me, since I always use 100GB for Windows and the rest of a drive for a data (F:) partition, where I move my Libraries such as Pictures, Music, etc.

Once you've decided where your server files will live, go to Machine -> Settings -> Shared Folders. Click the Add button to the right, and select the path to your shared folder -- it's okay if there's nothing in there at this point. For the "folder name" option, name it something memorable like "projects". Do not check any of the boxes -- we will handle this manually.

To mount the shared folders, we'll use the rc.local file. This is a file that runs scripts at the end of the boot process, or the beginning of login, one or the other. /etc/fstab is usually used to mount drives, but this is conveniently located before VirtualBox loads its VBoxSF service. I've read articles stating it's not correct to use the rc.local file for this purpose -- this is a dev server. I've never had a problem. We're going to use rc.local to manually mount our vboxsf share with the user and group www-data.

First let's create a directory. I like using /srv/host for my server files located on the host machine.

sudo mkdir /srv/host

sudo nano /etc/rc.local

We're also going to enable a log file at /tmp/rc.local.log so that we can see immediately if something goes horribly wrong.

#!/bin/sh -e
#
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exec 2> /tmp/rc.local.log
exec 1>&2
set -x

sudo mount -t vboxsf -o fmode=666,umask=0002,uid=www-data,gid=www-data projects /srv/host

exit 0

Do a restart, and we'll see how it worked! Create a file in your projects directory in Windows, so you can confirm.

sudo shutdown -r now

ll /srv/host

If you see your file(s) here, then we are ready to go! You have successfully installed a VirtualBox VM and are ready to plunge deeper. Next steps, we are going to install Apache or NGINX (todo: links), MySQL, PHP, Ruby, Node.JS, whatever you're into! Look for these guides over the next few weeks, or jump ahead now and find those resources online!