Skip to main content

Vagrant Cachier Plugin

This blog post might be outdated!
This blog post was published more than one year ago and might be outdated!
· 3 min read
Stephan Hochdörfer
Head of IT Business Operations

There's one plugin for Vagrant which I love to promote in my talks and this is the Cachier plugin. When giving my talks and mentioning the plugin I realized that not many people are aware of the plugin. That's the main reason I write the following lines. The downside of Vagrant is what whenever you destroy a virtual machine and build it again all packages (eg. .deb packages for the OS or Composer packages for the application) need to be downloaded again. Downloading and installing a lot of packages can be quite time consuming which in turn means developers try to avoid it. Which in turn means no one regularly checks if provisioning of the virtual machine still works as it should. The Cachier plugin is the solution for that problem. As the name implies the plugin will cache the downloaded packages and re-use them when possible. To achieve that the plugin will link several folders of the virtual machine back to the host, so that the packages are actually stored on the host, not the vm. Very clever.

To be able to use the Cachier plugin you have to install it first via vagrant:

vagrant plugin install vagrant-cachier

To make sure that your virtual machine is using the caching mechanism you have to explictly enable it via your Vagrantfile. Add the following files to your Vagrantfile:

# enable vagrant-cachier plugin if plugin is installed
if Vagrant.has_plugin?("vagrant-cachier")
config.cache.scope = :box
config.cache.enable :apt
config.cache.enable :apt_lists
config.cache.enable :composer
config.cache.enable :npm
end

The configuration logic is wrapped in an if statement to make sure that configuration is done only when the plugin is installed. This way vagrant will also run when the plugin is not installed. It is said that the Cachier plugin is able to detect which caches are needed but I love to explictly turn them of, just for the sake of it. In the example above the plugin with cache apt packages, Composer packages and npm packages. The packages are stored for the box scope which means other projects using the same base box will also use the same cache. As an alternative you can use the :machine scope to store the packages just for the specific machine you are working with.

There was one downside in our setup which in the end was easy to fix: The Cachier plugin does not set up the caching folders for the root user but for any other user. Since we use a bootstrapping script in our virtual machine to run puppet and from our puppet code let Composer run the root user actually was the one running Composer and not using the cached packages. The fix was simple and easy: Before we let puppet run in our bootstrap script we manually symlink the respective folders for the root user:

# Create .composer/cache symlink for root if vagrant-cachier is active
if [ -d /tmp/vagrant-cache/composer/ ]; then
if [ ! -d /root/.composer ]; then
mkdir /root/.composer
fi

if [ ! -L /root/.composer/cache ]; then
ln -s /tmp/vagrant-cache/composer/ /root/.composer/cache
fi
fi

The same solution was needed for caching the npm packages as root:

# Create .npm symlink for root if vagrant-cachier is active
if [ -d /tmp/vagrant-cache/npm/ ]; then
if [ ! -L /root/.npm ]; then
ln -s /tmp/vagrant-cache/npm/ /root/.npm
fi
fi

By using the Cachier plugin we could reduce the provisioning time in one of our projects from about 20min to about 6min which is a clear win for us.