Answers: <p>Another approach you can do is set up a nexus repository server where you host your npm modules and proxy the external ones.  It does not leverage the cache, but because the resources are within your local network or maybe in the same swarm it shouldn't take as long.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-03-21T05:08:15.570Z
Answers: 2018-03-21T05:08:15.570Z
Answers: Archimedes Trajano
Answers: <p>I finally solved this by using Docker image layer caching for the npm install, following <a href="https://stackoverflow.com/a/35774741/1258525">this answer</a></p>
  
  <p>This means I moved the npm install out of the Docker slave image and into the actually frontend image, here is my final Docker file that truly caches the npm install in between builds if package.config has no changes:</p>
  
  <pre><code>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 &amp;&amp; \
      yum clean all &amp;&amp; \
      yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm \
      yum -y makecache &amp;&amp; \
      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
  
  # https://stackoverflow.com/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 &amp;&amp; npm install
  RUN mkdir /app &amp;&amp; cp -a /tmp/node_modules /app/
  
  WORKDIR /app
  COPY . /app
  
  RUN npm run build-$ENVIRONMENT
  
  RUN cd /app &amp;&amp; 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"]
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2019-05-02T15:59:03.560Z
Answers: it doesn't solve your problem that was described in the questions. It's just another way to cache. Do you know the reason yet? @Brian
Answers: An Nguyen
Answers: CC BY-SA 4.0
Answers: 2019-05-02T22:43:57.583Z
Answers: @AnNguyen nope, and I spent alot of time trying to get npm cache to work. I suggest you use my solution
Answers: Brian Ogden
Answers: CC BY-SA 4.0
Answers: 2019-05-03T03:17:46.820Z
Answers: my situation is different. Every time a build is triggered a slave will be provisioned on k8s. So I cannot cache based on docker build process. I want to base on NPM cache so I can mount a persistent volume into slave every time it's provisioned
Answers: An Nguyen
Answers: CC BY-SA 4.0
Answers: 2021-04-02T14:48:46.670Z
Answers: How big is the final container?
Answers: Kraken
Answers: CC BY-SA 3.0
Answers: 2017-12-20T21:30:17.333Z
Answers: 2017-12-21T00:16:24.960Z
Answers: 2017-12-21T00:16:24.960Z
Answers: Brian Ogden
Body: <p>I have a Docker image, let's call it <code>frontend.image</code>, that I use for a Jenkins build slave. The Jenkins <a href="https://wiki.jenkins.io/display/JENKINS/Docker+Plugin" rel="noreferrer">Docker plugin</a> will spin up a container from this image and build artifacts inside the container. This all works great. In this case, the <code>frontend.image</code> is used to build an AngularJs app. Part of building this Angular app is to install npm packages the app requires.</p>
  
  <p>This process, npm install, seems to take a long time, 3 minutes it seems, npm always installs every package every time.</p>
  
  <p>So I added a volume for my slave, it is a host mounted volume, the Docker plugin will use this volume every time it runs the frontend container:</p>
  
  <p><a href="https://i.sstatic.net/V2Osl.png" rel="noreferrer"><img src="https://i.sstatic.net/V2Osl.png" alt="enter image description here"></a></p>
  
  <p>The user that executes the command <code>npm install</code> is <code>jenkins</code>. npm keeps a cache which you can find with command <code>npm config get cache</code> which outputs <code>/home/jenkins/.npm</code></p>
  
  <p>That is why I have the host volume <code>/slaves/volumes/tsl.frontend:/home/jenkins</code> mounted to my web container slave.</p>
  
  <p>I build my Angular app using a Jenkins project, builds no problem, many npm packages are installed. If ssh into my Docker host and run cmd <code>ls /slaves/volumes/tsl.frontend</code> I see lots of npm packages. This means my host volume mount for the slave worked. 
  <a href="https://i.sstatic.net/ggCdS.png" rel="noreferrer"><img src="https://i.sstatic.net/ggCdS.png" alt="enter image description here"></a></p>
  
  <p>Now I build the Jenkins project again, npm installs every single package again, even though the Docker slave build container is using the volume host mount. I can even confirm by bashing into the slave container with cmd <code>docker exec -it &lt;some_clever_random_container_id&gt; bash</code> then cmd <code>su jenkins</code> then cmd <code>npm cache ls</code> which lists many npm packages that are cached.
  <a href="https://i.sstatic.net/a7ldf.png" rel="noreferrer"><img src="https://i.sstatic.net/a7ldf.png" alt="enter image description here"></a></p>
  
  <p>So, even with my host mount volume, which has permissions <code>chmod 777</code> by the way so there is no permissions issues, I cannot get <code>npm install</code> to use the cache.</p>
  
  <p>In my Jenkins build, which spins up the Docker slave container, the first cmd I run is <code>npm cache ls</code> and many packages are listed, doesn't this mean my host volume is working as expected and the npm cache index has integrity aka not corrupted?</p>
  
  <p><a href="https://i.sstatic.net/lEu8b.png" rel="noreferrer"><img src="https://i.sstatic.net/lEu8b.png" alt="enter image description here"></a></p>
  
  <p>I have tried the regular <code>npm install</code> cmd, which, when I run on my localhost machine installs all the packages the first time and almost no packages the next time. And also the npm cache "hack" <code>npm --cache-min 9999999 install</code>, taken from <a href="https://stackoverflow.com/a/38827633/1258525">this SO answer</a> as well as cmd <code>npm --skip-installed --cache-min 9999999 install</code></p>
  
  <p><a href="https://stackoverflow.com/q/46963456/2777965">A related question</a> was posted on StackOverflow.</p>
  
Comments: CC BY-SA 3.0
Comments: 2017-10-26T09:46:25.823Z
Comments: I would bet the cache index is not stored within ~/.npm according to your description
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:19:39.313Z
Comments: @Tensibai you are incorrect and I am very sure about this, the user is jenkins, because that is what you are saying in another way, because I run npm cache ls as jenkins user and that lists packages, you are saying that npm install is being executed by another user
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:26:10.817Z
Comments: no, I'm saying the index itself is probably stored elsewhere, in /usr/local or whatever path npm is installed in or whatelse, I've no idea. This just sounds like npm is acting as if there was nothing in the cache, so I guess it doesn't list the directory but base itself on some kind of index elsewhere.
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:27:23.703Z
Comments: @Tensibai but the cmd npm config get cache returns /home/jenkins.npm as that path don't you think that confirms the location of the cache?
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:29:49.367Z
Comments: The location of the cache yes, that doesn't enforce the cache index is in the same location at all. I'd add a `npm cache ls` and a raw `ls ~/.npm/* -al` in the build script itself before any other build step just to ensure the state of the container when starting the build.
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:31:07.297Z
Comments: I'm just analysing the description, mount works, seems ok within the container, the only reason I could see for it failing is a corrupt cache index according to what npm verify does from the documentation. I've no experience with npm or nodejs, it's just guesses from the behavior.
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-10-26T16:50:08.590Z
Comments: @Tensibai thanks for you advice, it gives me some direction, will update shortly
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-10-26T20:10:42.503Z
Comments: @Tensibai well when I started the container the first cmd I ran is npm cache ls and many packages get listed
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-10-29T12:41:45.100Z
Comments: @BrianOgden The issue has been solved? Please post an answer.
Comments: 030
Comments: CC BY-SA 3.0
Comments: 2017-10-29T18:06:43.780Z
Comments: @Tensibai has not been solved
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-10-29T18:07:46.127Z
Comments: @Tensibai I have also tried to expand my question search for this https://stackoverflow.com/questions/46963456/npm-is-not-using-cache
Comments: Brian Ogden
Comments: CC BY-SA 3.0
Comments: 2017-11-06T19:50:28.743Z
Comments: @BrianOgden One possibility is that this is a symlink issue. Can you try a `readlink -f [filename]` on a few of the files that NPM has supposedly cached? Also, perhaps try running your NPM install with the `--no-bin-links` and without the global flag to prevent creation of symlinks. Finally, `npm cache verify` may give a hint as to the status of the cache.
Comments: user2640621
Comments: CC BY-SA 3.0
Comments: 2017-11-26T17:45:36.303Z
Comments: https://stackoverflow.com/a/35774741/2777965
Comments: 030
Tags: <docker><jenkins><npm>
Title: How to enable the npm cache in a Jenkins build slave that runs in docker?
UserDisplayName: Brian Ogden
ThreadText: # How to enable the npm cache in a Jenkins build slave that runs in docker?
  
  (Asked by: username_0 on 2017-10-26)
  
  I have a Docker image, let's call it `frontend.image`, that I use for a Jenkins build slave. The Jenkins [Docker plugin](https://wiki.jenkins.io/display/JENKINS/Docker+Plugin) will spin up a container from this image and build artifacts inside the container. This all works great. In this case, the `frontend.image` is used to build an AngularJs app. Part of building this Angular app is to install npm packages the app requires.
  
  This process, npm install, seems to take a long time, 3 minutes it seems, npm always installs every package every time.
  
  So I added a volume for my slave, it is a host mounted volume, the Docker plugin will use this volume every time it runs the frontend container:
  
  [![enter image description here](https://i.sstatic.net/V2Osl.png)](https://i.sstatic.net/V2Osl.png)
  
  The user that executes the command `npm install` is `jenkins`. npm keeps a cache which you can find with command `npm config get cache` which outputs `/home/jenkins/.npm`
  
  That is why I have the host volume `/slaves/volumes/tsl.frontend:/home/jenkins` mounted to my web container slave.
  
  I build my Angular app using a Jenkins project, builds no problem, many npm packages are installed. If ssh into my Docker host and run cmd `ls /slaves/volumes/tsl.frontend` I see lots of npm packages. This means my host volume mount for the slave worked.
  [![enter image description here](https://i.sstatic.net/ggCdS.png)](https://i.sstatic.net/ggCdS.png)
  
  Now I build the Jenkins project again, npm installs every single package again, even though the Docker slave build container is using the volume host mount. I can even confirm by bashing into the slave container with cmd `docker exec -it <some_clever_random_container_id> bash` then cmd `su jenkins` then cmd `npm cache ls` which lists many npm packages that are cached.
  [![enter image description here](https://i.sstatic.net/a7ldf.png)](https://i.sstatic.net/a7ldf.png)
  
  So, even with my host mount volume, which has permissions `chmod 777` by the way so there is no permissions issues, I cannot get `npm install` to use the cache.
  
  In my Jenkins build, which spins up the Docker slave container, the first cmd I run is `npm cache ls` and many packages are listed, doesn't this mean my host volume is working as expected and the npm cache index has integrity aka not corrupted?
  
  [![enter image description here](https://i.sstatic.net/lEu8b.png)](https://i.sstatic.net/lEu8b.png)
  
  I have tried the regular `npm install` cmd, which, when I run on my localhost machine installs all the packages the first time and almost no packages the next time. And also the npm cache "hack" `npm --cache-min 9999999 install`, taken from [this SO answer](https://stackoverflow.com/a/38827633/1258525) as well as cmd `npm --skip-installed --cache-min 9999999 install`
  
  [A related question](https://stackoverflow.com/q/46963456/2777965) was posted on StackOverflow.
  
  **Tags:** docker, jenkins, npm
  
  > **Comments:**
  > **username_1**: I would bet the cache index is not stored within ~/.npm according to your description  
  > **username_0**: @username_1 you are incorrect and I am very sure about this, the user is jenkins, because that is what you are saying in another way, because I run npm cache ls as jenkins user and that lists packages, you are saying that npm install is being executed by another user  
  > **username_1**: no, I'm saying the index itself is probably stored elsewhere, in /usr/local or whatever path npm is installed in or whatelse, I've no idea. This just sounds like npm is acting as if there was nothing in the cache, so I guess it doesn't list the directory but base itself on some kind of index elsewhere.  
  > **username_0**: @username_1 but the cmd npm config get cache returns /home/jenkins.npm as that path don't you think that confirms the location of the cache?  
  > **username_1**: The location of the cache yes, that doesn't enforce the cache index is in the same location at all. I'd add a `npm cache ls` and a raw `ls ~/.npm/* -al` in the build script itself before any other build step just to ensure the state of the container when starting the build.  
  > **username_1**: I'm just analysing the description, mount works, seems ok within the container, the only reason I could see for it failing is a corrupt cache index according to what npm verify does from the documentation. I've no experience with npm or nodejs, it's just guesses from the behavior.  
  > **username_0**: @username_1 thanks for you advice, it gives me some direction, will update shortly  
  > **username_0**: @username_1 well when I started the container the first cmd I ran is npm cache ls and many packages get listed  
  > **username_2**: @username_0 The issue has been solved? Please post an answer.  
  > **username_0**: @username_1 has not been solved  
  > **username_0**: @username_1 I have also tried to expand my question search for this https://stackoverflow.com/questions/46963456/npm-is-not-using-cache  
  > **username_3**: @username_0 One possibility is that this is a symlink issue. Can you try a `readlink -f [filename]` on a few of the files that NPM has supposedly cached? Also, perhaps try running your NPM install with the `--no-bin-links` and without the global flag to prevent creation of symlinks. Finally, `npm cache verify` may give a hint as to the status of the cache.  
  > **username_2**: https://stackoverflow.com/a/35774741/2777965  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2017-12-20. Score: 7 | Accepted answer
  
  I finally solved this by using Docker image layer caching for the npm install, following [this answer](https://stackoverflow.com/a/35774741/1258525)
  
  This means I moved the npm install out of the Docker slave image and into the actually frontend image, here is my final Docker file that truly caches the npm install in between builds if package.config has no changes:
  
  ```
  FROM centos:7
  MAINTAINER username_0
  
  # 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
  
  # https://stackoverflow.com/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"]
  
  ```
  
  > **Comments:**
  > **username_5**: it doesn't solve your problem that was described in the questions. It's just another way to cache. Do you know the reason yet? @username_0  
  > **username_0**: @username_5 nope, and I spent alot of time trying to get npm cache to work. I suggest you use my solution  
  > **username_5**: my situation is different. Every time a build is triggered a slave will be provisioned on k8s. So I cannot cache based on docker build process. I want to base on NPM cache so I can mount a persistent volume into slave every time it's provisioned  
  > **username_6**: How big is the final container?  
  
  ---
  
  ### Answer by username_4 on 2018-03-21. Score: 0
  
  Another approach you can do is set up a nexus repository server where you host your npm modules and proxy the external ones. It does not leverage the cache, but because the resources are within your local network or maybe in the same swarm it shouldn't take as long.
  
  
  ---
  
  