This is a follow up to my post, Set up VirtualBox for Web Development, where I describe how to configure a VirtualBox VM with two NICs so that you can develop on a local VM wherever you happen to be. I’m going to describe how to enhance that with a shared folder between your guest and host operating systems so that changes can be immediately reflected with a need to “upload” them to the virtual server.
One of the advantages to working with virtual machines for development is having a sandbox to throw stuff in. Not having to install PHP or MySQL on your local machine is nice, and if something goes wrong, just wipe it and start over (or boot from a snapshot). But wouldn’t it be nice if you could save your files and have the changes instantly reflected on the VM without going through an app like Transmit? I’ve been working with CodeKit recently, and one of the nice features is that it will refresh the browser for you automatically when you save your changes, but if you have to “upload” the files to a VM every time you save, this feature isn’t quite as useful. So, let’s fix that.
A couple of things came together in an interesting way leading up to this post. I’ve been working with CodeKit for a few weeks and it had started to become obvious that my workflow was a little flawed. Uploading to the VM after every save was getting old, even with Dropsend from TextMate. I knew about shared folders between VirtualBox host and guest, but gave up after briefly looking into it because I didn’t know how to install Guest Additions via the command line.
Then, someone showed me Vagrant. It’s an awesome app for automatically provisioning “lightweight, reproducible, and portable development environments.” I had a problem with it though; my MacBook is old and slow. Part of the automatic process is using Chef to essentially set up all the apps you need to run your environment – PHP, Apache, MySQL, etc. Everything went smoothly until Chef started doing its thing, then the CPU would jump to 100% and everything would lock up. I could limit this to 75% of the the host’s CPU if I wanted, but that wasn’t the real issue. I never really gave it a chance to finish, but it took long enough that it would be completely impractical for me to wait that long every time I needed to provision a VM for a new project. So, back to plain VirtualBox.
Let’s do this already!
As I mentioned, there is a way to set up a shared folder between the guest and host – Vagrant does this automatically for you, which is the main feature I was interested in anyway. Once you have the guest OS configured the way you want it, it’s only a few steps to create the shared folder:
First, install Guest Tools.
sudo apt-get install dkms
sudo apt-get install build-essential
sudo apt-get install linux-headers-$(uname -r)
After the machine reboots, go to the “Devices” menu and click “Install Guest Additions”. This will essentially add Guest Additions as a CD-Rom, just like if you were using a desktop OS, but you have to mount it manually. Then, run the Guest Additions setup.
sudo mkdir cdrom
sudo mount /dev/cdrom /media/cdrom
If you haven’t already, you’ll need to shut down the guest to add a shared folder in the VirtualBox settings. From VirtualBox, click on the VM you want to set up, go to “Settings”, “Shared Folders”, and add a new share. Then, mount it with the following, where “yourshare” is the name you gave the shared folder.
sudo mount -t vboxsf yourshare /path/to/mountdir
Now you can just save your files into that folder and they will be shared on the guest as well. Eventually, when I get a new machine, I’ll try Vagrant again. This works excellent for me right now though.
- The commands to install Guest Additions came straight from Michael Halls-Moore’s blog.
Instead of mounting the shared folder directly to the path you need it at, you may want to use a symbolic link to take advantage of the auto-mount feature of VirtualBox. When auto-mount is turned on, the folder will be mount in /media as the name you set it up as in VirtualBox, but it will have a prefix of ‘sf_’ in front of it. To create the symbolic link, you would run the following command.
ln -s /media/sf_yourshare /path/to/mount