Vue lecture

Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.

Docker Engine v28: Hardening Container Networking by Default

Docker simplifies containerization by removing runtime complexity and making app development seamless. With Docker Engine v28, we’re taking another step forward in security by ensuring containers aren’t unintentionally accessible from local networks. This update isn’t about fixing a single vulnerability — it’s about security hardening so your containers stay safe. 

What happened?

When you run a container on the default Docker “bridge” network, Docker sets up NAT (Network Address Translation) rules using your system’s firewall (via iptables). For example, the following command forwards traffic from port 8080 on your host to port 80 in the container. 

docker run -d -p 8080:80 my-web-app

However, if your host’s filter-FORWARD chain is permissive (i.e., ACCEPT by default) and net.ipv4.ip_forward is enabled, unpublished ports could also be remotely accessible under certain conditions.

This only affects hosts on the same physical/link-layer network as the Docker host. In multi-tenant LAN environments or other shared local networks, someone connected on an RFC1918 subnet (such as 192.168.x.x or 10.x.x.x) could reach unpublished container ports if they knew (or guessed) its IP address.

Who’s affected?

This behavior only affects Linux users running Docker versions earlier than 28.0.0 with iptables. Docker Desktop is not affected.

If you installed Docker on a single machine and used our defaults, without manually customizing your firewall settings, you’re likely unaffected by upgrading. However, you could be impacted if:

  • You deliberately set your host’s FORWARD chain to ACCEPT and rely on accessing containers by their IP from other machines on the LAN.
  • You bound containers to 127.0.0.1 or another loopback interface but still route external traffic to them using advanced host networking tricks.
  • You require direct container access from subnets, VLANs, or other broadcast domains without explicitly publishing ports (i.e., no p flags).

If any of these exceptions apply to you, you might notice that containers previously reachable by direct IP now appear blocked unless you opt out or reconfigure your networking.

What’s the impact?

This exposure would’ve required being on the same local network or otherwise having route-level access to the container’s RFC1918 IP range. It did not affect machines across the public internet. However, a malicious user could discover unpublished container ports, within LAN settings or corporate environments, and connect to them. 

For instance, they might add a custom route to the container’s subnet, using the following command:

ip route add 172.17.0.0/16 via 192.168.0.10

From there, if 192.168.0.10 is your Docker host with a permissive firewall, the attacker could send packets straight to 172.17.0.x (the container’s IP).

What are my next steps?

If you’ve been impacted, we recommend taking the following three steps:

1. Upgrade to Docker Engine 28.0

Docker Engine 28.0 now drops traffic to unpublished ports by default. 

This “secure by default” approach prevents containers from being unexpectedly accessible on the LAN. Most users won’t notice a difference, published ports will continue to function as usual (-p 8080:80), and unpublished ports remain private as intended.

2. Decide if you need the old behavior (opt-out)

If you connect to containers over the LAN without publishing ports, you have a couple of options:

Option 1: Disable Docker’s DROP policy
In /etc/docker/daemon.json, add the following:

{
  "ip-forward-no-drop": true
}

Or you can run Docker with the --ip-forward-no-drop flag. This preserves a globally open FORWARD chain. But keep in mind that Docker still drops traffic for unpublished ports using separate rules. See Option 2 for a fully unprotected alternative.

Option 2: Create a “nat-unprotected” network

docker network create -d bridge \\
  -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \\
  my_unprotected_net

3. Consider custom iptables management

Advanced users with complex network setups can manually configure iptables to allow exactly the traffic they need. But this route is only recommended if you’re comfortable managing firewall rules.

Technical details

In previous Docker Engine versions, Docker’s reliance on a permissive FORWARD chain meant that containers on the default bridge network could be reached if:

  1. net.ipv4.ip_forward was enabled (often auto-enabled by Docker if it wasn’t already).
  2. The system-wide FORWARD chain was set to ACCEPT.
  3. Another machine on the same LAN (or an attached subnet) routed traffic to the container’s IP address.

In Docker 28.0, we now explicitly drop unsolicited inbound traffic to each container’s internal IP unless that port was explicitly published (-p or --publish). This doesn’t affect local connections from the Docker host itself, but it does block remote LAN connections to unpublished ports.

Attacks: a real-world example

Suppose you have two hosts on the same RFC1918 subnet:

  • Attacker at 10.0.0.2
  • DockerHost at 10.0.0.3

DockerHost runs a container with IP 172.17.0.2, and Docker’s firewall policy is effectively “ACCEPT.” In this situation, an attacker could run the following command:

ip route add 172.17.0.2/32 via 10.0.0.3
nc 172.17.0.2 3306

If MySQL was listening on port 3306 in the container (unpublished), Docker might still forward that traffic. The container sees a connection from 10.0.0.2, and no authentication is enforced by Docker’s network stack alone. 

Mitigations in Docker Engine 28.0

By enforcing a drop rule for unpublished ports, Docker 28.0 now prevents the above scenario by default.

1. Default drop for unpublished ports

Ensures that local traffic to container IPs is discarded unless explicitly published.

2. Targeted adjustments to FORWARD policy

Originally, if Docker had to enable IP forwarding, it would set DROP by default. Now, Docker only applies that if necessary and extends the same logic to IPv6. You can opt-out with --ip-forward-no-drop or in the config file.

3. Unpublished ports stay private

The container remains accessible from the host itself, but not from other devices on the LAN (unless you intentionally choose “nat-unprotected”).

Why we’re making this change now

Some users have raised concerns about local-network exposure for years (see issues like #14041 and #22054). But there’s been a lot of change since then:

  • Docker was simpler: Use cases often revolved around single-node setups where any extra exposure was mitigated by typical dev/test workflows.
  • Ecosystem evolution: Overlay networks, multi-host orchestration, and advanced routing became mainstream. Suddenly, scenarios once relegated to specialized setups became common.
  • Security expectations: Docker now underpins critical workloads in complex environments. Everyone benefits from safer defaults, even if it means adjusting older assumptions.

By introducing these changes in Docker Engine 28.0, we align with today’s best practices: don’t expose anything without explicit user intent. It’s a shift away from relying on users to configure their own firewalls if they want to lock things down.

Backward compatibility and the path forward

These changes are not backward compatible for users who rely on direct container IP access from a local LAN. For the majority, the new defaults lock down containers more securely without breaking typical docker run -p scenarios.

Still, we strongly advise upgrading to 28.0.1 or later so you can benefit from:

  • Safer defaults: Unpublished ports remain private unless you publish or explicitly opt out.
  • Clearer boundaries: Published vs. unpublished ports are now unambiguously enforced by iptables rules.
  • Easier management: Users can adopt the new defaults without becoming iptables experts.

Quick upgrade checklist

Before you upgrade, here’s a recommended checklist to run through to make sure you’re set up for success with the latest release:

  1. Examine current firewall settings

    Run iptables -L -n and ip6tables -L -n. If you see ACCEPT in the FORWARD chain, and you depend on that for multi-subnet or direct container access, plan accordingly.
  2. Test in a controlled environment

    Spin up Docker Engine 28.0 on a staging environment. Attempt to reach containers that you previously accessed directly. Then, verify which connections still work and which are now blocked.
  3. Decide on opt-outs

    If you do need the old behavior, set "ip-forward-no-drop": true or use a “nat-unprotected” network. Otherwise, enjoy the heightened security defaults.
  4. Monitor logs and metrics

    Watch for unexpected connection errors or service downtime. If something breaks, check if it’s caused by Docker’s new drop rules before rolling back any changes.

Conclusion

By hardening default networking rules in Docker Engine 28.0, we’re reducing accidental container exposure on local networks. Most users can continue without disruption and can just enjoy the extra peace of mind. But if you rely on older behaviors, you can opt out or create specialized networks that bypass these rules.

Ready to upgrade? Follow our official installation and upgrade instructions to get Docker Engine 28.0 on your system today.

We appreciate the feedback from the community and encourage you to reach out if you have questions or run into surprises after upgrading. You can find us on GitHub issues, our community forums, or your usual support channels.

Learn more

Docker Security Advisory: AuthZ Plugin Bypass Regression in Docker Engine

Certain versions of Docker Engine have a security vulnerability that could allow an attacker to bypass authorization plugins (AuthZ) under specific circumstances. The base likelihood of this being exploited is low. This advisory outlines the issue, identifies the affected versions, and provides remediation steps for impacted users.

banner docker security advisory

Problem

Docker’s default authorization model is all-or-nothing. Users with access to the Docker daemon can execute any Docker command. For greater access control, authorization plugins (AuthZ) can be used. These plugins approve or deny requests to the Docker daemon based on authentication and command context.

In 2018, a security issue was discovered where an attacker could bypass AuthZ plugins using a specially crafted API request. This could lead to unauthorized actions, including privilege escalation. Although this issue was fixed in Docker Engine v18.09.1 in January 2019, the fix was not carried forward to later versions, resulting in a regression.

Vulnerability details

  • AuthZ bypass and privilege escalation: An attacker could exploit a bypass using an API request with Content-Length set to 0, causing the Docker daemon to forward the request without the body to the AuthZ plugin, which might approve the request incorrectly if not set to deny by default.
  • Initial fix: The issue was fixed in Docker Engine v18.09.1 January 2019.
  • Regression: The fix was not included in Docker Engine v19.03 or newer versions. This was identified in April 2024 and patches were released for the affected versions on July 23, 2024. The issue was assigned CVE-2024-41110.

Affected versions

Affected versionsPatched versions
<= v19.03.15, <= v20.10.27, <= v23.0.14, <= v24.0.9, <= v25.0.5, <= v26.0.2, <= v26.1.4, <= v27.0.3, <= v27.1.0> v23.0.14, >26.1.4, > v27.1.0

Who is impacted?

  • Users of Docker Engine v19.03.x and later versions who rely on authorization plugins to make access control decisions.

Who is not impacted?

  • Users of Docker Engine v19.03.x and later versions who do not rely on authorization plugins to make access control decisions and users of all versions of Mirantis Container Runtime are not vulnerable.
  • Users of Docker commercial products and internal infrastructure who do not rely on AuthZ plugins are unaffected.

Impact on Docker Desktop

  • Docker Desktop up to v4.32.0 includes affected versions of Docker Engine.
  • The impact for Docker Desktop is limited compared to production environments.
    • Exploitation requires access to the Docker API, which usually means the attacker needs to already have local access to the host machine, unless the Docker daemon is insecurely exposed over TCP.
    • Default Docker Desktop configuration does not include AuthZ plugins.
    • Privilege escalation is limited to the Docker Desktop VM, not the underlying host.
  • A patched version of Docker Engine is included in Docker Desktop 4.33.

Remediation steps

  1. Update Docker Engine:
  • If you are running an affected version, update to the most recent patched version.
  1. Mitigation if unable to update immediately:
  • Avoid using AuthZ plugins.
  • Restrict access to the Docker API to trusted parties, following the principle of least privilege.
  1. Update Docker Desktop:
  • If using an affected version, update to Docker Desktop 4.33 .
  • Ensure AuthZ plugins are not used and do not expose the Docker API over TCP without protection.
  • Docker Business subscribers can use Settings Management to enforce secure settings.

Learn more

How to Check Your Docker Installation: Docker Desktop vs. Docker Engine

Docker has become a leader in providing software development solutions, offering tooling that simplifies the process of developing, testing, deploying, and running applications using containers. As such, understanding Docker’s different products, like Docker Desktop, and components, like Docker Engine, and understanding how they work together is essential for developers looking to maximize their productivity and ensure compliance with Docker’s licensing terms. 

This post will clarify the distinctions and similarities between Docker Desktop and Docker Engine, and provide guidance on verifying which one you are currently using so you can make the most out of your experience.

Read on to explore how to distinguish between Docker Desktop and Docker Engine installations, identify when additional Docker tools are in use, understand Docker contexts, and review your Docker usage to ensure it complies with the Docker Licensing Agreement.

banner docker tips

Background

The word “Docker” has become synonymous with containerization to the degree that containerizing an application is increasingly referred to as “dockerizing” an application. Although Docker didn’t create containerization, the company was the first to bring this technology to the developer community in an easily understood set of tooling and artifacts. 

In 2015, Docker took the next step and created the Open Container Initiative (OCI) to define and specify how to build a container image, how to run a container image, and how to share container images. By donating the OCI to the Linux Foundation, Docker provided a level playing field for any application of container technology.

An open source effort headed up by Docker is the Moby Project. Docker created this open framework to assemble specialized container systems without reinventing the wheel. It provides a building block set of dozens of standard components and a framework for assembling them into custom platforms. 

Moby comprises several components, including a container engine, container runtime, networking, storage, and an orchestration system. Both the standalone free Docker Engine (also known Docker Community Edition or Docker CE) and the commercial Docker Desktop originated from the Moby Project. However, Docker Desktop has evolved beyond the Moby Project, with a full product team investing in the features and technology to support individual developers, small teams, and the requirements of large development teams.

Docker Engine vs. Docker Desktop

Docker Desktop is a commercial product sold and supported by Docker, Inc. It includes the Docker Engine and other open source components; proprietary components; and features like an intuitive GUI, synchronized file shares, access to cloud resources, debugging features, native host integration, governance, and security features that support ECI, air-gapped containers, and administrative settings management. To provide a consistent user experience across different operating systems, Docker Desktop uses the host systems’ native virtualization to run and manage a VM for the Docker Engine. This offers developers a turnkey solution for running a containerization toolset on any device or operating system. Users can leverage the Docker Engine at its core on any platform by downloading Docker Desktop.

Docker Engine is a component free to download individually, not as part of Docker Desktop, and runs as a standalone for free. It can run on any supported Linux distribution and includes the Docker CLI to run commands. Docker Engine will not run natively on Windows or macOS and does not come with a GUI or any of the advanced features provided by Docker Desktop.

How can I tell If I’m running Docker Desktop or just the Docker Engine?

You can determine if you’re using Docker Desktop or Docker Engine in a number of different ways. The following section provides guidance for checking from the filesystem and from within the Docker CLI tooling, which is a component in Docker Desktop as well.

1. GUI or icon

If you are using Docker Desktop, you will have either a windowed GUI or a menubar/taskbar icon of a whale (Figure 1).

Screenshot of Docker Desktop menu on macOs.
Figure 1: The macOS menu.

2. Check for an installation

The easiest way to check for Docker Desktop is to look for the installation; this can be automated by scripting or the use of an MDM solution.

Note that the following instructions assume that Docker Desktop is installed in the default location, which may result in false negatives if other installation paths are used.

Docker Desktop on macOS

On macOS, the Docker Desktop application is installed under the /Applications directory and is named Docker (Figure 2).

$ ls -alt /Applications/Docker.app/
total 0
drwxrwxr-x  49 root      admin  1568 Oct 13 09:54 ..
drwxr-xr-x@  9 jschmidt  admin   288 Sep 28 15:36 Contents
drwxr-xr-x@  3 jschmidt  admin    96 Sep  8 02:35 .
Screenshot of Docker application information on macOS, including Date Created, Modified, Version, and more.
Figure 2: Docker application installed on macOS.

Docker Desktop on Windows

On Windows, the Docker Desktop application is installed under the C:\Program Files folder and is named Docker (Figure 3).

C:\Users\qdzlug>dir "c:\Program Files\Docker"
 Volume in drive C has no label.
 Volume Serial Number is DEFE-FC15

 Directory of c:\Program Files\Docker

09/28/2023  02:22 PM    <DIR>          .
09/28/2023  02:22 PM    <DIR>          ..
09/28/2023  02:22 PM    <DIR>          cli-plugins
09/28/2023  02:21 PM    <DIR>          Docker
               0 File(s)              0 bytes
               4 Dir(s)  52,964,356,096 bytes free

C:\Users\qdzlug>
Screenshot of Docker application on Windows, showing file folder and date modified.
Figure 3: Docker application installed on Windows.

Docker Desktop on Linux

On Linux, the Docker Desktop application is installed under /opt/docker-desktop.

$ ls -lat /opt/docker-desktop/
total 208528
drwxr-xr-x 7 root root      4096 Sep 29 10:58  .
drwxr-xr-x 2 root root      4096 Sep 29 10:58  locales
drwxr-xr-x 5 root root      4096 Sep 29 10:58  resources
drwxr-xr-x 2 root root      4096 Sep 29 10:58  share
drwxr-xr-x 2 root root      4096 Sep 29 10:58  linuxkit
drwxr-xr-x 2 root root      4096 Sep 29 10:58  bin
drwxr-xr-x 7 root root      4096 Sep 29 10:57  ..
-rw-r--r-- 1 root root   5313018 Sep 27 12:10  resources.pak
-rw-r--r-- 1 root root    273328 Sep 27 12:10  snapshot_blob.bin
-rw-r--r-- 1 root root    588152 Sep 27 12:10  v8_context_snapshot.bin
-rw-r--r-- 1 root root       107 Sep 27 12:10  vk_swiftshader_icd.json
-rw-r--r-- 1 root root    127746 Sep 27 12:10  chrome_100_percent.pak
-rw-r--r-- 1 root root    179160 Sep 27 12:10  chrome_200_percent.pak
-rwxr-xr-x 1 root root   1254728 Sep 27 12:10  chrome_crashpad_handler
-rwxr-xr-x 1 root root     54256 Sep 27 12:10  chrome-sandbox
-rw-r--r-- 1 root root       398 Sep 27 12:10  componentsVersion.json
-rwxr-xr-x 1 root root 166000248 Sep 27 12:10 'Docker Desktop'
-rw-r--r-- 1 root root  10544880 Sep 27 12:10  icudtl.dat
-rwxr-xr-x 1 root root    252920 Sep 27 12:10  libEGL.so
-rwxr-xr-x 1 root root   2877248 Sep 27 12:10  libffmpeg.so
-rwxr-xr-x 1 root root   6633192 Sep 27 12:10  libGLESv2.so
-rwxr-xr-x 1 root root   4623704 Sep 27 12:10  libvk_swiftshader.so
-rwxr-xr-x 1 root root   6402632 Sep 27 12:10  libvulkan.so.1
-rw-r--r-- 1 root root      1096 Sep 27 12:10  LICENSE.electron.txt
-rw-r--r-- 1 root root   8328249 Sep 27 12:10  LICENSES.chromium.html

Note that the launch icon and location for Docker will depend on the Linux distribution being used.

3. Check a running installation

You can also check a running installation to determine which version of Docker is being used. To do this, you need to use the docker version command; the Server line will indicate the version being used.

Docker Desktop on macOS Arm64

The Server: Docker Desktop 4.24.0 (122432) line indicates using Docker Desktop.

$ docker version
Client:
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:28:49 2023
 OS/Arch:           darwin/arm64
 Context:           default

**Server: Docker Desktop 4.24.0 (122432)**
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:31:36 2023
  OS/Arch:          linux/arm64
  Experimental:     true
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker Desktop on Windows

The Server: Docker Desktop 4.24.0 (122432) line indicates using Docker Desktop.

C:\Users\qdzlug>docker version
Client:
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:32:48 2023
 OS/Arch:           windows/amd64
 Context:           default

**Server: Docker Desktop 4.24.0 (122432)**
 Engine:
  Version:          dev
  API version:      1.44 (minimum version 1.12)
  Go version:       go1.20.8
  Git commit:       HEAD
  Built:            Tue Sep 26 11:52:32 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

C:\Users\qdzlug>

Docker Desktop on Linux

C:\Users\qdzlug>docker info
Client:
 Version:    24.0.6
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.2-desktop.5
    Path:     C:\Program Files\Docker\cli-plugins\docker-buildx.exe
  compose: Docker Compose (Docker Inc.)
    Version:  v2.2.3
    Path:     C:\Users\qdzlug\.docker\cli-plugins\docker-compose.exe
  dev: Docker Dev Environments (Docker Inc.)
    Version:  v0.1.0
    Path:     C:\Program Files\Docker\cli-plugins\docker-dev.exe
  extension: Manages Docker extensions (Docker Inc.)

Docker Engine on Linux

The Server: Docker Engine - Community line indicates using the community edition.

$ docker version
Client: Docker Engine - Community
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:31:44 2023
 OS/Arch:           linux/amd64
 Context:           default

**Server: Docker Engine - Community**
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:31:44 2023
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          1.6.24
  GitCommit:        61f9fd88f79f081d64d6fa3bb1a0dc71ec870523
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfc
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Docker contexts

Note that multiple contexts can be installed on a system; this is most often seen in Linux where Docker Desktop and Docker Engine are installed on the same host. To switch between the two, the docker context use command is used. When you are in a context, you communicate with the daemon for that context; thus, in a dual installation situation, you would be switching between the Docker Desktop install and the host install.

To view contexts, you use docker context ls, then switch via docker context use CONTEXTNAME. The following example shows a Linux system with both installed.

$ docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                                     KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                     
desktop-linux       moby                Docker Desktop                            unix:///home/jschmidt/.docker/desktop/docker.sock               
$ docker version
Client: Docker Engine - Community
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:31:44 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:31:44 2023
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          1.6.24
  GitCommit:        61f9fd88f79f081d64d6fa3bb1a0dc71ec870523
 runc:
  Version:          1.1.9
  GitCommit:        v1.1.9-0-gccaecfc
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ docker context use desktop-linux
desktop-linux
Current context is now "desktop-linux"
$ docker version
Client: Docker Engine - Community
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:31:44 2023
 OS/Arch:           linux/amd64
 Context:           desktop-linux

Server: Docker Desktop 4.24.0 (122432)
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:32:16 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Other OCI tooling

Because both Docker Engine and Docker Desktop are OCI compliant, a number of solutions are presented and installed as “direct replacements” for Docker. This process usually involves creating helper aliases, scripts, or batch programs to emulate docker commands. 

You can check for aliases by running the command alias docker to see if there is an alias in place. This holds true for Linux and macOS, or a Linux distribution inside WSL2 on Windows.

$ alias docker # Docker aliased to podman
docker='podman'
$ alias docker # No alias present

You can also list the docker binary from the CLI to ensure that it is the official Docker binary:

$ ls -l `which docker` # Docker supplied by Homebrew on the Mac
lrwxr-xr-x  1 jschmidt  admin  34 Apr  2 12:03 /opt/homebrew/bin/docker -> ../Cellar/docker/26.0.0/bin/docker


$ ls -l `which docker` # Official Docker binary on the Mac
lrwxr-xr-x  1 root  wheel  54 Jan 10 16:06 /usr/local/bin/docker -> /Applications/Docker.app/Contents/Resources/bin/docker

Conclusion

To wrap up our exploration, note that there are also several offerings generically referred to as “Docker” available to use as part of your containerization journey. This post focused on Docker Engine and Docker Desktop.

At this point, you should be comfortable distinguishing between a Docker Desktop installation and a Docker Engine installation and be able to identify when other OCI tooling is being used under the docker command name. You should also have a high-level understanding of Docker contexts as they relate to this topic. Finally, you should be able to review your usage against the Docker Licensing Agreement to ensure compliance or simply log in with your company credentials to get access to your procured entitlements..

Learn more

Docker Desktop 4.20: Docker Engine and CLI Updated to Moby 24.0

We are happy to announce the major release of Moby 24.0 in Docker Desktop 4.20. We have dedicated significant effort to this release, marking a major milestone in the open source Moby project.

This effort began in September of last year when we announced we were extending the integration of the Docker Engine with containerd. Since then, we have continued working on the image store integration and contributing this work to the Moby project. 

In this release, we are adding support for image history, pulling images from private repositories, image importing, and support for the classic builder when using the containerd image store.

Patch Release Update: Experiencing startup issues mentioning “An unexpected error occurred”? Try updating to the newest version! We’ve addressed this in our 4.20.1 patch release.

Feature graphic with white 4.20 text on purple background

To explore and test these new features, activate the option Use containerd for pulling and storing images in the Features in Development panel within the Docker Desktop Settings (Figure 1). 

Screenshot of "Features in Development" page with "Use containerd for pulling and storing images" selected.
Figure 1: Select “Use containerd for pulling and storing images” in the “Features in development” screen.

When enabling this feature, you will notice your existing images are no longer listed, but there’s no need to worry. The containerd image store functions differently from the classic store, and you can only view one of them at a time. Images in the classic store can be accessed again by disabling the feature.

On the other hand, if you want to transfer your existing images to the new containerd store, simply push your images to the Docker Hub using the command docker push <my image name>. Then, activate the containerd store in the Settings and pull the image using docker pull <my image name>.

You can read all bug fixes and enhancements in the Moby release notes.

SBOM and provenance attestations using BuildKit v0.11

BuildKit v0.11 helps you secure your software supply chain by allowing you to add an SBOM (Software Bill of Materials) and provenance attestations in the SLSA format to your container images. This can be done with the container driver as described in the blog post Generating SBOMs for Your Image with BuildKit or by enabling the containerd image store and following the steps in the SBOM attestations documentation.

New Dockerfile inspection features

In version 4.20, you can use the docker build command to preview the configuration of your upcoming build or view a list of available build targets in your Dockerfile. This is particularly beneficial when dealing with multi-stage Dockerfiles or when diving into new projects.

When you run the build command, it processes your Dockerfile, evaluates all environment variables, and determines reachable build stages, but stops before running the build steps. You can use --print=outline to get detailed information on all build arguments, secrets, and SSH forwarding keys, along with their current values. Alternatively, use --print=targets to list all the possible stages that can be built with the --target flag.

We also aim to present textual descriptions for these elements by parsing the comments in your Dockerfile. Currently, you need to define BUILDX_EXPERIMENTAL environment variable to use the --print flag (Figure 2).

Screenshot showing Buildx_experimental environmental variable.
Figure 2: Using the new `–print=outline` command outputs detailed information
on build arguments, secrets, SSH forwarding keys and associated values.

Check out the Dockerfile 1.5 changelog for more updates, such as loading images from on-disk OCI layout and improved Git source and checksum validation for ADD commands in the labs channel. Read the Highlights from the BuildKit v0.11 Release blog post to learn more.

Docker Compose dry run

In our continued efforts to make Docker Compose better for developer workflows, we’re addressing a long-standing user request. You can now dry run any Compose command by adding a flag (--dry-run). This gives you insight on what exactly Compose will generate or execute so nothing unexpected happens.

We’re also excited to highlight contributions from the community, such as First implementation of viz subcommand #10376 by @BenjaminGuzman, which generates a graph of your stack, with details like networks and ports. Try docker compose alpha viz on your project to check out your own graph.

Conclusion

We love hearing your feedback. Please leave any feedback on our public GitHub roadmap and let us know what else you’d like to see. Check out the Docker Desktop 4.20 release notes for a full breakdown of what’s new in the latest release.

❌