Okay, if you are reading this, you probably already know that Docker (and not just Docker Desktop) on a MacOS can be awfully slow, especially for developers when the container is accessing files on the local drive via a volume mount. For the most part, this has not really been noticeable with the applications I develop against and so I have been happy to use the defaults. More recently though I have been working on a PHP application and due to its nature it required that "nearly" the whole development space needed to be mapped to a volume and the impact was very apparent even when using the gRPC FUSE option.
Using a fairly standard delegated mapping like the one below, we found that the average time to open our home page locally was ~600ms (with the gRPC fuse setting)
Though not the simplest page it wasn't the most complex we have to deal with, can we do better?
Using NFS Mounts
Now a common approach to addressing this issue has been to use an NFS mount instead, setting it up is quite complicated but thankfully it is well documented and scripts are readily available for us to use.
Switching to the above config for mounting the file system and running the same home page test reduced our average load time to ~290ms. This is a pretty good improvement but can we do better?
Mutagen is a file synchronization utility that can be used with containers and more recently, with the beta version at least, it can be configured using
Installing is quite easy, though it may take some time; there may be a faster approach but I just followed the hints from homebrew.
brew install mutagen-io/mutagen/mutagen-compose-beta
mutagen daemon start
Since we are using the beta we can define the mounts in our
Note: the permissions section was required as mutagen applies the default permissions of 0600 and 0700 for files and directories respectively however I require the permissions to be 0644 and 0755 so that I could launch the web application (nginx).
Finally, we need to use
mutagen-compose instead of
docker-compose on the command line (or in scripts). It takes a little longer to start due to the initial build of the docker volume; this can be tweaked by being more selective on what files need to be synchronized between the host and the docker volume.
Running the same test again, against the home page, we managed to reduce the average load time to ~160ms.
All of the above tests were done for a developer build, performance is much better for production builds which are hosted in the cloud.
load time (ms)
It seems that mutagen is definitely a candidate to mitigate some of the performance issues encountered with Docker on the MacOS and should be considered alongside other utilities like docker-sync (requires ruby) and docker-bg-sync.
As always, I hope you find this useful and your feedback is appreciated.