Предскажите кэш
Что будет пересобрано после изменения одного файла в src/?
FROM node:22-bookworm-slim
WORKDIR /app
COPY . .
RUN npm ci
CMD ["npm", "test"]Build context и слои
Команда docker build -t wms-tests:dev . передаёт текущий каталог как build context. Инструкции Dockerfile последовательно создают кэшируемые результаты. Если входные данные слоя изменились, этот слой и следующие за ним должны выполняться заново.
npm ci, затем добавляют исходники.# syntax=docker/dockerfile:1
FROM node:22-bookworm-slim AS runner
WORKDIR /app
COPY --chown=node:node package.json package-lock.json ./
RUN npm ci
COPY --chown=node:node src ./src
COPY --chown=node:node tsconfig.json ./
USER node
CMD ["npm", "test"]
RUN выполняется во время build и фиксирует результат в image. CMD задаёт команду по умолчанию для нового container и выполняется при start. Exec-form JSON помогает корректно передавать сигналы процессу.
Не отправляйте лишнее
Build context влияет на скорость, кэш и риск утечки файлов. Минимальный .dockerignore для Node-проекта:
node_modules
test-results
playwright-report
.git
.env
*.log.dockerignore не является механизмом хранения secrets. Пароли и registry tokens не должны попадать ни в context, ни в ARG/ENV, ни в слои. Для build-time secret используйте BuildKit secret mount.
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci
docker build --secret id=npmrc,src="$HOME/.npmrc" \
--tag wms-tests:dev .Проверка image как артефакта
docker build --tag wms-tests:dev .
docker image inspect wms-tests:dev \
--format 'user={{.Config.User}} cmd={{json .Config.Cmd}}'
docker history wms-tests:dev
docker run --rm wms-tests:dev- Build проходит из чистого context без локального
node_modules. - Повторный build без изменений использует cache.
- Изменение
src/не инвалидирует слойnpm ci. - Runtime запускается не от root, если повышенные права не нужны.
- Secrets отсутствуют в history, env и filesystem image.
Multi-stage: когда он нужен
Если TypeScript компилируется в JavaScript для production-сервиса, builder может содержать devDependencies и compiler, а финальный stage — только runtime-файлы. Для Playwright test runner финальный image всё равно содержит браузеры и test dependencies, поэтому цель multi-stage нужно формулировать конкретно, а не добавлять его автоматически.
«Кэш Dockerfile зависит от инструкции и её входов. Поэтому manifests копирую отдельно и запускаю npm ci до копирования часто меняющегося кода. RUN работает при build, а exec-form CMD задаёт основной process container. Context ограничиваю через .dockerignore, secrets передаю BuildKit mount, runtime по возможности запускаю не от root».
Проверка понимания
Первичные источники
- Dockerfile overview — основной материал.
- Building best practices — кэш, multi-stage и безопасный image.
- Dockerfile reference — точное поведение инструкций.
Покажите преподавателю Dockerfile проекта, если порядок слоёв или runtime user требуют компромисса.