use multistage builds
TrentonAdams opened this issue · 5 comments
The only way to ensure a "clean" image in the end is to create a new one. So, this cleanup here has no effect, the amount of image size will not change because of a yum clean all
, for example. It is better to use multi-staged images.
tomcat/8.5/jdk8/corretto/Dockerfile
Line 121 in 53eda0c
So, for example, at the top of Dockerfile you might go...
FROM amazoncorretto:8 AS init
# do common stuff here
FROM init AS build
# do build stuff here
FROM init AS final
# do final stuff here
COPY --from=build /some/build/path /final/path
Come to think of it, I'm not sure how this will help. I guess after a yum install you could copy the downloaded rpms and install them manually as part of a "final" image, so that it doesn't update the yum db? Anyhow, just a thought.
That whole segment is one RUN
line so removing packages there does effect image size
tomcat/8.5/jdk8/corretto/Dockerfile
Lines 20 to 135 in 53eda0c
See also https://github.com/docker-library/faq#multi-stage-builds
That whole segment is one RUN line so removing packages there does effect image size
Interesting, can you point me to the docs where using a single RUN does affect image size?
That's how Dockerfile
s work, in general; https://docs.docker.com/engine/reference/builder/#run:
The
RUN
instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in theDockerfile
.
Each RUN
instruction is roughly the same as doing docker run <previous-layer> <run-command>
followed by docker commit <container-id>
, so anything added and removed in a single RUN
command cannot possibly persist (because by the time Docker goes to initiate the commit
action, the files are gone):
$ docker pull alpine:3.11
3.11: Pulling from library/alpine
Digest: sha256:b276d875eeed9c7d3f1cfa7edb06b22ed22b14219a7d67c52c56612330348239
Status: Image is up to date for alpine:3.11
docker.io/library/alpine:3.11
$ cat Dockerfile1
FROM alpine:3.11
RUN dd if=/dev/urandom of=/test bs=1M count=1
$ cat Dockerfile2
FROM alpine:3.11
RUN dd if=/dev/urandom of=/test bs=1M count=1 && rm /test
$ docker build - < Dockerfile1
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM alpine:3.11
---> a187dde48cd2
Step 2/2 : RUN dd if=/dev/urandom of=/test bs=1M count=1
---> Running in 5d3476d7a761
1+0 records in
1+0 records out
Removing intermediate container 5d3476d7a761
---> 362f95f15851
Successfully built 362f95f15851
$ docker history 362f95f15851
IMAGE CREATED CREATED BY SIZE COMMENT
362f95f15851 19 seconds ago /bin/sh -c dd if=/dev/urandom of=/test bs=1M… 1.05MB
...
$ docker build - < Dockerfile2
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM alpine:3.11
---> a187dde48cd2
Step 2/2 : RUN dd if=/dev/urandom of=/test bs=1M count=1 && rm /test
---> Running in e8e8d2941b1d
1+0 records in
1+0 records out
Removing intermediate container e8e8d2941b1d
---> 70553719c1cd
Successfully built 70553719c1cd
$ docker history 70553719c1cd
IMAGE CREATED CREATED BY SIZE COMMENT
70553719c1cd 17 seconds ago /bin/sh -c dd if=/dev/urandom of=/test bs=1M… 0B
...
I did notice though that if you do the yum clean all && rm -rf /var/cache/yum
as a new RUN line, it increases the image size, not reduces it. Very strange.