Step by step notes for installing Docker under macOS via Canonical's Multipass.
- Docker Engine (daemon).
dockerCLI tool within the guest VM (technically not needed, but handy if working inside VM).- Installed
dockeranddocker-composeCLI tools (with Bash completion) on the macOS host.
Install Multipass for macOS (obviously).
Next, launch a new Multipass virtual machine.
Note
Setting desired Multipass virtual machine name in MACHINE_NAME environment variable, used in all following command examples.
$ MACHINE_NAME="my-docker"
$ PATH_TO_PROJECTS="/path/to/projects"
$ multipass launch \
--cloud-init ./cloud-init-docker.yaml \
--name $MACHINE_NAME \
26.04
$ multipass stop $MACHINE_NAME
$ multipass mount --type native \
$PATH_TO_PROJECTS $MACHINE_NAME
$ multipass start $MACHINE_NAME
$ multipass info $MACHINE_NAME
# Name: MACHINE_NAME
# State: Running
# Snapshots: 0
# IPv4: --
# Release: Ubuntu 26.04 LTS
# Image hash: 9daa955c3d4c (Ubuntu 26.04 LTS)
# CPU(s): --
# Load: --
# Disk usage: --
# Memory usage: --
# Mounts: /path/to/projects => /home/ubuntu/projectsBreaking this down:
- Create Ubuntu
26.04based virtual machine. - Configure VM using
cloud-init-docker.yaml- which will install and configure Docker dependencies. - Stop the instance in order to create a mount to (
path/to/projects) within the VM guest back to the macOS host. This is important forDockerfileoperations such asADD- ensuring Docker Engine within the VM guest can successfully map files stored within the macOS host filesystem.- Note: using
multipass mount --type nativeto create a native QEMU host mount, rather than the (slower) default of SSHFS.
- Note: using
Overview of tasks performed by cloud-init-docker.yaml:
- The
avahi-daemonprovides a well-known hostname to the Multipass VM via mDNS/Bonjour from the host (e.g. your macOS). - A series of
runcmdcommands to install required Docker Engine packages. - An addition of a
/etc/systemd/system/docker.service.d/httpapi.confsystemd unit drop-in, which starts the/usr/bin/dockerddaemon with the HTTP API listening on all networks.
Next, install docker and docker-compose CLI tools to the macOS host via cli-install.sh.
Note: script requires jq to be installed:
$ ./cli-install.sh
# Docker version 28.3.2, build 578ccf6
# Docker Compose version v2.38.2Finally, configure a DOCKER_HOST environment variable, allowing the docker CLI to locate Docker Engine running within the Multipass Ubuntu VM:
# first, ping VM to confirm it can be found from host
$ dns-sd -Gv4 "$MACHINE_NAME.local"
$ export DOCKER_HOST="tcp://$MACHINE_NAME.local:2375"
$ docker version
# Client:
# Version: 29.4.1
# API version: 1.54
# etc.
#
# Server: Docker Engine - Community
# Engine:
# Version: 29.4.1
# API version: 1.54 (minimum version 1.40)
# etc.Once proven working, DOCKER_HOST can be added to Dotfiles / ~/.bash_profile / etc.
Done!
Multipass has the concept of a primary instance, which is automatically used for commands such as start and shell. This behaviour can be somewhat undesirable - where it is preferred to use defined machine names against all multipass commands.
The primary instance mode can be disabled by setting an empty client.primary-name value:
$ multipass set client.primary-name=the enablement of this mode can now be confirmed:
$ multipass start
Name argument or --all is required
Note: the primary instance is disabled.
$ multipass shell
The primary instance is disabled, please provide an instance name.If the Multipass service ever falls away, such as with the following message:
$ multipass list
list failed: cannot connect to the multipass socketit can be restarted via the following commands:
$ sudo launchctl unload /Library/LaunchDaemons/com.canonical.multipassd.plist
$ sudo launchctl load -w /Library/LaunchDaemons/com.canonical.multipassd.plist