Wie aktiviere ich den npm-Cache in einem Jenkins-Build-Slave, der im Docker ausgeführt wird?


13

Ich habe ein Docker-Image, nennen wir es frontend.image, das ich für einen Jenkins-Build-Slave verwende. Das Jenkins Docker-Plug- in dreht einen Container aus diesem Image und erstellt Artefakte im Container. Das alles funktioniert super. In diesem Fall frontend.imagewird die zum Erstellen einer AngularJs-App verwendet. Zum Erstellen dieser Angular-App gehört auch die Installation von npm-Paketen, die die App benötigt.

Dieser Prozess, npm install, scheint lange zu dauern, 3 Minuten, npm installiert anscheinend jedes Mal jedes Paket.

Also habe ich ein Volume für meinen Slave hinzugefügt, es ist ein vom Host gemountetes Volume. Das Docker-Plugin verwendet dieses Volume jedes Mal, wenn es den Frontend-Container ausführt:

Bildbeschreibung hier eingeben

Der Benutzer, der den Befehl ausführt, npm installist jenkins. npm speichert einen Cache, den Sie mit befehl npm config get cachewelche Ausgaben finden können/home/jenkins/.npm

Aus diesem Grund habe ich das Host-Volume /slaves/volumes/tsl.frontend:/home/jenkinsauf meinem Webcontainer-Slave gemountet.

Ich baue meine Angular-App mit einem Jenkins-Projekt, baue kein Problem, viele npm-Pakete sind installiert. Wenn ich in meinen Docker-Host ssh und cmd starte, ls /slaves/volumes/tsl.frontendsehe ich viele npm-Pakete. Dies bedeutet, dass mein Host-Volume-Mount für den Slave funktioniert hat. Bildbeschreibung hier eingeben

Jetzt erstelle ich das Jenkins-Projekt erneut. Npm installiert jedes einzelne Paket erneut, obwohl der Docker-Slave-Build-Container den Volume-Host-Mount verwendet. Ich kann dies sogar bestätigen, indem ich mit cmd, docker exec -it <some_clever_random_container_id> bashcmd su jenkinsund cmd in den Slave-Container schlage, in npm cache lsdem viele zwischengespeicherte npm-Pakete aufgelistet sind. Bildbeschreibung hier eingeben

Selbst mit meinem Host-Mount-Volume, chmod 777für das übrigens keine Berechtigungsprobleme bestehen, kann ich npm installden Cache nicht verwenden.

In meinem Jenkins-Build, der den Docker-Slave-Container hochfährt, wird der erste Cmd ausgeführt, npm cache lsund viele Pakete werden aufgelistet. Bedeutet dies nicht, dass mein Host-Volume wie erwartet funktioniert und der npm-Cache-Index die Integrität aufweist, auch wenn er nicht beschädigt ist?

Bildbeschreibung hier eingeben

Ich habe das reguläre npm installcmd ausprobiert , das, wenn ich es auf meinem localhost-Rechner ausführe, beim ersten Mal alle Pakete und beim nächsten Mal fast keine Pakete installiert. Und auch der npm-Cache "Hack" npm --cache-min 9999999 install, entnommen aus dieser SO-Antwort sowie cmdnpm --skip-installed --cache-min 9999999 install

Eine verwandte Frage wurde auf StackOverflow gestellt.


Ich wette, der Cache-Index wird nicht innerhalb von ~ / .npm gemäß Ihrer Beschreibung gespeichert
Tensibai

@Tensibai Sie sind falsch und ich bin sehr sicher, dass der Benutzer Jenkins ist, denn das ist, was Sie auf eine andere Weise sagen, weil ich npm cache ls als Jenkins-Benutzer laufen lasse und die Pakete auflistet, sagen Sie, dass npm install ist von einem anderen Benutzer ausgeführt werden
Brian Ogden

Nein, ich sage, der Index selbst ist wahrscheinlich woanders gespeichert, in / usr / local oder in welchem ​​Pfad npm auch immer installiert ist, ich habe keine Ahnung. Das hört sich einfach so an, als würde npm so tun, als ob sich nichts im Cache befände. Ich vermute, es listet das Verzeichnis nicht auf, sondern basiert auf einem anderen Index.
Tensibai

@Tensibai aber die cmd npm config get cache gibt /home/jenkins.npm zurück, da dieser Pfad nicht den Ort des Caches bestätigt?
Brian Ogden

Der Cache-Speicherort, der den Cache-Index nicht erzwingt, befindet sich überhaupt am selben Speicherort. Ich würde ein npm cache lsund ein RAW ls ~/.npm/* -alin das Build-Skript selbst vor jedem anderen Build-Schritt einfügen, um den Zustand des Containers beim Starten des Builds sicherzustellen.
Tensibai

Antworten:


5

Ich löste schließlich das von Docker Bildschicht Caching für die NPM installieren, folgende diese Antwort

Dies bedeutet, dass ich die npm-Installation aus dem Docker-Slave-Image in das eigentliche Frontend-Image verschoben habe. Hier ist meine letzte Docker-Datei, die die npm-Installation zwischen den Builds wirklich zwischenspeichert, wenn package.config keine Änderungen aufweist:

FROM centos:7
MAINTAINER Brian Ogden

# Not currently being used but may come in handy
ARG ENVIRONMENT
ENV NODE_VERSION 6.11.1

RUN yum -y update && \
    yum clean all && \
    yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm \
    yum -y makecache && \
    yum -y install nginx-1.12.0 wget

# Cleanup some default NGINX configuration files we don’t need
RUN rm /etc/nginx/conf.d/default.conf

#############################################
# NodeJs Install
#############################################

#Download NodeJs package
RUN wget -q -O - https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz \
    | tar --strip-components=1 -xzf - -C /usr/local

# /programming//a/35774741/1258525
# 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 /app && cp -a /tmp/node_modules /app/

WORKDIR /app
COPY . /app

RUN npm run build-$ENVIRONMENT

RUN cd /app && cp -a dist/* /usr/share/nginx/html
COPY ./docker/conf/frontend.conf /etc/nginx/conf.d/frontend.conf
COPY ./docker/conf/nginx.conf /etc/nginx/nginx.conf


EXPOSE 80

CMD ["nginx"]

2
Es löst nicht Ihr Problem, das in den Fragen beschrieben wurde. Es ist nur eine andere Art zu cachen. Kennst du den Grund schon? @ Brian
An Nguyen

@AnNguyen Nein, und ich habe viel Zeit damit verbracht, den npm-Cache zum Laufen zu bringen. Ich schlage vor, Sie verwenden meine Lösung
Brian Ogden

meine situation ist anders. Jedes Mal, wenn ein Build ausgelöst wird, wird ein Slave auf k8s bereitgestellt. Ich kann also nicht basierend auf dem Docker-Erstellungsprozess zwischenspeichern. Ich möchte mich auf den NPM-Cache stützen, damit ich bei jeder Bereitstellung ein beständiges Volume in den Slave mounten kann
An Nguyen

0

Sie können auch einen Nexus-Repository-Server einrichten, auf dem Sie Ihre npm-Module hosten und die externen proxen. Der Cache wird nicht genutzt, aber da sich die Ressourcen in Ihrem lokalen Netzwerk befinden oder sich möglicherweise im selben Schwarm befinden, sollte dies nicht so lange dauern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.