Search code examples
javascriptnode.jsdockercontinuous-integrationtutum

How to cache node_modules on Docker build?


I've been trying for some time to cache node_modules on a Docker build. I've tried several approaches including the one here, but without success.

My main reason to cache is because it takes 30+ minutes to build my image, which is way too much.

My Dockerfile:

# This image will be based on the oficial nodejs docker image
FROM node:4.2.1

RUN npm install -g [email protected] && \
    npm install -g gulp && \
    npm install -g tsd

# Use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
ADD package.json /src/package.json
RUN cd /src && npm install

# Put all our code inside that directory that lives in the container
ADD . /src

# Set in what directory commands will run
WORKDIR /src

# Install dependencies
RUN cd /src && \
    tsd reinstall -so && \
    jspm install && \
    gulp build -p

# Tell Docker we are going to use this port
EXPOSE 3000

# The command to run our app when the container is run
CMD ["npm", "run", "start-production"]

I do not have a .dockerignore file. I added one before but it still didn't cache my node_modules.

So, how to I cache my node_modules? Feel free to suggest modifications to the Dockerfile.

Thanks!


Solution

  • I'm not sure whether it is the root of the error, but try to specify the destination folder in the ADD command and not the destination file.

    ADD package.json /src
    

    Moreover, you can use COPY instead of ADD (ADD can work with url and archives but you don't need it here).

    You can also specify your working directory earlier in the file.

    Try with this code :

        # This image will be based on the official nodejs docker image
        FROM node:4.2.1
        
        RUN npm install -g [email protected] && \
            npm install -g gulp && \
            npm install -g tsd
    
        # Set in what directory commands will run
        WORKDIR /src
        
        # Use changes to package.json to force Docker not to use the cache
        # when we change our application’s nodejs dependencies:
        COPY package.json ./
    
        RUN npm install
        
        # Put all our code inside that directory that lives in the container
        COPY . ./
        
        # Install dependencies
        RUN tsd reinstall -so && \
            jspm install && \
            gulp build -p
        
        # Tell Docker we are going to use this port
        EXPOSE 3000
        
        # The command to run our app when the container is run
        CMD ["npm", "run", "start-production"]