Публикуем новый перевод и надеемся, что рекомендации автора помогут вам оптимизировать образ Docker.
С момента своего создания Docker произвел революцию в том, как мы используем контейнеры. В основном это связано с простотой, которую обеспечивает Docker. Его можно использовать, даже не разбираясь в каких-либо сложных темах, связанных с контейнерами.
Если вы новичок в Docker, можете выбрать шаблон (базовый образ) и определить свои инструкции (команды Dockerfile), чтобы разместить свой код внутри образа и запустить его.
Простота Docker будем помогать вам в работе с самого начала его использования, а навык его оптимизации приходит с опытом и обычно требует времени.
Я работаю с Docker уже долгое время, поэтому решил поделиться опытом, как создавать контейнеры лучше, даже если вы новичок.
1. Определите кэшируемые юниты ➱
Знаете ли вы, что каждая команда RUN, включенная в Dockerfile, влияет на уровень кэширования?
Использование нескольких команд RUN для установки пакетов повлияет на производительность и эффективность процесса сборки. Использование одной команды RUN для установки всех пакетов и зависимостей поможет создать один кэшируемый юнит вместо нескольких.
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.*
2. Уменьшите размер образа
Размер образа играет важную роль в создании хорошего Dockerfile. Использование образов меньшего размера способствует быстрому развертыванию и снижает возможности для атак.
Удалите ненужные зависимости
Избегайте установки в образ ненужных инструментов, например, инструментов отладки.
Если менеджер пакетов применяет для установки рекомендуемые пакеты автоматически, используйте флаги менеджера пакетов и избегайте установки ненужных зависимостей.
RUN apt-get update && apt-get -y install --no-install-recommends
Совет: делитесь компонентами, которые используете повторно, между проектами с помощью Bit (Github).
Bit упрощает документирование, совместное и повторное использование независимых компонентов между проектами. Применяйте его для повторного использования кода, сохранения единообразия дизайна, совместной работы в команде, увеличения скорости доставки и создания масштабируемых приложений.
Bit поддерживает Node, TypeScript, React, Vue, Angular и др.
Изучите компоненты, опубликованные на Bit.dev
3. Поддержка образа
Выбор правильного базового образа для приложения очень важен.
Используйте официальный образ Docker
Использование официального образа Docker уменьшает его размер вследствие сокращения ненужных зависимостей, которые делают образ больше. Использование официального образа дает 3 основных преимущества:
- позволяет нам использовать образ, созданный на основе лучших практик,
- обеспечивает надежность образа и его сохранность,
- повышает доверие и безопасность.
# загрузить официальный базовый образ
FROM node:13.12.0-alpine
# установить рабочий каталог
WORKDIR /app
# добавить `/app/node_modules/.bin` в $PATH
ENV PATH /app/node_modules/.bin:$PATH
Использовать определенные теги
При выборе базового образа рекомендуется использовать определенный тег. Не используйте для образа latest тег. Latest тег со временем может получать критические изменения.
# загрузить официальный базовый образ
FROM node:13.12.0-alpine
Используйте минимальную версию сборки
Минимальная сборка уменьшает размер конечного образа. Это помогает разворачивать приложения быстрее и безопаснее.
Как видно из приведенного выше примера, при использовании минимальной сборки, размер образа меньше. Большинство образов используют сборку alpine. Alpine — это очень легкий образ со стандартным размером 2 МБ.
Используя образ на основе alpine, мы можем значительно уменьшить размер получаемого образа.
4. Воспроизводимость
Сборка из исходного кода в изолированной (consistent) среде
Если вы используете Docker, лучше создавать приложение в управляемой среде для обеспечения изолированности.
Мы должны избегать создания приложений в локальной среде и добавлять их в реестр.
В противном случае пакеты, которые вы установили в своей локальной среде, могут повлиять на согласованность образа. Наверное, никто не хочет оказаться в такой ситуации, поскольку это ставит под угрозу одно из основных преимуществ Docker — согласованное выполнение в разных средах.
Использование многоэтапных сборок для удаления зависимостей
Рекомендуется использовать многоэтапный способ развертывания приложений.
Это исключает использование зависимостей сборки в работающем контейнере.
Мы можем собрать приложение, используя уникальный образ сборки, который имеет dev-зависимости, и переместить скомпилированные бинарные файлы в отдельный образ контейнера для его запуска.
# Stage 0, "build-stage", based on Node.js, to build and compile the frontend
FROM node:13.12.0 as build-stage
WORKDIR /app
COPY package*.json /app/
RUN npm install
COPY ./ /app/
RUN npm run build
# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx
FROM nginx:1.15
COPY --from=build-stage /app/build/ /usr/share/nginx/html
В приведенном выше Dockerfile есть два отдельных этапа. Этап 0 используется для сборки node-приложения из исходного образа node, а этап 1 используется для копирования собранных файлов из образа сборки в образ веб-сервера (Nginx), который в конечном итоге обслуживает приложение.
Заключение
Это всё, что я хотел рассказать. Если вы новичок в Docker, я рекомендую попробовать описанные практики при создании своего первого образа. Это поможет вам понять тему глубже и позволит эффективно использовать Docker с первого дня работы.
Если вам известны другие крутые практики, делитесь в комментариях. Спасибо за прочтение!