Installing Docker
Which Docker to install on Windows, macOS or Linux, whether Docker Desktop's licence applies to you, and the three failures that hit almost everyone.
Installing Docker is usually ten minutes of clicking. The parts worth reading first are which Docker you should install, whether your employer needs to pay for it, and the three things that go wrong on nearly every machine.
Pick your platform for the step-by-step:
- Install Docker on Windows: Docker Desktop with the WSL 2 backend
- Install Docker on macOS: Intel and Apple Silicon
- Install Docker on Linux: Docker Engine from the official repository
Docker Desktop is not the only option
"Installing Docker" means different things on different systems, and the distinction matters both technically and commercially.
Docker Engine is the daemon that actually builds and runs containers. It is open source, runs natively on Linux, and is all a server needs.
Docker Desktop bundles that engine with a Linux virtual machine, a GUI, Docker Compose, a Kubernetes cluster and an update mechanism. On Windows and macOS it is effectively required, because containers are a Linux kernel feature and those systems need a Linux VM to provide one.
| Windows | macOS | Linux | |
|---|---|---|---|
| Runs containers natively | No (VM via WSL 2) | No (lightweight VM) | Yes |
| Usual choice | Docker Desktop | Docker Desktop | Docker Engine |
| GUI included | Yes | Yes | Optional |
| Licence may apply | Yes | Yes | No |
The licensing question
This catches teams out, so it is worth stating plainly. Docker Desktop requires a paid subscription for commercial use in organisations above a size threshold, at the time of writing, more than 250 employees or more than $10 million in annual revenue. Below that, and for personal use, education and open source, it remains free.
Docker Engine itself is Apache 2.0 licensed and free in all cases. The licence attaches to the Desktop product, not to containers or the engine.
If the subscription is a problem, the common alternatives are:
Most of these expose a Docker-compatible socket, so docker commands, Compose files and Testcontainers generally work unchanged.
Requirements
Windows: Windows 10 or 11, 64-bit, build 19041 or later. WSL 2 enabled. Hardware virtualisation enabled in BIOS or UEFI. 4 GB RAM minimum, 8 GB realistic.
macOS: macOS 12 or newer. Intel or Apple Silicon; the installer differs, so download the right one. 4 GB RAM minimum.
Linux: a 64-bit distribution with a reasonably current kernel. 2 GB RAM. You need sudo for the install and for the post-install group change.
Verify the installation
Three commands, in order. Each one rules out a different failure.
docker --version
Docker version 27.3.1, build ce12230
That only proves the CLI is on your PATH. The next one proves the daemon is running and reachable:
docker info --format '{{.ServerVersion}} {{.OperatingSystem}}'
27.3.1 Docker Desktop
Then confirm it can actually pull and run something:
docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
That single command exercises the registry connection, the image store, the container runtime and networking. If it works, your installation is sound.
Compose ships with current Docker as a plugin. Note it is docker compose, two words, not the old docker-compose binary:
docker compose version
Docker Compose version v2.29.7
The three failures almost everyone hits
1. "permission denied" on the socket (Linux)
permission denied while trying to connect to the Docker daemon socket at
unix:///var/run/docker.sock
The daemon socket is owned by root. Rather than prefixing every command with sudo, add yourself to the docker group:
sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world
newgrp applies the change to the current shell; otherwise log out and back in. Group membership is read at login, which is why "I already ran usermod" and "it still fails" are both true at the same time.
Be aware of what this grants: the docker group is effectively root on the host, since anyone in it can mount the host filesystem into a privileged container. On a shared machine, consider rootless mode instead.
2. "Cannot connect to the Docker daemon"
Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
Is the docker daemon running?
The CLI works and nothing is listening. On Linux the service is not started:
sudo systemctl status docker
sudo systemctl enable --now docker
On Windows or macOS, Docker Desktop is not running. Launch it and wait for the whale icon to stop animating. The CLI is installed by the same package, so it is available long before the VM has booted.
3. Virtualisation disabled (Windows)
Docker Desktop requires the Server service to be enabled
Hardware assisted virtualization and data execution protection must be
enabled in the BIOS
Check whether Windows can see it:
systeminfo | findstr /C:"Virtualization"
If it reports No, enable Intel VT-x or AMD-V in your BIOS or UEFI, often labelled SVM Mode on AMD boards. Then confirm WSL 2 is present and current:
wsl --install
wsl --set-default-version 2
wsl --status
After it works
Two settings worth changing straight away on Docker Desktop.
Resource limits. Desktop's VM claims a fixed slice of CPU and memory. The defaults are conservative for real builds and generous if you only run the occasional container. Adjust under Settings → Resources.
Disk reclamation. Images, build cache and dangling volumes accumulate quickly, and the VM's disk does not shrink on its own:
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 47 3 18.2GB 14.6GB (80%)
Build Cache 312 0 9.1GB 9.1GB
docker system prune -a --volumes
That removes every stopped container, unused image, unused network and unused volume. It is safe in the sense that running containers are untouched, and destructive in the sense that --volumes deletes data you have not explicitly kept. Read the confirmation prompt.
Key takeaways
- Docker Engine and Docker Desktop are different products. The engine is free everywhere; the licence applies to Desktop.
- Desktop needs a paid subscription above roughly 250 employees or $10M revenue. Free below that, and for personal, education and open source use.
- Linux runs containers natively. Windows and macOS run a Linux VM underneath, which is why Desktop exists.
docker run --rm hello-worldexercises registry, storage, runtime and networking in one command.permission deniedon Linux means add yourself to thedockergroup, and that group is effectively root.- "Cannot connect to the daemon" means the CLI is fine and nothing is listening. Start the service or the Desktop app.
- Run
docker system dfoccasionally. Reclaimable space reaching double-digit gigabytes is normal and unprompted.
Check your understanding
Permission denied that survives usermod
On Ubuntu, docker run fails with "permission denied ... /var/run/docker.sock". You run sudo usermod -aG docker $USER and try again in the same terminal. It still fails. Why?
Frequently Asked Questions
Is Docker Desktop free for commercial use?
Only below a size threshold. Docker Desktop requires a paid subscription for business use in organisations with more than 250 employees or more than $10 million in annual revenue; it stays free for personal use, education, non-commercial open source and smaller companies. Docker Engine, the daemon that builds and runs containers, is Apache 2.0 licensed and free in every case, which is why Linux servers and CI runners are unaffected. If the subscription is a blocker on developer machines, Podman, Colima and Rancher Desktop all expose a Docker-compatible interface.
What is the difference between Docker Desktop and Docker Engine?
Docker Engine is the daemon plus CLI that does the actual work, and on Linux it runs containers directly against the host kernel. Docker Desktop is a packaged product that bundles that engine with a Linux virtual machine, a GUI, Compose, an optional Kubernetes cluster and automatic updates. On Windows and macOS the VM is not optional, containers are a Linux kernel feature, which is why Desktop or an equivalent is required there and merely convenient on Linux.
How do I fix "permission denied" on /var/run/docker.sock?
Add your user to the docker group with sudo usermod -aG docker $USER, then run newgrp docker or log out and back in. The change will not affect an already-open shell, because supplementary groups are read at login, which is why it often appears not to have worked. Understand the trade: anyone in the docker group can mount the host filesystem into a privileged container, so it is equivalent to root access on that machine. On shared systems, rootless mode is the safer arrangement.
How do I know Docker installed correctly?
Run three commands. docker --version proves the CLI is on your PATH. docker info proves the daemon is running and the CLI can reach it. docker run --rm hello-world proves the whole path works. Registry authentication, image pull, storage, container runtime and networking, and prints a confirmation message. If the first two succeed and the third fails, the problem is connectivity or registry access rather than the installation.
Why does Docker say "Cannot connect to the Docker daemon"?
The CLI is installed and nothing is listening on the socket, which is a different problem from Docker being missing. On Linux, start the service with sudo systemctl enable --now docker. On Windows or macOS, Docker Desktop is not running or is still starting. The CLI ships with the same installer and works long before the VM has finished booting, so this appears often right after installing. Check the whale icon has stopped animating before retrying.
Do I need WSL 2 to run Docker on Windows?
In practice yes. Docker Desktop's WSL 2 backend is the supported and far faster option; the older Hyper-V backend is deprecated. Run wsl --install then wsl --set-default-version 2, and make sure hardware virtualisation is enabled in the BIOS, systeminfo | findstr /C:"Virtualization" tells you whether Windows can see it. Containers then run inside a managed Linux distribution, with bind mounts noticeably faster when your project lives on the WSL filesystem rather than under /mnt/c.