Хорошо, я нашел эту отличную статью об эффективности при написании файла докера.
Это пример плохого файла докера, добавляющего код приложения перед выполнением 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
оно установлено.apt-get clean
. Кроме того, добавьте ./node_modules в свой .dockerignore, чтобы избежать копирования рабочего каталога в созданный контейнер и ускорить этап копирования контекста сборки.package.json
к конечному положению покоя также отлично работает (исключая любые cp / mv).Странно! Никто не упоминает о многоступенчатой сборке .
# ---- Base Node ---- FROM alpine:3.5 AS base # install node RUN apk add --no-cache nodejs-current tini # set working directory WORKDIR /root/chat # Set tini as entrypoint ENTRYPOINT ["/sbin/tini", "--"] # copy project file COPY package.json . # # ---- Dependencies ---- FROM base AS dependencies # install node packages RUN npm set progress=false && npm config set depth 0 RUN npm install --only=production # copy production node_modules aside RUN cp -R node_modules prod_node_modules # install ALL node_modules, including 'devDependencies' RUN npm install # # ---- Test ---- # run linters, setup and tests FROM dependencies AS test COPY . . RUN npm run lint && npm run setup && npm run test # # ---- Release ---- FROM base AS release # copy production node_modules COPY --from=dependencies /root/chat/prod_node_modules ./node_modules # copy app sources COPY . . # expose port and define CMD EXPOSE 5000 CMD npm run start
Замечательный туто здесь: https://codefresh.io/docker-tutorial/node_docker_multistage/
источник
COPY
заявлением послеENTRYPOINT
?Я обнаружил, что самый простой подход - использовать семантику копирования Docker:
Это означает, что если вы сначала явно скопируете
package.json
файл, а затем запуститеnpm install
шаг, он может быть кэширован, а затем вы можете скопировать остальную часть исходного каталога. Еслиpackage.json
файл был изменен, то это будет новый файл, и он повторно запустит кеширование установки npm для будущих сборок.Фрагмент из конца Dockerfile будет выглядеть так:
источник
cd /usr/app
вы можете / должны использоватьWORKDIR /usr/app
./usr/app
образа, который создаст файл/usr/app/node_modules
с зависимостями, установленными из npm install.COPY . /usr/app
разве не будет копироватьpackage.json
файл снова/usr/app
вместе с остальными файлами?Я полагаю, вы уже знаете, но вы можете включить файл .dockerignore в ту же папку, содержащую
чтобы избежать раздувания изображения при нажатии на docker hub
источник
вам не нужно использовать папку tmp, просто скопируйте package.json в папку приложения вашего контейнера, выполните некоторые работы по установке и скопируйте все файлы позже.
источник