Проблема: коли змінюється composer.lock чи package-lock.json, шар з composer install чи npm ci інвалідується, і усі пакети завантажуються з інтернету заново, навіть якщо змінився один.
Cache mount - каталог, що зберігається між збираннями на збирачі, але не потрапляє в шари образу:
# syntax=docker/dockerfile:1
FROM composer:2 AS vendor
WORKDIR /app
COPY composer.json composer.lock ./
RUN --mount=type=cache,target=/tmp/cache \
COMPOSER_CACHE_DIR=/tmp/cache \
composer install --no-dev --no-scripts --prefer-dist --no-interaction
FROM node:22-alpine AS assets
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
npm ci
COPY . .
RUN npm run build
Тепер при зміні одного пакета менеджер бере решту з кешу на диску збирача - збирання прискорюється з хвилин до секунд.
Чим це відрізняється від кешу шарів:
| Кеш шарів | Cache mount | |
|---|---|---|
| що кешується | результат інструкції цілком | лише вміст каталогу |
| коли втрачається | будь-яка зміна вхідних файлів інструкції | лише при очищенні кешу збирача |
| потрапляє в образ | так | ні |
Обидва механізми працюють разом: незмінений composer.lock - кеш шару, змінений - cache mount робить перевстановлення дешевим.
Інші типові застосування:
apt/apk:--mount=type=cache,target=/var/cache/apt(у Debian-образах треба ще вимкнути автоматичну чистку кешу apt);- кеш збирачів (Go, Rust, Gradle);
- кеш Vite чи інших інструментів збирання фронтенду.
Параметри:
id=- явна назва кешу, щоб різні етапи чи проєкти ділили (або не ділили) його;sharing=locked- для пакетних менеджерів, які не терплять одночасного доступу (apt);uid,gid,mode- права, якщо збирання виконується не від root.
Обмеження: cache mount живе на конкретному збирачі. У CI на одноразових раннерах він порожній при кожному запуску - там допомагає експорт кешу (registry, GitHub Actions cache) чи постійний збирач. Також вміст cache mount недетермінований: збирання не повинно від нього залежати для правильності - лише для швидкості.