Docker и node_modules - помещают их в слой или том?

Я планирую среду docker dev и сомневаюсь, является ли работа npm install как кешированный уровень хорошей идеей.

Я понимаю, что есть способы оптимизации dockerfiles, чтобы избежать перестройки node_modules, если package.json не изменится, однако я не хочу полностью перестраивать node_modules каждый раз изменяется package.json. Свежий npm install занимает 5 минут для нас, и изменения в package.json происходят достаточно часто. Для того, чтобы кто-то часто просматривал запросы на тягу и переключающие ветки, им приходилось страдать через бесконечное количество 5 минут npm installs каждый день.

Не было бы лучше в таких случаях, как мой, как-то установить node_modules в том, чтобы он сохранялся в сборках, а небольшие изменения в package.json не приводили к перестройке всего дерева зависимостей?

Ответ 1

Да. Не перестраивайте node_modules снова и снова. Просто вставьте их в контейнер данных и установите его только для чтения. Вы можете иметь центральный процесс перестраивать node_modules время от времени.

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

Что-то вроде этого (untested!):

docker build -t my/module-container - <<END_DOCKERFILE
FROM busybox
RUN mkdir -p /usr/local/node
VOLUME /usr/local/node
END_DOCKERFILE

docker run --name=module-container my/module-container

docker run --rm --volumes-from=module-container \
    -v package.json:/usr/local/node/package.json \
    /bin/bash -c "cd /usr/local/node; npm install"

Теперь контейнер данных module-container будет содержать модули, указанные package.json в /usr/local/node/node_modules. Теперь его можно смонтировать в производственных контейнерах с помощью --volume-from=module-container.