Como habilitar o cache npm em um Jenkins build slave que é executado no docker?

13

Eu tenho uma imagem do Docker, vamos chamá-la frontend.image, que eu uso para um Jenkins build slave. O plug - in Jenkins Docker girará um contêiner nesta imagem e criará artefatos dentro do contêiner. Tudo isso funciona muito bem. Nesse caso, o frontend.imageé usado para criar um aplicativo AngularJs. Parte da criação desse aplicativo Angular é instalar os pacotes npm necessários.

Esse processo, npm install, parece levar muito tempo, 3 minutos, o npm sempre instala todos os pacotes todas as vezes.

Então, adicionei um volume para o meu escravo, é um volume montado no host, o plug-in do Docker usará esse volume sempre que executar o contêiner de front-end:

insira a descrição da imagem aqui

O usuário que executa o comando npm installé jenkins. O npm mantém um cache que você pode encontrar com o comando npm config get cacheque gera/home/jenkins/.npm

É por isso que tenho o volume do host /slaves/volumes/tsl.frontend:/home/jenkinsmontado no meu escravo de contêiner da web.

Eu construo meu aplicativo Angular usando um projeto Jenkins, não cria nenhum problema, muitos pacotes npm estão instalados. Se o ssh no meu host do Docker e executar o cmd ls /slaves/volumes/tsl.frontend, vejo muitos pacotes npm. Isso significa que o volume do meu host montado para o escravo funcionou. insira a descrição da imagem aqui

Agora, construo o projeto Jenkins novamente, o npm instala todos os pacotes novamente, mesmo que o contêiner de construção escravo do Docker esteja usando a montagem do host de volume. Posso até confirmar baseando-me no contêiner escravo com cmd docker exec -it <some_clever_random_container_id> bash, cmd su jenkinse cmd, npm cache lsque lista muitos pacotes npm armazenados em cache. insira a descrição da imagem aqui

Portanto, mesmo com o volume de montagem do host, que possui permissões chmod 777a propósito, para que não haja problemas de permissões, não consigo npm installusar o cache.

Na minha compilação Jenkins, que gira o contêiner escravo do Docker, o primeiro cmd que eu executo é npm cache lse muitos pacotes estão listados, isso não significa que o volume do meu host está funcionando conforme o esperado e o índice de cache npm tem integridade, ou seja, não está corrompida?

insira a descrição da imagem aqui

Eu tentei o npm installcmd normal , que, quando eu executo na minha máquina localhost, instala todos os pacotes na primeira vez e quase nenhum pacote na próxima vez. E também o cache npm "hack" npm --cache-min 9999999 install, extraído dessa resposta do SO e do cmdnpm --skip-installed --cache-min 9999999 install

Uma pergunta relacionada foi publicada no StackOverflow.

Brian Ogden
fonte
Eu apostaria o índice de cache não é armazenada dentro de ~ / .npm de acordo com sua descrição
Tensibai
@ Tensibai você está incorreto e tenho muita certeza disso, o usuário é o jenkins, porque é isso que você está dizendo de outra maneira, porque eu executo npm cache ls como usuário do jenkins e que lista os pacotes, você está dizendo que a instalação do npm é sendo executado por outro usuário
Brian Ogden
não, estou dizendo que o próprio índice provavelmente está armazenado em outro lugar, em / usr / local ou em qualquer caminho em que o npm esteja instalado ou não, não tenho idéia. Parece que o npm está agindo como se não houvesse nada no cache, então acho que ele não lista o diretório, mas se baseia em algum tipo de índice em outro lugar.
Tensibai 26/10
@ Tensibai, mas a configuração do cmd npm obtém o cache retorna /home/jenkins.npm como esse caminho, você não acha que confirma a localização do cache?
Brian Ogden
O local do cache sim, que não impõe o índice do cache, está no mesmo local. Eu adicionaria um npm cache lse um raw ls ~/.npm/* -alno próprio script de compilação antes de qualquer outra etapa da compilação apenas para garantir o estado do contêiner ao iniciar a compilação.
Tensibai 26/10

Respostas:

5

Finalmente resolvi isso usando o cache da camada de imagem do Docker para a instalação do npm, seguindo esta resposta

Isso significa que movi a instalação do npm para fora da imagem escrava do Docker e para a imagem realmente front-end, eis o meu arquivo final do Docker que realmente armazena em cache a instalação do npm entre as compilações, se package.config não tiver alterações:

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
fonte
2
isso não resolve o problema descrito nas perguntas. É apenas outra maneira de armazenar em cache. Você já sabe o motivo? @Brian
An Nguyen
@AnNguyen não, e eu passei muito tempo tentando fazer o cache do npm funcionar. Eu sugiro que você use minha solução
Brian Ogden
minha situação é diferente. Toda vez que uma construção é acionada, um escravo é provisionado no k8s. Portanto, não posso armazenar em cache com base no processo de construção do docker. Quero base sobre cache do NPM para que eu possa montar um volume persistente em escravo cada vez que é provisionado
An Nguyen
0

Outra abordagem que você pode fazer é configurar um servidor de repositório nexus no qual hospede seus módulos npm e faça proxy dos externos. Ele não utiliza o cache, mas como os recursos estão dentro da sua rede local ou talvez no mesmo enxame, não deve demorar tanto tempo.

Archimedes Trajano
fonte