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
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 <firstname.lastname@example.org> 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 <email@example.com> ---> 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:
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.