4 Aug 2021
Hello! Today I would like to share my experience of improving Docker performance on macOS with Mutagen.
Docker on macOS has performance issues by default. It's related to mounting volumes and osxfs file system. It seriously affects applications with many I/O operations. So, a Symfony-based web application can handle a request for a few seconds.
There are several options for using Docker on macOS.
In this post, I'm going to describe Mutagen configuration. Mutagen provides files synchronization in real-time.
Firstly need to install Mutagen on macOS and start service:
brew install mutagen-io/mutagen/mutagen
mutagen daemon start
As a demo project, I used placeholder-service - a service for generating images placeholders.
Then need to create an additional docker-compose file for Mutagen: docker-compose-osx.yml
.
As soon as we have a separate config, Mutagen doesn't affect docker for Linux.
version: '3'
services:
php-fpm:
container_name: placeholder-service_php_fpm_1
volumes:
- placeholder-service-www:/var/www
nginx:
volumes:
- placeholder-service-www:/var/www
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/sites/:/etc/nginx/sites-available
- ./docker/nginx/conf.d/:/etc/nginx/conf.d
- ./docker/logs:/var/log
volumes:
placeholder-service-www:
There is a named volume: placeholder-service-www
.
There is also unique name placeholder-service_php_fpm_1
for php-fpm
container.
After that need to create mutagen.yml
configuration file.
sync:
defaults:
mode: "two-way-resolved"
flushOnCreate: true
ignore:
vcs: true
configurationBeta:
permissions:
defaultFileMode: 0666
defaultDirectoryMode: 0666
placeholder-service-www:
alpha: "./"
beta: "docker://placeholder-service_php_fpm_1/var/www"
ignore:
paths:
- ".idea"
- "var"
- "vendor"
# Set up the service and any volumes before creating sessions.
beforeCreate:
- docker-compose -f docker-compose.yml -f docker-compose-osx.yml up --build --detach
# Set up the main services after creating sessions. At this point, sessions will
# have been established and code pushed to the shared volume.
# After this is done, we can start up the deployment scripts.
afterCreate:
- docker-compose -f docker-compose.yml -f docker-compose-osx.yml up --build --detach
- docker-compose exec php-fpm composer install
# Tear down all services and remove the code volume after terminating sessions.
afterTerminate:
- docker-compose -f docker-compose.yml -f docker-compose-osx.yml down --remove-orphans || true
# Define common utility commands.
commands:
logs: docker-compose -f docker-compose.yml -f docker-compose-osx.yml logs --follow
There are a merging of docker-compose.yml
and docker-compose-osx.yml
configuration files.
There is also configuration for placeholder-service-www
volume, that implement automatic synchronisation for /var/www
directory of placeholder-service_php_fpm_1
container.
Permissions are configured in configurationBeta
sections.
Problems with permissions also can be fixed by granting full access to /var/www.
Then need to disable tracking permissions for git.
docker-compose exec php-fpm chmod -R 777 /var/www
git config core.fileMode false
Installation is described in Readme. Firstly let's run a demo project without Mutagen:
git clone https://github.com/antonshell/placeholder-service.git
cd placeholder-service/
docker-compose up
docker-compose exec php-fpm composer install
Loading sample page takes 480ms.
Then stop containers and run with Mutagen:
docker-compose down --remove-orphans || true
mutagen project start || mutagen project terminate
docker-compose exec php-fpm chmod -R 777 /var/www
git config core.fileMode false
Loading sample page takes 83ms.
Demo project available on github. There is also Pull Request with Mutagen configuration. That's all for today. Thank you for your attention!