Контейнеризация Node-приложения
Упакуйте сервис и всё, что ему нужно, в один переносимый образ
- объяснить разницу между образом и контейнером;
- написать корректный
Dockerfileдля Express-приложения; - упорядочить инструкции так, чтобы кэш слоёв работал на вас, а не против;
- уменьшить и защитить образы с помощью многоэтапной сборки;
- подставлять конфигурацию через переменные окружения во время запуска;
- собирать, запускать и пробрасывать порты для контейнеризованного приложения.
1. От "у меня работает" к морскому контейнеру
Вы завершили промежуточные курсы: умеете строить Express API с маршрутизацией, middleware, JWT-авторизацией, валидацией, слоем SQL или MongoDB и тестами. На вашей машине всё работает идеально. Затем коллега клонирует проект -- и он ломается: у него Node версии 16, не хватает переменной окружения, нативный модуль не компилируется или системная библиотека другой версии. Код тот же самый; отличается окружение.
Аналогия. До стандартных морских контейнеров груз загружали навалом, штука за штукой, и каждый корабль, кран и грузовик обращались с ним по-своему. Стальной контейнер изменил всё: упакуйте товар один раз -- и любой корабль или кран в мире перевезёт эту одинаковую коробку, не заботясь о содержимом. Docker-образ -- это такая коробка для программ. Вы один раз упаковываете приложение, его среду Node, зависимости и файлы; любой хост с Docker запустит эту одинаковую коробку, не вникая в то, как она собрана.
Docker делает это через виртуализацию на уровне ОС. Контейнер -- это изолированный процесс на Linux-ядре хоста, а не полноценная виртуальная машина со своим ядром. Поэтому контейнеры стартуют за миллисекунды и почти не добавляют накладных расходов, при этом давая каждому приложению свою файловую систему, сетевое представление и пространство процессов.