-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Description
Relates to moby/moby#38599
note: this is the same behavior as the classic builder, so we should discuss if we can change this without introducing a breaking change 😞
I think there's a bug in the copy behavior (both in classic builder, and in buildkit); it's come up a few times, and matching with the docker cp documentation;
SRC_PATHspecifies a directory:
DEST_PATHdoes not exist
DEST_PATHis created as a directory and the contents of the source directory are copied into this directoryDEST_PATHexists and is a file
- Error condition: cannot copy a directory to a file
DEST_PATHexists and is a directory
SRC_PATHdoes not end with/.(that is: slash followed by dot)
- the source directory is copied into this directory
SRC_PATHdoes end with/.(that is: slash followed by dot)
- the content of the source directory is copied into this directory
So without the trailing /., this line should result in dir itself being copied to /existingdir/dir; similar to cp:
Without trailing /.;
docker run --rm --workdir=/test alpine sh -c 'apk add --no-cache --quiet tree && mkdir -p src/dir/subdir dest/existingdir && touch src/dir/subdir/nestedfile && cp -R src/dir dest/existingdir && cd /test/dest && tree'
.
└── existingdir
└── dir
└── subdir
└── nestedfile
3 directories, 1 fileWith trailing /.;
docker run --rm --workdir=/test alpine sh -c 'apk add --no-cache --quiet tree && mkdir -p src/dir/subdir dest/existingdir && touch src/dir/subdir/nestedfile && cp -R src/dir/. dest/existingdir && cd /test/dest && tree'
.
└── existingdir
└── subdir
└── nestedfile
2 directories, 1 fileIn a Dockerfile; without trailing /.;
DOCKER_BUILDKIT=1 docker build -<<EOF
FROM alpine AS source
RUN mkdir -p /dir/subdir && touch /dir/subdir/nestedfile
FROM alpine AS no_slash_dot
WORKDIR /dest
RUN apk add --no-cache --quiet tree
RUN mkdir existingdir
COPY --from=source /dir existingdir
RUN tree; exit 1
EOFProduces;
.
└── existingdir
└── subdir
└── nestedfile
2 directories, 1 file
And with;
DOCKER_BUILDKIT=1 docker build -<<EOF
FROM alpine AS source
RUN mkdir -p /dir/subdir && touch /dir/subdir/nestedfile
FROM alpine AS slash_dot
WORKDIR /dest
RUN apk add --no-cache --quiet tree
RUN mkdir existingdir
COPY --from=source /dir/. existingdir
RUN tree; exit 1
EOFProduces the same;
.
└── existingdir
└── subdir
└── nestedfile
2 directories, 1 file
The behavior should match the cp -R result
Reactions are currently unavailable