Docker for Dummies, I mean Developers

I

mages, Containers, and Tags! Oh My! Docker is the new hotness in the software world. Dockerize all of the things! For my tastes, Docker is really more of an operations tool for packaging and deploying self contained apps. However, it is making its way into the development circles. I have been finding that, sometimes, developers have a hard time understanding all of the pieces and how the fit together. They tend to copy and paste commands from docs and tutorials and pray to the gods that there app is running. Confusion between containers, and images, building and running and what tags are just has them typing themselves in circles. But fear not! There is a simple way to think about Docker and all of its pieces that will make all of the pain go away.

Object Oriented Programming

You, like most developers, probably have a firm under standing of OOP. You live and breathe ( or put up with ) it on a daily basis. Think of Docker as an Object Orientated Programming environment. Here is the break down:

ConceptCorrelation
ImageClass
ContainerClass Instance
Registry( hub )GIT Repository
TagGIT Tag

Object-oriented programming , -n, noun.,

A programming language model organized around objects derived from classes

Lets take the following events as an example

  1. Build a new Image for an application we are working on
  2. Spin up a couple containers on different ports
  3. delete one of the containers
  4. recreated the container

Thinking in OOP, the code to do that would look like this:

// create a new class
var App = Docker.build( 'Dockerfile' );  
var app_1 = new App({ port:3000, volume:'/opt/data' });  
var app_2 = new App({ port:3001, volume:'/opt/data' });

delete app_1;

app_1 = new App({ port:3000, volume:'/var/data'});  

Pretty simple! This is something we can understand. Using the Docker command line, isn't much different. It is just a different language, and it would translate as such:

$ docker build -t App -f Dockerfile .
$ docker run --name=app_1 -p 3000:3000 -v $HOME/data:/opt/data App
$ docker run --name=app_2 -p 3001:3000 -v $HOME/data:/opt/data App

$ docker stop app_1
$ docker rm app_2

$ docker run --name=app_1 -p 3000:3000 -v $HOME/data:/opt/data App

Now, maybe we have our app in production and people are reporting bugs. We don't need to ssh in to a server or debug running instances. We can pull the production tag and just run it locally.

OOP Code

var Production = Docker.pull('esatterwhite/codedependant:production');  
var Postgres = Docker.pull('posgresql'); // set up a database

var pg = new Postgres({ port:5432 });  
var prod = new Production({ port:3000, database:pg });  

Docker cli

$ docker pull esatterwhite/codedependant:production
$ docker pull postgresql
$ docker run --name=pg -p 5432:5432 -d postgresql
$ docker run -it --name=prod -p 3000:3000 --link pg:postgres esatterwhite/codedependant:production

We could take this one step further, forego the links and use docker networking.

OOP Code

var Production = Docker.pull('esatterwhite/codedependant:production');  
var Postgres = Docker.pull('posgresql'); // set up a database

var prodnet = Docker.network('production')

// gasp!
with( prodnet ){  
    var pg = new Postgres({ port:5432 });
    var prod = new Production({ port:3000 });
};

Docker cli

$ docker network create prodnet
$ docker pull esatterwhite/codedependant:production
$ docker pull postgresql
$ docker run --name=pg --net=prodnet -p 5432:5432 -d postgresql
$ docker run -ti --name=prod --net=prodnet -p 3000:3000 esatterwhite/codedependant:production

Once I have finished debugging and making the necessary adjustments, I would build a new Image, tag it and push it to the registry - A lot like git.

OOP Code

var Production = Docker.build( 'Dockerfile' );  
Docker.tag( Production,'v1.0.1');  
Docker.tag( Production, 'production');  
Docker.push( Production, 'esatterwhite/codedepenant');  

Docker cli

$ docker build -t esatterwhite/codedependant:v1.0.1 .
$ docker tag esatterwhite/codedependant:production esatterwhite/codedepednant:v1.0.0
$ docker push esatterwhite/codedependant

When you put aside the larger ecosystem that docker has evolved into, and focus on basic building blocks it provides, it really isn't that much to digest. Images are just a kind of class, containers are instances of images. You use the Docker cli to manipulate them.

class oop docker