Docker in OSX via boot2docker or Vagrant: getting over the hump

There are bucket loads of fantastic Docker related blog posts out there. This is yet another tldr guide to get the readers over the hump, particularly illustrating how you can mount local file systems onto a Docker container with Vagrant.

Before we begin, Docker is a client/daemon application. Docker daemon can listen to commands from the Docker client. The client is thin and all containers are hosted on the daemon. This means if you point Docker client to another daemon endpoint, the usual available list of images and containers will change. This is a good thing.

Installing Docker on OSX

As stated on the official Docker installation guide, install via Homebrew is highly recomended.

brew install boot2docker
brew install docker

Note that brew only installs the Docker client on OSX. boot2docker is the VirtualBox wrapper that will fire up Docker daemon. This is important as at the time of writing, commands performed on Docker clients are executed and takes place on the Docker daemon. For example, mounting files to a container really refers to mounting files from the server that the Docker daemon is running to the desired container. This is a cause of many confusion.

Running Docker with boot2docker

The installation guide is really good, and here is a tldr version. Note that the following script uses a different boot2docker port. This is to avoid port conflict with the Docker daemon via Vagrant later.

echo “export DOCKER_PORT=14243” >> ~/.boot2docker/profile 
boot2docker init
boot2docker start
export DOCKER_HOST=tcp://localhost:14243
docker version

If all goes well, doing docker version will yield the following.

docker_version. all good

docker_version. all good

Setting up Docker with Vagrant

The steps are based on John Zanchetta’s blog post, with all of the Vagrant steps trimmed and one network routing step found redundant. This is the tldr version and it assumes you are comfortable with Vagrant

Step 1 – Provision the Docker daemon box
Using the following Vagrant file, fire up the VM called docker

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.define :docker do |docker|
        docker.vm.box = "precise64"
        docker.vm.box_url = "http://files.vagrantup.com/precise64.box"
        docker.vm.network "forwarded_port", guest: 80, host:58080
        docker.vm.network "forwarded_port", guest: 4243, host: 4243
        $script = <<SCRIPT
wget -q -O - https://get.docker.io/gpg | apt-key add -
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
apt-get update -qq 
apt-get install -q -y --force-yes lxc-docker
usermod -a -G docker vagrant
sed -e 's/DOCKER_OPTS=/DOCKER_OPTS=\"-H 0.0.0.0:4243\"/g' /etc/init/docker.conf > /vagrant/docker.conf.sed
cp /vagrant/docker.conf.sed /etc/init/docker.conf
rm -f /vagrant/docker.conf.sed
service docker restart
SCRIPT
       docker.vm.provision :shell, :inline => $script
    end
 end

Step 2 – Vagrant or boot2docker, an easy switch
Point the DOCKER_HOST to the Vagrant-based Docker daemon. Note that by simply changing the DOCKER_HOST, you can point your Docker client to whichever Docker daemon you so desire; boot2docker or Vagrant-based for example.

export DOCKER_HOST=tcp://localhost:4243
docker version

If all goes well, you are ready to build!

Step 3 – Build your first Docker container and mount volumes in Docker with Vagrant
Once you have a container built, mounting the /vagrant is no different from mounting any other directories to the container from the Docker daemon. For example

docker run -t -i --name test --volume /vagrant:/vagrant:rw example:test

Easy!

Step 4 – Make your first push, my only advice
This blog post would not be complete without recommending you to perform your first Docker push.

If like me, you have created your container with “example” as the repository, and “test” as the tag based on a Dockerfile

docker build -t example:test .

And upon pushing (assuming the username is “yves”), for example

docker login
docker push yves/example

You will notice the following response:

The push refers to a repository [yves/example] (len: 0)
2014/05/31 00:46:35 No such id: yves/example

This is because the push command needs username, which has to be part of the repository name. However, the above example, the repository name is merely just “example”.

The work around here, based on scouring issues #720, is to create a new tag that includes the username as part of the repository name. For example:

docker tag  yves/example:test_tag
docker push yves/example

then watch the magic unfold in front of your very eyes.

The big take away is to always prefix your repository name with your docker.io username, followed by a /. For example, yves/ubuntu, yves/centos yves/whatever.

My docker image, yves/yves, is built based on the Vagrant file mentioned in https://macyves.wordpress.com/2014/05/20/release-management-part1-test-automation-with-vagrant-and-jenkins-build-pipeline/

Why Vagrant over boot2docker?

At the time of writing, mounting directories from your OSX machine to a container hosted by boot2docker is quite a mind field. See issues #3957. boot2docker is very well supported, but I feel more at ease with Vagrant.

Side note

Docker is really resilient. Simply retry the same command when encountering failures during image building or pushing to docker.io. This is in part thanks to the untagged images that floats around Docker daemon and that an image is really a repository containing a bunch of changesets performed, akin to Git.

However, if you wish to clean up all untagged images, see this blog post.

Advertisements

Backend to frontend dev: from zero to hero pt.1 – Getting started

tl;dr

Highly recommend using a framework, one such as Backbone.js and it is completely worthwhile doing the tutorial from http://addyosmani.github.io/backbone-fundamentals/. For other possible framework combos, see http://todomvc.com/.

Intro

Companies such as Facebook and Twitter, Google and Apple arguably leads the frontend experience for webapps, both in design and interaction. The current status quo for webapps is Single Page Applications (SPAs). These applications are expected to be high performance, responsive, functional and simple to use.

If you are a seasoned devop, well versed in your favourite programming language and a wizard with modern day webstack/tools, such as Varnish Cache :), where would you begin to dabble in frontend development? What frameworks (if any) would you use and where would you start? Join me on an epic journey through the frontend development world. This blog series aims to demystify frontend technologies and provide a new starting point for anybody who is well versed in the backend but wishes to dabble in modern day frontend development.

Part 1 of this series aim to serve as a clear starting point amongst the plethora of information available on the web. It is written for anybody looking to get going with front end development for the first time. Details on the frameworks, tooling, automated testing and various other full-stack topics will be discussed in the following blogs in the series. And in case you are wondering, yes, TDD/BDD, CI and test automation has all found its way into frontend development and looks to be rather stable and well defined.

All technologies mentioned are currently used within my product development team. The blog is a real-life account of my journey through the frontend development world.

Children of the 80s, Geocities much?

Traditional frontend development has gone through quite an amazing transformation. Harking back to the late 90s, where JavaScript and Cascading Style Sheets were gaining adoption and momentum, coupled with HTML, these three technologies and their respective tooling has gone through tremendous transformation.

Like most children of the 80s, Geocities was the bomb in the 90s. Like most basketball-card-collecting and 90210-watching Aussie kid, I jumped on this bandwagon back in high school and started creating my very first website with simple HTML and JS component, mostly written with the help of HotDog by Sausage Software. This was the very bleeding edge of WYSIWYG editor for HTML at the time. It had very limited JS support if I recall correctly, mostly in the form of prepaid snippets that allowed very rudimentary animations on your awesome Geocities website. CSS was out the window as we stayed true blue with background colours and crude inline CSS. But we knew. We knew that this holy trinity of JS, HTML and CSS would change the world. We just needed somebody tear us away from the countless amazing Geocities website dedicated warez, phreaking and cracks.

As the following terms “newbs”, “zomg”, and “hax0r” made its way into online chat, server-side rendering technologies such as JSP, Servlets, Spring garnered much popularity amongst B2B and enterprise applications. Technologies like Google Web Toolkit was emergent and Google arguably lead the charge in realising the power of client-side process. A truly distributed platform, where single-page-application (SPA) demonstrated the potential in providing both a scalable architecture and beautiful user interactions. Then it all changed in 2009. Node.js was released.

Node.js leverage the power of Chrome’s V8 JS engine. It allowed JS to run server-side. This, ironically, opened the gateway to standardising frontend development. As build frameworks and package manager started to appear, it highed the lack of standardised approach for JS apps that are developed and deployed for the browsers.

JS frameworks and libraries

There are numerous combination of frameworks, not to mention there are quite a few thought leaders in frontend development. In order to start making sense of the massive permutation of possibilities, and to avoid wading through a ton of out dated material, my whole hearted suggestion is to pick a framework that is current and relevant, maintained, established, matured and ships with solid documentation. I recommend Backbone.js and the starting point is http://addyosmani.github.io/backbone-fundamentals/ and http://todomvc.com/.

There are quite a number of JS frameworks out there. Go with jQuery as a starting point. Note that it has fallen out of favour of late. But without hands on, it would be hard pressed to form your own opinion.

For those that would like to try out some hispter functional programming and wishes to include awesome words such as functors, morphisms and monads into their daily vocabulary, have a look at Underscore.js.

CSS framework

With a name like Syntactically Awesome Stylesheets (SASS), how can you say no? This is a good starting point to jump into the deep end of pre-processed CSS. You will be compiling CSS in no time! Also SASS is more than LESS.

Project scaffolding

Projects, build tools and tooling. Your frontend project deserves a package manager and mechanism to integrate with continuous integration servers via build scripts.

Go with Grunt. When starting a new project, you could also consider yeoman. Personally, I have gone down the Grunt path, as I wish to understand the rationale and the reason behind yeoman’s frontend development process.