如何在Docker文件中使用“ADD”命令包含Docker构建上下文之外的文件?

从Docker文档中:

路径必须位于生成的上下文中;您不能添加../something/something,因为docker构建的第一步是将上下文目录(和子目录)发送到docker守护进程。

我不想重组我的整个项目,只是为了在这件事上适应Docker。我想将所有Docker文件保存在同一个子目录中。

此外,Docker似乎还不支持符号链接:Dockerfile ADD命令不支持主机#1676上的符号链接。

我唯一能想到的另一件事是包含一个预构建步骤,将文件复制到Docker构建上下文中(并配置我的版本控制以忽略这些文件)。还有比这更好的解决方法吗?


当前回答

我个人对一些答案感到困惑,所以决定简单地解释一下。

当想要创建图像。

我总是选择项目的根作为Dockerfile中的上下文。

例如,如果您使用COPY命令,如COPY。

第一个点(.)是上下文,第二个点(。)是容器工作目录

假设上下文是项目根、点(.),代码结构如下

sample-project/
  docker/
    Dockerfile

如果要构建映像

您的路径(运行docker build命令的路径)是/full-path/sample-project/,你应该这样做

docker build -f docker/Dockerfile . 

如果您的路径是/full-path/sampleproject/docker/,你应该这样做

docker build -f Dockerfile ../ 

其他回答

我在一个项目和一些数据文件中遇到了同样的问题,由于HIPAA的原因,我无法在回购上下文中移动这些文件。我最终使用了2个Dockerfile。一个构建主应用程序,而不需要我在容器外部所需的东西,并将其发布到内部存储库。然后,第二个dockerfile提取该图像并添加数据,然后创建一个新图像,然后将其部署并永远不会存储在任何地方。不太理想,但它对我将敏感信息排除在回购之外的目的起到了作用。

正如GitHub问题中所描述的那样,构建实际上发生在/tmp/docker-12345中,因此相对路径如/相对添加/some文件是相对于/tmp/docker-12345的。因此,它将搜索/tmp/relative add/some文件,该文件也显示在错误消息中*

不允许包含来自构建目录之外的文件,因此这将导致“禁止路径”消息。"

我经常发现自己为此使用--buildarg选项。例如,在Dockerfile中放入以下内容后:

ARG SSH_KEY
RUN echo "$SSH_KEY" > /root/.ssh/id_rsa

你可以这样做:

docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .

但请注意Docker文档中的以下警告:

警告:不建议使用构建时间变量来传递密钥,如github密钥、用户凭据等。使用docker history命令,映像的任何用户都可以看到构建时间变量值。

在我的例子中,Dockerfile就像一个包含占位符的模板一样编写,我使用配置文件将其替换为实际值。

所以我不能直接指定这个文件,而是像这样将其导入docker构建:

sed "s/%email_address%/$EMAIL_ADDRESS/;" ./Dockerfile | docker build -t katzda/bookings:latest . -f -;

但由于管道的原因,COPY命令无法工作。但上述方法通过-f(明确表示未提供文件)来解决问题。只执行-如果不使用-f标志,则不会提供上下文和Dockerfile,这是一个警告。

使用链接解决问题:

ln路径/to/file/outer/context/file_to_copy/文件_to_copy

在Dockerfile上,只需:

复制file_to_COPY/path/to/file