DEV Community

Cover image for Small tip to reduce your Docker images size
Christian
Christian

Posted on • Edited on

Small tip to reduce your Docker images size

Hi everyone, first post on dev.to, I whish to be more active in the future!

Today I want to explain a small tip I recently fond out to reduce the Docker images size, in my case I was able to reduce the size by half!

Let's assume that you are working with a language like Ruby or Python, even if these languages are not compiled they often need some system libraries to work properly, in particular if you are working with databases (MySQL, SQLite, Postgres) you need to compile the gem or the library for the specific architecture of your machine.

In my case I'm working with Ruby and I'm trying to install the SQLite gem that, unfortunately, requires the build-base system library.

Here is the project I'm working on:
Faenz Analytics

So I thought to install it, compile the SQLite gem and uninstall everything I do not need anymore, here is my Dockerfile:

FROM ruby:3.0.4-alpine3.15
WORKDIR /faenz-analytics
RUN apk update && \
    apk add make && \
    apk add build-base && \ # this takes 200Mb of space!!
    apk add sqlite-dev

# ...some instructions

RUN bundle install  # installing Ruby gems
RUN apk del build-base

# ...some other instructions
Enter fullscreen mode Exit fullscreen mode

easy, right? we installed build-base, compiled and installed the gems and removed build-base to reduce the image size.

The problem is that this does not work! The image size is the same as if we did not remove build-base. Let's discover why.

We wrote three RUN instructions, each one generates a layer and these layer are put togheter by Docker to create the final image:

  1. the first RUN installs the system libraries
  2. the second RUN install the gems/libraries by Ruby or whatever language you are using
  3. the third RUN removes the system libraries

since we installed the system libraries in one of the layer they will take some space and will increase the image size, there's no way we can reduce the image size with the next layers.

It's like a sum with no negative numbers. The size can only increase or stay the same from a layer to another.

What? Don't give up, we got this šŸš€

Here is the solution: put these operations in the same layer!

FROM ruby:3.0.4-alpine3.15
WORKDIR /faenz-analytics
RUN apk update && \
    apk add make && \
    apk add sqlite-dev

# ...some instructions

RUN apk add build-base && \
    bundle install && \
    apk del build-base

# ...some other instructions
Enter fullscreen mode Exit fullscreen mode

grouping the operations in just one RUN instruction avoids Docker to waste space to store the build-base in a layer. The layer is generated at the end of the instruction so we are going to install, use the build-base and prontly remove it so that the layer will not contain it at all.

With this little tip my image size went from 400Mb to 170mb, less than half!

If you want to exagerate with the micro optimizations, you can apply the same solution to apk update (or apt-get update for debian/ubuntu images) by deleting the cache created by this command:

RUN apk update && \
    add build-base && \
    # install other dependencies here...
    bundle install && \
    apk del build-base && \
    rm -rf /var/cache/apk && \
    rm -rf tmp/cache
Enter fullscreen mode Exit fullscreen mode

I'm not a Docker expert, so, if you know a better solution or want to share similar tips to reduce the image size please leave a comment, I'm all ears šŸ™

Top comments (5)

Collapse
 
sainig profile image
Gaurav Saini

Hmm, I used to do this too. This is a nice solution for many simpler use cases.

But I personally prefer multi stage builds, makes for much cleaner docker files and more predictable caching.

Collapse
 
a_chris profile image
Christian

Ehi thanks for the suggestion, I'm already using multi stage build for my project github.com/a-chris/faenz to generate the frontend assets but I think it is really hard to use to install gems and move them to the final image, there are so many stuff to move

Collapse
 
creatorarno profile image
Ahmad Khan

hii

Can u help me solve an error?

Collapse
 
a_chris profile image
Christian

what's the error?

Collapse
 
creatorarno profile image
Ahmad Khan