Контейнери Linux потребують ядра Linux. На macOS (і Windows) Docker Desktop запускає легку віртуальну машину, і контейнери працюють усередині неї. Файли проєкту лежать на диску macOS, а процес у контейнері читає їх через межу віртуальної машини - механізм спільного доступу до файлів.
Чому це повільно для PHP і Node-проєктів: проблема не в розмірі файлів, а в їх кількості. Автозавантажувач Composer, node_modules, кеші фреймворку - кожен запит до Laravel відкриває й перевіряє сотні файлів; збирання фронтенду - тисячі. Кожна операція з файлом через межу ВМ коштує набагато дорожче, ніж на локальному диску.
Механізми й еволюція:
- gRPC FUSE, osxfs - старі механізми, дуже повільні на великих проєктах;
- VirtioFS - сучасний механізм за замовчуванням на macOS, значно швидший, але на великих репозиторіях усе ще відчутно повільніший за нативну файлову систему;
- Synchronized file shares - Docker Desktop тримає синхронізовану копію каталогу всередині ВМ (з файловим кешем), і контейнери читають її з нативною швидкістю. Розрахований на великі репозиторії (сотні тисяч файлів). Доступний у платних підписках Docker (Pro, Team, Business).
Практичні прийоми, що працюють незалежно від механізму:
- не монтувати залежності:
vendorіnode_modules- в іменованих томах (лишаються всередині ВМ) або встановлювати в образі; - монтувати лише потрібне: не весь проєкт з
.git, логами й кешем, а каталоги з кодом; - кеші й скомпільовані файли (
storage/framework,bootstrap/cache) - у томі чи tmpfs, а не на bind mount; - OPcache з
validate_timestampsі розумною частотою перевірки - менше звернень до файлової системи; docker compose watchзsync- копіювати змінені файли в контейнер замість спільного доступу;- ресурси ВМ: достатньо пам'яті й процесорів у налаштуваннях Docker Desktop.
Альтернативи Docker Desktop: OrbStack (швидший доступ до файлів і менше споживання ресурсів на macOS), Colima. Або відмовитися від Docker для самого PHP у розробці - Laravel Herd запускає PHP нативно, а в Docker лишаються лише бази й допоміжні сервіси.
На Linux проблеми немає: контейнери працюють на тому самому ядрі, і bind mount - це звичайне монтування без накладних витрат.
Докладніше в документації: Синхронізовані файлові спільні каталоги