Будівельна інженерія та дизайн
Покрокове керівництво по будівництву багатоступінчастих Docker Images
Table of Contents
Що таке багатоступінчасті Docker?
Багатоступінчасті конструктори Docker є функцією, введеними в Docker 17.05, що дозволяє використовувати кілька виписки в один докер-файл. Кожен інструкція починається новий етап, який може мати власний базовий образ, залежності і команди. Артифати можуть бути вибірково скопіювати з одного етапу в інший, в той час як кінцевий образ тільки зберігає те, що строго необхідний для запуску програми. Цей підхід виключає необхідність вручну ланцюжка Dockerfiles або спирається на складні сценарії побудови, і він різко знижує розмір зображення, включаючи компілятори, бібліотеки розробки, проміжні файли.
Основна ідея полягає в відокремленні середовища збірки з середовища виконання. У типовому одноступеневій будівлі розробник встановлює всі інструменти для побудови (наприклад, компілятори, менеджери пакетів, тестові засади) в тому ж образі, який буде використовуватися для виробництва. Це збиває зображення і збільшує поверхню атаки. Багатоступінчасті збірки вирішують це за допомогою товстого, функціонально-багатого зображення для компіляції, а потім копіювання тільки отриманих артефактів в мінімальний робочий час зображення, наприклад або .
Переваги багатоступінчастих будівель
Переваги використання багатоступеневий будівель виходять за межі простого зменшення розмірів. Вони мають глибокий вплив на безпеку, підтримувальну працездатність та швидкість розгортання.
1. Зменшений розмір зображення
За допомогою розвантаження часових залежностей багатоступеневих будівель часто усаджують зображення на 50% до 90%. Наприклад, додаток Node.js побудовано за допомогою повного зображення (на 300MB) можна відшліфувати до 20MB, скопіюючи тільки побудовану папку в бази. Цей накопичувач економить безпосередньо перекладається на більш швидших часів, менше пропускної здатності мережі та менші витрати реєстру.
2. Покращена безпека
Кожен встановлений пакет або інструмент у контейнерному зображенні є потенційною вразливістю. Багатоступінкові збірки дозволяють виключити компілятори, дебугери та бібліотеки розвитку з кінцевого зображення, значно зменшуючи поверхню атаки. Ви навіть можете використовувати зображення, такі як або для етапу runtime, які містять тільки лезо мінімум для виконання програми бінарними.
3. Потокове будування процесів
Всі етапи побудови визначаються в одному Dockerfile, що робить процес самовмістженим і легкою для версії. CI/CD трубопроводи вигідні від однієї точки входу: Dockerfile. Немає необхідності підтримувати окремі сценарії побудови або ручний режим очищення.
4. Підвищення відтворюваності та консистенції
Оскільки вся будівля захоплюється одним Dockerfile, будь-який розробник або система може відтворювати точні однакові шари. Використання конкретних версій тегів для базових зображень, що забезпечують стабільні зведення по всьому середовищах.
Будівництво багатоступеневий Dockerfile: крок за кроком
Цей прохід охоплює створення багатопоточної багатопоточної Dockerfile для додатка Node.js та React. Те ж принципи застосовуються до будь-якої складеної мови.
1. Планувати свої етапи
Перед написанням коду, наведено на етапи, які потрібно. Типовий багатопоточний збір має щонайменше два етапи:
- Будівельна сцена] – встановлює всі інструменти, встановлює залежності, і працює команда збирання.
- Рунчасний етап – використовує зображення бази, копіює лише вбудовані артефакти з стадії будівельника, і визначає поведінку робочого часу.
Для складних проектів, які можна додати проміжні етапи для проведення випробувань, статичного аналізу або стиснення активів.
2. Написати етапу будівництва
Почати з базовим зображенням, який включає в себе необхідний інструментчай. Використовуйте , іменовані етапи] з , щоб доставити їх пізніше. Для Node.js:
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
Ключові моменти:
- Використовуйте для детермінування, більш швидкого встановлення залежності.
- Тримайте команди як окремі шари при можливості застигання.
- Встановлення інструментів для побудови (наприклад, TypeScript, webpack) в цьому етапі тільки.
3. Додати проміжний етап тестування (Оптіальність)
Щоб забезпечити якість коду, додайте стадію, яка працює тести. Цей етап може використовувати зображення будівельника або встановити додаткові інструменти. Тому що це не кінцевий етап, тестові збої не будуть присутніми в кінцевому зображенні.
FROM builder AS test
RUN npm run test
Ви можете запустити цей етап у CI-провіднику , щоб зловити збої рано без побудови всього кінцевого зображення.
4. Визначення етапу виконання
Для React-додатку зображення робочого часу може бути сервером Nginx. Для API Backend це може бути непрозорий базовий образ або мінімальний Alpine з режимом роботи Node.js. Копіювати лише необхідні артефакти, використовуючи .
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Якщо вам потрібен робочий час Node.js, не вдається копіювання від будівельника; замість перевстановлення виробничих залежностей в стадії runtime:
FROM node:14-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]
5. Побудувати і протестувати зображення
Створіть кінцевий образ за допомогою стандартного командного рядка:
docker build -t myapp:latest .
Для перевірки розміру, запуску і порівняння з одностороннім будівництвом. Запуск контейнера і підтвердження заявки відповідає правильно:
docker run -d -p 8080:80 myapp:latest
curl http://localhost:8080
Кращі практики для багатоступеневий будівель
- Використовувати конкретні теги основного зображення] – уникнути для запобігання сюрпризів. або .
- Оптимізуйте шар кешування – копіювання і перед іншим вихідним кодом, щоб шар не був визнаний тільки при зміні залежності.
- Leverage buildKit – включити BuildKit з для швидкого збирання, внутрання, кращого паралелізму.
- Створити декілька фінальних етапів для різних середовищ] – наприклад, стадія розвитку з дебулінговими інструментами та виробничим етапом з загартованим базовим зображенням.
- Use для побудови будівель - у розробці можна зупинити на стадії отримання реверсії та карти джерела, після чого перебудувати для виробництва.
- Keep секрети з зображень – use Docker BuildKit прапор, якщо потрібно пройти попередню частину під час збирання; ніколи не включати їх у кінцевий образ.
Загальні шаблони та використання випадків
Мови, що використовуються для заповнення (Go, Rust, C++)
Для статичних бункерів, етап виконання може використовуватися (порожня базова картина). Тільки бінарний і можливо, файл конфігурації копіюються. Приклад для Go:
FROM golang:1.20-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .
FROM scratch
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]
Python додатків
Використовуйте стадію будівельника для установки залежностей і складання будь-яких розширень C, після чого скопіюйте лише встановлені пакети на етапі виконання:
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .
FROM python:3.11-slim
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app /app
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
Frontend з сервером API
Створіть як передній і задньої частини в одному файлі Dockerfile. Використовуйте окремі етапи будівельника для кожного, після чого скопіюйте як артефакти в один разовий образ:
FROM node:14-alpine AS frontend-builder
WORKDIR /app
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ .
RUN npm run build
FROM node:14-alpine AS api-builder
WORKDIR /app
COPY api/package*.json ./
RUN npm ci
COPY api/ .
RUN npm run build
FROM node:14-alpine
WORKDIR /app
COPY --from=frontend-builder /app/build ./public
COPY --from=api-builder /app/dist ./dist
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]
Виправлення несправностей багатоступінкових будівель
- Layer кешування не працює] – забезпечити команди замовлення залежностей перед вихідним кодом. Використовуйте для виключення непотрібних файлів.
- Артифат не знайдено] – перевірте шляхи в ] заява. Етап будівельника повинен випускати вихід в зазначене місце. Використовуйте для знезараження.
- Secret leakage] – ніколи не копіювати всі каталоги, які можуть містити або ]. Виявлено копіювання тільки необхідних файлів.
- Large фінальні зображення незважаючи на багатоступеню] – перевірте, чи випадково копіюєте або весь джерело. Використовуйте для перегляду розмірів шару.
Висновок
Багатоступінчасті Docker будує є кутовим каменім сучасної контейнеризації. Вони дозволяють вам носити худі, безпечні зображення, зберігаючи процес збірки простий і документальний в одному Dockerfile. Розокремлюючи побоювання між будівництвом і runtime ви можете різко зменшити розмір зображення, поліпшити безпеку, і потокові лінії CI / CD трубопроводів. Методи показали, що тут застосовуються майже будь-який стек - чи ви будуєте Node.js, Go, Python, Java або передові програми. Почати, перетворюючи існуючі Dockerfiles в багатоступеневих будівель, і ви відразу побачите поліпшення в швидкості будівництва, ефективності розгортання і загальні інфраструктурні витрати.
Для отримання більш детальної інформації див. у розділі . Редакція та посібник з побудови багатоступеней . . Докери. Найкращі практики . Приклади реального способу життя також доступні в Докерська бібліотечна документація.