Back last year in the summer of 2012, I switched my site from Posterous over to Octopress having then decided to remove the dependency on a proprietary blogging platform, primarily because all the site data was held with an organisation that may on a whim choose to cease the service. Case in point, in February of this year Posterous announced they were closing down the service – having been acquired by Twitter back in March 2012, you would probably agree that this was inevitable.
If you’re not familiar with Octopress, it’s a static blogging platform framework built on top of Jekyll, which itself is a simple, blog aware, static site generator. It takes a template directory containing raw text files in various formats, runs it through Markdown and Liquid converters, and spits out a complete, ready-to-publish static website suitable for serving on a preferred web server. Jekyll is very minimalistic and very efficient. The most important thing to realize about Jekyll is that it creates a static representation of a website requiring only a static web-server. Traditional dynamic blogs like WordPress require a database and server-side code. Heavily trafficked dynamic blogs must employ a caching layer that ultimately performs the same job Jekyll sets out to do; serve static content.
Since there are no server side requirements, the dependencies for building out the site therefore exist on your own machine. If you’ve ever followed the documentation on the Octopress site, you’ll have an implementation similar to what I had in place last year – on my Windows 7 machine, I had installed Git for Windows, along with Yari to install and manage Ruby). Once all the relevant RubyGems were installed, I was able to create and maintain my Octopress site, but since I was publishing to Amazon S3, I also needed to use CloudBerry Explorer for Amazon S3 to manually upload the generated content. SkyDrive was also used to store a synced copy of the site data.
Initially using an Amazon S3 bucket to host the static content and Amazon CloudFront as the CDN, in the past few days I’ve just switched over to hosting the site content on Heroku and using CloudFlare as the CDN. It has been quite a number of months since I last made a post, and while working on the move it has quickly become apparent that the local system I was previously using no longer existed (had since been rebuilt), along with the various software components required to post to and maintain the site.
This time around, rather than re-install all the various components again, I wanted to find a more suitable solution which would allow me to update the site from a number of different machines; i.e. a more portable or reproducible method of setting up the environment to allow ongoing maintenance of the site. Some Goggling later, I came across a very interesting piece of software called Vagrant, which allows exactly that.
Vagrant provides easy to configure, reproducible, and portable work environments by isolating dependencies and their configuration within a single disposable, consistent environment. From a single Vagrantfile, regardless of the platform being Mac, Windows or Linux, the environment will be brought up in the exact same way, against the same dependencies, all configured in the exact same way.
Not without it’s own requirements, Vagrant requires an installation of VirtualBox to be present (used to manage the virtual machines), and also an SSH client (used to connect into the virtual machines). On my Windows 7 system, my preference was to install Cygwin with the OpenSSH package – if you’re installing Cygwin to a system where you don’t have administrative rights, make sure you rename SETUP.EXE (retrieved from the Cygwin site) to anything else, such as CYGWIN.EXE, else the system will trigger UAC and prompt for administrative credentials.
With Cygwin, VirtualBox and Vagrant now installed (with default configuration), I then opened up a Cygwin Terminal. By default, I was my in my Cygwin home directory (C:\cygwin\home\andrew.allen) – for example’s sake, this is where I built my Vagrant environment, but if you have your own preference where to store your project data, you should change to the relevant directory on your system. I then typed the following commands:
vagrant init precise32 http://files.vagrantup.com/precise32.box vagrant up vagrant ssh
Once these three commands completed, I had a new virtual machine started in VirtualBox, running Ubuntu 12.04 LTS 32-bit to which I had was now connected via SSH – now that was pretty cool, and took little to no effort.
Next, I configured the machine with the dependencies I needed for Octopress. In the Cygwin Terminal window, I typed the following:
sudo su - apt-get update && apt-get install -y git curl curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3 source /usr/local/rvm/scripts/rvm rvm rubygems latest gem install bundler gem install heroku exit exit
This installed Git, cURL, RVM, Ruby 1.9.3 with RubyGems dependencies including support for publishing to Heroku, then disconnected from the VM. Here is the clever bit – by updating the Vagrantfile with these commands, bringing up this environment in future would automatically install these components. When I first ran the ‘vagrant init’ command, it created the Vagrantfile in the current directory – I opened this file up in notepad, and added the following lines, just before the last ‘end’:
config.vm.synced_folder "/Personal Data/SkyDrive/Projects/www.andrewallen.co.uk", "/projects/www.andrewallen.co.uk" config.vm.provision :shell, :path => "bootstrap.sh"
The first line creates a mapping between my host system where I wanted to store my Octopress site, and a folder within the virtual machine, while the second line contains a reference to a script file which will contain the commands I manually executed previously. I saved the file, closed notepad, created a new file in the same directory called ‘bootstrap.sh’ then added the following lines:
#!/usr/bin/env bash apt-get update && apt-get install -y git curl curl -L https://get.rvm.io | bash -s stable --ruby=1.9.3 source /usr/local/rvm/scripts/rvm rvm rubygems latest gem install bundler
Now when the virtual machine is brought on-line with ‘vagrant up’, this script file will be transferred into the VM and executed as root. Saving the file and closing notepad, I proved this to be the case – switching back to the Cygwin Terminal window, I ran the following commands:
vagrant destroy -f vagrant up vagrant ssh
Once I was connected back to a newly created VM instance, I ran ‘ruby —version’ which confirmed that ruby 1.9.3 was successfully installed. Taking a copy of the Vagrantfile I had created, anyone can now bring up the exact same environment, ready for use by Octopress. Back in the Cygwin Terminal window, I ran the following commands to configure a clean Octopress site, within the project directory I had mapped within the Vagrantfile:
cd /projects/www.andrewallen.co.uk/ git clone git://github.com/imathis/octopress.git octopress rm octopress/.rvmrc rm octopress/.rbenv-version cd octopress bundle install rake install
These files were directly written to the mapped folder on my host machine, which also happens to be within my SkyDrive folder, and not within the VM itself.
Following this work, I am now in the position of being able to bring up an environment to support the management of my site quickly, easily and consistently, but also that all my site data is stored safely, synced automatically, and version controlled within my SkyDrive account. On any machine, I am now able to quickly recreate my blogging environment.
Using the Vagrantfile that I’ve created, you can now bring up an environment with all the correct pre-requisites and dependencies to support an Octopress site, by just installing Vagrant and VirtualBox onto your preferred platform (Mac, Windows, Linux) along with a suitably installed SSH client.