Images#

This page focuses on the features associated with docker images.

Build image#

You can build docker images using the docker build <path to the folder> command. The <folder path> should contain a dockerfile with the instructions to build the images.

Check more in the corresponding page.


Consider example - the following cell creates the simplest possible dockerfile it just modifies alpine linux to echo message this_is_new_container at container startup.

cat << 'EOF' > images_files/dockerfile

FROM alpine
CMD ["echo", "this_is_new_image"]

EOF

Note: Even if the Dockerfile is located in the current working directory, you still need to specify the path to folder in the docker build command. In such cases, you should use the command docker build ..

The following example demonstrates the construction of a Docker image. It employs images_files as the working directory to emphasize the need for explicitly specifying . as the path.

Also here is specified -t docker_build_example option it specifies name of the container.

cd images_files
docker build -t docker_build_example . &> /dev/null
cd ..

After executing the previous cell, you’ll be able to find the docker_build_example image in the list of images.

docker images
REPOSITORY             TAG       IMAGE ID       CREATED      SIZE
docker_build_example   latest    1615e7501182   3 days ago   7.83MB

Ok, finally, let’s try to run container based on the image we created, to make sure that docker completes the instructions specified in the dockerfile.

docker run --rm docker_build_example
docker rmi docker_build_example
this_is_new_image
Untagged: docker_build_example:latest
Deleted: sha256:1615e7501182ca1dc43eb1affa2173af6bc3214c030c5ef0acb4ca96bdb6a916

Commit container to image#

The docker commit command allows you to save the current state of a container as a new image. This is useful if you have made changes or created something new within a container and want to preserve these modifications. To save the current state of a container as a new image, use the following syntax:

docker commit <container name> <new image name>

As an example, let us run Alpine Linux and try to ask it Python version.

docker run --rm --name commit_container -itd alpine
docker exec commit_container python3 --version
7a095fff8ce568c6a238676ee753d8c99ed99705b89dded46daa52682675cd69
OCI runtime exec failed: exec failed: unable to start container process: exec: "python3": executable file not found in $PATH: unknown

As a result, we got an error. No big deal - we could install Python on any system.

docker exec commit_container apk add python3 &> /dev/null
docker exec commit_container python3 --version
Python 3.12.3

After installation we have the Python version. Now by using commit we “freeze” such state of the container as the image. And any container created on from this image will be just like alpine linux but with installed python.

docker commit commit_container alpine_with_python
docker run --rm -itd --name al_py alpine_with_python
docker exec al_py python3 --version
7a40579ac221bcc570751f0ab496e10291134448f5885e7c614d0544b21c69a1
Python 3.12.3

So containers that use the alpine_with_python image as a base will have the python version by default.

docker stop commit_container al_py
docker rmi alpine_with_python
commit_container
Error response from daemon: No such container: al_py
Untagged: alpine_with_python:latest
Deleted: sha256:909728da78e4e6032ade63f135f729f85075df783e86c72688e20f152f5d27ec
Deleted: sha256:d45b95ae0c5e8765eebc035f638f39e1cfcf6d20cd0df26e0915f9ab087793c5

Prune images#

Docker prune allows you to remove a set of images. By default, it removes containers with the <none> tag, which are typically intermediate images that were replaced by other containers with the same tag. These <none> images can be safely removed.


Consider the example where we are creating two images in Docker-in-Docker — one with a specified tag and the other created in such a way that it has the tag <none>:<none>.

docker pull alpine &> /dev/null

docker build - &> /dev/null << EOF
FROM alpine
RUN mkdir hello
EOF 

The following cell shows that everything is created as expected.

docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
<none>       <none>    70cc108d4522   3 minutes ago   7.83MB
alpine       latest    b0c9d60fc5e3   3 days ago      7.83MB

With docker image prune, you are removing dangling images.

Note: By default, it prompts for confirmation. To bypass this prompt, use the -f or --force flag.

docker image prune -f
Deleted Images:
deleted: sha256:70cc108d4522de1ecaf84eb8de6da565a0a3025233e0049d2fd4face1f9da62a

Total reclaimed space: 0B

So now there are no containers with the <none>:<none> tag—they have been pruned.

docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
alpine       latest    b0c9d60fc5e3   3 days ago   7.83MB

Dockerfile directives#

Dockerfile directives describe the behaviour of the dockerbuild command.

Directive

Description

FROM

Sets the base image for the new image.

WORKDIR

Sets the working directory within the image.

COPY

Copies files or directories from the host to the image.

RUN

Executes commands in a new layer on top of the current image.

CMD

Provides a command that will run when a container is started.

EXPOSE

Informs Docker that the container listens on the specified network ports.

ENV

Sets environment variables.

ADD

Copies files, directories, or remote file URLs from the host to the image.

ENTRYPOINT

Configures a container to run as an executable.

VOLUME

Creates a mount point with specified path and marks it as holding external data.

USER

Sets the username or UID to use when running the image.

LABEL

Adds metadata to an image.

ARG

Defines a variable that users can pass at build-time to the builder.

ONBUILD

Adds a trigger instruction to be executed when the image is used as a base for another build.

STOPSIGNAL

Sets the system call signal that will be sent to the container to exit.

HEALTHCHECK

Tells Docker how to test a container to check that it is still working.

SHELL

Allows the default shell used for the shell form of commands to be overridden.

Check more in specific page for dockerfile directives.

History (layers)#

With docker history <image name>, you can view the manipulations used to create the image. Some of them are layers — a layer is a row in the history with a non-zero SIZE.


The following cell pulls the alpine image, and showen history of the layer.

docker pull alpine &> /dev/null
docker history alpine
IMAGE          CREATED      CREATED BY                                      SIZE      COMMENT
b0c9d60fc5e3   3 days ago   CMD ["/bin/sh"]                                 0B        buildkit.dockerfile.v0
<missing>      3 days ago   ADD alpine-minirootfs-3.21.2-x86_64.tar.gz /…   7.83MB    buildkit.dockerfile.v0

Note: A 0B size history event for specifying CMD represents metadata of the image. It is part of the history but not a layer.

The following code creates a new image based on the alpine loaded in the previous cell. It adds two RUN commands.

docker build -t extra_layer - &> /dev/null << EOF
FROM alpine
RUN echo "hello world" > test_file 
RUN echo "hello world"
EOF 

The result is two RUN commands in the history of the image.

docker history extra_layer
IMAGE          CREATED              CREATED BY                                      SIZE      COMMENT
9872f645ca65   About a minute ago   RUN /bin/sh -c echo "hello world" # buildkit    0B        buildkit.dockerfile.v0
<missing>      About a minute ago   RUN /bin/sh -c echo "hello world" > test_fil…   12B       buildkit.dockerfile.v0
<missing>      3 days ago           CMD ["/bin/sh"]                                 0B        buildkit.dockerfile.v0
<missing>      3 days ago           ADD alpine-minirootfs-3.21.2-x86_64.tar.gz /…   7.83MB    buildkit.dockerfile.v0