I'm running a cluster of nodeJS applications - which should be very small as they are run as microservices. Only a few of them need extra things like bcrypt or imagemagick - which makes some trouble from time to time for me.
Right now I'm using node:10.13-alpine
as a base image for all Dockerfiles to build my apps. For some of them I need to add dependencies via apk
and so on. So these images become bigger. Is it the best approach to use a alpine image, which gets bigger by adding needed packages (e.g. python, gcc...)? Or should I use a full image?
If I would use node:10.13
, the base image would be a lot bigger, but if my understanding is correct my applications would only add a small layer as the same base image is used. So at the end it is better to use one big node image??
In general, the node docker image size of the applications is over 1 GB most of the time.
Because usually docker images contains only necessary minimum - in case of ubuntu image, only base system, without GUI (which is rarely used in containers) and without most tools. Ubuntu image actually relatively big - there are much smaller ones.
Alpine Linux is a Linux distribution built around musl libc and BusyBox. The image is only 5 MB in size and has access to a package repository that is much more complete than other BusyBox based images. This makes Alpine Linux a great image base for utilities and even production applications.
No, it doesn't come with npm. You'd want to use one of the node images such as github.com/nodejs/docker-node/blob/… which has an alpine base image but comes with npm.
Alpine images are smaller, since other packages using a lot of libraries, which are not used by your solution.
What's are the benefits to use small images?
The benefits are: less memory, better performance, security and maintainability.
A smaller docker image reduce the size needed on disk, but disk space is cheap.
Much more important is that it also consume less memory, which is limited on every server. If you reduce the amount of base images on your server, this also lead that you need less memory at all. Less memory means also you have less swapping and so you can get some performance improvements in having all base images loaded in memory.
Another feature is, that base images from alpine using less depend libraries, which improve the overall security. You can separate risks easily, with your base alpine image and using on top images which only use the apk, which really needed. This has also advantages regarding the overall maintenance.
You can see on https://hub.docker.com/r/library/node/tags/, that the alpine version has no vulnerabilities. All other image version have some issues, which may target the security of your solution.
Why the default is still "buildpack-deps" and why you maybe should use them?
When you read the official documentation to the docker images for node:
https://hub.docker.com/_/node/
Main takeaways are:
For me this means finally, that you can use the normal package in the most cases, if you use other images build on "buildpack-deps". It maybe possible to be the better solution, in this case since you don't have the need beside of the "buildpack-deps" to hold an "alpine" base image in on your disk and memory.
Conclusion
If you have "only" alpine images on your docker environment, then you should go with "alpine" or if the security of the "node" containers are really important to you.
In most cases the "node" images based on "buildpack-deps" are suitable, since you have other docker containers based on "buildpack-deps".
In future I assume more and more packages will be available based on "alpine" and then you should go with node-alpine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With