Уменьшаем размер образа Docker для приложения Next.js

Введение

Docker  —  это открытая платформа для разработки, доставки и запуска приложений.

NextJS  —  гибкий фреймворк React со строительными блоками для создания быстрых веб-приложений.

Контейнеризация приложения

Прежде чем что-либо оптимизировать, упакуем приложение в контейнер.

Создаем файл Dockerfile:

touch Dockerfile

Ненужные файлы «игнорируем» в dockerignore:

node_modules
.next
.vscode
.gitignore
README.md
.dockerignore
.git

Контейнеризируем приложение my-space:

Это простейший пример контейнеризации, теперь сделаем сборку:

docker build -t my-space .

Но посмотрите на размер:

2,42 Гб! Такой тяжелый образ не опубликовать.

Уменьшаем размер

alpine

В Node.js поддерживается соответствие тега образа node:alpine и его вариантов для конкретных версий дистрибутивов Alpine Linux и среды выполнения Node.js. Размер оригинальной версии  —  примерно 1 Гб.

Перейдем к версии alpine:

Размер уменьшился на 800 Мб, до 1,65 Гб.

Многоэтапные сборки

Многоэтапные сборки применяются для оптимизации Dockerfiles, делая их простыми и удобными в сопровождении.

Создадим в Dockerfile два этапа: builder и runner.

Так мы избавляемся от ненужных файлов в образе:

Переместим их из builder в runner, который в итоге и используем:

Размер сокращается на 300 Мб, до 1,36 Гб.

Удаление повторяющихся слоев

Кое-что у нас дублируется: зависимости для каждого этапа установлены дважды. Хотя размер проекта прежний, размер образа остается большим из-за кэширования и слоев.

Убираем node_modules из этапа сборки:

Размер теперь менее 500 Мб, вполне приличный для приложения NextJS.

Сделаем еще меньше.

Трассировка выходного файла

В Next.js во время сборки автоматически выполняется трассировка каждой страницы и ее зависимостей.

Так выявляются все файлы, необходимые для развертывания производственной версии приложения, а размер развертываний значительно сокращается.

Раньше при развертывании с Docker до выполнения next start устанавливались все файлы из пакета dependencies. Начиная с Next.js 12, трассировкой выходных файлов в каталоге .next/ включаются только нужные файлы.

В файле next.config.js активируем автономный вывод:

experimental: {
outputStandalone: true,
},

И создается папка в .next/standalone с возможностью затем развертываться без установки node_modules:

Размер стал 176 Мб, достаточно маленький для большинства случаев.

Заключение

Это была простая оптимизация размеров докерных образов. Чтобы выбрать подходящую для вашего приложения, загляните в документацию Docker.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Kyle Le: Reduce Docker Image size for your Next.js App

Предыдущая статьяПрограммируем с ChatGPT: 10 советов
Следующая статьяЧистота и порядок: 3 правила для идеальной базы кода