From this trial, it looks like Docker's COPY
command doesn't preserve symlinks -- rather, it "follows" symlinks and copies the target file(?):
$ ls -l
total 4
lrwxrwxrwx 1 user domain users 1 Mar 26 09:37 a -> b
-rw-r--r-- 1 user domain users 0 Mar 26 09:37 b
lrwxrwxrwx 1 user domain users 1 Mar 26 09:41 c -> d
-rw-r--r-- 1 user domain users 0 Mar 26 09:41 d
-rw-r--r-- 1 user domain users 54 Mar 26 09:39 Dockerfile
$
# Dockerfile
FROM alpine:3.7 as base
COPY [ "./*", "/foo/bar/" ]
$ docker build -t foo:tmp . && docker run -it foo:tmp
[+] Building 1.1s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 116B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.7 0.8s
=> [internal] load build context 0.0s
=> => transferring context: 12.52kB 0.0s
=> CACHED [1/2] FROM docker.io/library/alpine:3.7@sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10 0.0s
=> [2/2] COPY [ ./*, /foo/bar/ ] 0.1s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => writing image sha256:81531080243eedcb443c7fe0c9e85df92515a6cf3f997c549414cae9bf6ca925 0.0s
=> => naming to docker.io/library/foo:tmp 0.0s
/ # ls -l /foo/bar/
total 4
-rw-r--r-- 1 root root 67 Mar 26 16:43 Dockerfile
-rw-r--r-- 1 root root 0 Mar 26 16:37 a
-rw-r--r-- 1 root root 0 Mar 26 16:37 b
-rw-r--r-- 1 root root 0 Mar 26 16:41 c
-rw-r--r-- 1 root root 0 Mar 26 16:41 d
/ #
This behavior appears to be the same whether I'm copying from my context or from another Docker image layer.
Is there some way I can get Docker copy to preserve symlinks i.e. instead of it "following" them and creating hard files? Or is there some convention to work around this situation?
The context behind this question is that a base layer I'm copying from has (a lot of) a mix of files and symlinks that point to them. Example: libfoo.so -> libfoo.so.1 -> libfoo.so.1.0.0
I spent a while searching online for this topic, but found surprisingly few hits. Most "close" questions were about symlinks to directories, which isn't the same as my situation. The closest hit I got was this unfortunately unanswered question: https://forums.docker.com/t/copying-symlinks-into-image/39521
This works if you try to copy the entire directory as a unit, rather than trying to copy the files in the directory:
COPY ./ /foo/bar/
Note that there are some subtleties around copying directories: the Dockerfile COPY
documentation notes that, if you COPY
a directory,
NOTE: The directory itself is not copied, just its contents.
This is fine for your case where you're trying to copy the entire build context. If you have a subdirectory you're trying to copy, you need to make sure the subdirectory name is also on the right-hand side of COPY
and that the directory name ends with /
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With