Пошук уроків, статей та іншого контенту
FROM, WORKDIR, COPY, RUN та CMD — покроковий рецепт побудови власного образу застосунку.
Dockerfile — звичайний текстовий файл із послідовністю інструкцій, кожна з яких додає новий шар до образу, що будується. docker build читає цей файл і виконує інструкції по черзі, створюючи готовий, незмінний образ.
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD ["node", "server.js"]Кожен Dockerfile починається з FROM — базового образу, поверх якого будуються всі наступні шари. Практично завжди варто починати з офіційного образу відповідної мови виконання (node, python) із конкретним тегом версії, а не будувати операційну систему з абсолютного нуля.
WORKDIR встановлює поточну робочу директорію для всіх наступних інструкцій (COPY, RUN, CMD) — аналог cd у звичайному терміналі, але зафіксований у самому образі. Якщо вказаної директорії не існує, Docker створює її автоматично.
COPY <джерело на хості> <призначення в образі> копіює файли з машини, де відбувається збірка, у файлову систему образу. У прикладі вище файли копіюються у два прийоми навмисно — причина розібрана детально в наступному уроці про кешування шарів збірки.
RUN виконує команду один раз, під час побудови образу (не під час запуску контейнера) — типово для встановлення залежностей чи системних пакетів. Результат виконання (нові чи змінені файли) фіксується як новий шар образу.
CMD задає команду, яка виконується, коли з образу запускають контейнер (docker run), — на відміну від RUN, вона не виконується під час збірки образу. Детальна різниця між CMD і спорідненою інструкцією ENTRYPOINT — форма перевизначення аргументів при запуску — вже розібрана в статті «Docker: CMD проти ENTRYPOINT» (розділ Статті) і тут не повторюється.
docker build -t my-app:1.0 . # -t: тег нового образу; "." — контекст збірки (поточна папка)Контекст збірки (останній аргумент, зазвичай .) — папка, чий вміст доступний інструкціям COPY під час збірки. Docker відправляє весь вміст цієї папки демону збірки заздалегідь, тому зайві великі файли в контексті (наприклад, node_modules, що не потрібен у сирому вигляді) сповільнюють кожну збірку — саме цю проблему вирішує .dockerignore, детально в наступному уроці.
Плутати RUN і CMD за моментом виконання — RUN виконується один раз під час збірки образу, CMD — щоразу під час запуску контейнера з цього образу.
COPY . . одним рядком одразу на початку Dockerfile — працює, але втрачає переваги кешування шарів збірки (детально в наступному уроці), сповільнюючи повторні збірки після кожної дрібної зміни коду.
Використання латест-тегу базового образу (FROM node, без версії) — та сама проблема невідтворюваності, що й при docker pull без явного тегу.
Dockerfile описує покроковий рецепт побудови образу: FROM задає базовий образ, WORKDIR — робочу директорію, COPY переносить файли з хоста в образ, RUN виконує команди під час збірки (встановлення залежностей), CMD задає команду за замовчуванням при запуску контейнера. docker build -t читає Dockerfile і будує готовий, тегований образ.