-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Hello :-)
We've been using the buildctl to build images and have found that the cache is reporting a hit for two files with the same name, modified date, and size; but different contents.
A script to reproduce via buildctl:
( echo 'FROM alpine'; echo 'COPY /test /'; echo 'RUN cat /test' ) > Dockerfile
touch timestamp
echo XXX > test
touch -r timestamp test
buildctl --addr tcp://... build --progress plain --frontend=dockerfile.v0 --local context=. --local dockerfile=.
echo YYY > test
touch -r timestamp test
buildctl --addr tcp://... build --progress plain --frontend=dockerfile.v0 --local context=. --local dockerfile=.
The first buildctl outputs:
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 76B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/alpine:latest
#3 ...
#4 [auth] library/alpine:pull token for registry-1.docker.io
#4 DONE 0.0s
#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 2.4s
#5 [1/3] FROM docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300
#5 resolve docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 0.1s done
#5 CACHED
#6 [internal] load build context
#6 transferring context: 35B done
#6 DONE 0.0s
#7 [2/3] COPY /test /
#7 DONE 0.1s
#8 [3/3] RUN cat /test
#8 0.157 XXX
#8 DONE 0.2s
Whilst the second invocation hits the cache, even though file test
has been modified:
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 76B done
#1 DONE 0.1s
#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.1s
#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.3s
#4 [1/3] FROM docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300
#4 resolve docker.io/library/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 0.0s done
#4 DONE 0.0s
#5 [internal] load build context
#5 transferring context: 25B done
#5 DONE 0.0s
#6 [2/3] COPY /test /
#6 CACHED
#7 [3/3] RUN cat /test
#7 CACHED
The same caching occurs when using buildkit via docker build
, a script to demonstrate:
export DOCKER_BUILDKIT=1
( echo 'FROM alpine'; echo 'COPY /test /'; echo 'RUN cat /test' ) > Dockerfile
touch timestamp
echo XXX > test
touch -r timestamp test
docker build --progress plain .
echo YYY > test
touch -r timestamp test
docker build --progress plain .
And the second command output shows:
...
#5 [internal] load build context
#5 transferring context: 25B done
#5 DONE 0.0s
#6 [2/3] COPY /test /
#6 CACHED
#7 [3/3] RUN cat /test
#7 CACHED
However, when using non-buildkit Docker build the output is correct:
Sending build context to Docker daemon 3.584kB
Step 1/3 : FROM alpine
---> a24bb4013296
Step 2/3 : COPY /test /
---> f48bf3a0ef13
Step 3/3 : RUN cat /test
---> Running in 9db3e9cac159
XXX
Removing intermediate container 9db3e9cac159
---> 1aff2dd86b42
Successfully built 1aff2dd86b42
Sending build context to Docker daemon 3.584kB
Step 1/3 : FROM alpine
---> a24bb4013296
Step 2/3 : COPY /test /
---> 9b36a97fcdd8
Step 3/3 : RUN cat /test
---> Running in 3a281bc7d637
YYY
Removing intermediate container 3a281bc7d637
---> 07b77738e34d
Successfully built 07b77738e34d
It seems that buildkit isn't actually checking the contents of the file, and is just assuming that the same name, size, and modified date means the files are identical - even though they aren't.
Thanks for your time - please let us know if you would like any more details or any such.