Jak buforować instrukcję instalacji RUN npm, gdy Docker buduje plik Dockerfile

Obecnie rozwijam backend węzła dla mojej aplikacji. Podczas dokowania (docker build .) najdłuższą fazą jest RUN npm install. Runy instrukcji RUN npm install Na każdej małej zmianie kodu serwera, wpływając na produktywność poprzez zmuszanie programisty do czekania na zakończenie kompilacji za każdym razem.

Znalazłem, że uruchomienie npm install tam, gdzie mieszka kod aplikacji i dodanie node_modules do kontenera z instrukcją ADD rozwiązuje ten problem, jest to jednak dalekie od najlepszych praktyk. Informatyka trochę łamie całą ideę dokowania go i powoduje, że kontener waży znacznie więcej.

Jakieś inne rozwiązanie?
Author: ohadgk, 2016-03-03

4 answers

OK więc znalazłem ten świetny artykuł o wydajności podczas pisania pliku Dockera.

Jest to przykład złego pliku dokującego, który dodaje kod aplikacji przed uruchomieniem instrukcji 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"]

Dzieląc kopię aplikacji na 2 instrukcje kopiujące (jedną dla pakietu.plik json i inne dla reszty plików) i uruchomienie instrukcji instalacji npm przed dodaniem rzeczywistego kodu, każda zmiana kodu nie spowoduje uruchomienia instalacji npm Instrukcja, tylko zmiany Pakietu.json go uruchomi. Better practice Docker file:

FROM ubuntu
MAINTAINER David Weinstein <[email protected]>

# 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"]

Tutaj jest paczka.Dodano plik json, zainstaluj jego zależności i skopiuj je do kontenera WORKDIR, gdzie mieszka aplikacja:

ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/

Aby uniknąć fazy instalacji npm na każdej kompilacji Dockera, po prostu skopiuj te linie i zmień ^ / opt / app^ do lokalizacji, w której mieszka twoja aplikacja wewnątrz kontenera.

 82
Author: ohadgk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-24 11:42:49

Odkryłem, że najprostszym podejściem jest wykorzystanie semantyki kopiowania Dockera:

Instrukcja COPY kopiuje nowe pliki lub katalogi z i dodaje je do systemu plików kontenera na ścieżce .

Oznacza to, że jeśli najpierw skopiujesz plik package.json, a następnie wykonasz krok npm install, który może być buforowany, a następnie skopiujesz resztę katalogu źródłowego. Jeśli plik package.json został zmieniony, to będzie nowy i ponownie uruchomi instalację npm buforowanie tego dla przyszłych kompilacji.

Fragment z końca pliku Dockerfile wyglądałby następująco:

# install node modules
COPY package.json /usr/app/package.json
RUN  cd /usr/app && npm install

# install application
COPY . /usr/app
 10
Author: J. Fritz Barnes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-03 17:01:27

Dziwne! Nikt nie wspomina o wielostopniowej budowie .

# ---- 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

Awesome tuto here: https://codefresh.io/docker-tutorial/node_docker_multistage/

 9
Author: Abdennour TOUMI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 08:54:57

Wyobrażam sobie, że możesz już wiedzieć, ale możesz dołączyć .plik dockerignore w tym samym folderze zawierającym

node_modules
npm-debug.log

Aby uniknąć wzdęcia obrazu po naciśnięciu na docker hub

 2
Author: usrrname,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-25 15:42:13