Reputation: 1591
Every time I build my docker image it appears to grow in 5-10mb for no apparent reason.
Each time I am building, I'm adding a single line comment to a ruby.
Below are 3 images that are built with single line changes to the code and running docker -it <img_id> /bin/sh
and then du -d1
from the root. All 3 have no blocks/file-size differences.
Any idea as to why I'm losing 5-10mb per build?
9add242d3e75 2 hours ago 438MB
# du -d1
4 ./run
1472 ./var
4 ./opt
4 ./tmp
4972 ./lib
0 ./proc
4 ./srv
4 ./mnt
359692 ./usr
16 ./media
264 ./sbin
0 ./dev
0 ./sys
1740 ./etc
1084 ./bin
8 ./root
4 ./home
42024 ./app
411300 .
45ed1ea39f3a 13 hours ago 432MB
# du -d1
4 ./run
1472 ./var
4 ./opt
4 ./tmp
4972 ./lib
0 ./proc
4 ./srv
4 ./mnt
359692 ./usr
16 ./media
264 ./sbin
0 ./dev
0 ./sys
1740 ./etc
1084 ./bin
8 ./root
4 ./home
42024 ./app
411300 .
4740856ed1b7 13 hours ago 421MB
# du -d1
4 ./run
1472 ./var
4 ./opt
4 ./tmp
4972 ./lib
0 ./proc
4 ./srv
4 ./mnt
359692 ./usr
16 ./media
264 ./sbin
0 ./dev
0 ./sys
1740 ./etc
1084 ./bin
8 ./root
4 ./home
42024 ./app
411300 .
[EDIT]
Using dive, I was able to see that the bloat is coming from a COPY
command that does increase in size (the tmp/ folder), but I have a specific command to rm -rf tmp
to reclaim that space.
It appears the COPY
is caching the size?
The final image size remains even though I am deleting the thing that causes the size difference?
COPY showing tmp/ w/ bloatRUN rm -rf tmp
to remove bloat
Upvotes: 1
Views: 3102
Reputation: 1591
Found the answer here: https://forums.docker.com/t/why-run-command-which-deletes-files-inflates-image-size/33670/6
This is expected behavior because a COPY
is bringing in the files.
There's an experimental (as of Oct '19) flag --squash
that can be used on docker build
, but it loses the primary advantages of layers.
I'll have to figure out a different scheme to avoid bringing files in through the tmp folder.
[EDIT] I ended up using intermediary containers to 'strip' out what I didn't want.
ARG BUILDER_REPO='replace-repo'
FROM ${BUILDER_REPO} as build_img
WORKDIR /app
RUN rm -rf tmp
FROM ruby:2.6.5-alpine
WORKDIR /app
COPY --from=build_img /app .
Worked great for me, from 200mb -> 140mb
Upvotes: 1
Reputation: 70
Not able to comment yet so have to type it up here. Your last answer does sound right. As long as there is a COPY in your Dockerfile, the size of the image increases to the stuff you copy. Even if you have a RUN rm -rf later on, your image still stays the same size because the Docker layer to execute the RUN rm -rf tmp is separate to the COPY layer. So the first layer which does the COPY increases the size to the thing you are copying. Then you have the RUN layer which removes the tmp. So to put it in a different perspective, its like for your RUN layer to remove the tmp, the tmp first needs to be filled with the contents of COPY layer. So even though after the RUN layer executes you are supposed to have tmp emptied, that layer still needs the data that its supposed to remove to be present from the previous layer.
One way for you to avoid this is to use Docker volumes. You can use docker run while passing it the volume to mount and what directory to mount it at inside the container. Check this post How to mount host volumes into docker containers in Dockerfile during build where they discuss different options of doing this
Upvotes: 1