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.


Subscribe to the newsletter and join the free email course.

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
}

Remember to share on social media!
If you like this text, please share it on Facebook/Twitter/LinkedIn/Reddit or other social media.

If you want to contact me, send me a message on LinkedIn or Twitter.

Would you like to have a call and talk? Please schedule a meeting using this link.


Bartosz Mikulski
Bartosz Mikulski * MLOps Engineer / data engineer * conference speaker * co-founder of Software Craft Poznan & Poznan Scala User Group

Subscribe to the newsletter and get access to my free email course on building trustworthy data pipelines.