Skip to content

Build Your First Image (docker commit)


What if you could take a running (or stopped) container, make a few changes, and turn exactly what you have into a new image?

That’s what docker commit lets you do. In this practical exercise, we’ll start with a running container, make changes to it, and then capture those changes as a new image.

Along the way, we’ll see Image Layered Architecture in action—and understand how a container’s state can become a new image layer. That’s why be till the end.

Build Image with docker commit

We will take a very simple example which every viewers can relate.

The default ubuntu base image doesn’t even have a minimal text editor like nano. For some purpose you need nano for every container that will have base image of ubuntu but unfortunately it doesn’t have it by default.

Fortunately, you can use that ubuntu base image, spin up a container, install nano text editor inside the container and commit that container.

After commiting the container, Docker will create new image that will already have nano baked up and you will now use this image as your base instead of ubuntu beacause the new image will have everything ubuntu has plus the nano you need the most.

Note

I delibarately choose this simpler example so every viewers can relate. In fact, every app (be it in python or Java or C++ or any language) follows the similar approach.
No developer likes re-installing runtime or compiler everytime new container is spinned up. So, new image is created which will have all those on it.

Enough taking, let’s start.

Step1: Start a Container With ubuntu Base

Run the ubuntu container interactively so that we can install nano text editor.

docker container run -it --name=base ubuntu

Note

Containers name (--name) is not mandatory but it gives you clarity. You will remember the name you choose, not what Docker has choosed for you.

Step2: Install nano From Running Container

This is the indication you are inside your container i.e you get container shell.

root@2b1db7457694/#

Install nano from inside the container:

apt update && apt install nano -y

Verify if nano exits:

which nano

You will get:

/usr/bin/nano

Step3: Commit The Container That Has nano

This container (named based in first step) has nano. You need to commit this container that will create a new Docker image. The new Docker imamge then will have nano pre-installed.

You can leave your container running or exit it. It doesn’t matter at all — you can commit both kind of containers. And to commit our base container:

docker container commit -m "Add nano on top of ubuntu image" base ubuntu-with-nano

You will get the SHA-256 hash (image id) as output:

sha256:9faee7dc7d3368b44291e7f07f9834f9260c36a44d99851d84c3f657b835aa9e

Now Docker has created new image named ubuntu-with-nano with nano pre-installed.

Tip

At this stage, you can also remove the base container. That’s a cleanup.

docker container rm base

Step4: Verify New Image Has nano

First list the images:

docker container ls

The output verifies you have a new image that you previous created (ubuntu-with-nano):

IMAGE                     ID             DISK USAGE   CONTENT SIZE   EXTRA
ubuntu-with-nano:latest   9faee7dc7d33        229MB         71.5MB        
ubuntu:latest             678c6550cc43        160MB         45.3MB

To verify if the image ubuntu-with-nano really contains the text editor nano you can run the container with which nano command directly:

docker container run ubuntu-with-nano which nano

This will print:

/usr/bin/nano

Layered Architecture In Action (docker image history)

Let’s see our image listing (docker image ls) again:

IMAGE                     ID             DISK USAGE   CONTENT SIZE   EXTRA
ubuntu-with-nano:latest   9faee7dc7d33        229MB         71.5MB        
ubuntu:latest             678c6550cc43        160MB         45.3MB

The thing I had been hiding from you was docker image history command (coz it makes sense only at the last) which shows how many layers any image is consists of. For our image ubuntu-with-nano, check the history:

docker image history ubuntu-with-nano

The output (stripped for readiability):

1  IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
2  9faee7dc7d33   17 minutes ago   /bin/bash                                       42.4MB    Add nano on top of ubuntu image
3  678c6550cc43   2 weeks ago      umoci raw add-layer --image /home/buildd/roc…   12.3kB    Add rock control metadata
4  <missing>      2 weeks ago      umoci config --image /home/buildd/rockcraft-…   0B        Set annotations

Did you notice something in the output?

See the third line, isn’t 678c6550cc43 the ID of ubuntu base image — the base image for our ubuntu-with-nano image. It proves that ubuntu is the base for our image.

Nothing more: “A word to the wise is enough.

Last updated on