Automated deployments with Docker, Ansible & Go (Part 1 of N)


I have been experimenting with using Go CD, Ansible and Docker as a means of automating deployments. This post and the subsequent ones document what needs to be done to achieve seamless deployments. The first part of this series will deal with installing and configuring Docker.

Installing Docker

If you have never heard of Docker the following links explain what Docker is? and highlight the key differences between containers and VMs see

Now that we know what Docker is? differences between Containers and Virtualization and a few basic commands we can jump right into the thick of things and start setting up a container.

Note: I tried this on Ubuntu but the steps should be pretty much the same for CentOS or any other variant of Linux.

Installing Docker on Ubuntu

Install docker by following the instructions here. Once installed verify that docker is running by typing

First steps

Download and start a container

sudo docker run -i -t ubuntu /bin/bash

If you are behind a proxy and docker fails to fetch the images, try setting proxy in /etc/default/docker. The command above will download the ubuntu docker image and then launch and Initialize it. because we ran docker in interactive mode (-i) docker will drop you into the container’s shell. CTRL+D to exit.

To start a docker container as a daemon/running in the background use the -d option, One of the most common mistakes is to choose a process that exits right after the container starts, any process that runs inside the container needs to keep running either as a daemon or in the background with ‘&’. If the process inside the container exits then the the container also exits.

Interacting with containers

to see running containers use the command

docker ps

To see all containers even the ones that have exited use

docker ps -a

to attach to a daemonized container first get the containers ID and then use that with docker’s attach command

docker attach container_id

to restart a stopped container or to pause a container use

docker start container_id
docker pause container_id

to unpause a paused container use

docker unpause container_id

Cleanup

Docker does not come with a cleanup command yet, you can use a little bash fu

docker ps -a | grep "weeks ago" | awk '{print $1}' | xargs docker rm

you can grep for “days ago” or “hours ago”

or to delete all containers

docker ps -a -q | xargs docker rm

Sharing folders

To mount a host directory in the container use the -v option

for e.g

docker run -v /tmp:/tmp/source -t -i ubuntu /bin/bash

this should mount host directory /tmp to container directory /tmp/source

you can use apt-get in download only mode with the -d option to download packages and save then in the shared folder. On the host the apt-get -d option downloads the packages to /var/cache/apt/archives

download and copy any packages you need to install into the hosts /tmp directory then install it from within the container.

Saving changes to the container

Once the container is customized to your liking, you need to save the changes to do this use the commit command

docker commit container_id image_name

Note: when run in interactive mode the container ID will part of the bash prompt e.g

root@664cbf2186cb:/tmp/source#

else you can get the container ID by executing the docker’s ‘ps’ command.

Docker networking

By default Docker sets up a network interface called docker0 and assigns a private IP in the 172.x range to this interface, this will be a non-routable address and cannot be reached from the host or the external network. Docker also supports networking between containers using the link command. If you want the docker image to be reachable from the host and outside network there are a couple of ways to achieve this

  • create a bridge with the active interface.
  • Port forwarding
Bridge network

on ubuntu first install bridge-utils on the host via apt-get

sudo apt-get install bridge-utils

Then install pipework. To install first download the shell script

save it in /usr/bin as pipework and then make it executable.

To start a container in bridge mode:

ubuntu=$(docker run -v /tmp:/tmp/source -d phusion/baseimage /usr/bin/weborf &)
pipework br1 $ubuntu 192.168.1.1/24
ip addr add 192.168.1.254/24 dev br1

Port forwarding

Forwarding a port on the container to the docker host is easy, use the -p option to map a port from the container to a port on the host.
Note: that the docker container still uses the default IP address in the 172.x.x.x range. Anything not explicitly forwarded will still be inaccesible.

Docker has two options for port forwarding, EXPOSE and -p option. The difference between these two is that EXPOSE only exposes the port to other docker containers but not to host or external network. the -p option exposes port to host and external network. The -p option implicitly calls the EXPOSE command.

Next post will deal with

  • Networking between containers
  • Security
  • Docker files
  • Private repositories

References:
How to remove old docker.io containers