5.4 Creating a Docker Image from a Dockerfile

You use the docker build command to create a Docker image from the definition contained in a Dockerfile.

The following example demonstrates how to build an image named mymod/httpd with the tag v2 based on the oraclelinux:7-slim image so that it can run an Apache HTTP server.

To create a Docker image from a Dockerfile:

  1. Make a directory where you can create the Dockerfile, for example:

    # mkdir -p /var/docker_projects/mymod/httpd
    Note

    You do not need to create the Dockerfile on the same system on which you want to deploy containers that you create from the image. The only requirement is that the Docker Engine can access the Dockerfile.

  2. In the new directory, create the Dockerfile, which is usually named Dockerfile. The following Dockerfile contents are specific to the example:

    # Dockerfile that modifies oraclelinux:7-slim to include an Apache HTTP server
    FROM oraclelinux:7-slim
    MAINTAINER A N Other <another@example.com>
    RUN sed -i -e '/^\[main\]/aproxy=http://proxy.example.com:80' /etc/yum.conf
    RUN yum -y install httpd
    RUN echo "HTTP server running on guest" > /var/www/html/index.html
    EXPOSE 80
    ENTRYPOINT /usr/sbin/httpd -D FOREGROUND

    The # prefix in the first line indicates that the line is a comment. The remaining lines start with the following instruction keywords that define how Docker creates the image:

    ENTRYPOINT

    Specifies the command that a container created from the image always runs. In this example, the command is /usr/sbin/httpd -D FOREGROUND, which starts the HTTP server process.

    EXPOSE

    Defines that the specified port is available to service incoming requests. You can use the -p or -P options with docker run to map this port to another port on the host. Alternatively, you can use the --link option with docker run to allow another container to access the port over Docker's internal network (see Section 5.7, “Communicating Between Docker Containers”).

    FROM

    Defines the image that Docker uses as a basis for the new image.

    MAINTAINER

    Defines who is responsible for the Dockerfile.

    RUN

    Defines the commands that Docker runs to modify the new image. In the example, the RUN lines set up the web proxy, install the httpd package, and create a simple home page for the server.

    For more information about other instructions that you can use in a Dockerfile, see https://docs.docker.com/engine/reference/builder/.

  3. Use the docker build command to create the image :

    # docker build --tag="mymod/httpd:v2" /var/docker_projects/mymod/httpd/
    Sending build context to Docker daemon  2.048kB
    Step 1/6 : FROM oraclelinux:7-slim
    Trying to pull repository docker.io/library/oraclelinux ... 
    7-slim: Pulling from docker.io/library/oraclelinux
    a8d84c1f755a: Pull complete 
    Digest: sha256:d574213fa96c19ae00269730510c4d81a9979ce2a432ede7a62b62d594cc5f0b
    Status: Downloaded newer image for oraclelinux:7-slim
     ---> c3d869388183
    Step 2/6 : MAINTAINER A N Other <another@example.com>
     ---> Running in 26b0ba9f45e8
    Removing intermediate container 26b0ba9f45e8
     ---> f399f426b849
    Step 3/6 : RUN yum -y install httpd
     ---> Running in d75a9f312202
    Loaded plugins: ovl
    Resolving Dependencies
    --> Running transaction check
    ---> Package httpd.x86_64 0:2.4.6-88.0.1.el7 will be installed
    ...
    Complete!
    Removing intermediate container d75a9f312202
     ---> aa3ab87bcae3
    Step 4/6 : RUN echo "HTTP server running on guest" > /var/www/html/index.html
     ---> Running in dddedfc56849
    Removing intermediate container dddedfc56849
     ---> 8fedc8516013
    Step 5/6 : EXPOSE 80
     ---> Running in 6775d6e3996f
    Removing intermediate container 6775d6e3996f
     ---> 74a960cf0ae9
    Step 6/6 : ENTRYPOINT /usr/sbin/httpd -D FOREGROUND
     ---> Running in 8b6e6f61a2c7
    Removing intermediate container 8b6e6f61a2c7
     ---> b29dea525f0a
    Successfully built b29dea525f0a
    Successfully tagged mymod/httpd:v2

Having built the image, you can test it by creating a container instance named httpd2:

[root@host ~]# docker run -d --name httpd2 -P mymod/httpd:v2
c7de8e1ea355b29a0d0c435edf580565b6bb6df716fea5497182a89e15534ec7
Note

You do not need to specify /usr/sbin/httpd -D FOREGROUND as this command is now built into the container.

The -P option specifies that Docker should map the ports exposed by the guest to a random available high-order port (higher than 30000) on the host.

You can use docker inspect to return the host port that Docker maps to TCP port 80:

[root@host ~]# docker inspect --format='{{ .NetworkSettings.Ports }}' httpd2
map[80/tcp:[map[HostIp:0.0.0.0 HostPort:49153]]]

In this example, TCP port 80 in the guest is mapped to TCP port 49153 on the host.

You can view the web content served by the guest by pointing a browser at port 49153 on the host. If you access the content from a different system, you might need to allow incoming connections to the port on the host.

You can open the port by updating the firewall:

[root@host ~]# firewall-cmd --add-port=49153/tcp
success
[root@host ~]# firewall-cmd --permanent --add-port=49153/tcp
success

You can also use curl to test that the server is working:

[root@host ~]# curl http://localhost:49153
HTTP server running on guest