wake-up-neo.com

So speichern Sie die RUN npm-Installationsanweisung, wenn das Docker eine Docker-Datei erstellt

Ich entwickle derzeit ein Node-Backend für meine Anwendung. Beim Andocken (Docker Build.) Ist die längste Phase der RUN npm install. Die RUN npm install-Anweisung wird bei jeder kleinen Servercode-Änderung ausgeführt und wirkt sich auf die Produktivität aus, da der Entwickler jedes Mal warten muss, bis der Build abgeschlossen ist.

Ich habe festgestellt, dass die Ausführung von npm install, wo sich der Anwendungscode befindet, und das Hinzufügen der node_modules zum Container mit der ADD-Anweisung dieses Problem löst. Es bricht gewissermaßen die Idee des Verderbens und bewirkt, dass der Container viel mehr wiegt.

Irgendwelche andere Lösung?

50
ohadgk

Ok, also fand ich diesen großartigen Artikel über Effizienz beim Schreiben einer Docker-Datei.

Dies ist ein Beispiel für eine fehlerhafte Docker-Datei, die den Anwendungscode vor dem Ausführen der Anweisung RUN npm install hinzufügt:

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

Durch Aufteilen der Kopie der Anwendung in 2 COPY-Anweisungen (eine für die package.json-Datei und die andere für die restlichen Dateien) und Ausführen der npm-Installationsanweisung, bevor der eigentliche Code hinzugefügt wird, wird durch jede Codeänderung die RUN-npm-Installation ausgelöst Anweisung, nur Änderungen der package.json werden es auslösen. Besser üben Docker-Datei:

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

An dieser Stelle wird die package.json-Datei hinzugefügt. Installieren Sie die Abhängigkeiten und kopieren Sie sie in den Container WORKDIR, in dem sich die App befindet:

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

Um die npm-Installationsphase bei jedem Docker-Build zu vermeiden, kopieren Sie einfach diese Zeilen und ändern Sie ^/opt/app ^ an den Ort, an dem sich Ihre App im Container befindet.

89
ohadgk

Ich habe festgestellt, dass der einfachste Ansatz darin besteht, die Kopiersemantik von Docker zu nutzen:

Mit der COPY-Anweisung werden neue Dateien oder Verzeichnisse aus dem Pfad kopiert und dem Dateisystem des Containers hinzugefügt.

Das bedeutet, wenn Sie die package.json-Datei zuerst explizit kopieren und dann den npm install-Schritt ausführen, kann sie zwischengespeichert werden und Sie können dann den Rest des Quellverzeichnisses kopieren. Wenn sich die package.json-Datei geändert hat, wird dies neu sein und die für zukünftige Builds erforderliche Zwischenspeicherung von npm erneut ausführen.

Ein Ausschnitt aus dem Ende einer Docker-Datei würde folgendermaßen aussehen:

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

# install application
COPY     . /usr/app
16
J. Fritz Barnes

Seltsam! Niemand erwähnt mehrstufiges Build

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

Super Tuto hier: https://codefresh.io/docker-tutorial/node_docker_multistage/

16
Abdennour TOUMI

Ich kann mir vorstellen, dass Sie es vielleicht bereits wissen, aber Sie könnten eine .dockerignore -Datei in den gleichen Ordner einfügen

node_modules
npm-debug.log

so vermeiden Sie das Aufblähen Ihres Bildes, wenn Sie auf Andocken-Hub drücken

5
usrrname

sie müssen den tmp-Ordner nicht verwenden. Kopieren Sie package.json einfach in den Anwendungsordner Ihres Containers. 

COPY app/package.json /opt/app/package.json
RUN cd /opt/app && npm install
COPY app /opt/app
0
Mike Zhang