Learnitweb

1. Introduction

A container image is a standardized package that includes all of the files, binaries, libraries, and configurations to run a container. Images are like stopped containers. Images are regarded as build-time constructs, while containers are considered run-time constructs.

There are two important principles of images:

  • Images are immutable. Once an image is created, it can’t be modified. You can only make a new image or add changes on top of it.
  • Container images are composed of layers. Each layer represented a set of file system changes that add, remove, or modify files.

The terms image, Docker image, container image, and OCI image are all interchangeable and refer to the same concept. A container image is a read-only package that contains all the necessary components to run an application. This includes the application code, its dependencies, a minimal set of OS elements, and metadata. A single image can be used to launch multiple containers.

As a developer, you can think of container images as being similar to classes. Just as you can instantiate one or more objects from a class, you can create one or more containers from a single image. Like code can be pushed to Github, images can be pushed to a registry, the most popular one is the Docker Hub. Container images are obtained by pulling them from a registry. The pull operation downloads the image to your local Docker host, where Docker can then use it to launch one or more containers.

Images consist of multiple layers stacked together and presented as a single object. Each image contains a minimal operating system and all the necessary files and dependencies to run an application. Since containers are intended to be fast and lightweight, images are typically small, although Windows images tend to be much larger.

We use the docker run and docker service create commands to start one or more containers from a single image. Once a container is started from an image, the two become interdependent. You cannot delete the image until all containers using it have been stopped and removed.

2. Image size

The whole purpose of a container is to run a single application or service. Images are intended to be small. Only bare minimum dependencies. For example, a Linux image is of few MB in size. It does not contain different shells and package managers. Images also don’t include a kernel because containers share the kernel of the host they’re running on. Images contain few important filesystem components and that is why it is usually said as “images contain just enough OS”.

Note that the Windows images can be of few GB in size. This is because how Windows OS is different from a Linux OS. Due to their size Windows images take long time to push and pull.

3. Pulling images

A freshly installed Docker host will not have any images in its local repository. On a Linux host, the local image repository is typically located in /var/lib/docker/.
If you’re using Docker on your Mac or PC with Docker Desktop, everything runs inside of a VM.

To check images in local repository, use docker images command.

C:\>docker images
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
simple-node-app   latest    328c28b10f66   35 hours ago   917MB
ubuntu            latest    b1e9cef3f297   4 weeks ago    78.1MB

To pull images, use docker pull command.

C:\>docker pull redis:latest
latest: Pulling from library/redis
302e3ee49805: Pull complete
5d0249d9189d: Pull complete
4825c5e95815: Pull complete
b0ce50685fa2: Pull complete
455886c7d31b: Pull complete
96377887d476: Pull complete
4f4fb700ef54: Pull complete
5fac73c23c9b: Pull complete
Digest: sha256:2be488bff9702ce71ae3d1d23eb04c03083ca3d35612e344b6c84c584ca10223
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

Now run the docker images command again and you should see the latest pulled image.

C:\>docker images
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
simple-node-app   latest    328c28b10f66   35 hours ago   917MB
ubuntu            latest    b1e9cef3f297   4 weeks ago    78.1MB
redis             latest    7e49ed81b42b   2 months ago   117MB

4. Filtering (–filter)

The filtering flag (-f or --filter) format is of "key=value". If there is more than one filter, then pass multiple flags (e.g., --filter "foo=bar" --filter "bif=baz").

The currently supported filters are:

  • dangling (boolean – true or false)
  • label (label=<key> or label=<key>=<value>)
  • before (<image-name>[:<tag>], <image-id> or <image@digest>) – filter images created before given id or references
  • since (<image-name>[:<tag>], <image-id> or <image@digest>) – filter images created since given id or references
  • reference (pattern of an image reference) – filter images whose reference matches the specified pattern

Here are few examples:

$ docker images --filter "reference=myapp*"
$ docker images --filter "dangling=true"
$ docker images --filter "label=version=1.0"
$ docker images --filter "reference=myapp:*" --filter "dangling=false"
// images larger than 1GB
$ docker images --format "{{.Size}} {{.Repository}}:{{.Tag}}" | grep -E '[0-9]+G'

5. Docker Format Examples

5.1 Example 1: Customizing docker images Output

To list images with custom fields, you can use the --format option with the docker images command. For example:

docker images --format "{{.Repository}}:{{.Tag}} - {{.ID}} - {{.Size}}"

This will output something like:

myapp:latest - abcdef123456 - 500MB
anotherapp:v1.0 - 123456abcdef - 300MB

5.2 Example 2: Filtering and Formatting Containers

You can also use the --format option with the docker ps command to customize the output for running containers:

docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

This command will display the output in a table format with specific columns:

ID          IMAGE        STATUS         PORTS
abcdef1234  myapp:latest Up 2 minutes   0.0.0.0:80->80/tcp
123456abcd  anotherapp   Exited (0)     2 minutes ago

5.3 Example 3: Output Specific Fields

If you want to list only specific fields, you can do so by specifying them. For example, to get just the names of all containers:

docker ps -a --format "{{.Names}}"

This will give you a simple list of container names.

5.4 Example 4: Using JSON Format

If you prefer JSON output, you can use the following command:

docker ps --format '{{json .}}'

This will output each container’s details in JSON format, which can be useful for processing with other tools.

5.5 Example 5: Getting the Container Exit Codes

To see the exit codes of all containers, you can run:

docker ps -a --format "{{.Names}}: {{.State}}"

This might return output like:

myapp: running
anotherapp: exited (0)

6. Docker Search

To search Docker Hub from the command line interface (CLI), you can use the docker search command. This command allows you to find images available on Docker Hub based on a specified keyword.

docker search <search_term>

6.1 Example Usage

6.1.1 Basic search

To search for images related to “nginx”, you would run:

docker search nginx

This command will return a list of images that match the search term along with their descriptions and other metadata. Example output might look like:

C:\>docker search nginx
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                             Official build of Nginx.                        20236     [OK]
nginx/nginx-ingress               NGINX and  NGINX Plus Ingress Controllers fo…   94
nginx/unit                        This repository is retired, use the Docker o…   63
nginx/nginx-prometheus-exporter   NGINX Prometheus Exporter for NGINX and NGIN…   43
nginx/nginx-ingress-operator      NGINX Ingress Operator for NGINX and NGINX P…   2
nginx/nginx-quic-qns              NGINX QUIC interop                              1

6.1.2 Search with Filtering

You can also combine the --filter option with your search to refine results. For example, to search for only official images:

docker search --filter "is-official=true" nginx

6.1.3 Limiting Results

To limit the number of results returned, you can use the --limit option:

docker search --limit 5 nginx

The search command queries the Docker Hub registry, so you need to have an active internet connection. The search results include the following columns:

  • NAME: The name of the image.
  • DESCRIPTION: A brief description of the image.
  • STARS: The number of stars (likes) that the image has received, indicating popularity.
  • OFFICIAL: Indicates whether the image is an official Docker image.
  • AUTOMATED: Indicates whether the image is built automatically.

7. Deleting images

Docker images can accumulate on your system over time, especially when you’re building and testing applications frequently. If not managed, these images can consume significant disk space.

  • Deleting an image will remove the image and all of its layers from your Docker host.
  • If an image layer is shared by another image, it won’t be deleted until all images that reference it have been deleted.
  • You cannot delete an image while it’s being used by a running container. To remove the image, you’ll first need to stop and remove any associated containers.

7.1 Delete a Specific Docker Image

To delete a specific image, use the docker rmi command followed by the image ID or image name.

docker rmi <image_id>

For example, to delete an image with the ID 9c3d0c93cf3b, the command would be:

docker rmi 9c3d0c93cf3b

Alternatively, you can use the image name and tag:

docker rmi myapp:latest

7.2 Force Delete an Image

If a Docker image is being used by a running or stopped container, Docker will prevent you from deleting it by default. In such cases, you can use the -f (force) option to remove the image:

docker rmi -f <image_id>

Caution: Be careful when using the -f option, as it will delete the image even if it’s being used by a container.

7.3 Delete all dangling images

To delete all dangling images, use the command:

docker image prune

This command will prompt you to confirm the deletion. To skip the confirmation, add the -f flag:

docker image prune -f

7.3 Delete All Unused Images

Sometimes you may want to clean up all unused images that are not associated with any running containers. To do this, run:

docker image prune -a

This will remove all images that are not currently being used by any containers.

To avoid the confirmation prompt, you can also add the -f flag:

docker image prune -a -f

7.4 Delete Multiple Images

If you want to delete multiple images at once, you can provide multiple image IDs or names to the docker rmi command:

docker rmi <image_id_1> <image_id_2> <image_id_3>

For example:

docker rmi 9c3d0c93cf3b 2c5e00c7e2f4 6b5f7b9e3f12

7.5 Delete All Images

If you want to completely remove all images from your system, use the following command:

docker rmi $(docker images -q)

This command fetches all image IDs using docker images -q and passes them to docker rmi.

To force delete all images, you can add the -f flag:

docker rmi -f $(docker images -q)

8. Conclusion

Docker images are fundamental to containerized applications, serving as the blueprint for creating containers. They consist of multiple layers, each contributing to the final application environment. Efficiently managing Docker images, including creating, tagging, sharing, and cleaning up unused images, is key to optimizing storage and system performance. By understanding how images work and using Docker’s commands effectively, you can ensure smooth and efficient container operations across different environments.