Question

Best practices for reducing Docker image size for Node.js apps?

I’ve been using Docker to containerize my Node.js application, but my image size is quite large, and it’s affecting build times and deployments.

What are some best practices or strategies for reducing the size of a Docker image for a Node.js app? Should I be concerned about using specific base images, and are there any tips for cleaning up unnecessary files during the build process? Thanks in advance for your help!


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
October 8, 2024
Accepted Answer

Hey there! 👋

Reducing the size of Docker images is always a good idea, especially when working with Node.js apps since smaller images help speed up your builds and deployments! Here are a few things that I usually do:

  1. Instead of using the default node image, you can opt for node:alpine, which is a minimal version of the Node.js image based on Alpine Linux. It’s significantly smaller than the regular images:

    FROM node:alpine
    
  2. Use multi-stage builds. This allows you to keep your final image clean and only include the necessary production dependencies. Here’s a basic example:

    # First stage: Build the app
    FROM node:alpine AS build
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    RUN npm run build
    
    # Second stage: Production
    FROM node:alpine
    WORKDIR /app
    COPY --from=build /app .
    CMD ["node", "server.js"]
    

    With this, you only ship the final built app, excluding any development dependencies or unnecessary files which can help a lot!

  3. Just like .gitignore, a .dockerignore file can prevent unnecessary files (like node_modules, logs, or .git) from being copied into your Docker image. Here’s an example .dockerignore:

    node_modules
    logs
    .git
    
  4. Combine commands into a single RUN statement to reduce the number of layers in the final image:

    RUN apk add --no-cache bash && \
        npm install && \
        npm cache clean --force
    
  5. When installing packages, make sure you clean up caches and unnecessary files. For example:

    RUN npm install && npm cache clean --force
    
  6. When building for production, use the NODE_ENV environment variable to exclude dev dependencies:

    ENV NODE_ENV=production
    RUN npm install
    

Let me know if you need any more help!

- Bobby

KFSys
Site Moderator
Site Moderator badge
October 8, 2024

Heya,

Without a more indepth knowledge of the image itself we could only provide you with some general tips like:

Use a Minimal Base Image

  • Alpine Linux: This is a minimal base image that can significantly reduce the size of your image compared to larger images like node or ubuntu. You can use the official Node.js Alpine image:
FROM node:18-alpine
Alpine-based images are much smaller but may require some additional setup for native modules since they don’t include all system dependencies by default.

Multi-Stage Builds

Multi-stage builds allow you to separate the build environment from the production environment, meaning you can install and compile dependencies in one stage and then copy only the necessary files to the final image.

# Build Stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
COPY . .

# Production Stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app /app
CMD ["node", "app.js"]

###Clean Up Node Modules

  • roduction Dependencies Only: Ensure you only install production dependencies in your final image:
RUN npm ci --only=production
This prevents the inclusion of unnecessary development dependencies in the final build.
  • Prune Dev Dependencies: After installing dependencies, prune anything not required in production:
RUN npm prune --production

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.