Docker related articles
In-depth articles and comparisons related to Docker, including image optimization and performance analysis.
In-depth articles and comparisons related to Docker, including image optimization and performance analysis.
1. Getting Started
Select an article from the sidebar to begin.
1 - Alpine vs Ubuntu Image: Performance Comparison for Docker Builds
A detailed comparison between Alpine and Ubuntu Docker images, focusing on performance differences in build times and test execution.
When I was working on a UI project I remarked that unit tests(Jest) were running really slowly on our CI pipeline
(Jenkins). On my local machine, the tests were running in about 1 minute, but on Jenkins, it was taking around 10
minutes.
I was wondering why ?
I tested several Jest configurations and ended up adding these parameters --runInBand and --ci. It made the build
not too slow but still it takes ~7 minutes to run on Jenkins.
1. Alpine vs Ubuntu Docker Image

After checking several forums, I decided to migrate to an Ubuntu-based image. The slowness could be because Alpine uses
musl instead of glibc (used by Ubuntu) as C standard library. Note that the musl library is not always slower than
glibc, but musl is designed to be lightweight.
Here are the results for my specific case. I tested npm install/ci/build/test on my local machine using different Docker
images. | Distribution | Node Version | npm ci/install time | Jest time |
Below is a detailed comparison table of different Node.js Docker images (Ubuntu vs Alpine) for key performance metrics:
| Distribution | Image Size | Memory usage React watch mode | npm ci duration | npm install duration | npm run build duration | jest duration |
|---|
| Ubuntu node:20.9.0 | 924MB | 1.54GB | 02:53 | 00:13 | 00:40 | 00:47 |
| Ubuntu node:23 | 905MB | 1.54GB | 01:31 | 00:25 | 00:31 | 00:31 |
| Alpine node:20.9.0-alpine3.18 | 883MB | 1.37GB | 02:10 | 01:56 | 02:01 | 01:00 |
| Alpine node:23-alpine3.20 | 902MB | 1.37GB | 01:56 | 00:33 | 01:28 | 00:33 |
Please note that npm ci/install time is highly dependent on the network, and the results are quite similar. More tests
would be required to have a better overview of the performance. We could also compare with Yarn (I noticed on some
personal projects that Yarn is faster than npm).
The image size is quite similar, practically identical between Ubuntu node:23 and Alpine node:23. So, the argument of
image size is not always a good comparison point to choose between Alpine and Ubuntu.
Where we can see a real difference is in the build time, where Ubuntu is clearly the winner. Also, upgrading from Node
20 to Node 23 shows a noticeable performance boost. We went from ~1 minute to ~30 seconds to run Jest on Alpine,
and a boost also occurs for Ubuntu..
Node 23 makes following warning disappear:
(node:9) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added to [TLSSocket].Use emitter.setMaxListeners() to increase limit
Finally, here is the difference between the pipeline using Ubuntu or Alpine: OK, test and build are still running quite
slowly on Jenkins, probably due to the machine used and maybe version of docker used. But it takes about 4 minutes less
to test and build Storybook using the Ubuntu-based image. 
As a conclusion, ubuntu is not always the winner, and the choice between Alpine and Ubuntu should be part of our
performance tests. Alpine is often considered more secure due to its smaller attack surface, but on the other hand,
Ubuntu has a larger community and more resources dedicated to security and patching.
Also, have a look to
some best practices you should apply when creating a Dockerfile.
Do not hesitate to use my new
AI Docker Skill to
get personalized recommendations for optimizing your Docker images and improving build performance using an AI Copilot
Agent.