Safeguard
Supply Chain Security•

How to Install Docker on Ubuntu, Windows and Mac, Safely

Install Docker Engine from Docker's signed apt repo on Ubuntu, or Docker Desktop on Windows and Mac, then verify the download and keep it patched.

Safeguard Security Team
36 min read

Install Docker only from docs.docker.com and download.docker.com. On Ubuntu or Debian, add Docker's signed apt repository and install docker-ce with its plugins; on Windows, install Docker Desktop per user with the WSL 2 backend; on a Mac, download the Docker.dmg that matches your chip. Then verify the download, think hard before joining the root equivalent docker group, and patch Docker like any other privileged service.

"How to install Docker" is one of the most common install searches, and most answers stop at "it runs hello-world". This guide goes further. Every command below comes from Docker's own documentation or Microsoft's, fetched on 23 October 2026, and each section explains what the command does to your machine and what it trusts.

Key takeaways

  • On a Linux server you want Docker Engine, installed from Docker's apt repository. On Windows and macOS you want Docker Desktop, which runs Engine inside a small virtual machine.
  • Docker Desktop is free for personal use, education, non-commercial open source and small businesses. Docker's terms say larger enterprises (more than 250 employees or more than $10 million USD in annual revenue) need a paid subscription, as do government entities.
  • Remove distro packages such as docker.io and podman-docker before installing Docker's packages. Docker's docs call them unofficial and say they may conflict.
  • The get.docker.com convenience script is for test and development machines; Docker does not recommend it for production.
  • Verify what you download: the apt key at download.docker.com should show fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, and each Docker Desktop release publishes a SHA-256 checksums.txt.
  • Anyone in the docker group, or docker-users on Windows, effectively has root or administrator rights on that host. Rootless mode removes that trade off for many workloads.
  • Published container ports bypass ufw and firewalld rules on Linux. Plan your firewall before you run docker run -p.
  • Track Docker's security announcements page and the Desktop release notes. Confirm each machine actually updated.

Docker Engine vs Docker Desktop: which one do you need?

Docker Engine is the daemon (dockerd), the docker CLI, containerd, and the Buildx and Compose plugins. It runs natively on Linux, and Docker's Ubuntu page links its license as Apache 2.0.

Docker Desktop is an application for Windows, macOS and Linux that bundles Engine, the CLI, Compose and a dashboard, and runs Engine inside a lightweight virtual machine: usually WSL 2 on Windows, and Docker's own VM manager on a Mac. On Linux, Desktop's VM uses its own desktop-linux context, so images from a separately installed Engine are not visible inside it.

Your machineWhat to installLicence position (Docker's own pages)Admin rights neededWhere to get it
Ubuntu or Debian server, CI runner, cloud VMDocker Engine from Docker's apt repositoryEngine is Apache 2.0sudo to installdownload.docker.com via apt
Ubuntu or Debian desktop, you want a GUIDocker Desktop for Linux, or EngineDesktop terms apply, including to Engine obtained through Desktopsudo to installdocs.docker.com Desktop for Linux page
Windows 10 22H2 or Windows 11 23H2 and laterDocker Desktop, per user, WSL 2 backendDesktop terms applyNone for per user; once for first WSL 2 enablementdesktop.docker.com, or the Microsoft Store listing linked from Docker's page
Mac with Apple siliconDocker Desktop, Apple silicon .dmgDesktop terms applyNone for the default installdesktop.docker.com
Mac with Intel chipDocker Desktop, Intel .dmgDesktop terms applyNone for the default installdesktop.docker.com
Windows ServerNot Docker DesktopDocker says Desktop is not supported on server editionsFollow Microsoft's Windows containers guidancelearn.microsoft.com

What the Docker Desktop licence actually says

Docker puts its terms at the top of every Desktop install page: commercial use in larger enterprises, meaning more than 250 employees or more than $10 million USD in annual revenue, "requires a paid subscription." Desktop is free for small businesses below both thresholds, personal use, education and non-commercial open source. Government entities need a subscription, and Pro, Team and Business plans include commercial use. Desktop will not start until you accept the Docker Subscription Service Agreement.

The Linux Desktop page adds a detail people miss: Docker Engine obtained through Docker Desktop is also covered by those terms in a larger enterprise. Engine installed on its own from the apt repository is not. If you are near the thresholds, read the agreement itself.

How to install Docker Engine on Ubuntu, step by step

Docker's Ubuntu page currently lists these 64-bit releases: Ubuntu 26.10 (Stonking), 26.04 LTS (Resolute), 24.04 LTS (Noble) and 22.04 LTS (Jammy). Supported architectures are x86_64 (amd64), armhf, arm64, s390x and ppc64le. Derivatives such as Linux Mint are not officially supported, though Docker says they may work.

Step 1: Remove conflicting packages

Your distribution may ship its own Docker packages. Docker's page names docker.io, docker-compose, docker-compose-v2, docker-doc, docker-buildx and podman-docker, plus standalone containerd and runc, because Docker Engine bundles its own as containerd.io. Remove them first:

sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc | cut -f1)

apt may report that none of these are installed. That is fine. Removing these packages does not delete /var/lib/docker, so existing images, containers and volumes survive.

Step 2: Add Docker's GPG key and apt repository

This is the part that makes the install trustworthy. The key goes into /etc/apt/keyrings, and the repository entry uses Signed-By so apt only trusts that key for Docker's repository, not for every repository on the system.

# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

The file uses the deb822 format. Suites resolves to your release codename, such as noble, and Architectures to your CPU architecture. Before running sudo apt update the second time, check the key fingerprint as described in the verification section below.

Step 3: Install the packages

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

That installs the daemon, the CLI, containerd, Buildx and the Compose v2 plugin (docker compose, with a space). On Debian and Ubuntu the service starts automatically and is enabled at boot.

Step 4: Confirm it is running

sudo systemctl status docker
sudo systemctl start docker
sudo docker run hello-world

You only need systemctl start if the status shows the service is not running. hello-world pulls a tiny test image from Docker Hub, runs it, prints a confirmation and exits. Note the sudo: at this point the docker group exists but has no members, which is the safest default.

Pinning a specific version

Production hosts often need a known version rather than whatever is newest. List what the repository offers, then install an exact version string:

apt list --all-versions docker-ce
VERSION_STRING=5:29.8.2-1~ubuntu.24.04~noble
sudo apt install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

The version string above is the example from Docker's page for Ubuntu 24.04. Use one that apt list actually shows for your release.

What changes on Debian

Debian 13 (Trixie) and Debian 12 (Bookworm) are the supported releases on Docker's Debian page, on amd64, armhf, arm64 and ppc64le. The steps are the same with three differences: the conflicting package list has no docker-compose-v2, the key and repository URLs say debian, and Suites reads only VERSION_CODENAME:

sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

On Debian testing or a derivative such as Kali, Docker says to replace the codename expression with the matching Debian release name, for example trixie.

If a host cannot reach the repository, Docker documents downloading the five .deb files from download.docker.com and installing them with sudo dpkg -i. apt's signature checking no longer protects you then, so record and check the hashes yourself, and repeat the process for every upgrade.

The firewall caveat to read before you publish a port

Docker's install pages open with a security warning that many guides skip. If you manage the firewall with ufw or firewalld, ports you expose with Docker bypass those firewall rules. Docker is compatible with iptables-nft and iptables-legacy, rules created directly with nft are not supported, and Docker says custom rules belong in the DOCKER-USER chain. In practice: a database container started with a published port on a cloud VM can be reachable from the internet even though ufw status says that port is closed. Bind published ports to 127.0.0.1 when they only need local access, and put real filtering in DOCKER-USER or in the cloud provider's network controls.

docker.io, the convenience script or Docker's repo: what is the difference?

There are four common ways to get Docker onto Ubuntu, and they differ in who builds the packages and how updates arrive.

MethodWho builds itHow updates arriveSignature checkingDocker's guidance
Docker's apt repository (docker-ce)Dockerapt from download.docker.comapt verifies against Docker's key via Signed-ByRecommended route for Engine
Distro package (docker.io)Your distributionYour distribution's normal update channelapt verifies against the distribution's keysListed as an unofficial package to remove before installing Docker's
Convenience script (get.docker.com)DockerScript sets up the repo; you then upgrade with aptScript configures the repo; you must trust the script itselfTest and development only
Manual .deb filesDockerYou download and install each new versionNone at install time unless you check hashes yourselfFor hosts that cannot use the repo

The distro package is not malicious or abandoned. It is built and patched by the distribution on the distribution's schedule, and its package names and file layout differ from Docker's. The problem is mixing them: installing docker-ce on top of docker.io or a separate containerd creates conflicts, which is why Docker's first step removes them. Pick one source per host and stick with it.

When the convenience script is acceptable

The script at get.docker.com detects your distribution, configures the package manager and installs the latest stable Docker, containerd and runc without asking. Docker lists its limits: it needs root, allows little customisation, installs dependencies without confirmation, can pull in an unexpected major version, and is not designed to upgrade an existing install. Docker's advice is short: "Always examine scripts downloaded from the internet before running them locally."

On a throwaway VM or development box, download it to a file, read it, and preview it with the dry run flag rather than piping it into a shell:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh --dry-run
sudo sh get-docker.sh

Afterwards, upgrade with apt; Docker says re-running the script can cause problems. Never use test.docker.com on anything that matters, because it installs from the test channel, which includes betas and release candidates.

How to install Docker Desktop on Windows with WSL 2

Windows requirements

For the WSL 2 backend on x86_64, Docker requires WSL 2.1.5 or later; Windows 10 22H2 (build 19045) or Windows 11 23H2 (build 22631) or higher, in the Enterprise, Pro or Education editions; the LanmanServer service set to Automatic; and a 64-bit CPU with SLAT, 8 GB of RAM and virtualization enabled in BIOS or UEFI. Home editions run Linux containers only, Windows containers need Pro or Enterprise, and Docker supports only Windows versions still in Microsoft's servicing timeline. An Arm build is in Early Access.

Step 1: Install or update WSL

Open PowerShell as administrator and check your version:

wsl --version

If no version details appear, Docker says you are probably on the old inbox WSL, which must be updated:

wsl --install
wsl --update

Microsoft's WSL page says wsl --install needs Windows 10 version 2004 (build 19041) or later, or Windows 11. It enables the required features, installs Ubuntu by default, sets new distributions to WSL 2 and asks you to restart. wsl.exe --list --verbose shows which WSL version each distribution uses. If the Microsoft Store is blocked, Docker points to the MSI on the official WSL GitHub releases page.

Step 2: Download from Docker and verify

Download Docker Desktop Installer.exe from the button on Docker's Windows install page or from the Desktop release notes. Both point at desktop.docker.com. Docker also links an official Microsoft Store listing for x86_64. Then check the file before you run it; the verification section below has the exact commands.

Step 3: Install per user

Docker now recommends the per-user mode for most people. It installs to %LOCALAPPDATA%\Programs\DockerDesktop, writes registry keys under HKCU, and needs no administrator rights to install or update. Docker's own comparison table describes it as a smaller attack surface with no privileged system service. The interactive installer asks which mode you want. From a terminal:

# Per-user installation (no admin required)
Start-Process 'Docker Desktop Installer.exe' -Wait -ArgumentList 'install', '--user'

From Command Prompt:

start /w "" "Docker Desktop Installer.exe" install --user

Per-user mode supports the WSL 2 and Docker VMM backends but not Windows containers or Hyper-V. Enabling WSL 2 for the first time still needs administrator rights once per machine.

Step 4: Start Docker Desktop and accept the terms

Desktop does not start on its own after installation. Search for Docker Desktop in the Start menu, read the Subscription Service Agreement summary, and select Accept. Then open a terminal and run docker run hello-world.

All users installs and the docker-users group

Windows containers and the Hyper-V backend need an all-users install from an elevated prompt. It installs to C:\Program Files\Docker\Docker, adds the privileged com.docker.service, and needs administrator rights to update.

# All-users installation (run as administrator)
Start-Process 'Docker Desktop Installer.exe' -Wait install

When the administrator account differs from the daily user, Docker documents adding that user to docker-users:

net localgroup docker-users <user> /add

Docker warns that membership is "equivalent to granting administrative privileges on the host," and that Linux containers on WSL 2 do not need the group. Add only people who need Windows containers or Hyper-V management.

How to install Docker Desktop on a Mac (Apple silicon or Intel)

Mac requirements

Docker supports Desktop on the current macOS release and the two previous major releases, on Apple silicon and Intel, with at least 4 GB of RAM. Download the .dmg for your chip (Apple menu, About This Mac tells you which). On Apple silicon, Docker recommends Rosetta 2 for a few optional tools, though it is no longer strictly required:

softwareupdate --install-rosetta

Interactive install

  1. Quit tools that might call Docker in the background, such as VS Code, terminals and agent apps. An interrupted copy can leave a half copied app that Gatekeeper flags as damaged.
  2. Open Docker.dmg and drag Docker into Applications.
  3. Start Docker.app, read the agreement summary, and accept.

Current releases need no privileged access by default: CLI tools go to $HOME/.docker/bin, added to your PATH, and the default Docker socket is not created. You can change both under Settings, Advanced.

Command line install for managed Macs

sudo hdiutil attach Docker.dmg
sudo /Volumes/Docker/Docker.app/Contents/MacOS/install
sudo hdiutil detach /Volumes/Docker

The install command accepts flags such as --accept-license and --user=<username>, which performs privileged configuration once so the user is not prompted for root on first run. Docker says MDM managed fleets should use its PKG installer instead.

How to verify what you installed

Downloading from the right domain is the first control. Checking what arrived is the second. Docker's tooling gives you three anchors.

The apt repository signing key

The repository key at https://download.docker.com/linux/ubuntu/gpg (and the identical Debian key) identifies itself as "Docker Release (CE deb)", created 22 February 2017. When we downloaded it on 23 October 2026, the primary key fingerprint was:

9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88

You can print the fingerprint of the file you saved, without importing it into a keyring, with GnuPG's --show-keys command:

gpg --show-keys /etc/apt/keyrings/docker.asc

Compare the output against the value above and against any copy your organisation already trusts. Docker's current install page does not print the fingerprint, so if the two ever disagree, stop and investigate before running apt update. Once the key is in place, apt checks every package Docker publishes against it, and Signed-By keeps that trust scoped to Docker's repository.

Docker Desktop installer checksums

Each download link on Docker's release notes page has a checksum link beside it, pointing to a checksums.txt file in the same release folder on desktop.docker.com. For release 4.96.3 (22 October 2026), the Windows x86_64 file held one line: a SHA-256 hash followed by the installer's file name.

On Windows, Get-FileHash uses SHA256 by default:

Get-FileHash '.\Docker Desktop Installer.exe' -Algorithm SHA256

On macOS, use the system's shasum tool:

shasum -a 256 Docker.dmg

The hash must match checksums.txt for the same release and architecture. It will not catch a compromised download server, but it does catch corruption, the wrong architecture, and a file that came from somewhere else.

Signatures: Authenticode on Windows, Gatekeeper on macOS

Docker's install pages do not describe code signing, so treat this as a check you make with your operating system's tools. Docker's 4.82.0 release notes do say the updater verifies the Authenticode signature of a downloaded installer before running it. You can inspect that signature yourself:

Get-AuthenticodeSignature -FilePath '.\Docker Desktop Installer.exe'

Look for a Status of Valid and read the signer certificate. NotSigned or HashMismatch means do not run the file.

On a Mac, Gatekeeper checks downloaded apps for a Developer ID signature and, for notarized apps, Apple's statement that it "checked it for malicious software and none was detected." A warning that Docker.app comes from an unidentified developer is a red flag about where the file came from.

Verify the running install

After installing, confirm what you are actually talking to:

docker info
docker context ls

docker info prints client and server versions and security options; on a rootless daemon it lists rootless under Security Options. docker context ls shows which engine your CLI targets, which matters when Desktop and Engine coexist on Linux, because Desktop switches the current context to desktop-linux while it runs.

Post-install: the docker group is root equivalent

On Linux, the daemon listens on a Unix socket owned by root. Out of the box only root (or sudo) can talk to it. Docker's post-install page explains how to let a normal user run docker by adding them to the docker group, and it leads with a warning that the group grants root-level privileges to its members.

The reason is simple. Anyone who can ask the daemon to start a container can ask for a container that mounts the host's root filesystem, or runs privileged. The daemon will do it, as root. So docker group membership is equivalent to passwordless sudo on that machine, and malware running as your user inherits it.

Adding your user, if you accept the trade

On a single user development VM, the convenience is often worth it:

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world

If you ran Docker with sudo earlier and now see a permission denied warning about ~/.docker/config.json, Docker's fix is to delete ~/.docker/ or reset its ownership:

sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
sudo chmod g+rwx "$HOME/.docker" -R

Never add people to the docker group on a shared server. Use audited sudo rules or rootless mode instead.

Rootless mode, and when to use it

Rootless mode runs both the daemon and containers as a normal user inside a user namespace. Docker describes its purpose as "to mitigate potential vulnerabilities in the daemon and the container runtime." Unlike userns-remap, where the daemon still runs as root, nothing runs as root except the newuidmap and newgidmap helpers from the uidmap package. Your user needs at least 65,536 subordinate IDs in /etc/subuid and /etc/subgid.

If you want rootless only, disable the system daemon first:

sudo systemctl disable --now docker.service docker.socket
sudo rm /var/run/docker.sock

With Docker's packages installed, run the setup tool as your normal user, not with sudo. If it is missing, install docker-ce-rootless-extras:

sudo apt-get install -y docker-ce-rootless-extras
dockerd-rootless-setuptool.sh install

The tool creates a systemd user service and a rootless CLI context. To start the daemon at boot, enable the service and lingering:

systemctl --user enable docker
sudo loginctl enable-linger $(whoami)

Data lives in ~/.local/share/docker. Docker lists real limits: no AppArmor, checkpoint, overlay networks or SCTP port exposure; ports below 1024 need extra setup; docker run -p does not propagate source IPs by default; and resource limits need cgroup v2 with systemd.

Access modelWho can control the daemonEffective privilegeGood fit
Rootful daemon, sudo dockerUsers with sudoRoot, but every use is a logged sudo callShared servers, production hosts
Rootful daemon, docker groupEvery group memberRoot, without a password promptSingle user development VMs you control
Rootless daemonOnly the owning userThat user's privilegesLinux developer laptops, shared build hosts, CI where features allow
Docker DesktopThe desktop userThe Desktop VM, separated from the hostWindows and macOS workstations

Where do lookalike Docker downloads and images come from?

Popular developer tools attract imitations: search ads pointing to repackaged installers, "free download" sites that bundle adware, and old install scripts copied between blogs. The defence is boring and reliable.

  • Start at docs.docker.com and follow its download buttons. Desktop installers come from desktop.docker.com. Engine packages, the apt key and the repository live at download.docker.com. The convenience scripts are served from get.docker.com.
  • The only other Desktop source Docker's Windows page links is its Microsoft Store listing.
  • Do not download Desktop from a mirror, a "portable" build, or an older version someone re-hosted. Docker's release notes say versions older than six months are no longer available for download, which is a clue that any site still offering them is not Docker.
  • On managed fleets, distribute Docker from your own software catalogue after verifying it once.

Images are software downloads too

Installing Docker is the first download. Every docker pull after that is another one, and it runs code on your machine. Lookalike images follow the same pattern as lookalike installers: names that resemble a popular project, published by an account that is not the project. Prefer Docker Official Images, which Docker says are reviewed and published by a dedicated Docker-sponsored team working openly on GitHub, or images published by the upstream project itself. Pin images by digest in production so a tag cannot silently change under you.

One change to plan for: Docker is retiring Docker Content Trust for Docker Official Images and recommends planning a move to another signing and verification approach, naming Sigstore and Notation as examples. For more on building safer images, see our Docker image security checklist, the image security quick start, and why ADD with a remote URL needs a checksum.

How to keep Docker Engine and Docker Desktop patched

Docker Engine on Ubuntu and Debian

Engine patches arrive through apt. Docker's upgrade instruction is to repeat the install step:

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

If you pin versions, pick the new string from apt list --all-versions docker-ce. A package upgrade can restart the daemon and the containers it runs, so treat it as maintenance and test major versions on a staging host first. Hosts installed from .deb files never update themselves.

Docker Desktop on Windows and Mac

In Desktop's Software updates settings, Automatically check for updates is on by default and shows a notice in the Docker menu and Dashboard, while Always download updates is off by default. On 4.92 and earlier, a third switch updates components such as Compose and the CLI on their own. Turn on background downloads for individual machines, and use your device management tool for fleets. Docker notes that releases roll out gradually and usually reach everyone within a week.

Tracking Docker security advisories

Two pages carry Docker's security information:

  • Docker security announcements at docs.docker.com/security/security-announcements, which has an RSS feed. Each entry names the fixed version and the CVE.
  • Docker Desktop release notes, where each release has a Security heading when relevant.

Two recent entries show why this matters. On 20 August 2025, Docker Desktop 4.44.3 fixed CVE-2025-9074, where a malicious container could reach the Docker Engine and launch additional containers without the Docker socket being mounted, potentially exposing user files on the host. Docker's advisory notes that Enhanced Container Isolation did not mitigate it. On 22 October 2026, Desktop 4.96.3 removed trust for certificates issued by the compromised eMudhra intermediate CAs, which Docker says could otherwise have let an attacker with network access intercept TLS connections made by the Docker CLI and daemon. Our explainer on the eMudhra key compromise covers that incident.

In both cases the fix only protected people who installed the new release, so check versions rather than assuming auto-update worked.

How to uninstall Docker cleanly

Removing Docker Engine from Ubuntu and Debian

sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
sudo rm /etc/apt/sources.list.d/docker.sources
sudo rm /etc/apt/keyrings/docker.asc

The two rm -rf lines delete every image, container and volume. Back up named volumes you care about before running them. Docker notes that configuration files you edited, such as a custom daemon.json, must be removed by hand. Removing the source file and key matters: a stale key and repository entry left on a host is trust you no longer intend to grant.

If you used rootless mode, also remove the user's data under ~/.local/share/docker and the user service the setup tool created, following Docker's rootless documentation.

Docker Desktop on Windows

Docker warns that uninstalling Desktop destroys local containers, images, volumes and other Docker data, so back up first. Uninstall from Settings, Apps, or from the CLI by running the installer with uninstall:

Start-Process 'Docker Desktop Installer.exe' -Wait uninstall

The installer is in C:\Program Files\Docker\Docker\ for all-users installs and %LOCALAPPDATA%\Programs\DockerDesktop\ for per-user installs. Docker lists leftover locations you can remove afterwards:

C:\ProgramData\Docker
C:\ProgramData\DockerDesktop
C:\Program Files\Docker
C:\Users\<your user name>\AppData\Local\Docker
C:\Users\<your user name>\AppData\Roaming\Docker
C:\Users\<your user name>\AppData\Roaming\Docker Desktop
C:\Users\<your user name>\.docker

The WSL distributions you installed for your own use are separate from Docker Desktop and stay until you unregister them.

Docker Desktop on macOS

Use Troubleshoot, Uninstall in the Dashboard, or the CLI, then move Docker.app to the Trash:

/Applications/Docker.app/Contents/MacOS/uninstall
rm -rf ~/Library/Group\ Containers/group.com.docker
rm -rf ~/.docker

An "operation not permitted" error on ~/Library/Containers/com.docker.docker/ during uninstall is expected according to Docker. You can remove that folder later after granting your terminal Full Disk Access.

Docker Desktop on Ubuntu

sudo apt remove docker-desktop
rm -r $HOME/.docker/desktop
sudo rm /usr/local/bin/com.docker.cli
sudo apt purge docker-desktop

Then remove the credsStore and currentContext entries from $HOME/.docker/config.json, which Docker says can conflict with a future Docker setup.

Common Docker install errors and how to fix them

Permission denied on /var/run/docker.sock

Your user is not allowed to use the daemon socket, which is the secure default. Use sudo, set up rootless mode, or on a single user machine add yourself to the docker group and log in again.

"Cannot connect to the Docker daemon"

Docker's troubleshooting page says this means the daemon is not running, or your client is pointed at a different, unreachable host. Check in that order:

docker info
sudo systemctl is-active docker
sudo systemctl start docker

Then check the DOCKER_HOST environment variable and docker context ls. A leftover DOCKER_HOST from a rootless or remote setup, or a desktop-linux context after Docker Desktop on Linux has stopped, is a common cause.

WSL 2 is not installed or too old

Run wsl --version in an elevated PowerShell. No version output means the old inbox WSL, so run wsl --update; Docker needs 2.1.5 or later. wsl.exe --set-version <Distro> 2 converts a WSL 1 distribution, and wsl -l -v confirms.

Virtualization is disabled in BIOS

An "Unexpected WSL error" from Docker Desktop with a code ending in HCS_E_HYPERV_NOT_INSTALLED or ERROR_NOT_SUPPORTED usually means virtualization is off or WSL components are missing. Check the Performance tab in Task Manager, or run systeminfo. If virtualization is off, enable the vendor's option (often labelled VT-x) in BIOS or UEFI. If the hypervisor is installed but not launched at boot, Docker's fix is to run this as administrator and restart:

bcdedit /set hypervisorlaunchtype auto

Conflicts with old packages

Errors about files owned by another package mean a distro docker.io, containerd or runc is still installed. Run the removal command from Step 1, then install Docker's packages again. Keep only one Docker entry in /etc/apt/sources.list.d/.

"Docker.app is damaged and can't be opened"

Docker attributes this to another app calling the Docker CLI while you dragged Docker.app into Applications. Quit IDEs, terminals and agent apps, move /Applications/Docker.app to the Trash, empty it, re-mount the .dmg and reinstall.

Where Safeguard fits, honestly

Safeguard does not install Docker, check your apt keys, or inspect the Docker daemon or Desktop installation itself. Everything above works without it. The link is what happens next: once Docker is installed, you start pulling base images and building your own, and those images carry operating system packages and application dependencies with their own vulnerabilities. Safeguard scans the container images you build and run (for example safeguard scan --image <name> from the CLI, with results written as JSON under ./output), produces SBOMs for them, matches components against vulnerability databases, and shows which of your projects contain a given component and version. With autonomous remediation switched on, it can open fix pull requests that bump a base image or dependency. Gold Registry offers hardened base images where one fits your stack. For the scanning side in more depth, see how to scan Docker images for vulnerabilities and securing Docker containers.

Common mistakes

  • Pasting curl | sh from a random blog. Use Docker's apt repository on anything long lived, and if you use the convenience script, download it, read it and dry run it.
  • Mixing docker.io and docker-ce. One source per host. Remove the distro packages first.
  • Adding every developer to the docker group on a shared server. That hands each of them root. Use sudo rules or rootless mode.
  • Trusting ufw to protect published ports. Docker's own docs say published ports bypass ufw and firewalld rules.
  • Installing for all users, then adding everyone to docker-users. Per-user mode avoids a privileged service, and WSL 2 work does not need the group.
  • Skipping the checksum because the site looked right. Compare against checksums.txt from the release notes. It takes a few seconds.
  • Assuming auto-update happened. Check the version on each machine after an advisory, especially for fixes like CVE-2025-9074.

FAQ

How do I install Docker on Ubuntu 24.04?

Remove conflicting packages, add Docker's GPG key to /etc/apt/keyrings/docker.asc, create /etc/apt/sources.list.d/docker.sources pointing at https://download.docker.com/linux/ubuntu with your codename, run sudo apt update, then sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin. Confirm with sudo docker run hello-world. The same steps work on 22.04, 26.04 and 26.10.

Is Docker Desktop free?

For personal use, education, non-commercial open source and small businesses with fewer than 250 employees and less than $10 million in annual revenue, yes. Docker's terms say larger enterprises and government entities need a paid subscription. Docker Engine installed on Linux from Docker's repository is Apache 2.0 licensed and not covered by the Desktop agreement.

Do I need Docker Desktop on Linux?

No. On a Linux server, install Docker Engine. Desktop for Linux is an option if you want the graphical dashboard and its extra tools, but it runs a VM with its own desktop-linux context, and Docker recommends stopping Engine while you use Desktop to avoid port conflicts.

Should I install docker.io or docker-ce?

Pick one. docker-ce comes from Docker's repository and follows Docker's releases. docker.io is built by your distribution and updated through its channel. Docker's docs list docker.io among packages to remove before installing Docker's own, because the two conflict.

Is the get.docker.com script safe?

It is Docker's own open source script, but Docker says it is not recommended for production. It needs root, installs without asking, can jump major versions, and should not be used to upgrade. Download it, read it, run it with --dry-run first, and use it only on test or development machines.

How do I install Docker on Windows 11 Home?

Install or update WSL with wsl --install or wsl --update from an elevated PowerShell, then run the Docker Desktop installer in per-user mode. Windows 11 needs version 23H2 (build 22631) or later. Home editions run Linux containers only; Windows containers need Pro or Enterprise.

How do I run Docker without sudo?

Either add your user to the docker group with sudo usermod -aG docker $USER and log out and back in, accepting that the group is root equivalent, or set up rootless mode with dockerd-rootless-setuptool.sh install. Rootless is the safer choice when it supports the features you need.

Can I install Docker on Raspberry Pi or ARM?

Yes, on a supported OS. Docker's Ubuntu packages cover arm64 and armhf, and its Debian packages cover arm64 and armhf (arm/v7), so a board running a supported Ubuntu or Debian release follows the same apt repository steps. Check the supported versions list on Docker's page for your exact OS first.

Fix it without waiting for upstream

Installing Docker is where your container supply chain starts. Every base image and dependency you pull afterwards can carry a known vulnerability, and the question becomes how quickly the fix reaches the images you ship.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

None of these demos install Docker. They show what happens after it is installed, when the images you build start pulling in packages and dependencies. To try the CLI yourself, download it from https://safeguard.sh/download and follow the setup guide at https://docs.safeguard.sh/docs/cli .

The first demo is a real CLI session. After install, safeguard opens the interactive terminal, you ask it to fix the lodash CVE in a repo, and it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. The same approval flow applies when the vulnerable component sits in an application you are about to package into a Docker image.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with its device code, and then scans from the terminal. On a workstation where you have just installed Docker, that is how you would scan local projects and images without sending source code elsewhere; our post on how the local runner and offline mode work has the details.

Click through it at your own pace, or open it full screen.

The third demo shows the desktop app sending work to a computer running the CLI, with each command approved before it runs. If you are rolling Docker out across a team, it keeps a person in charge of every command that touches a build machine.

Click through it at your own pace, or open it full screen.

Quick check

Why is adding your user to the docker group a security decision, not just a convenience?

Because anyone who can talk to the Docker daemon can start a container that mounts the host filesystem or runs privileged, and the daemon does it as root. Docker's post-install page warns that the group grants root-level privileges. Rootless mode avoids that trade off.

What two things should you check before running a Docker Desktop installer?

That it came from desktop.docker.com (or Docker's linked Microsoft Store listing), and that its SHA-256 hash matches the checksums.txt linked beside that download in Docker's release notes. On Windows you can also confirm the Authenticode signature status is Valid.

Sources

Last reviewed: 23 October 2026. Supported OS versions, installer flags and licence terms change between Docker releases; check the linked Docker pages before you install.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.