We laid a good foundation of the fundamentals of the Docker technology. In this section, we are going to focus on crafting an image with the HTTP service, launch the HTTP service inside the container using the crafted image, and then, demonstrate the connectivity to the HTTP service running inside the container.
In this section, we are going to craft a Docker image in order to install Apache2
on top of the Ubuntu 14.04
base image, and configure a Apache HTTP Server
to run as an executable, using the ENTRYPOINT
instruction.
In Chapter 3, Building Images, we illustrated the concept of the Dockerfile to craft an Apache2
image on top of the Ubuntu 14.04
base image. Here, in this example, we are going to extend this Dockerfile by setting the Apache
log path and setting Apache2
as the default execution application, using the ENTRYPOINT
instruction. The following is a detailed explanation of the content of Dockerfile
.
We are going to build an image using ubuntu:14.04
as the base image, using the FROM
instruction, as shown in the Dockerfile
snippet:
########################################### # Dockerfile to build an apache2 image ########################################### # Base image is Ubuntu FROM ubuntu:14.04
Set authors' detail using MAINTAINER instruction
# Author: Dr. Peter MAINTAINER Dr. Peter <[email protected]>
Using one RUN
instruction, we will synchronize the apt
repository source list, install the apache2
package, and then clean the retrieved files:
# Install apache2 package RUN apt-get update && apt-get install -y apache2 && apt-get clean
Set the Apache log directory path using the ENV
instruction:
# Set the log directory PATH ENV APACHE_LOG_DIR /var/log/apache2
Now, the final instruction is to launch the apache2
server using the ENTRYPOINT
instruction:
# Launch apache2 server in the foreground ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
In the preceding line, you might be surprised to see the FOREGROUND
argument. This is one of the key differences between the traditional and the container paradigm. In the traditional paradigm, the server applications are usually launched in the background either as a service or a daemon because the host system is a general-purpose system. However, in the container paradigm, it is imperative to launch an application in the foreground because the images are crafted for a sole purpose.
Having prescribed the image building instruction in the Dockerfile
, now let's move to the next logical step of building the image using the docker build
subcommand by naming the image as apache2
, as shown here:
$ sudo docker build -t apache2 .
Let's now do a quick verification of the images using the docker images
subcommand:
$ sudo docker images
As we have seen in the previous chapters, the docker images
command displays the details of all the images in the Docker host. However, in order to illustrate precisely the images created using the docker build
subcommand, we highlight the details of apache2:latest
(the target image) and ubuntu:14.04
(the base image) from the complete image list, as shown in the following output snippet:
apache2 latest d5526cd1a645 About a minute ago 232.6 MB ubuntu 14.04 5506de2b643b 5 days ago 197.8 MB
Having built the HTTP server image, now let's move on to the next session to learn how to run the HTTP service.
In this section, we are going to launch a container using the Apache HTTP server image, we crafted in the previous section. Here, we launch the container in the detached mode (similar to a Unix daemon process) using the -d
option of the docker run
subcommand:
$ sudo docker run -d apache2 9d4d3566e55c0b8829086e9be2040751017989a47b5411c9c4f170ab865afcef
Having launched the container, let's run the docker logs
subcommand to see whether our Docker container generates any output on its STDIN
(standard input) or STDERR
(standard error):
$ sudo docker logs 9d4d3566e55c0b8829086e9be2040751017989a47b5411c9c4f170ab865afcef
As we have not fully configured the Apache HTTP server; you will find the following warning, as the output of the docker logs
subcommand:
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.13. Set the 'ServerName' directive globally to suppress this message
From the preceding warning message, it is quite evident that the IP address assigned to this container is 172.17.0.13
.
In the preceding section, from the warning message, we found out that the IP address of the container is 172.17.0.13
. On a fully configured HTTP server container, no such warning is available, so let's still run the docker inspect
subcommand to retrieve the IP address using the container ID:
$ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' 9d4d3566e55c0b8829086e9be2040751017989a47b5411c9c4f170ab865afcef 172.17.0.13
Having found the IP address of the container as 172.17.0.13
, let's quickly run a web request on this IP address from the shell prompt of the Docker host, using the wget
command. Here, we choose to run the wget
command with -qO-
in order to run in the quiet mode and also display the retrieved HTML file on the screen:
$ wget -qO - 172.17.0.13
Here, we are showcasing just the first five lines of the retrieved HTML file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <!-- Modified from the Debian original for Ubuntu Last updated: 2014-03-19
Awesome, isn't it? We got our first service running in a container, and we are able to reach out to our service from our Docker host.
Furthermore, on a plain vanilla Docker installation, the service offered by one container is accessible by any other container within the Docker host. You can go ahead, launch a new Ubuntu container in the interactive mode, install the wget
package using apt-get
, and run the same wget -qO - 172.17.0.13
command, as we did in the Docker host. Of course, you will see the same output.