(This is the second article in a series of four - following on from Vagrant, Docker, Virtualenv - the dev trifecta. The next article in this series is now available - Docker services. Code from this series of articles will be made available on Github as yunojuno/trifecta.)
As discussed in the opening article, the base platform for our developer environment is provided by Vagrant. This provides a common operating environment which supports the other elements of our solution - Docker and Virtualenv - and provides a consistent platform across all host operating systems (so developers can work on OSX, Linux, Windows). We'll be building Python apps, so we also want a clean Python environment - with all the dependencies required to install additional pre-requisites.
In order to provide as clean an environment as possible, we build our Vagrant box from scratch off of the official ubuntu/trusty64 base box. Our Vagrantfile is extremely simple - we run a single provisioning shell script, which I'll run through here.
1. The first thing to do is update local packages:
echo "-> Update installed packages"
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get autoremove -y
2. Before installing Python, we need a set of additional libraries to ensure that we can build Python from source. Working this list out involves a lot of trial-and-error, Googling, and StackOverflow research. This is the list we end up with:
echo "-> Install libraries required to build python from source"
sudo apt-get install -y \
libreadline6 libreadline6-dev \
3. Now we are in a position to build Python. We want 2.7.9, as that matches the runtime we use on Heroku (the default Ubuntu 14.04 Python is 2.7.6):
echo "-> Downloading source files for Python 2.7.9"
tar -xvf Python-2.7.9.tgz;
echo "-> Building Python from source"
sudo make install;
echo "-> Updating /usr/bin symlink"
sudo rm -f /usr/bin/python
sudo ln -s /usr/local/bin/python /usr/bin/python
4. Now that we have a new Python, we need to reinstall the setuptools and pip, so that we can install additional python packages:
echo "-> Installing python-dev and mercurial"
sudo apt-get install python-dev mercurial -y
# Because: http://stackoverflow.com/a/12780859/45698
echo "-> Installing easy_install and mercurial"
sudo python ez_setup.py
sudo easy_install -U mercurial
echo "-> Installing pip"
sudo python get-pip.py
5. Install Docker, and Docker-Compose, in order to support the second element in our solution - service isolation (replicating the concept of Heroku add-ons).
echo "-> Installing docker"
wget -qO- https://get.docker.com/ | sh
echo "-> Adding user to docker group"
sudo usermod -aG docker vagrant
echo "-> Installing docker-compose"
sudo pip install docker-compose
6. Install Virtualenv and Virtualenvwrapper to enable the third element of our solution - isolated Python environments, mimicing the Heroku slug concept:
echo "-> Installing virtualenv and virtualenvwrapper"
sudo pip install virtualenv virtualenvwrapper
echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
7. Finally, we install the Heroku toolbelt. This is not a mandatory requirement, but does enable us to do things like restore remote database backups locally (which we will investigate further in the next article on Docker services):
echo "-> Installing Heroku toolbelt (inc. foreman)"
sudo wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
We now have a complete baseline environment into which we can install our "addons" (as docker containers) and application (as a virtualenv). Onwards.
# Congratulations, you now have a vanilla development environment.
# * Pip, Mercurial, Git, Python-dev are used to install python deps
# * Virtualenv is used to run the Django app in isolation
# * Docker and docker-compose to run containers
The next article in this series is now available - Docker services