Оптимизация образов Dockerfile для NextJS


Оптимизация образов Dockerfile для NextJS

Докер-образы NextJS слишком велики. Поэтому эта статья будет посвящена тому, как оптимизировать dockerfile для производства. Здесь я использую 2 способа оптимизации образов docker.

Полный исходный код здесь

Установка

Сначала нам нужно создать проект в nextjs. В качестве примера я использую Vercel, проект здесь.

Структура проекта:

.
├── @types
│   └── remark-html.d.ts
├── README.md
├── _posts
│   ├── dynamic-routing.md
│   ├── hello-world.md
│   └── preview.md
├── components
│   ├── alert.tsx
│   ├── avatar.tsx
│   ├── container.tsx
│   ├── cover-image.tsx
│   ├── date-formatter.tsx
│   ├── footer.tsx
│   ├── header.tsx
│   ├── hero-post.tsx
│   ├── intro.tsx
│   ├── layout.tsx
│   ├── markdown-styles.module.css
│   ├── meta.tsx
│   ├── more-stories.tsx
│   ├── post-body.tsx
│   ├── post-header.tsx
│   ├── post-preview.tsx
│   ├── post-title.tsx
│   └── section-separator.tsx
├── interfaces
│   ├── author.ts
│   └── post.ts
├── lib
│   ├── api.ts
│   ├── constants.ts
│   └── markdownToHtml.ts
├── next-env.d.ts
├── package.json
├── pages
│   ├── _app.tsx
│   ├── _document.tsx
│   ├── index.tsx
│   └── posts
│       └── [slug].tsx
├── postcss.config.js
├── public
│   ├── assets
│   │   └── blog
│   │       ├── authors
│   │       │   ├── jj.jpeg
│   │       │   ├── joe.jpeg
│   │       │   └── tim.jpeg
│   │       ├── dynamic-routing
│   │       │   └── cover.jpg
│   │       ├── hello-world
│   │       │   └── cover.jpg
│   │       └── preview
│   │           └── cover.jpg
│   └── favicon
│       ├── android-chrome-192x192.png
│       ├── android-chrome-512x512.png
│       ├── apple-touch-icon.png
│       ├── browserconfig.xml
│       ├── favicon-16x16.png
│       ├── favicon-32x32.png
│       ├── favicon.ico
│       ├── mstile-150x150.png
│       ├── safari-pinned-tab.svg
│       └── site.webmanifest
├── styles
│   └── index.css
├── next.config.js
├── tailwind.config.js
└── tsconfig.json
Вход в полноэкранный режим Выход из полноэкранного режима

Затем установите и соберите этот блог:

➜  blog-starter git:(master) ✗ yarn
➜  blog-starter git:(master) ✗ yarn build
➜  blog-starter git:(master) ✗ yarn start
Войти в полноэкранный режим Выйти из полноэкранного режима

Ваш блог должен быть запущен и работать на localhost:3000.

Сборка на Docker

Игнорируйте ненужные файлы с помощью .dockerignore:

node_modules
*.DS_Store
.next
.gitignore
README.md
.dockerignore
LICENSE
.docker
.gitlab
Войдите в полноэкранный режим Выйти из полноэкранного режима

Здесь у нас есть 3 сценария dockerfile. Сначала я использую базовый Dockerfile:

➜  blog-starter git:(master) ✗ docker build -t blog-with-basic-dockerfile -f .docker/basic.dockerfile .
Вход в полноэкранный режим Выход из полноэкранного режима

# Check docker images
➜  blog-starter git:(master) ✗ docker images
REPOSITORY                                       TAG                               IMAGE ID       CREATED          SIZE
blog-with-basic-dockerfile                       latest                            b70f75178890   8 seconds ago    370MB
Вход в полноэкранный режим Выход из полноэкранного режима

В этом сценарии мы построили nextjs image размером 370MB.

Далее мы используем многоступенчатый докер с помощью Multi Stage Docker:

➜  blog-starter git:(master) ✗ docker build -t blog-with-multistage-dockerfile -f .docker/multistage.dockerfile .
Войти в полноэкранный режим Выход из полноэкранного режима

# Check docker images
➜  blog-starter git:(master) ✗ docker images
REPOSITORY                                           TAG                               IMAGE ID       CREATED           SIZE
blog-with-multistage-dockerfile                      latest                            07c84ea2173a   38 seconds ago    339MB
Войти в полноэкранный режим Выход из полноэкранного режима

В этом способе я использую модуль node-prune в стадии BUILD после установки пакетов. node-prune может удалять ненужные файлы из node_modules:

         files total 43,924
       files removed 12,814
        size removed 28 MB
            duration 866ms
Вход в полноэкранный режим Выйти из полноэкранного режима

Хехе, уменьшилось на 28 МБ. Вы можете следовать этому руководству для настройки в вашем базовом образе ноды. Итак, это изображение было оптимизировано 370MB -> 339MB.

Наконец, мы собираем dockerfile с многоступенчатым docker и включаем режим standalone для NextJS. Создаем файл next.config.js с содержимым:

module.exports = {
    output: "standalone"
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Nextjs может автоматически создавать автономную папку, в которую копируются только необходимые файлы для развертывания на производстве, включая некоторые файлы в node_modules. Больше документации.

Начнем с Dockerfile:

➜  blog-starter git:(master) ✗ docker build -t blog-with-multistage-standalone-dockerfile -f .docker/multistage_standalone.dockerfile .
Вход в полноэкранный режим Выход из полноэкранного режима

# Check docker images
➜  blog-starter git:(master) ✗ docker images
REPOSITORY                                                      TAG                     IMAGE ID       CREATED           SIZE
blog-with-multistage-standalone-dockerfile                      latest                  07c84ea2173a   38 seconds ago    119MB
Войти в полноэкранный режим Выход из полноэкранного режима

Вот это да! Отлично … Размер изображений составляет всего 119MB.

Итак, я представил 3 способа оптимизации размера изображения, но … они работают очень медленно. В следующем посте я покажу вам, как создать изображение быстрее.

Спасибо за прочтение 😁😁😁😁

Оцените статью
devanswers.ru
Добавить комментарий