Earlier posts on my blog show that I like to run my development environments on virtual machines rather than directly on my own OS. In the past I did this using VirtualBox, nowadays I prefer using Vagrant (my previous blog post probably gave that away already) which makes managing development VMs a lot easier. If you’re not already using Vagrant I highly recommend you give it a try. There’s an excellent introduction on Railscasts if you like screencasts, otherwise the Vagrant website should most certainly help you get started. I like to do most of my work on shell sessions, and to do this effectively I have the need to customize all of my Vagrant boxes to have my own settings. In this article I’ll show you how you can easily setup Vagrant to customize your Vagrant boxes to your heart’s content.
Vagrant directly supports adding your own customizations to all your boxes by specifying your own Vagrantfile in ~/.vagrant.d/, any settings configured in that Vagrantfile are loaded before loading the project’s own Vagrantfiles (for more details on how this works you should take a look at the documentation). With that in mind let’s get started!
Here’s what my shell environment of choice requires:
- My dotfiles (my personal configuration files)
All that is needed is to get ~/.vagrant.d/Vagrantfile setup to install the required software and grab my dotfiles.
Installing software on a Vagrant box can be done easily enough using one of the supported provisioners, I’m not an expert on using Chef or Puppet so I’ll go with the Shell provisioner (it simply uses Shell scripts). The following Bash script will install the software I need assuming the Vagrant box I’m using uses apt for installing packages (which Debian based distros like Ubuntu do):
#!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive apt-get update > /dev/null apt-get -y install tmux vim zsh git-core
The DEBIAN_FRONTEND=noninteractive setting will prevent dialogs that ask you to enter settings while installing and/or updating packages and will use the default instead, you’ll need this setting because you can’t interactively answer these prompts when the Vagrant provisioner runs (in fact it would stop provisioning at the first prompt, since it would wait for an answer forever). The rest of the script should explain itself if you are familiar with apt.
To use the script simply call the Shell provisioner in ~/.vagrant.d/Vagrantfile like so (this assumes that the script is saved as ~/.vagrant.d/scripts/provision):
Vagrant::Config.run do |config| config.vm.provision :shell, :path => File.join(File.dirname(__FILE__), "scripts", "provision") end
Bringing up any Vagrant box will now install Tmux, Vim, Zsh and Git before the box’s own provisioning is done.
Grabbing the dotfiles
Next up is getting my dotfiles onto the Vagrant box, I’ll do this by copying them from my own machine since that already has the latest copy of them. I can share the directory that has my dotfiles with my Vagrant boxes by adding a line to ~/.vagrant.d/Vagrantfile:
Vagrant::Config.run do |config| config.vm.share_folder "v-dotfiles", "/home/vagrant/.dotfiles", File.expand_path("~/.dotfiles") config.vm.provision :shell, :path => File.join(File.dirname(__FILE__), "scripts", "provision") end
The above makes my dotfiles available in ~vagrant/.dotfiles on the Vagrant box, to actually get the dotfiles in the appropriate places I’ll need to modify the earlier created shell script. My dotfiles directory has it’s own setup script which copies the various files to the appropriate places, I can simply execute that script as the vagrant user to get everything setup:
#!/usr/bin/env bash export DEBIAN_FRONTEND=noninteractive apt-get update > /dev/null apt-get -y install tmux vim zsh git-core su -c "cd /home/vagrant/.dotfiles && ./setup" vagrant
The above Shell script uses su to ensure that the setup script is executed by the vagrant user because the Vagrant Shell provisioner runs in a sudo environment which causes the script to be executed by the root user, and my script needs to run as the user it’s executed for in order to copy the files to the appropriate places. If your dotfiles directory doesn’t have such a script you can either create one or simply add commands to the provision script to copy them from there.
Bringing up any Vagrant box will now have it ready to go with my tools and settings.
Now that we’ve come to the end of this article you should have an idea of how you can setup Vagrant to add your own personalized customizations to all of the Vagrant boxes you run. Hopefully this will help you get your Vagrant boxes running the way you want them to.