¿Cómo habilitar el caché npm en un esclavo de compilación Jenkins que se ejecuta en docker?

13

Tengo una imagen de Docker, llamémosla frontend.image, que uso para un esclavo de compilación Jenkins. El complemento Jenkins Docker hará girar un contenedor a partir de esta imagen y creará artefactos dentro del contenedor. Todo esto funciona muy bien. En este caso, frontend.imagese usa para construir una aplicación AngularJs. Parte de la construcción de esta aplicación Angular es instalar paquetes npm que la aplicación requiere.

Este proceso, npm install, parece tomar mucho tiempo, parece que 3 minutos, npm siempre instala todos los paquetes cada vez.

Así que agregué un volumen para mi esclavo, es un volumen montado en el host, el complemento Docker usará este volumen cada vez que ejecute el contenedor frontend:

ingrese la descripción de la imagen aquí

El usuario que ejecuta el comando npm installes jenkins. npm mantiene un caché que puede encontrar con el comando npm config get cacheque genera/home/jenkins/.npm

Es por eso que tengo el volumen del host /slaves/volumes/tsl.frontend:/home/jenkinsmontado en mi contenedor web esclavo.

Construyo mi aplicación Angular usando un proyecto Jenkins, construye sin problemas, se instalan muchos paquetes npm. Si ssh en mi host Docker y ejecuta cmd ls /slaves/volumes/tsl.frontend, veo muchos paquetes npm. Esto significa que mi montaje de volumen de host para el esclavo funcionó. ingrese la descripción de la imagen aquí

Ahora vuelvo a compilar el proyecto Jenkins, npm instala cada paquete nuevamente, a pesar de que el contenedor de compilación esclavo Docker está utilizando el montaje de host de volumen. Incluso puedo confirmar golpeando en el contenedor esclavo con cmd, docker exec -it <some_clever_random_container_id> bashluego cmd y su jenkinsluego cmd, npm cache lsque enumera muchos paquetes npm que se almacenan en caché. ingrese la descripción de la imagen aquí

Entonces, incluso con mi volumen de montaje de host, que tiene permisos chmod 777por cierto, por lo que no hay problemas de permisos, no puedo npm installusar el caché.

En mi compilación Jenkins, que hace girar el contenedor esclavo Docker, el primer cmd que ejecuto es npm cache lsy se enumeran muchos paquetes, ¿no significa esto que mi volumen de host funciona como se esperaba y que el índice de caché npm tiene integridad también conocida como no está dañada?

ingrese la descripción de la imagen aquí

He probado el npm installcmd normal , que, cuando ejecuto en mi máquina localhost, instala todos los paquetes la primera vez y casi ningún paquete la próxima vez. Y también el "hack" de caché npm npm --cache-min 9999999 install, tomado de esta respuesta SO así como cmdnpm --skip-installed --cache-min 9999999 install

Se publicó una pregunta relacionada en StackOverflow.

Brian Ogden
fuente
Apuesto a que el índice de caché no se almacena dentro de ~ / .npm según su descripción
Tensibai
@Tensibai eres incorrecto y estoy muy seguro de esto, el usuario es jenkins, porque eso es lo que estás diciendo de otra manera, porque ejecuto npm cache ls como usuario de jenkins y eso enumera los paquetes, estás diciendo que npm install es siendo ejecutado por otro usuario
Brian Ogden
no, estoy diciendo que el índice en sí mismo probablemente esté almacenado en otro lugar, en / usr / local o cualquier ruta en la que esté instalado npm o lo que sea, no tengo idea. Esto suena como que npm está actuando como si no hubiera nada en el caché, así que supongo que no enumera el directorio sino que se basa en algún tipo de índice en otro lugar.
Tensibai
@Tensibai pero la configuración cmd npm obtiene caché devuelve /home/jenkins.npm como esa ruta ¿no crees que eso confirma la ubicación de la caché?
Brian Ogden
La ubicación de la memoria caché sí, eso no exige que el índice de la memoria caché se encuentre en la misma ubicación. Agregaría un npm cache lsy un raw ls ~/.npm/* -alen el script de compilación en sí mismo antes de cualquier otro paso de compilación solo para asegurar el estado del contenedor al iniciar la compilación.
Tensibai

Respuestas:

5

Finalmente resolví esto usando el almacenamiento en caché de la capa de imagen de Docker para la instalación de npm, siguiendo esta respuesta

Esto significa que moví la instalación de npm fuera de la imagen esclava de Docker y la coloqué en la imagen de la interfaz, aquí está mi archivo Docker final que realmente almacena en caché la instalación de npm entre compilaciones si package.config no tiene cambios:

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"]
Brian Ogden
fuente
2
no resuelve el problema que se describió en las preguntas. Es solo otra forma de almacenar en caché. ¿Ya sabes la razón? @Brian
An Nguyen
@AnNguyen no, y pasé mucho tiempo tratando de hacer que npm cache funcione. Sugiero que use mi solución
Brian Ogden,
Mi situación es diferente. Cada vez que se activa una compilación, se proporcionará un esclavo en k8s. Por lo tanto, no puedo almacenar en caché según el proceso de construcción de Docker. Quiero basarme en la memoria caché NPM para poder montar un volumen persistente en esclavo cada vez que se aprovisiona
un Nguyen
0

Otro enfoque que puede hacer es configurar un servidor de repositorio nexus donde aloje sus módulos npm y proxy los externos. No aprovecha el caché, pero debido a que los recursos están dentro de su red local o tal vez en el mismo enjambre, no debería tomar tanto tiempo.

Arquímedes Trajano
fuente