Learn how to test the capabilities of docker-slim on Java and Python images and containerized Spring and Flask apps.
If you’ve ever worked with Docker, there’s likely been at least one time when it started taking up significant storage space on your computer. For example, some of your images took a long time to download in a CI/CD pipeline. Some common approaches to this problem are to:
- Swap out the base image for something lighter
- Reduce the number of
RUNstatements in your Dockerfile
- Remove cached package manager artifacts as part of your Dockerfile
These steps, while helpful, can take up a significant amount of time and effort. Thankfully, there are open source tools that can automatically minify an existing Docker image. Enter docker-slim.
This post aims to showcase and test out the capabilities of
docker-slim for several use cases:
- Optimizing a larger, debian based Docker image running a Java app.
- Optimizing a smaller, alpine-based Docker image running a Python app.
I highly recommend checking out
docker-slim using the link above; here’s the repository’s description:
“Don’t change anything in your Docker container image and minify it by up to 30x (and for compiled languages even more) making it secure too! (free and open source)”
I know what you’re thinking.
Surely this is too good to be true.
Either that, or you’re wondering if this applies to heavily layered images with many
Let’s have a look.
Dockerfile 1: Containerized Spring (Java) app
First, let’s take a quick look at the Dockerfile supporting my HelloWorld Java app:
FROM openjdk:8 EXPOSE 8080 COPY . /usr/src/myapp WORKDIR /usr/src/myapp CMD ["./mvnw", "spring-boot:run"]
When built, it yields an image this size:
REPOSITORY TAG IMAGE ID CREATED SIZE javatest latest dff8c8aa3566 7 seconds ago 520MB
That’s pretty hefty. Admittedly, this could be shaved down by using a smaller alpine-based image, but we’ll explore that in the Python example. For now, let’s see what
docker-slim can do for us.
$ docker-slim build --target javatest:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE javatest.slim latest 76c7a799c027 6 seconds ago 214MB javatest latest dff8c8aa3566 3 minutes ago 520MB
So, from running one command and without refactoring the Dockerfile manually, we went from 520MB (with what was a pretty simple Dockerfile) to 214MB (41% of its original size!).
The million-dollar question of course is: does the app the image is serving still function?
$ docker run --name javatest -P -d javatest.slim:latest 3c2148270edac2a19a7f1df1c26ab7daa29bae7243a25fe1bfc20a6261f4f9f8 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3c2148270eda javatest.slim:latest "./mvnw spring-boot:…" 7 seconds ago Up 6 seconds 0.0.0.0:55030->8080/tcp javatest $ curl http://localhost:55030 <p>Hello there</p>%
Yes, it does.
Dockerfile 2: Containerized Flask (Python) app
So, the results from the JDK image were pretty impressive. Let’s try something more challenging and move on to our next Dockerfile:
FROM python:3.8-alpine3.13 ADD . /api WORKDIR /api RUN pip install -r requirements.txt EXPOSE 80 CMD ["python", "src/main.py"]
This time, let’s use a much smaller (alpine-based) image, running a bare-bones Flask app.
Let’s build the image as-is and see what we have to work with:
REPOSITORY TAG IMAGE ID CREATED SIZE pythontest latest 55c25c2b963a About an hour ago 64.1MB
The initial image is 64.1MB—not a lot to work with there. However, let’s still see what
docker-slim can do for us:
$ docker-slim build --target pythontest:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE pythontest.slim latest 4ae57b3849c0 14 seconds ago 18.4MB pythontest latest 55c25c2b963a About an hour ago 64.1MB
Starting with an already slimmed down image (64.1MB), we still see a reduction down to 18.4MB (28.7% of its original size).
Having run through the above two examples, we can say the following of
- It most certainly does work, and
- It greatly optimizes small images that didn’t even need it in the first place.
Again, you can (and definitely should) check out DockerSlim’s GitHub repository for a deeper dive into usage, as well as instructions on how to install it. Happy optimizing!
Don’t forget to sign up for more updates here.