Slim containers are faster (less stuff to move around) and more secure (fewer places for vulnerabilities to sneak in). However, these benefits of slim containers come at a price - such containers lack (the much-needed at times) exploration and debugging tools. It might be quite challenging to tap into a container that was built from a distroless or slim base image or was minified using DockerSlim or alike. Over the years, I've learned a few tricks how to troubleshoot slim containers, and it's time for me to share.
A container image is a combination of layers where every layer represents some intermediary state of the final filesystem. Such a layered composition makes the building, storage, and distribution of images more efficient. But from a mere developer's standpoint, images are just root filesystems of our future containers. And we often want to explore their content accordingly - with familiar tools like
file. Let's try to see if we can achieve this goal using nothing but the means provided by Docker itself.
GoogleContainerTools' distroless base images are often mentioned as one of the ways to produce small(er), fast(er), and secure(r) containers. But what are these distroless images, really? Why are they needed? What's the difference between a container built from a distroless base and a container built from scratch? Let's take a deeper look.
Many of us these days seem to be in pursuit of better container images. And this is for good reasons! Bloated images with many (potentially unneeded) moving parts slow down development and give more space for a CVE to sneak in. Luckily, there is a number of ways to produce slim and secure images, and everyone just needs to pick
their poison a suitable one. But before doing so, it's good to become aware of a potential dissonance between what we say is important for us (securing our software supply chains) and what may actually drive our decisions (keeping out dev loops fast).
I was hacking containers recently and noticed, that Docker started featuring the
docker scan command in the
docker build output. I've been ignoring its existence for a while, so evidently, it was time to finally try it out.
Scanning official Python images
docker scan command uses a third-party tool, called Snyk Container. Apparently, it's some sort of a vulnerability scanner. So, I decided, mostly for the sake of fun, to scan one of my images. And it just so happened that it was a fairly basic thing:
# latest stable at the time FROM python:3.9 RUN pip install Flask COPY server.py server.py ENV FLASK_APP=server.py ENV FLASK_RUN_PORT=5000 ENV FLASK_RUN_HOST=0.0.0.0 EXPOSE 5000 CMD ["flask", "run"]
docker build -t python-flask . and then
docker scan python-flask. To my utter surprise, the output was huge! Here is just an excerpt: