Building Docker images for my NodeJS-TypeScript project was a breeze… at first. But soon, every npm install
during a build became a dreaded time sink. The thought of another tiny change triggering another agonizing wait filled me with developer despair.
Let’s peek behind the curtain of my experiment. I was facing agonizingly long build times with my original Dockerfile. It looked something like this:
FROM node:lts-alpine
# Set up directories and permissions
RUN mkdir -p /app/node_modules && chown -R node:node /app
WORKDIR /app
# Copy essential files
COPY ["package.json", "package-lock.json", "tsconfig.json", "./"]
COPY ./src ./src
# Install dependencies and compile code
RUN npm install
RUN npx tsc
USER node
EXPOSE 8000
CMD [ "node", "dist/index.js" ]
The key breakthrough? Shifting dependency installation! With just two lines swapped, those excruciating build times became a distant memory. Here’s the optimized masterpiece:
FROM node:lts-alpine
# Set up directories and permissions
RUN mkdir -p /app/node_modules && chown -R node:node /app
WORKDIR /app
# Copy essential files
COPY ["package.json", "package-lock.json", "tsconfig.json", "./"]
# Install dependencies and compile code
RUN npm install
COPY ./src ./src
RUN npx tsc
USER node
EXPOSE 8000
CMD [ "node", "dist/index.js" ]
What’s the secret sauce? It all boils down to dependency installation timing. In the original file, we copied everything (including source code) before installing dependencies. That meant even minor code changes triggered a full re-installation, dragging out the process.
The tweak? We moved npm install
before copying the source code. Now, Docker can cache that dependency layer, saving precious time on subsequent builds! Plus, the final image sheds unnecessary baggage, shrinking from 138.87 MB to a svelte 129.6 MB.
To further improve caching and build times:
- Multi-Stage Builds: Consider using multi-stage builds to isolate dependency installation and create even smaller final images.
- Caching Strategies: Explore different caching strategies and tools for Node.js projects, such as
npm ci
or Yarn's offline cache.
And that is all for now.