Docker在上下文之后遵循符号链接

Rav*_*avi 59 symlink symlink-traversal docker dockerfile

另一个Docker符号链接问题.我有一堆文件要复制到我的所有Docker构建中.我的目标结构是:

parent_dir
    - common_files
        - file.txt
    - dir1
        - Dockerfile  
        - symlink -> ../common_files
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我想在我在dir1中构建docker时复制file.txt.但我不想保留file.txt的多个副本.根据这个链接,从docker版本0.10开始,docker build必须

按照容器根目录中的符号链接获取ADD构建说明.

但是当我在Dockerfile中使用这些行中的任何一行构建时,我都没有这样的文件或目录:

ADD symlink /path/dirname 要么 ADD symlink/file.txt /path/file.txt

mount选项不会为我解决(跨平台......).我尝试tar -czh . | docker build -t没有成功.

有没有办法让Docker遵循符号链接并将common_files/file.txt复制到构建的容器中?

h3n*_*rik 53

这是不可能的,也不会实施.请看一下关于github问题#1676的讨论:

我们不允许这样做,因为它不可重复.机器上的符号链接与我的机器不同,相同的Dockerfile会产生两种不同的结果.同时使用/ etc/paasswd的符号链接会导致问题,因为它会链接主机文件而不是本地文件.

  • 多么可惜,虽然我看到了这一点,但我没有遵循逻辑而且它咬了我.Git完美地处理了symblinks,我也希望构建能够在所有检查源代码库的机器和环境中工作.?! (7认同)
  • 是“不可重复”吗?真是个笑话——它是可重复的,具体取决于用例。例如,如果我们都在某个存储库中拉取和构建,则在使用“ADD”时在存储库中使用符号链接是完全合法的。 (3认同)
  • 您的引用`在容器的根目录中跟踪符号链接以获取ADD构建说明.意味着*在容器*符号链接内部遵循.不在构建上下文目录中.在`ADD file.txt/dir/file.txt`中,目录`dir`可以是符号链接.我在答案中引用的参数仍然有效,并且在最新版本中仍未遵循符号链接.当您将符号链接存储在*git*等修订控制系统中时,可能会遇到问题(关于重复性).因此,请参阅[此问题](http://stackoverflow.com/questions/86402/how-can-i-get-git-to-follow-symlinks). (2认同)
  • 我明白你关于 git 中符号链接的观点。但符号链接不必进入 git。一个简单的设置脚本可以准备本地环境来创建符号链接。对我来说,从维护的角度来看,保留共享文件的“n”个副本的成本似乎太高了。也许我必须用 apache 来提供它。谢谢。 (2认同)
  • 我不明白其中的道理。如何从 URL 重复添加文件,而不是从同一个 Git 存储库的父目录添加文件? (2认同)

jda*_*ski 20

如果有人仍然遇到这个问题,我在 superuser.com 上找到了一个非常好的解决方案:

https://superuser.com/questions/842642/how-to-make-a-symlinked-folder-appear-as-a-normal-folder

它基本上建议使用 tar 取消引用符号链接并将结果提供给 docker build:

$ tar -czh . | docker build -
Run Code Online (Sandbox Code Playgroud)

  • 您可以在此处删除“-z”选项(压缩,因为不需要它),“tar”将文件发送到 docker build 命令时运行速度更快。 (3认同)

Eug*_*ene 10

我知道它破坏了 docker build 的可移植性,但您可以使用硬链接而不是符号:

ln /some/file ./hardlink
Run Code Online (Sandbox Code Playgroud)

  • 需要明确的是,这适用于文件,而不是目录。 (21认同)

sha*_*unc 9

一种可能性是在父目录中运行构建,使用:

$ docker build [tags...] -f dir1/Dockerfile .
Run Code Online (Sandbox Code Playgroud)

(或等效地,在子目录中,)

$ docker build  [tags...] -f Dockerfile ..
Run Code Online (Sandbox Code Playgroud)

Dockerfile 必须配置为使用适当的路径进行复制/添加。根据您的设置,您可能希望.dockerignore父级中的a省略您不想放入上下文中的内容。


小智 8

我只需在相同的背景下解决这个问题。我的解决方案是使用分层 Docker 构建。换句话说:

parent_dir
  - common_files
    - Dockerfile
    - file.txt

- dir1
    - Dockerfile (FROM common_files:latest)
Run Code Online (Sandbox Code Playgroud)

缺点是你必须记住在 dir1 之前构建 common_files。优点是,如果您有许多从属图像,那么由于使用公共层,它们都会稍微小一些。


Pau*_*oll 5

对于其他有此问题的人,请参见此链接。我个人选择了“构建通用基础映像”解决方案,并且效果很好。