Managing Docker images might become a bit of a painful experience, especially when looking at your storages: very “simple” images like node end up quite fat and contribute to sucking up a good chunck of your HDD.
At the same time, the most painful moment with Docker images is, at least for me, when you want to pull and run a brand new image, not available on your machine (or production servers, not much difference): you will need to wait until the whole image gets downloaded before being able to play around with it1.
At the end of the day, one thing is clear: we’d like to shrink images as much as possible. Turns out, the easiest solution is, as often, the simplest one: start small, end small.
There are plenty of resources on limiting the size of your images / containers, but today I am going to start with this very simple approach.
Busybox
If you are not familiar with it, let me introduce busybox to you: a very tiny linux distribution (~2.5mb) which can be summarized in “an OS with a bunch of bare-minimum binaries”: busybox is so well done that has been dockerized and used quite extensively within the docker ecosystem.
The nice thing is that, being so small, busybox takes nothing to run:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
This is it, I downloaded and ran whoami
on busybox in 17 seconds,
tethering from my phone2.
The only problem with busybox is the following:
1 2 3 |
|
You got it, busybox is so bare that it only includes a few binaries to let you play with3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
So, not having a package manager might be quite of a painful thing if you need to run real world apps that need to rely on environments such as python, nodejs and so on: we need to find another minimal distribution that can give us a substantial help on that front.
Alpine
Alpine is a busybox-based linux distribution on steroids: it is gaining so much traction in the Docker ecosystem since it has 2 features that, combined together, make it quite of a valuable base image: it is ~5mb in size and uses the apk package manager.
So, of course, people love it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
There you go: a super-shrunk python environment in less than 2 minutes, without “dirtying” your own hardware.
Your node app with Alpine
Once I discovered alpine I started wondering if I could run some of my node apps on it — which led me to this simple Dockerfile:
1 2 3 |
|
Nothing more, nothing less; at this point, let me create a simple server and run it through this image:
1 2 3 4 |
|
And what about the size of our image?
1 2 |
|
Quite sweet, less than 25mb!
(you can also use imagelayers to compare it to other public Docker images4)
Conclusion
The easiest solution is always the simplest one: start from a very small base image, add as you need:
- use Alpine when you can simply rely on a package manager
- use a full-blown image, for example, when you need to compile stuff or to use the uber-latest version of some library
- use busybox if you’re the emacs guy
Personally, I think I will be experimenting a lot with Alpine in the upcoming weeks: since we, at Namshi, rely on containers in all our apps5 it’d be quite intriguing to test alpine in development and production environments.
- Sure, Docker caches and re-uses layer, but the first time is always painful! ↩
- A Samsung Galaxy S3, so quite lame of a phone as well… :) ↩
- busybox is actually one binary that implements the usual unix commands like cat, etc etc ↩
- I am quite sure someone has a smaller, more complete NodeJS image on the hub, just search for it ↩
- Or, say, 90% of them: there is still some legacy stuff… :) ↩