This lesson covers the platform details that differ between Windows, macOS and Linux and that cause most first-week problems. After it you will be able to choose between Docker Desktop and Docker Engine, configure the WSL 2 backend on Windows, fix the classic "permission denied" error on Linux, and tune Docker Desktop's resource settings.
Containers need a Linux kernel. On Linux, Docker Engine runs natively as a system service. On Windows and macOS, Docker Desktop starts a small Linux virtual machine, runs the daemon inside it, and forwards the docker CLI, ports and files to that VM so the experience feels native.
| | Docker Engine | Docker Desktop | |---|---|---| | Platforms | Linux only | Windows, macOS, Linux | | Includes | daemon, CLI, Compose and Buildx plugins | Engine plus GUI dashboard, Kubernetes, extensions | | Runs as | systemd service | Application with an embedded VM | | Licence | Free (Apache 2.0) | Free for personal use and small businesses; paid for larger organizations |
For servers and CI runners, install Docker Engine. For a developer laptop on Windows or macOS, install Docker Desktop.
Docker Desktop on Windows uses the Windows Subsystem for Linux 2 as its backend. WSL 2 provides a real Linux kernel, which is faster and more compatible than the older Hyper-V backend.
# Run in an elevated PowerShell, then reboot
wsl --install
wsl --set-default-version 2
wsl --updateAfter installing Docker Desktop, open Settings > Resources > WSL integration and enable your distribution (for example Ubuntu). The docker command then works from both PowerShell and the WSL shell, and both talk to the same daemon.
Two performance rules matter on Windows:
\\wsl$\Ubuntu\home\you\project), not on C:\. Bind mounts across the Windows-to-Linux boundary are dramatically slower and break file watchers.Desktop can also switch to Windows containers from the tray menu, but this course, like most real-world work, uses Linux containers.
On Apple silicon (M-series) the Desktop VM is arm64, so images are pulled as linux/arm64 by default. Most official images publish multi-architecture manifests, so this is transparent. When an image only exists for amd64, request it explicitly and Docker emulates it with Rosetta or QEMU:
docker run --platform linux/amd64 --rm some/amd64-only-imageEmulated containers are slower; prefer native arm64 images when they exist. File sharing uses VirtioFS, the fastest option for bind mounts on macOS.
The sample code at the top installs Docker Engine from Docker's own apt repository on Ubuntu or Debian, which stays current, unlike the distribution's docker.io package. Fedora and RHEL use dnf with the equivalent repository. After installation:
sudo systemctl enable --now docker # start on boot
docker ps
# permission denied while trying to connect to the Docker daemon socketThat error means your user cannot access /var/run/docker.sock, which is owned by root:docker. Add yourself to the docker group and start a new login session (or run newgrp docker). Membership in this group is equivalent to root, so grant it deliberately. If you prefer not to, rootless mode (dockerd-rootless-setuptool.sh install) runs the daemon as your own user, with minor limitations such as no ports below 1024 by default.
In the Desktop dashboard, Settings > Resources sets CPU, memory and disk for the VM (on Windows with WSL 2, memory is governed by a .wslconfig file in your user profile instead). Docker Engine exposes daemon.json for options such as the default logging driver, and Kubernetes enables a one-click single-node cluster you will use in the orchestration lesson. Verify everything from a terminal:
docker context ls # desktop-linux should be marked with *
docker run --rm hello-world
docker compose versionsystemctl status docker.docker works in PowerShell but not in Ubuntu: enable that distribution under WSL integration.exec format error: the image architecture does not match the machine; add --platform.Why does Docker Desktop on Windows and macOS need a virtual machine?
arm64 images by default; use --platform linux/amd64 only when necessary.docker group or use rootless mode, and enable the service with systemd.docker context ls, docker run hello-world and docker compose version confirm a healthy setup.Next lesson: Images vs Containers — understand the difference between the template and the running instance.