Optimising Docker Image Sizes: “Self-extracting” Node.js Applications

Home » Blog » Software » Enterprise Software » Optimising Docker Image Sizes: “Self-extracting” Node.js Applications

As a follow-up on last week’s article on tools for inspecting Docker images, and Docker image sizes in particular, today I’d like to introduce another – more custom – approach for reducing the size of Docker images for production deployments.

As a means of shaving off an additional 50 MB from the packaged application in question I came up with an idea somewhat reminiscent of the self-extracting archives of yore (of the WinRAR and 7-Zip flavours, for instance) for reducing the size of Docker images for containerized Node.js applications:

The basic idea is to tar-gzip a Node.js application’s node_modules directory at build time and to unpack that directory again at runtime.

First, we have to provide a RUN instruction like the following to our Dockerfile, specifically its build stage, if we’re using multi-stage builds (which we should …):

Then, we need to add an ENTRYPOINT or CMD instruction like this one, for example, to the stage in our Dockerfile responsible for starting our application at runtime:

Finally, we insert that start:production NPM script we referenced above in our application’s package.json file:

This start:production script contains the tar -xzvf node_modules.tar.gz && rm node_modules.tar.gz responsible for unpacking our Node.js application’s node_modules directory again, without which the application of course wouldn’t be able to run because it’d lack its dependencies. By chaining these commands – and the node command following them – with the logical AND operator && provided by POSIX-compatible operating systems (e.g.: a Unix such as macOS, Linux, or BSD-based operating systems) we make sure that each subsequent command will only be executed if its predecessor has been executed successfully.

Consequently, the process takes slightly longer to start, but the overall Docker image size in this particular case was reduced by roughly 50 MB, which, of course, depending your use case might not matter at all or be an absolute boon. As often is the case in software development and, in fact, computer science at large, such considerations are a matter of trade-offs.

In this case, we’re trading in a faster application start-up for a smaller image size, which, depending on your target environment (e.g., embedded systems) might be a key concern.

About the author: Bjoern
Independent IT consultant, entrepreneur

Leave a Comment