Friday March 20, 2015 - tags:    docker, microservice

Working with Docker images & containers


This is the second in a series of posts where I explore how to setup a dockerised micro-service node.js architecture. In this post we will examine docker images and containers, and how to work with them.

The source code for these posts can be found here: dockerised-micro-service-node-js-architecture

The introduction and future posts to this series can be found here:

In this post

Port forwarding

From a networking perspective, things are a little more complicated running docker on a Mac. The docker container is running in a VirtualBox VM running an OS, generally linux, so we need to create a port forwarding rule in VirtualBox to forward traffic to the VM to make it available to docker.

Lets stop boot2docker.

$ boot2docker stop
Forward 27017 for mongo

This command invokes the VirutalBox command VirtualManage to add a port forwarding rule to the VM named, boot2docker-vm. The rule created is named guestmongodb, the protocol is set to tcp and we forward any traffic arriving on port 27017 to port 27017 on the VM.

$ VBoxManage modifyvm "boot2docker-vm" --natpf1 "guestmongodb,tcp,,27017,,27017"

Pulling a Docker image

The Docker Hub is a public registry maintained by Docker. It contains over 15,000 images you can download and use to build containers.

Lets pull our first image from the docker repository, dockerfile/mongodb a mongodb image.

You can see the docker file for this image here:

$ docker pull dockerfile/mongodb

Lets list our docker images.

$ docker images

This command should return the following:

REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE  
dockerfile/mongodb   latest              e8ddda3ca0be        2 weeks ago         702.8 MB  

Lets have a look at the dockerfile for the mongodb image we just used; this image uses as a base image dockerfile/ubuntu, so the mongodb instance is running on ubuntu. The RUN command install various libs and and installs mongodb.
A volume is then mounted at /data/db, and the working directory for this container is defined as /data, so CMD and RUN commands are run from this folder. The CMD statement is executed when we run the container, this is executing the mongod command which starts mongodb. Two ports are exposed 27017, mongodbs default port and 28017 mongodbs http interface.

Container's persist until you remove them, and you can only do that by doing

# Pull base image.
FROM dockerfile/ubuntu

# Install MongoDB.
RUN \  
  apt-key adv --keyserver hkp:// --recv 7F0CEB10 && \
  echo 'deb dist 10gen' > /etc/apt/sources.list.d/mongodb.list && \
  apt-get update && \
  apt-get install -y mongodb-org && \
  rm -rf /var/lib/apt/lists/*

# Define mountable directories.
VOLUME ["/data/db"]

# Define working directory.

# Define default command.
CMD ["mongod"]

# Expose ports.
#   - 27017: process
#   - 28017: http
EXPOSE 27017  
EXPOSE 28017  

Starting a container

Lets start a container hosting our mongo image. First lets start boot2docker

$ boot2docker up
Run mongo container

Lets create and start our first container, its a container hosting mongodb, -d runs this as a daemon, -p defines its port 27017; mongodbs default port, --name names the container mongodb. dockerfile/mongodb is the name of the image we will use for this container.

$ docker run -d -p 27017:27017 --name mongodb dockerfile/mongodb

Lets see which containers are running:

List running containers
$ docker ps -a
CONTAINER ID        IMAGE                       COMMAND             CREATED              STATUS              PORTS                                 NAMES  
8879ef38162e        dockerfile/mongodb:latest   "mongod"            About a minute ago   Up About a minute   28017/tcp,>27017/tcp   mongodb  

Talking to the container

Lets run a few commands against our mongo container and make sure this is working correctly.

$ mongo
$ show dbs
$ exit

You should see the following output.

admin  (empty)  
local  0.078GB  

Cleaning up containers and images

Lets examine a few commands to allow us to clean things up:

Stop a container

Stop a running container by container id
First list the containers.

$ docker ps -a

Then grab the container id and stop by id.

$ docker stop efadf619aaba
Restart or start a container

Start or restart a running container by container id
First list the containers.

$ docker ps -a

Grab the container id and start or restart by id.

$ docker start efadf619aaba
$ docker restart efadf619aaba
Delete a single container

We can also remove containers individually:
First list the containers.

$ docker ps -a

Now grab the container id and delete by id.

$ docker rm efadf619aaba
Get logs for a single container

We can also view the containers logs:
First list the containers.

$ docker ps -a

Now grab the container id and view the logs

$ docker logs efadf619aaba
Delete a single image

We can also delete images; first list the images.

$ docker images

Now grab the image id and delete by id.

$ docker rmi efadf619aaba
Stop all containers

The following command will stop all running containers

$ docker stop $(docker ps -a -q)
Delete all containers

This command will delete all containers

$ docker rm $(docker ps -a -q)
Delete all images

This command will delete all images

$ docker rmi $(docker images -q)