How to reduce the size of Docker images

I have a Node.js application that I run as a docker container. Here is the Docker file for this application.

FROM ubuntu ARG ENVIRONMENT ARG PORT RUN apt-get update -qq RUN apt-get install -y build-essential nodejs npm nodejs-legacy vim RUN mkdir /consumer_portal ADD . /consumer_portal WORKDIR /consumer_portal RUN npm install -g express RUN npm install -g path RUN npm cache clean RUN npm install EXPOSE $PORT ENTRYPOINT [ "node", "server.js" ] CMD [ $PORT, $ENVIRONMENT ] 

Can I change something in this Docker file to reduce docker image size

+5
source share
6 answers

Using the official node alpine image as the base image, like most of the ones offered here, is a simple solution to reduce the overall image size, because even the basic alpine image is much smaller compared to the ubuntu base image.

A Docker file might look like this:

 FROM node:alpine ARG ENVIRONMENT ARG PORT RUN mkdir /consumer_portal \ && npm install -g express path COPY . /consumer_portal WORKDIR /consumer_portal RUN npm cache clean \ && npm install EXPOSE $PORT CMD [ "node", "server.js" ] 

This is almost the same and should work as expected. Most of the commands from your ubuntu image can be applied in the same way in an alpine image.

When I add mock-data to create a similar project, as you could, I get a 491 MB ubuntu image and an alpine version only 62.5 MB:

 REPOSITORY TAG IMAGE ID CREATED SIZE alpinefoo latest 8ca6f338475e 5 minutes ago 62.5MB ubuntufoo latest 38620a1bd5a6 6 minutes ago 491MB 
+3
source

Try to put all the RUN instructions together, this will reduce the number of intermediate images. (But this will not reduce the size).

Adding rm -rf /var/lib/apt/lists/* after apt-get update will reduce the image size by removing all the useless apt-get stuff.

You can also remove vim from your image in the last RUN statement.

 FROM ubuntu ARG ENVIRONMENT ARG PORT RUN apt-get update \ && apt-get install -y build-essential nodejs npm nodejs-legacy vim \ && rm -rf /var/lib/apt/lists/* \ && mkdir /consumer_portal ADD . /consumer_portal WORKDIR /consumer_portal RUN npm install -g express \ && npm install -g path \ && npm cache clean \ && npm install EXPOSE $PORT ENTRYPOINT [ "node", "server.js" ] CMD [ $PORT, $ENVIRONMENT ] 
+1
source

If you rely on Ubuntu then smart move should do it

 RUN apt-get update && apt-get install -y \ build-essential \ cwhatever-you-want \ vim \ && rm -rf /var/lib/apt/lists/* 

The last line will clear a lot :) You should always apt-get the update on the same line, because otherwise it will be cached and will not start in the next builds if you add another lib to install.

0
source

1) Most likely, moving to Alpine. I just ported the Ubuntu docker file to Alpine and switched from 1.5 to 585 MB. I followed these instructions . Please note: you will use apk instead of apt-get, and Alpine's package names are slightly different.

2) It is also possible to reduce levels by merging start commands (each new start command creates a new layer).

 RUN apt-get update -qq && apt-get install -y build-essential nodejs npm nodejs-legacy vim RUN npm install -g express path && npm cache clean && npm install 

3) You may also be interested in a multi-stage assembly in which you copy only the necessary components into the final image.

0
source

Container image size is a problem that needs to be fixed properly.

Some suggest using alpline distribution to save space.

This is basically a good suggestion, as there is a nodejs image for alpine that is ready to use.

But you have to be careful here because you need to collect all the binaries. Even _node_modules_ usually only contains javascript packages, in some cases you have a binary that needs to be created.

If your docker file is working right now, this should not be your business, but as you move from ubuntu to a different kind of image, it is better to keep in mind that all binaries that you need to use in the future should be compiled into alpine image.

He said that you should think about how you use your image before choosing where to reduce the size.

Is your application the only application that lives separately only in its own container without any other node application?

If the answer is no, you should know that the size of each image in the local docker registry does not count as a summary to get the total size used.

Instead, you need to split each image in the base layers and summarize each uniq layer.

I mean, one image is not that important if you have many node applications that run on node.

You can save space by splitting _node_modules_ by exporting it as a volume that contains all the necessary dependencies.

Or better, you can start with the official nodejs image to create an intermediate image containing the dependency root of your applications. For example expressjs and path. And then set the selected dependencies in each application image.

Thus, you get the advantage of sharing common layers, reducing the overall size of the local registry of local dockers.

Minor considerations

You do not need to set the express and the way around the world inside the container image.

Do you really need vim in the container? Note that modifying a container is unsafe even in development. You can use the volume to specify resources in the server file system. Or copy the file / folder from your container while you work. And if you just need to read something, just use commands like less, more or cat.

0
source

Think about it: try using --no-install-recommends when installing apt-get packages. This will reduce the image size. For more information, see this blog post.

There is a good blog that will tell you a few steps to reduce image size.

Docker Image Reduction Tips https://hackernoon.com/tips-to-reduce-docker-image-sizes-876095da3b34

0
source

Source: https://habr.com/ru/post/1267182/


All Articles