Muliple stage build not having expected size

I have a docker file like this:

FROM ubuntu:20.04 AS build-dependency

COPY custom_function/ ./custom_function/

RUN echo "Start install php7.3"
RUN apt -y update && apt -y install software-properties-common
RUN add-apt-repository ppa:ondrej/php
RUN apt-get update
RUN apt-get install -y php7.3 php7.3-common php7.3-mysql php7.3-xml php7.3-xdebug php7.3-xmlrpc php7.3-curl php7.3-gd php7.3-imagick php7.3-cli php7.3-dev php7.3-imap php7.3-mbstring php7.3-opcache php7.3-soap php7.3-zip php7.3-intl -y
RUN echo "PHP 7.3 installed"

# Run installation script for custom function
RUN echo "Update apt source and install nodejs 20 for custom function"
RUN apt-get -y install curl
RUN curl -sL https://deb.nodesource.com/setup_20.x | /bin/bash
RUN apt-get install -y nodejs
RUN cd /custom_function
WORKDIR /custom_function
RUN npm i

FROM gcr.io/distroless/nodejs20-debian12 AS prod
COPY --from=build-dependency /custom_function /custom_function
COPY --from=build-dependency /usr/bin /usr/bin
COPY --from=build-dependency /usr/lib /usr/lib

ENTRYPOINT ["/bin/bash", "-c", "cd /custom_function && npm run prod"]

So I had used docker image ls to list out the size of the gcr.io/distroless/nodejs20-debian12

and it was

gcr.io/distroless/nodejs20-debian12 latest 12dd79d88d7b N/A 171MB

Also when I use dive to inspect the image then the step for
every single COPY command. It shouldn’t get pass 180MB.

So why the final image is 926MB

I just don’t understand why. This is maybe not a fault but I just don’t get why it is like that. Distroless should make our container way more lighter. Right?

you do apt-get update and install, it will create some cache files.

Some if those might help:

sudo apt-get clean
sudo apt-get autoremove
sudo apt-get autoclean

Try to run docker image history IMAGENAME. That will show the size of the layers. You can also start the container and check the size inside

docker run --rm --entrypoint "" IMAGENAME du -shx /

Or do it folder by folder:

docker run --rm --entrypoint "" IMAGENAME sh -c 'du -shx /*'

If the container size is normal, you shouldn’t see an almost 1GB image.

Thatwas in the first stage :slight_smile:

1 Like

Yeah
 no luck on finding improvement. But thanks to

I did find that the docker file is not the problem. The problem is I try to run PHP and NodeJS in the same distroless image. It goes against distroless fundamentals so that’s why it’s so large in size. The only way is trying to separate or change the architecture of my code

Here’s what I do to reduce the docker image size which you can give it a try at your end

Approach 1: Use of --no-install-recommends install in apt.

  • You can avoid installation of recommended packages by included the flag --no-install-recommends when using APT in your Dockerfile. Eg

RUN apt-get update && apt-get -y --no-install-recommends install \

Note: this could result in some missing libraries in your application image which you may have to add back explicitly, but this will ultimately give you more control in the dependencies in your project.

Approach 2: remove downloaded files from apt during installation to reduce docker image size

RUN rm -rf /var/lib/apt/lists/*

Maybe you can also save using more light weight images like alpine linux or so depending on your use-case

1 Like

You probably meant removing the apt cache in the same instruction where the installation happens. Otherwise it will not affect the image size as it will just create a new layer hiding the files, but not removing them.

Also in this specific case that this topic was about, there was no apt install in the final stage so apt could not affect that stage at all. It was still a good general advise.