Docker Hands-on

This blog is part of my Docker series. In this blog, I will cover some Hands-on stuff that I tried with Docker.

I installed Docker in my Ubuntu 12.04 that is running on Virtualbox using the procedure here. I have also installed Docker in Ubuntu 14.04 using the procedure here. To install a specific version of Docker and not the latest, use the procedure here.

Following is the docker version that got installed. I have seen recently that 1.4.1 is the default version that gets installed.

$ docker --version
Docker version 1.3.1, build 4e9bbfa
$ sudo docker version
Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa

To test the basic container functionality, try the following:

$ sudo docker run -t -i ubuntu:14.04 /bin/bash

This will pull the Ubuntu 14.04 image from Docker repository and run a bash shell inside the container. Now try the following commands:

$ sudo docker images
REPOSITORY           TAG            IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu               14.04          5506de2b643b        8 weeks ago         199.3 MB

The above command shows the docker images present in localhost.

$ sudo docker ps
CONTAINER ID      IMAGE            COMMAND       CREATED         STATUS         PORTS    NAMES
ce1b5eff4e71      ubuntu:14.04     "/bin/bash"   3 hours ago     Up 3 hours              agitated_darwin     

The above command shows the running containers. Now, lets try to create a docker image/container with running apache web service and export the image to Dockerhub.

Lets take the Ubuntu 14.04 base image and install necessary components for apache.

$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@27eba3e5a18a:/# apt-get update
root@27eba3e5a18a:/# apt-get install -y apache2

Since Docker uses a multi-layer filesystem, we can look at the filesystem differences using the docker diff command.

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
27eba3e5a18a        ubuntu:14.04        "/bin/bash"         3 minutes ago       Up 3 minutes                            naughty_wozniak
$ sudo docker diff 27eba3e5a18a
A /.wh..wh.plnk/100.81255
A /.wh..wh.plnk/377.81253
A /.wh..wh.plnk/389.81507
C /etc
A /etc/apache2
A /etc/apache2/apache2.conf
A /etc/apache2/conf-available

Lets commit the changes made to the container to create a new Docker image.

$ sudo docker commit -m="installed apache" -a="Sreenivas" 27eba3e5a18a smakam/apache
$ sudo docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
smakam/apache                        latest              eff78d940e51        9 seconds ago       234.8 MB

We can see the new image above. Lets start the container using the new image that we created above.

$ sudo docker run -d -p 81:80 smakam/apache /usr/sbin/apache2ctl -D FOREGROUND
$ sudo docker ps
5ff2485b6864 smakam/apache:latest "/usr/sbin/apache2ct 6 seconds ago Up 6 seconds>80/tcp nostalgic_sinoussi
$ sudo docker port 5ff2485b6864
80/tcp ->

In the above command, we have run the container as a daemon using “-d” option. We have run the apache2ctl in foreground so that the container does not exit after starting the apache service. The service is started in port 80 and is exposed to host using port 81. If we go to the browser in localhost and do “localhost:81”, we will see the apache2 default webpage.

Next, lets push the new Docker image to Dockerhub. For that, we need to first create account in Dockerhub. It is free to create and host public images. Dockerhub is a repository to share Docker images.

$ sudo docker login
$ sudo docker push smakam/apache
$ sudo docker search smakam
NAME                DESCRIPTION   STARS     OFFICIAL   AUTOMATED              
smakam/apache                     0        

Above, we have pushed the apache image to the Dockerhub repository and also we can see the image when we did a search by username in Dockerhub.

Manually creating a docker image is little painful. There is another approach to create a Docker image using Dockerfile. Following is a sample Dockerfile for creating Ubuntu 14.04 image with apache service.

FROM ubuntu:14.04
MAINTAINER Sreenivas Makam <>

RUN apt-get update

# Install apache2
RUN apt-get install -y apache2

ENTRYPOINT ["/usr/sbin/apache2ctl"]

First line “FROM” defines the source image from where this new image needs to be built. The second line “MAINTAINER” defines the author. The next set of commands with “RUN” clause defines the commands that installs additional applications on the base image. “EXPOSE” command defines the ports that this container needs to expose. “ENTRYPOINT” defines the command that needs to be executed when the container is run and the “CMD” defines options for the “ENTRYPOINT”. Here, we start the apache service when the container is started. Following command creates the image using the DockerFile. Run the command on the same directory where Dockerfile is present. The created image can be pushed to docker hub using similar commands mentioned above.

$ sudo docker build -t smakam/apache1 .
$ sudo docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
smakam/apache1                       latest              65cc372ce42a        7 minutes ago       234.8 MB
smakam/apache                         latest              b16acd121751        18 minutes ago      234.8 MB

Following command removes the containers and images.

$ sudo docker stop 4d4f0c1f15fa
$ sudo docker rmi smakam/apache1
$ sudo docker rmi smakam/apache

Sometimes, containers fail to get cleaned up because of which image deletion fails. Following command will delete all existing containers.

sudo docker ps -a -q | xargs -n 1 -I {} sudo docker rm {}

When we push the Docker images to Dockerhub, Dockerfile does not get pushed. To push the Dockerfile, we need to link with repository management tool like github or bitbucket. The steps needed are:

  • Get account in github or bitbucket.
  • From dockerhub, link the accounts from here to either github or bitbucket. I have github account.
  • Push the Dockerfile to github.
  • From dockerhub, when we create repository, select automated build and select location from github where Dockerfile is present. This will build the image automatically. Also, when there are changes to Dockerfile committed to github, automatic builds are triggered.
  • My example Dockerfile at github is here, corresponding docker image is here.

Few other notes:

  • Docker images are stored in /var/lib/docker/
  • Using “docker inspect <contid>”, we can get detailed information about the containers.
  • Using “docker logs <contid>”, we can find out any errors happening during container creation or execution.
  • To get a shell for a running container, we can use “docker attach <contid>”, this works only when the container was started with a bash shell originally. If the container was started as a daemon and we need to get the shell, use “docker exec -t -i <contid> /bin/bash”. “docker exec” got introduced in docker 1.4.1.
  • Before creating a new Docker image, its better to do a quick search in Dockerhub. Most likely, we will find the image we need or we can use that as a base to create a new image.

For details on how to manage data inside container and how to share data between host machine and container and between containers, please refer here.


5 thoughts on “Docker Hands-on

  1. Although this content was created in 2014, most the content is fresh and very useful. Continue good work and write good articles.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s