Best way to build an image

I have just started to learn Docker. I have a nodeJs web application and built 2 images of it using 2 different Dockerfile. The 2 images are really different in size. Can someone tell me why they are really different in size even though they use the same alpine, node, and npm version, and which one is the recommended way to build a nodeJS application image?

First Dockerfile which created a 91.92MB image:

FROM alpine
RUN apk add --update nodejs npm curl
COPY . /src
WORKDIR /src
RUN npm install
EXPOSE 8080
ENTRYPOINT ["node", "./app.js"]

Second Dockerfile which created a 259.57MB image:

FROM node:19-alpine3.16

RUN apk add --update npm curl

COPY . /src

WORKDIR /src

RUN npm install

CMD [ "node", "./app.js" ]

The difference in size between the two Docker images can be attributed to the base image used and the way the images are built. In the first Dockerfile, the base image used is Alpine, which is a lightweight Linux distribution. This means that the final image will only contain the essential packages required to run the application. On the other hand, in the second Dockerfile, the base image used is a pre-built Node.js image that includes many other packages and dependencies. This could be the reason why the second image is larger.

In terms of the recommended way to build a Node.js application image, it depends on the specific requirements of the application. If the application has minimal dependencies and requires a lightweight runtime environment, using a minimal base image like Alpine would be a good option. However, if the application has complex dependencies and requires a more comprehensive runtime environment, using a pre-built Node.js image would be a better option.

In summary, the choice of the base image and the way the Docker images are built can have a significant impact on the final image size. It’s important to choose the right base image and optimize the Dockerfile to create a lightweight and efficient Docker image for the application.