Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are Docker COPY's rules about symlinks / how can I preserve symlinks?

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

like image 772
StoneThrow Avatar asked Nov 15 '22 22:11

StoneThrow


1 Answers

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 /.

like image 166
David Maze Avatar answered Dec 09 '22 10:12

David Maze