Make Magento 2 & Docker on MacOS faster with docker-sync

Joaquín Ruiz - 12th June 2019

Make Magento 2 & Docker on MacOS faster with docker-sync
  • Date:   12th June 2019
  • Category:

      Docker

  • Comments:

      0

Docker on MacOS for development have serious performance problems, especially working with Magento 2 & Docker, why? On Linux systems, Docker directly leverages the kernel of the host system, and file system mounts are native. On Windows and Mac, it’s slightly different. They do not provide a Linux Kernel, so Docker starts a virtual machine with a small Linux installed and runs Docker containers in there.

Magento 2 & Docker

Therefore Docker for Mac still starts a virtual machine. It also brought its own hypervisor “hyperkit” and shared file system “osxfs”. Unfortunately, “osxfs” is not fast enough. You can read more about this problem in this official post from Docker: https://docs.docker.com/docker-for-mac/osxfs-caching/.

Although the new versions of Docker for Mac brings new performance flags to mount-points of Docker Volumes (“delegated” and “cached”), they are insufficient for platforms like Magento 2, because of the amount of files that need to be read in a request lifecycle.

Make Magento 2 & Docker faster with docker-sync
Make Magento 2 & Docker faster with docker-sync

Docker-Sync

Then the solution is not to use the filesystem at all. Docker-sync is an alternative tool to the native volumes sharing of Docker for Mac. 

Docker-Sync provides different sync strategies each with its own pros and cons. You have to choose the one that is suitable for you.

I’m going to give you below the best sync strategy that worked for me with Docker+MacOS+Magento2.

For example, we have this shared volume in our docker-compose.mac.yml:

  apache:
    image: jokiruiz/magento2
    container_name: m2_apache
    ports:
      - "80:80" 
    volumes:
      - ./magento2:/var/www/html

So, we change the volumes and make them “nocopy” and “delegated”, we also need to specify the new volume as external.

  apache:
    image: jokiruiz/magento2
    container_name: m2_apache
    ports:
      - "80:80" 
    volumes:
      - apache-sync:/var/www/html:nocopy,delegated
(...)
volumes:
  apache-sync:
    external: true

Once we specify the new “apache-sync” volume, we need to specify it in a docker-sync.yml file:

version: "2"

options:
  verbose: true
  compose-file-path: 'docker-compose.mac.yml'
  cli_mode: 'auto'
  max_attempt: 3000

syncs:
  apache-sync:
    notify_terminal: true
    src: './magento2'
    sync_strategy: 'unison'
    sync_excludes: [
      'Path .git',
      'Name .gitignore',
      'BelowPath node_modules',
      'BelowPath bower_components',
      'BelowPath sass-cache',
      'BelowPath .sass-cache',
      'Path var/cache',
      'Path var/page_cache',
      'Path var/session',
      'BelowPath .DS_Store'
    ]
    sync_userid: '1000'
    max_attempt: 10

Once we have our docker-compose.mac.yml and docker-sync.yml ready, we can start our services. First of all, start docker-sync:

docker-sync start

And finally start your docker containers with docker-compose:

docker-compose -f docker-compose.mac.yml up -d 

And Enjoy the Speed! 😀

I have used unison strategy for Magento 2, but you have other strategies depending on your OS and platform https://docker-sync.readthedocs.io/en/latest/advanced/sync-strategies.html Which one do you prefer? Comment below and Share!

The Author

Joaquín Ruiz (aka Joki)
Joki is a Computer Engineer, Senior Full-Stack Developer and Lead Developer, specialized in web and e-commerce. Joki has also a wide international experience as freelance and working in agencies.