When docker is told to copy directory a to directory b, it copies contents of a into b. b and any of its
parents might not exist:
FROM alpine
RUN mkdir src && touch src/f1
FROM alpine
RUN apk add tree
COPY --from=0 src dst
RUN tree dst
COPY --from=0 src dst/src
COPY --from=0 src dst/t/t/t/src
RUN tree dst$ docker build .
...
Step 5/9 : COPY --from=0 src dst
---> 87bfed92c3e7
Step 6/9 : RUN tree dst
---> Running in e98fda6589d2
dst
└── f1
0 directories, 1 file
Removing intermediate container e98fda6589d2
---> 9ec0bbfb8783
Step 7/9 : COPY --from=0 src dst/src
---> 755ddbc20ffb
Step 8/9 : COPY --from=0 src dst/t/t/t/src
---> fbec59252877
Step 9/9 : RUN tree dst
---> Running in aa1c96daf48a
dst
├── f1
├── src
│ └── f1
└── t
└── t
└── t
└── src
└── f1
5 directories, 3 files
Removing intermediate container aa1c96daf48a
---> e17b187e6767
That differs from how cp (that we all know and love :)) behaves:
$ mkdir src && touch src/f1
$ cp -r src dst
$ tree
.
├── dst
│ └── f1
└── src
└── f1
2 directories, 3 files
$ cp -r src dst
$ tree
.
├── Dockerfile
├── dst
│ ├── f1
│ └── src
│ └── f1
└── src
└── f1
3 directories, 4 files
$ cp -r src dst/t/t/t
cp: cannot create directory 'dst/t/t/t': No such file or directory