Хорошо, я нашел эту отличную статью об эффективности при написании файла докера.
Это пример плохого файла докера, добавляющего код приложения перед выполнением RUN npm install
инструкции:
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
WORKDIR /opt/app
COPY . /opt/app
RUN npm install
EXPOSE 3001
CMD ["node", "server.js"]
Разделив копию приложения на 2 инструкции КОПИРОВАНИЯ (одна для файла package.json, а другая - для остальных файлов) и запустив инструкцию установки npm перед добавлением фактического кода, любое изменение кода не приведет к запуску установки RUN npm. инструкции, только изменения package.json вызовут ее. Лучше практиковаться в файле докеров:
FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>
# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app
EXPOSE 3000
CMD ["node", "server.js"]
Сюда добавляется файл package.json, устанавливаются его зависимости и копируются в контейнер WORKDIR, где находится приложение:
ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/
Чтобы избежать фазы установки npm в каждой сборке докеров, просто скопируйте эти строки и измените ^ / opt / app ^ на место, где ваше приложение находится внутри контейнера.
ADD
не приветствуется в пользуCOPY
, афаик.COPY
еще эффективнее. IMO, последние два абзаца не нужны, поскольку они дублируют друг друга, а также с точки зрения приложения не имеет значения, где в файловой системе находится приложение, еслиWORKDIR
оно установлено.