Docker II – Building A Container

In our last post we gave overview as to what Docker was and how it could help in deploying software. This week we will be show you how to create a container to display a simple static web page.

Whilst there are numerous ways to run Docker we will assume that you already have an environment setup (https://docs.docker.com/installation/#installation). At Solid Gear we primarily use Ubuntu servers and setup our Docker hosts using the updated Docker packages as described in https://docs.docker.com/installation/ubuntulinux/. In order to follow the rest of this guide you should be able run the ‘docker ps’ command without any errors:

$ docker ps
CONTAINER ID        IMAGE          COMMAND             CREATED             STATUS              PORTS               NAMES

‘Hello World’

o get us started we will start up a predefined container registered at the Docker Hub and have that container echo out ‘Hello World’. Using the ‘docker run’ command we can start a container that is defined in an image locally or remotely in a registry (a centralized repository).

$ docker run ubuntu:14.04 /bin/echo 'Hello world'
Unable to find image 'ubuntu:14.04' locally
14.04: Pulling from ubuntu
e9e06b06e14c: Pull complete
a82efea989f9: Pull complete
37bea4ee0c81: Pull complete
07f8e8c5e660: Already exists
ubuntu:14.04: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:125f9479befe1f71562b6ff20fb301523a2633902ded6d50ade4ebcd7637a035
Status: Downloaded newer image for ubuntu:14.04
Hello world

So what did that command do? If we did not already have the ubuntu:14.04 image downloaded, docker would pull the image from the registry and reconstruct it layer by layer (more on layers later). Note that had we specified a different version or tag we would install the version of Ubuntu that goes with that tag, e.g. ubuntu:15.04. Once downloaded we start up the container using ‘run’ and execute the command ‘echo Hello World’. Note that if we run the command again we won’t need to re-download the image as we already have a local copy:

$ docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world

Defining a container

Docker containers are defined using a Dockerfile. This file specifies the base container against which we will build up our application. For example with our sample container we will start with the following container definition:

FROM ubuntu:14.04
MAINTAINER Grant Croker <gcroker+docker@solidgear.es>
RUN apt-get update && apt-get install apache2

This specifies the base image we want to use for the container, in this case Ubuntu 14.04, the maintainer and the software we want to install. To build this container you save the above Dockerfile and use the ‘docker build’ command e.g.:

$ docker build -t gcroker/docker-demo .

We can start up the container but right now it does not do very much:

$ docker run -d -p 80:80 gcroker/docker-demo

To confirm this we use the ‘docker ps’ command to list the current and old containers (-a).

$ docker ps -a
CONTAINER ID   IMAGE                        COMMAND      CREATED       STATUS                    PORTS      NAMES
ba7a22ac0419   gcroker/docker-demo:latest   "/bin/bash"  4 seconds ago Exited (0) 1 seconds ago             kickass_swartz

Now we need to add our web page and a script to start apache. First create a file called hello_world.html with the following contents in the folder where you have the Dockerfile:

<html>
    <head>
        <title>Docker - Hello World</title>
    </head>
    <body>
        <p>
            Hello World!!
        </p>
    </body>
</html>

Then we need to add that file to our Dockerfile by appending the following lines:

COPY hello_world.html /var/www/html/
CMD ["/usr/sbin/apache2ctl", "-e", "info", "-DFOREGROUND"]

The first line copies in our newly created web page. The CMD statement is used by the container to execute Apache in the foreground with the error logs going to the console.

We need to rebuild the container with the new statements and you’ll note that ‘docker build’ does not rebuild the container from scratch, rather it builds on top of the previous container definition, layering on the new instructions:

$ docker build -t gcroker/docker-demo .
Step 0 : FROM ubuntu:14.04
 ---> 07f8e8c5e660
Step 1 : MAINTAINER Grant Croker <gcroker+docker@solidgear.es>
 ---> Using cache
 ---> f12ac6b46f7b
Step 2 : RUN apt-get update && apt-get install -y apache2
 ---> Using cache
 ---> 8dd3d98002ab
Step 3 : COPY hello_world.html /var/www/html/
 ---> 85be7f25b089
Removing intermediate container 79248e637bf1
Step 4 : CMD /usr/sbin/apache2ctl -e info -DFOREGROUND
 ---> Running in 2ac337e8aa74
 ---> 9738a8c77aee
Removing intermediate container 2ac337e8aa74
Successfully built 9738a8c77aee

We should now be able to start up the container and connect to it:

$ docker run -d -p 80:80 gcroker/docker-demo

In the above command we are executing the container in background/daemon mode (-d), mapping port 80 on the host server to port 80 where Apache is listening inside the container (-p 80:80).

To confirm the container is running, we use the ‘docker ps’ command:

$ docker ps
CONTAINER ID  IMAGE                        COMMAND                CREATED        STATUS         PORTS              NAMES
f95e0da2d3ee  gcroker/docker-demo:latest   "/usr/sbin/apache2ct   7 minutes ago  Up 7 minutes   0.0.0.0:80->80/tcp furious_einstein

And can view logs using the ‘docker logs’ command:

$ docker logs f95e0da2d3ee
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.20. Set the 'ServerName' directive globally to suppress this message.

The final test will be to connect to the server with a web browser using the IP address or name of the docker host to confirm that we can access the web page we created:

Docker hello world web
Next time we will be looking at a more complex application that uses multiple containers and how to connect them.

The complete files for this post can be downloaded from the docker-demo repository on Github.

 

Related articles

Docker – Shipping software

Deploying a secure and private Docker registry

ChatOps – Listening to the machines

 

Leave a Comment

¿Necesitas una estimación?

Calcula ahora