Today the EC2 machine that I have been using to run my blog application for the past couple years expires, so I had to move to a new instance. Unfortunately, while I had done a great job of automating the setup for my blog, I had not done a good job of automating the bootstrapping of the operating systems that I use. I think it is really important that system initialization steps be automated, so you can easily deploy additional nodes, rebuild exact systems from scratch, and quickly recover from a disaster.
To make things easier, I wrote a bootstrapping script for the two operating systems that I use (OSX and Ubuntu), which sets up the software I need to develop in Python and Node.js, and start the initialization script that is part of my blog repo. This article will introduce my bootstrapping script.
The canonical reference will always be at https://gist.github.com/mattsnider/5485500. Here is what the script looked like at the time of this writing:
#!/bin/bash # expects python is installed with OS distribution # single line command for execution # wget -O - <RAW_URL> | bash # determine environment if hash apt-get 2>/dev/null; then echo "Bootstrapping UBUNTU" UBUNTU=true # update apt-get and install a C compiler sudo apt-get -y update && sudo apt-get -y upgrade sudo apt-get -y install gcc else echo "Bootstrapping OSX" # on OSX we use brew as the application repo ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)" brew doctor OSX=true fi # install python, when necessary if [ $UBUNTU ]; then sudo apt-get -y install python-dev python-setuptools fi # setup pip and virtualenv sudo easy_install pip sudo pip install virtualenv sudo pip install virtualenvwrapper mkdir $HOME/.virtualenvs # install git if [ $UBUNTU ]; then sudo apt-get -y install git fi if [ $OSX ]; then brew install git fi # install node and npm if [ $UBUNTU ]; then sudo apt-get install node npm fi if [ $OSX ]; then brew install node npm fi
To run the script as a single command, grab the raw URL from the gist and execute:
wget -O - <RAW_URL> | bash # eg. wget -O - https://gist.github.com/mattsnider/5485500/raw/ec8b38022145dac41b1ef4ad5dd262cc845b4ee0/bootstrap.sh | bash
The script is broken up logically and comments atop each section describe what the section is doing. First, the code determines the operating system by checking if the program
apt-get exists. For either OS a temporary variable is created to be used by later
if statements. When the OS is Ubuntu, it updates
apt-get and ensures that a C compiler is installed. When the OS is OSX, it installs
brew which will be used as the application packaging tool for installing new software.
The next step is to ensure
python-setuptools are installed, so we have python and can use
easy_install to install
pip. This is kept logically separate from the first step, in-case I decide to support additional operating systems in the future.
The third step installs
virtualenvwrapper, and ensures that the required
~/.virtualenv exists. These tools are a must have for any python developer.
Next the script installs
git for repository management and lastly it installs
npm for development in Node.js.
At this point the system is ready to run whatever initialization scripts you have for your application. For my blog, I need to manually clone the git repo, create a virtual environment, and install fabric in that environment. Then I have a fabric script that automates the rest of the installation.