This is a series of blog posts that discusses containerd feature support in all Docker Desktop releases.
Containerd is a container runtime that is used by Docker Desktop to manage the lifecycle of containers. It is a lightweight and efficient runtime that provides a high level of performance and scalability.
In recent releases of Docker Desktop, the containerd integration has been improved significantly. This has resulted in a number of new features and bug fixes.
Enabling containerd under Docker Desktop 4.25.0
Once enabled, the action turns on the experimental containerd image store. This brings new features like:
- Faster container startup performance by lazy-pulling images
- Multi-platform images
New Features
The following new features and bug fixes have been added to containerd in Docker Desktop 4.25.0:
- The
docker push
now supports "Layer already exists" and "Mounted from" progress statuses. - The
docker save
is now able to export images from all tags of the repository. - Hides push upload progress of manifests, configs, and indexes (small json blobs) to match the original push behavior.
- Fixes
docker diff
containing extra differences. - Fixes
docker history
not showing intermediate image IDs for images built with the classic builder. - Fixes
docker load
not being able to load images from compressed tar archives. - Fixes registry mirrors not working.
- Fixes
docker diff
not working correctly when called multiple times concurrently for the same container. - Fixes
docker push
not reusing layers when pushing layers to different repositories on the same registry.
Seamless docker push
Progress
The docker push
now supports "Layer already exists" and "Mounted from" progress statuses.The following CLI shows how to use the new "Layer already exists" and "Mounted from" progress statuses in docker push:
docker push ajeetraina/python-server-containerd
Using default tag: latest
The push refers to repository [docker.io/ajeetraina/python-server-containerd]
31ce7ceb6d44: Layer already exists
a51e61299508: Layer already exists
52c18e7c0370: Layer already exists
e5bdf2767f0c: Layer already exists
7e3a4096bd91: Layer already exists
fbb83f1095ec: Layer already exists
29a750cd488e: Layer already exists
d7474f67085f: Layer already exists
f9d6d3ab9c73: Layer already exists
e853c4c8d2b4: Already exists
latest: digest: sha256:38d9e6bd2bf22e3fb762b81ea7951c203550060ee91368d7c38bd8405689558c size: 856
This will push the my-image:latest image to the registry, displaying the new progress statuses.
Exporting All Image Tags with docker save
The docker save
is now able to export images from all tags of the repository. To export all of the tags of an image to a tar archive, use the following command:
docker save ajeetraina/python-server-containerd -o python-server-containerd:dev
file python-server-containerd:dev
python-server-containerd:dev: POSIX tar archive
This will create a tar archive containing all of the layers for the my-image image, regardless of tag.
Original Push Behavior Restored
To maintain consistency with the original push behavior, the upload progress of manifests, configs, and indexes (small JSON blobs) during docker push has been hidden. This improvement results in cleaner and more familiar output for users.
To push an image to a registry mirror, use the following command:
docker push -q ajeetraina/python-server-containerd
docker.io/ajeetraina/python-server-containerd:latest
This will push the ajeetraina/python-server-containerd image to Docker Hub quietly
Fixes docker diff
containing extra differences.
To diff a container that is using a mounted volume, use the following command:
$ docker diff --mounts /path/to/mount/:/mount my-container
This will show the differences between the container's filesystem and the mounted volume.
Fixes docker history
not showing intermediate image IDs for images built with the classic builder.
docker history ajeetraina/python-server-containerd
IMAGE CREATED CREATED BY SIZE COMMENT
38d9e6bd2bf2 7 minutes ago CMD ["/bin/sh" "-c" "python3 app.py"] 0B buildkit.dockerfile.v0
<missing> 7 minutes ago EXPOSE map[8000/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 7 minutes ago COPY . . # buildkit 20.5kB buildkit.dockerfile.v0
<missing> 7 minutes ago USER appuser 0B buildkit.dockerfile.v0
<missing> 7 minutes ago RUN |1 UID=10001 /bin/sh -c python -m pip in… 1.36MB buildkit.dockerfile.v0
<missing> 7 minutes ago RUN |1 UID=10001 /bin/sh -c adduser --di… 53.2kB buildkit.dockerfile.v0
<missing> 7 minutes ago ARG UID=10001 0B buildkit.dockerfile.v0
<missing> 7 minutes ago WORKDIR /app 8.19kB buildkit.dockerfile.v0
<missing> 7 minutes ago ENV PYTHONUNBUFFERED=1 0B buildkit.dockerfile.v0
<missing> 7 minutes ago ENV PYTHONDONTWRITEBYTECODE=1 0B buildkit.dockerfile.v0
<missing> 3 weeks ago CMD ["python3"] 0B buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c set -eux; savedAptMark="$(a… 14.7MB buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PYTHON_GET_PIP_SHA256=22b849a10f86f5ddf7… 0B buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PYTHON_GET_PIP_URL=https://github.com/py… 0B buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PYTHON_SETUPTOOLS_VERSION=65.5.1 0B buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PYTHON_PIP_VERSION=23.2.1 0B buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c set -eux; for src in idle3 p… 20.5kB buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c set -eux; savedAptMark="$(a… 41.4MB buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PYTHON_VERSION=3.11.6 0B buildkit.dockerfile.v0
<missing> 3 weeks ago ENV GPG_KEY=A035C8C19219BA821ECEA86B64E628F8… 0B buildkit.dockerfile.v0
<missing> 3 weeks ago RUN /bin/sh -c set -eux; apt-get update; a… 10.2MB buildkit.dockerfile.v0
<missing> 3 weeks ago ENV LANG=C.UTF-8 0B buildkit.dockerfile.v0
<missing> 3 weeks ago ENV PATH=/usr/local/bin:/usr/local/sbin:/usr… 0B buildkit.dockerfile.v0
<missing> 9 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 9 days ago /bin/sh -c #(nop) ADD file:c58f86cd28b3a97f8… 108MB
To push an image to different repositories on the same registry and reuse layers, use the following command:
$ docker push repository1/my-image:latest repository2/my-image:latest
This will push the my-image:latest image to both repository1 and repository2, reusing layers where possible.