What is inside a Docker image?

Some time ago, I had to modify one application which did not have a Dockerfile in its source code repository. Apparently, someone forgot to commit it. I could make the changes, but how do I deploy it?

Fortunately, I could download the previous docker image from the Docker repository and check what was inside. So, how do we check what is inside a Docker image?

As the first step, we must save a Docker image as a tar file.

1
docker save — output image.tar <image name>

Now, we can create a new directory and unpack the tar file into it.

1
2
mkdir extracted
tar -xf image.tar -C extracted

The directory contains directories for every layer in this docker image. In the case of my image, the content of the tar file looks like this:

1
2
3
4
5
6
7
8
0e5176443be87e22a05ce7b9e28b623289f6722465fb9c3579c6b98c2419aa89.json
4bfac6fe3333e456db496465d112632e00986bf42400faee457a87c8db947b5f
56ce86a9ea9ac8876df7cc6ed93044050915d43fae7db3f33c78521e2e80a43d
a1700ea4465fc48b04e06501ae0dd47a21bc95eddbf90fde6f9c63e38c819da0
bfc566732015e74554c940abfdedb5ca215be6a392cad0f189b171298527cc09
cd15ebb84d8e12670ea5f1757b2b45d00496d73a0d0c688e2896928b52a707bc
manifest.json
repositories

Let’s look at the manifest.json file. It contains an array of docker layers listed in order of their creation.

1
2
3
4
5
6
7
8
9
10
[{
"Config": "0e5176443be87e22a05ce7b9e28b623289f6722465fb9c3579c6b98c2419aa89.json",
"RepoTags": ["sbt:latest"],
"Layers": [
"4bfac6fe3333e456db496465d112632e00986bf42400faee457a87c8db947b5f/layer.tar",
"bfc566732015e74554c940abfdedb5ca215be6a392cad0f189b171298527cc09/layer.tar",
"cd15ebb84d8e12670ea5f1757b2b45d00496d73a0d0c688e2896928b52a707bc/layer.tar",
"56ce86a9ea9ac8876df7cc6ed93044050915d43fae7db3f33c78521e2e80a43d/layer.tar",
"a1700ea4465fc48b04e06501ae0dd47a21bc95eddbf90fde6f9c63e38c819da0/layer.tar"]
}]

We see that the last layer is defined in the file “a1700ea4465fc48b04e06501ae0dd47a21bc95eddbf90fde6f9c63e38c819da0/layer.tar”. For demonstration purposes, I unpacked the image created while writing the blog post about building a project inside a Docker container.

Hence I expect that the last layer contains files modified while creating a new user. Let’s verify that.

In the directory, there is a layer.tar file which I must unpack. After unpacking it, I see that it contains an empty “/home/appuser” directory and some files in the “/etc” directory. Which files does it contain? Only the “/etc” files which have been modified in the last step of Dockerfile. In this case, the files containing information about Linux users.

1
2
> ls etc
group group- passwd passwd- shadow shadow-

We can repeat the same steps to see modifications done in every other layer of the docker image.

There is one more thing. At the end of the Dockerfile, I defined the default user. Where does it store this information?

To find this, we must once again look at the directory which contains the last Docker layer. There is a JSON file in it which configures the working directory and the user. In the case of my image, the configuration looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
"config": {
"Hostname": "",
"Domainname": "",
"User": "appuser",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/jvm/java-1.8-openjdk/jre/bin:/usr/lib/jvm/java-1.8-openjdk/bin",
"LANG=C.UTF-8",
"JAVA_HOME=/usr/lib/jvm/java-1.8-openjdk/jre",
"JAVA_VERSION=8u171",
"JAVA_ALPINE_VERSION=8.171.11-r0",
"SCALA_VERSION=2.12.7",
"SBT_VERSION=1.2.3"
],
"Cmd": [
"/bin/sh"
],
"ArgsEscaped": true,
"Image": "sha256:f48ad349b9aafb3e1512619fbf43307f5ab7a464c87b38fdaace51d788317aee",
"Volumes": null,
"WorkingDir": "/home/appuser",
"Entrypoint": null,
"OnBuild": [],
"Labels": null
}

Did you enjoy reading this article?
Would you like to learn more about leveraging AI to drive growth and innovation, software craft in data engineering, and MLOps?

Subscribe to the newsletter or add this blog to your RSS reader (does anyone still use them?) to get a notification when I publish a new essay!

Newsletter

Do you enjoy reading my articles?
Subscribe to the newsletter if you don't want to miss the new content, business offers, and free training materials.

Bartosz Mikulski

Bartosz Mikulski

  • MLOps engineer by day
  • AI and data engineering consultant by night
  • Python and data engineering trainer
  • Conference speaker
  • Contributed a chapter to the book "97 Things Every Data Engineer Should Know"
  • Twitter: @mikulskibartosz
  • Mastodon: @mikulskibartosz@mathstodon.xyz
Newsletter

Do you enjoy reading my articles?
Subscribe to the newsletter if you don't want to miss the new content, business offers, and free training materials.