Brew install Docker on a Mac and know where its files sit
brew install docker finishes in a few seconds. docker --version prints a version number. docker ps then fails, saying it cannot connect to the Docker daemon. Nothing went wrong and nothing needs repairing. That command installed the client and only the client, and on a Mac there is no engine for it to talk to until something else provides one.
The confusion is structural rather than accidental. Two different packages answer to the word docker in Homebrew, they install completely different things, and the one that most instructions on the internet name is not the one that runs containers. Sorting that out first, and then knowing which paths the install writes to, turns Docker on a Mac from a black box into something that can be sized, moved and removed on purpose.
What the docker formula actually contains
The formula named docker in Homebrew's core tap is built from the source repository github.com/docker/cli. Its build step compiles exactly one target, github.com/docker/cli/cmd/docker, and then generates shell completions for bash, zsh, fish and PowerShell. The current stable version is 29.8.1 and the licence is Apache-2.0. There is no daemon in it, no virtual machine, and no container runtime.
The formula itself says so, in a way that is easy to miss. It carries a caveat, but the caveat is wrapped in a Linux only block: on Linux it prints a note that the daemon component is provided in a separate formula, brew install docker-engine. On a Mac that message never appears, because docker-engine declares a Linux requirement and is not installable on macOS at all. So the one place the packaging tells the truth about the missing engine is the one platform where the advice is not needed.
The client lands in the Homebrew prefix, which is /opt/homebrew/bin/docker on Apple silicon and /usr/local/bin/docker on Intel, following Homebrew's documented default prefixes of /opt/homebrew for macOS on Apple silicon and /usr/local for macOS on Intel.
Why there is no warning about the cask
Homebrew also has a cask called docker-desktop, and that cask records docker as an old token, because it was renamed. When a name exists as both a formula and a cask, Homebrew's argument resolution tries the formula first and, on success, normally prints a warning that a cask of the same name also exists. The resolution code then makes one exception: the warning is suppressed when the requested name is one of the conflicting cask's old tokens.
docker is exactly that case. The result is that brew install docker installs a client with no engine, and says nothing at all about the package that would have provided one. The silence is a rule firing correctly, not an oversight to work around. The reliable habit is to write --formula or --cask on every install, so the intent is in the command rather than in the resolution order.
Three ways to get an engine, compared
A Mac cannot run Linux containers directly. Something has to provide a Linux virtual machine and a daemon inside it. There are three practical answers, and the choice is mostly about licensing and about how much of the machine is handed over.
| Approach | What to install | Engine runs in | Notes |
|---|---|---|---|
| Docker Desktop | brew install --cask docker-desktop |
A VM managed by the app | Paid subscription above the free tier thresholds |
| Colima | brew install colima plus brew install docker |
A Lima VM started from the terminal | MIT licence, 2 CPUs and 2 GiB by default |
| Remote engine | brew install docker only |
Another machine | Client points at a remote daemon through a context |
The third row is worth naming because it is often overlooked. The client installed by the formula is a complete client. Pointed at a daemon somewhere else through a Docker context, it needs no local virtual machine at all, which suits a laptop that already has a build server or a development host available to it.
Docker Desktop through Homebrew, and what it costs
brew install --cask docker-desktop installs the application. The cask's current version is 4.92.0, it declares auto_updates true, it requires macOS 14 or newer, and it conflicts with the rancher cask. Because docker is registered as an old token of this cask, brew install --cask docker still resolves to it, which is why instructions written years apart can both appear to work.
The licensing is the part to settle before installing rather than after. Docker's own documentation states that Docker Desktop is free for small businesses, defined as fewer than 250 employees and less than 10 million US dollars in annual revenue, as well as for personal use, education and non-commercial open source projects, and that it requires a paid subscription for professional use in larger organisations, for government entities and for commercial use beyond the free tier. The same page puts the threshold the other way round at the top: commercial use in larger enterprises, meaning more than 250 employees or more than 10 million US dollars in annual revenue, requires a paid subscription.
The system requirements are short. A supported version of macOS, which Docker defines as the current release and the two previous major releases, and at least 4 GB of RAM. Rosetta 2 is recommended for the best experience but is no longer strictly required, with a few optional command line tools still needing it. Current versions run the Linux VM on the Apple Virtualization framework by default; HyperKit is retained in the documentation only as historical context for older configurations.
One consequence of auto_updates true is that brew upgrade will not necessarily touch the application. Homebrew compares the installed bundle's version metadata against the cask and skips the upgrade when the installed application looks the same version or newer, because an application that updated itself would otherwise be downgraded. Including it anyway means naming it explicitly or passing --greedy.
Where every file sits after a Desktop install
This is the part worth writing down, because the answer is spread across five different places and only one of them is in the Applications folder.
The application installs at /Applications/Docker.app, and the command line tools ship inside it, at /Applications/Docker.app/Contents/Resources/bin. What varies is where the symlinks to them go. Docker's documentation describes two options: the user setting installs the CLI tools to $HOME/.docker/bin, which is the default from version 4.89.0 onwards and is automatically added to the shell PATH, and the system setting installs them to /usr/local/bin, which requires a password from 4.89.0 onwards.
Homebrew's cask definition shows the same thing from the other side. It links a specific set of binaries into /usr/local/bin, including docker, docker-credential-osxkeychain, docker-credential-ecr-login, docker-credential-desktop and kubectl.docker, plus docker-compose into /usr/local/cli-plugins, and it installs bash, zsh and fish completions into the Homebrew prefix.
The socket is not where most documentation assumes. Docker Desktop's real socket is at ~/.docker/run/docker.sock. The familiar /var/run/docker.sock is an optional symlink, created by a startup task with ln -s -f when the corresponding setting is enabled, so that clients hard coded to the default path keep working. Privileged work goes through a helper installed at /Library/PrivilegedHelperTools/com.docker.socket and /Library/PrivilegedHelperTools/com.docker.vmnetd, which the application talks to over the Unix domain socket /var/run/com.docker.vmnetd.sock for things like binding ports below 1024.
Containers and images are not in /var/lib/docker the way they are on Linux. Docker Desktop stores them in a single large disk image file, whose location the documentation says to read from Settings, then Resources, then Advanced. In practice that file lives under the application's container directory, which is why Homebrew's zap list for this cask names ~/Library/Containers/com.docker.docker among the paths it removes. Docker's own instructions for measuring it are concrete:
cd ~/Library/Containers/com.docker.docker/Data/vms/0/data
ls -klsh Docker.raw
The reason the documentation gives that command rather than pointing at Finder is that many tools report the maximum size of the disk image rather than the space it is actually using. A Docker.raw that reads as 64 GB may be occupying a couple of gigabytes. The example in Docker's FAQ shows exactly that: an actual size of 2,333,548 KB against a maximum of 64 GB.
The rest of the user library is enumerated by Homebrew's zap list, which is the most complete inventory available without reverse engineering the installer: ~/.docker, ~/Library/Application Support/Docker Desktop, ~/Library/Group Containers/group.com.docker, ~/Library/Caches/com.docker.docker, ~/Library/Caches/Docker Desktop, ~/Library/Logs/Docker Desktop, ~/Library/Preferences/com.docker.docker.plist and the saved application state for the Electron front end. Reading those directory sizes next to each other is the fastest way to find out what is actually consuming the disk, and a file manager with a built-in terminal shows the sizes and takes the follow up command in the same window.
Two cautions come straight from the documentation. Do not move the disk image file in Finder, because Docker Desktop loses track of it; use the Disk image location control in Settings instead. And reducing the maximum size of the disk image deletes the current file, which means all containers and images are lost.
Colima, for an engine that does not need a subscription
brew install colima installs Colima, currently 0.10.3, under the MIT licence, with lima as its only dependency. Colima's own documentation is explicit about the division of labour: the Docker client is required for the Docker runtime, and is installable with brew install docker. So the formula that looked useless on its own is exactly the right half of this pairing.
After colima start, the documentation states that the docker client works on macOS with no additional setup. The default virtual machine has 2 CPUs, 2 GiB of memory and 100 GiB of storage, which is adjustable with --cpu, --memory and --disk at start time or by editing the configuration with colima start --edit.
Colima is not limited to Docker. colima start --runtime containerd sets up containerd, with colima nerdctl for interacting with it, and from version 0.7.0 there is an Incus runtime as well. From version 0.10.0, on Apple silicon and macOS 13 or newer, --vm-type krunkit is available.
Compose needs one extra step in this setup, and the formula says what it is. docker-compose, currently 5.5.1, is a Docker plugin rather than a standalone binary, and its caveat asks for cliPluginsExtraDirs to be added to ~/.docker/config.json pointing at $HOMEBREW_PREFIX/lib/docker/cli-plugins so the client can find it. Skipping that step produces a client that reports no compose command while the plugin sits installed on disk.
Reclaiming the disk, and removing the lot
Space inside the virtual machine and space on the host are two different numbers, and only the first responds to the usual commands. docker system df -v reports detailed usage, docker image ls and docker container ls -a list what exists, and docker system prune removes stopped containers, unused networks, dangling images and build cache.
How quickly the host gets that space back depends on the disk image format. Docker's documentation states that with a file named Docker.raw the space is reclaimed within a few seconds, while with Docker.qcow2 it is freed by a background process after a few minutes. Either way, space is only freed when images are deleted, and never automatically when files are deleted inside a running container. To force the issue at any point, the documented command is docker run --privileged --pid=host docker/desktop-reclaim-space.
Removing Docker Desktop through Homebrew does more than delete the application. The cask's uninstall stanza unloads the com.docker.helper, com.docker.socket and com.docker.vmnetd launch services, quits the application and its Electron front end, deletes the two privileged helper tools from /Library/PrivilegedHelperTools, and removes ~/.docker/bin. What it does not remove is the data, including the disk image, which is what brew uninstall --cask --zap docker-desktop is for. Zap is also documented as capable of removing files shared between applications, so it belongs to a permanent removal rather than a reinstall.
What to change first
Decide which engine the machine is allowed to run before installing anything, because the answer is a licensing question rather than a technical one, and then install the matching pair explicitly with --formula or --cask rather than trusting a bare name. Once it is running, measure the disk image with ls -klsh rather than Finder, and keep the Settings control as the only way the file ever moves. Reading those library folders and firing the follow up command from the same place is the working shape Atriens is built for.
Frequently asked questions
Why does `docker ps` fail after `brew install docker` succeeds?
Because the formula named docker builds only the command line client from github.com/docker/cli, with no daemon and no virtual machine. On a Mac there is nothing for the client to connect to until Docker Desktop, Colima or a remote context provides an engine. The formula's note about the separate docker-engine package only prints on Linux, where that package can actually be installed.
What is the difference between `brew install docker` and `brew install --cask docker-desktop`?
The first installs the client only. The second installs the Docker Desktop application, which brings a Linux virtual machine, the daemon and its own copies of the CLI tools. The cask also records docker as an old token, so brew install --cask docker resolves to the same thing, which is why older instructions still appear to work.
Is Docker Desktop free to use at work?
Docker's documentation states that it is free for small businesses with fewer than 250 employees and less than 10 million US dollars in annual revenue, as well as for personal use, education and non-commercial open source projects. Above those thresholds, and for government entities, a paid subscription is required. Docker Pro, Team and Business subscriptions include commercial use.
Where are Docker images and containers stored on a Mac?
In a single large disk image file rather than in /var/lib/docker. The location is shown in Settings, under Resources and then Advanced, and it sits inside the application's container directory, which is why Homebrew's zap list for the cask includes ~/Library/Containers/com.docker.docker. Check the real size with ls -klsh Docker.raw from ~/Library/Containers/com.docker.docker/Data/vms/0/data, because most tools report the maximum size instead.
Why does the Docker disk image look enormous in Finder?
The file is created at its maximum size and fills in as it is used, and Docker's documentation warns that many tools report that maximum rather than the actual usage. The ls -klsh output gives both numbers at once. Reducing the maximum through Settings deletes the current disk image and everything in it, so it is not a way to free space without losing containers.
Can Docker be run on a Mac without Docker Desktop?
Yes. Colima installs from Homebrew, depends only on Lima, and is MIT licensed; its documentation says the Docker client from brew install docker is required and that after colima start the client works with no further setup. The default virtual machine has 2 CPUs, 2 GiB of memory and 100 GiB of storage. Compose needs cliPluginsExtraDirs added to ~/.docker/config.json so the plugin is found.