bentomas.com

Development virtual machines on OS X using VirtualBox and Ubuntu

This post is going to be a blatant rip off of Bradley Wright’s excellent write-up about Development virtual machines on OS X using VMWare and Ubuntu. That article changed the way I develop on my Mac (I recommend reading it first if you are going to proceed. He covers the reasons for doing this and many of the steps much more eloquently than I).

Today I decided to give Sun’s free VirtualBox a try, and these are the steps I took to do it:

What you will need:

For those that have used VMWare Fusion, VirtualBox is a little different. Instead of just creating a virtual machine, you create both the machine and a virtual hard drive on which to store it.

We’ll start with creating the virtual machine, and in the process create the hard drive. Open up VirtualBox and start by clicking “New”. Follow along with the wizard that pops up. Most of the questions are pretty straightforward. I chose

Next, start the virtual machine and follow the instructions for the “first run”. When prompted for the “Installation Media”, choose “Image File”. I used the button to launch the “Virtual Media Manager” and dragged the Ubuntu ISO image I downloaded earlier into the area that popped up. Then I selected that ISO file as my image file.

When Ubuntu finally loads and the install screen pops up…

  1. Choose your language
  2. We want to make a small change to our Ubuntu install. Hit F4 to get the different install modes and choose “Install a minimal virtual machine”
  3. Start the installation
  4. Just like Bradley recommends, I don’t install any pre-configured server options and leave it absolutely bare bones. We can install anything we want later quite easily with apt-get.

Once your virtual machine is up and running it is probably a good idea at this point to update the system…

  1. sudo apt-get update (this updates the package sources)
  2. sudo apt-get upgrade (this updates the installed packages)

And because you’ll want to ssh into your virtual machine at some point…

  1. sudo apt-get install ssh

Next we need to install the VirtualBox ‘Guest Additions’, which will allow us to mount local folders from our Mac as shared folders in Ubuntu.

  1. As per the VirtualBox documentation, first install Dynamic Kernel Module Support with sudo apt-get install dkms
  2. Restart your virtual machine with sudo shutdown -r now to ensure that the previous changes take effect
  3. Install the VirtualBox Guest Additions by going to the “Devices” menu and choosing “Install Guest Additions”. What this does is load a virtual disc image into your “Virtual Media Manager”
  4. Attach this disc image to the virtual machine by going to the “Devices” menu and choosing “Mount CD/DVD-ROM” and then “CD/DVD-ROM Image…”. From there select “VBoxGuestAdditions.iso”.
  5. Mount the disc image with the command mount /cdrom
  6. Install the necessary tools to be able to compile the additions with sudo apt-get install linux-headers-server build-essential
  7. Finally, run the guest additions installer which is located at /cdrom. There are multiple scripts in there, so you want to choose the one that is appropriate for your system. The command I used was sudo sh /cdrom/VBoxLinuxAdditions-amd64.run

Phew!

Next let’s add a shared folder to our virtual machine.

  1. Go to “Devices” and choose “Shared Folders…”
  2. Click the add-folder-icon
  3. For the “Folder Path” type the full path to a folder on your mac. I am mounting my Sites folder, so I put: /Users/benjamin/Sites
  4. For the “Folder Name” type the name you want to use to mount it. I put: sites
  5. Check “Make Permanent”
  6. We need to create a directory for where you want to mount this shared folder. This is the “mount point”. In this case I want to mount it into my Ubuntu home directory. Type the following command, mkdir ~/sites.

Update: The original way I recommended mounting the directories (by editing /etc/fstab) doesn’t work. To quote:

If you want to have it mount automatically upon each boot, put the mount command in /etc/rc.local (Debian based distro’s), or whatever script is run at the end of the boot process. The Shared Folders service should mount them automatically, but that doesn’t always happen. Using /etc/fstab has little effect, because that file is processed before the SF module is loaded and will fail to mount the share. Sometimes, the share does get mounted because the GA check for it when they are loaded upon boot, but it’s very flaky, meaning it doesn’t work most of the time. You’re better of with the first option.

So, it appears the one time I tested it was a part of that “sometimes”. The correct way to do this is…

  1. Using your favorite text editor, edit /etc/rc.local. I edit it with the following command: sudo vi /etc/rc.local
  2. Add the following line to the end of the file: mount -t vboxsf -o defaults,ttl=5,uid=1000,gid=1000 sites /home/benjamin/sites or more generically: mount -t vboxsf -o defaults,ttl=5,uid=<user id>,gid=<group id> <folder name> <mount point> (you can find your “user id” and “group id” by running the id command, but usually they are both 1000).

Unfortunately at this point there is no way to communicate with the virtual machine. By default VirtualBox uses NAT for its virtual networking and to quote from the documentation about NAT:

A virtual machine with NAT enabled acts much like a real computer that connects to the Internet through a router. The “router”, in this case, is the VirtualBox networking engine, which maps traffic from and to the virtual machine transparently. The disadvantage of NAT mode is that, much like a private network behind a router, the virtual machine is invisible and unreachable from the outside internet; you cannot run a server this way unless you set up port forwarding

And the only way to set up port forwarding is via the command line. There is no GUI for it. This isn’t exactly the easiest to set up and frankly not as flexible as I would like. It seems like I am setting up a new virtual machine every week and I don’t want to have to a) remember the commands to add port forwarding or b) keep track of which ports point to which virtual machines.

My solution was to switch the virtual networking mode from NAT to Bridged. Bridged mode essentially makes it so the virtual machine connects to the same router your mac connects to for its internet connection. This means it has an IP address that is accessable to anyone one your network. I then configured my router to always give the virtual machine the same IP address so I could create a local hostname for it (with a command like ghost). Problem solved!

The option to switch from NAT to Bridged mode is in the settings for the Virtual Machine. Once you have switched it, log in again and type the following command: ifconfig. This will tell you the ip address of the vm. Now you can ssh into this virtual with that ip address.

And voilá we’re all done!

Thus far (after having only used it for a few hours) I am liking VirtualBox. It is much snappier to start and stop than VMWare Fusion, and the size of the virtual machine is much smaller (about 1GB as compared to 4GB). The lack of a great headless mode might prove to be frustrating though. We’ll see!