In your home directory, create a FundamentalsOfDocker folder and navigate to it:
$ mkdir ~/FundamentalsOfDocker
$ cd ~/FundamentalsOfDocker
In the preceding folder, create a sample1 subfolder and navigate to it:
$ mkdir sample1 && cd sample1
Use your favorite editor to create a file called Dockerfile inside this sample folder with the following content:
FROM centos:7
RUN yum install -y wget
Save the file and exit your editor.
Back in the Terminal, we can now build a new container image using the preceding Dockerfile as a manifest or construction plan:
$ docker image build -t my-centos .
Please note that there is a period at the end of the preceding command. This command means that the Docker builder is creating a new image called my-centos using the Dockerfile that is present in the current directory. Here, the period at the end of the command stands for current directory. We could also write the preceding command as follows, with the same result:
$ docker image build -t my-centos -f Dockerfile .
But we can omit the -f parameter, since the builder assumes that the Dockerfile is literally called Dockerfile. We only ever need the -f parameter if our Dockerfile has a different name or is not located in the current directory.
The preceding command gives us this (shortened) output:
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos:7
7: Pulling from library/centos
af4b0a2388c6: Pull complete
Digest: sha256:2671f7a3eea36ce43609e9fe7435ade83094291055f1c96d9d1d1d7c0b986a5d
Status: Downloaded newer image for centos:7
---> ff426288ea90
Step 2/2 : RUN yum install -y wget
---> Running in bb726903820c
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirror.dal10.us.leaseweb.net
* extras: repos-tx.psychz.net
* updates: pubmirrors.dal.corespace.com
Resolving Dependencies
--> Running transaction check
---> Package wget.x86_64 0:1.14-15.el7_4.1 will be installed
...
Installed:
wget.x86_64 0:1.14-15.el7_4.1
Complete!
Removing intermediate container bb726903820c
---> bc070cc81b87
Successfully built bc070cc81b87
Successfully tagged my-centos:latest
Let's analyze this output:
- First, we have the following line:
Sending build context to Docker daemon 2.048kB
The first thing the builder does is package the files in the current build context, excluding the files and folder mentioned in the .dockerignore file, if present, and sends the resulting .tar file to the Docker daemon.
- Next, we have the following lines:
Step 1/2 : FROM centos:7
7: Pulling from library/centos
af4b0a2388c6: Pull complete
Digest: sha256:2671f7a...
Status: Downloaded newer image for centos:7
---> ff426288ea90
The first line tells us which step of the Dockerfile the builder is currently executing. Here, we only have two statements in the Dockerfile, and we are on step 1 of 2. We can also see what the content of that section is. Here is the declaration of the base image, on top of which we want to build our custom image. What the builder then does is pull this image from Docker Hub if it is not already available in the local cache. The last line of the preceding snippet indicates which ID the just-built layer gets assigned by the builder.
- Now, follows the next step. I have shortened it even more than the preceding one to concentrate on the essential part:
Step 2/2 : RUN yum install -y wget
---> Running in bb726903820c
...
...
Removing intermediate container bb726903820c
---> bc070cc81b87
Here, again, the first line indicates to us that we are in step 2 of 2. It also shows us the respective entry from the Dockerfile. On line two, we can see Running in bb726903820c, which tells us that the builder has created a container with ID bb726903820c inside, which it executes the RUN command. We have omitted the output of the yum install -y wget command in the snippet since it is not important in this section. When the command is finished, the builder stops the container, commits it to a new layer, and then removes the container. The new layer has ID bc070cc81b87, in this particular case.
- At the very end of the output, we encounter the following two lines:
Successfully built bc070cc81b87
Successfully tagged my-centos:latest
This tells us that the resulting custom image has been given the ID bc070cc81b87, and has been tagged with the name my-centos:latest.
So, how does the builder work, exactly? It starts with the base image. From this base image, once downloaded into the local cache, it creates a container and runs the first statement of the Dockerfile inside this container. Then, it stops the container and persists the changes made in the container into a new image layer. The builder then creates a new container from the base image and the new layer, and runs the second statement inside this new container. Once again, the result is committed to a new layer. This process is repeated until the very last statement in the Dockerfile is encountered. After having committed the last layer of the new image, the builder creates an ID for this image and tags the image with the name we provided in the build command: