Пошук уроків, статей та іншого контенту
З’ясуєте, що входить до build context, як Docker передає його демону та як виключати зайві файли через .dockerignore.
Build context — це набір файлів і каталогів, доступних під час збирання Docker-образу.
У команді:
docker build .крапка в кінці означає: «використати поточний каталог як build context».
Docker читає файли з цього каталогу та його підкаталогів. Саме ці файли можна використовувати в Dockerfile за допомогою інструкцій COPY і ADD.
Наприклад, маємо таку структуру:
my-app/
├── Dockerfile
├── index.html
├── src/
│ └── app.js
└── README.mdЯкщо виконати команду з каталогу my-app:
docker build .то build context міститиме:
Dockerfile;
index.html;
каталог src;
файл src/app.js;
README.md;
інші файли всередині my-app.
Під час виконання docker build Docker CLI знаходить build context і передає його Docker daemon або іншому builder-у, який виконує збирання образу.
У спрощеному вигляді процес виглядає так:
Docker CLI визначає каталог build context.
З каталогу вибираються файли, які не виключені через .dockerignore.
Файли передаються builder-у.
Builder виконує інструкції з Dockerfile.
Інструкції COPY та ADD можуть використовувати файли з переданого context.
Під час збирання можна побачити повідомлення про передавання context:
[internal] load build context
[internal] transferring context: 12.3kBЧим більше файлів входить до context, тим більше даних потрібно проаналізувати або передати. Це може сповільнити збирання, особливо якщо каталог містить залежності, кеші або великі файли.
Конкретний спосіб передавання залежить від builder-а, але правило залишається однаковим: Docker може використовувати лише файли з build context.
У команді docker build останній аргумент — це build context:
docker build [опції] PATHНаприклад:
docker build .Тут:
. — поточний каталог;
Dockerfile за замовчуванням шукається в цьому каталозі;
поточний каталог стає build context.
Dockerfile можна назвати інакше або розмістити в іншому каталозі, використавши опцію -f:
docker build -f docker/Dockerfile .У цьому прикладі:
docker/Dockerfile — файл інструкцій;
. — build context.
Це важливе розрізнення. Розташування Dockerfile не визначає build context. Його визначає останній аргумент команди.
Якщо файл входить до build context, його можна скопіювати в образ:
FROM busybox:1.36
WORKDIR /app
COPY index.html .
COPY src/ ./src/
CMD ["find", "/app", "-type", "f"]У цьому прикладі Docker може знайти index.html і каталог src, оскільки вони знаходяться в context.
Шляхи в COPY вказуються відносно кореня build context:
COPY src/app.js /app/app.jsНе потрібно писати шлях відносно розташування Dockerfile.
Припустімо, структура проєкту така:
project/
├── secret.txt
└── app/
├── Dockerfile
└── index.htmlЯкщо збирання запускається з каталогу app:
cd app
docker build .то secret.txt не входить до build context. Інструкція:
COPY ../secret.txt /app/secret.txtне дасть доступу до цього файлу.
Щоб secret.txt був доступний, context потрібно вказати на каталог project:
docker build -f app/Dockerfile .Тоді . — це project, і в Dockerfile можна було б звернутися до файлу так:
COPY secret.txt /app/secret.txtВодночас не варто додавати до context більше файлів, ніж потрібно. Саме для цього використовують .dockerignore.
.dockerignore.dockerignore — це файл із правилами, які визначають, що потрібно виключити з build context.
Зазвичай його створюють у корені build context:
my-app/
├── .dockerignore
├── Dockerfile
├── package.json
├── package-lock.json
├── node_modules/
├── .git/
└── src/Приклад .dockerignore:
node_modules
.git
.gitignore
.env
*.log
dist
coverageЦі правила виключають:
каталог node_modules;
каталог .git;
файл .gitignore;
файл .env;
усі файли з розширенням .log;
каталоги dist і coverage.
Після цього Docker не передаватиме виключені файли builder-у як частину звичайного build context.
.dockerignoreне замінює контроль доступу до секретів. Якщо секрет не повинен потрапити в образ або процес збирання, його не слід додавати до build context взагалі.
.dockerignoreREADME.md
node_modulesТакі правила виключають відповідні файли або каталоги з усього context.
*.log
*.tmpВиключають файли із заданими розширеннями.
**/node_modulesВиключає каталоги node_modules, зокрема вкладені.
Рядки, що починаються з #, є коментарями:
# Залежності встановлюються під час збирання
node_modules
# Службові дані Git не потрібні в образі
.gitСимвол ! може повернути файл до context після ширшого виключення:
*.log
!important.logУ цьому прикладі всі .log-файли виключаються, крім important.log.
Правила обробляються послідовно, тому порядок має значення.
Створімо простий проєкт:
docker-context-demo/
├── .dockerignore
├── Dockerfile
├── app.txt
├── debug.log
├── node_modules/
│ └── unused.txt
└── src/
└── message.txtФайл Dockerfile:
FROM busybox:1.36
WORKDIR /app
COPY . .
CMD ["find", "/app", "-type", "f", "-print"]Файл .dockerignore:
*.log
node_modulesФайл app.txt:
Основний файл застосункуФайл src/message.txt:
Повідомлення з каталогу srcЗберімо образ:
cd docker-context-demo
docker build -t context-demo .Запустімо контейнер:
docker run --rm context-demoУ результаті серед файлів в /app будуть приблизно такі:
/app/app.txt
/app/src/message.txtФайл debug.log і каталог node_modules не потраплять до образу, оскільки їх виключає .dockerignore.
Без .dockerignore ці файли входили б до context, а команда COPY . . скопіювала б їх в образ.
.dockerignore і COPY.dockerignore впливає не лише на передавання context, а й на результат інструкцій COPY та ADD.
Якщо в .dockerignore є правило:
.envто така інструкція не скопіює файл:
COPY .env /app/.envФайл не доступний як звичайна частина context, тому збирання завершиться помилкою.
Використання:
COPY . /appтакож не копіює файли, виключені через .dockerignore.
Dockerfile і сам .dockerignore обробляються builder-ом окремо. Вони можуть бути передані для виконання та обробки збирання, але їх не слід розглядати як звичайні файли, які можна скопіювати в образ через COPY.
.dockerignore для Node.js-проєктуДля проєкту на Node.js часто використовують такий варіант:
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
.git
.gitignore
.env
.env.*
coverage
distЗалежності можна встановити всередині образу з package.json і lock-файла, а локальний каталог node_modules не передавати до Docker.
Приклад Dockerfile:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "start"]У цьому випадку:
package.json і package-lock.json копіюються в образ;
npm ci встановлює залежності всередині образу;
локальний node_modules не копіюється, якщо він зазначений у .dockerignore;
решта дозволених файлів проєкту копіюється через COPY . ..
Команда:
docker build docker/використовує каталог docker/ як context. Файли поруч із цим каталогом не будуть доступні.
Якщо Dockerfile розташований у docker/, але застосунку потрібен корінь проєкту, використовуйте:
docker build -f docker/Dockerfile ..dockerignore не в тому каталозі.dockerignore шукається в корені build context, а не обов’язково поруч із Dockerfile.
Для команди:
docker build -f docker/Dockerfile .потрібен файл:
.dockerignoreу поточному каталозі, який позначено крапкою як context.
Якщо .env, ключі або локальні налаштування не виключені, вони можуть потрапити до build context і бути скопійованими в образ:
COPY . .Додайте такі файли до .dockerignore:
.env
*.key
*.pemАле краще взагалі не зберігати секрети в каталозі, який використовується як context.
Не слід запускати збирання з кореня файлової системи або з каталогу, де містяться великі архіви, кеші й залежності:
docker build /Обирайте найменший каталог, який містить усі необхідні файли, і доповнюйте його .dockerignore.
COPY прочитає файл поза contextШлях у COPY не може надати доступ до батьківського каталогу:
COPY ../config.json /app/config.jsonПотрібно або змінити build context, або перемістити потрібний файл у context.
Build context — це каталог, доступний builder-у під час збирання образу.
У команді docker build . крапка визначає поточний каталог як context.
Docker CLI передає context Docker daemon або іншому builder-у.
COPY і ADD можуть використовувати лише файли з context.
Файл .dockerignore виключає непотрібні файли та каталоги з context.
.dockerignore розташовується в корені build context.
До .dockerignore зазвичай додають .git, node_modules, логи, кеші, результати збірки та секрети.
Менший context пришвидшує збирання та зменшує ризик випадково додати зайві файли до образу.