如何从 Dockerfile 复制文件夹到 docker 图像?

我在 Dockerfile 中尝试了以下命令: COPY * /,结果非常惊讶。看起来这个简单的 docker 代码从 globb 中遍历这些目录,然后将每个文件转储到目标目录中,同时尊重地忽略我的目录结构。

至少我是这样理解 this ticket的,它当然与我得到的结果相符。

我想这种行为仍然存在的唯一原因一定是有其他的方法可以做到这一点。但是对于一只脑子很小的熊来说,要理解这些并不容易,有人知道吗?

300167 次浏览

作为 在你的机票上提到过:

你有 COPY files/* /test/,它扩展到 COPY files/dir files/file1 files/file2 files/file /test/
如果将其分解为单独的 COPY命令(例如 COPY files/dir /test/) ,您将看到(无论好坏) COPY将把每个参数 dir的内容复制到目标目录。不是参数 dir本身,而是内容。

对于 COPY 不能保留顶级目录这一事实,我并不感到激动,但是这种情况已经持续了一段时间了。

因此,以保存向下兼容的名义,COPY/ADD不可能是一个目录结构。

唯一的解决办法是使用一系列 RUN mkdir -p /x/y/z来构建目标目录结构,然后使用一系列 docker ADD(每个文件夹填充一个)。
(根据注释,是 ADD,而不是 COPY)

使用 ADD代替 COPY。假设您想要将目录 src 中的所有内容从 host 从 Container 复制到目录 dst:

ADD src dst

注意: 目录 dst 将在容器中自动创建。

正如@Vonc 所说,现在不可能添加这样的命令。唯一的解决办法是提到文件夹,创建它并向其中添加内容。

# add contents to folder
ADD src $HOME/src

Would create a folder called Src in your directory and add contents of your folder Src into this.

用 a/替换 *

所以

COPY * <destination>

使用

COPY / <destination>

使用 ADD(医生)

ADD命令可以接受作为 <src>参数:

  1. 文件夹 内心构建文件夹(与 Dockerfile 相同的文件夹)。然后在 Dockerfile 中添加一行,如下所示:
ADD folder /path/inside/your/container

或者

  1. 主机文件系统中任何位置的单文件归档文件。 要创建存档,请使用以下命令:
tar -cvzf newArchive.tar.gz /path/to/your/folder

然后在 Dockerfile 中添加一行,如下所示:

ADD /path/to/archive/newArchive.tar.gz  /path/inside/your/container

备注:

  • ADD will automatically extract your archive.
  • 尾部斜杠的存在/不存在很重要,请参阅链接文档

COPY . <destination>

你的情况就是这样:

COPY . /

我不能完全理解原始海报的情况,但我可以证明在 Dockerfile 使用 COPY 复制目录结构是可能的。

假设您有这样的文件夹结构:

folder1
file1.html
file2.html
folder2
file3.html
file4.html
subfolder
file5.html
file6.html

要将其复制到目标映像,可以使用这样的 Dockerfile 内容:

FROM nginx


COPY ./folder1/ /usr/share/nginx/html/folder1/
COPY ./folder2/ /usr/share/nginx/html/folder2/


RUN ls -laR /usr/share/nginx/html/*

The output of docker build . as follows:

$ docker build --no-cache .
Sending build context to Docker daemon  9.728kB
Step 1/4 : FROM nginx
---> 7042885a156a
Step 2/4 : COPY ./folder1/ /usr/share/nginx/html/folder1/
---> 6388fd58798b
Step 3/4 : COPY ./folder2/ /usr/share/nginx/html/folder2/
---> fb6c6eacf41e
Step 4/4 : RUN ls -laR /usr/share/nginx/html/*
---> Running in face3cbc0031
-rw-r--r-- 1 root root  494 Dec 25 09:56 /usr/share/nginx/html/50x.html
-rw-r--r-- 1 root root  612 Dec 25 09:56 /usr/share/nginx/html/index.html


/usr/share/nginx/html/folder1:
total 16
drwxr-xr-x 2 root root 4096 Jan 16 10:43 .
drwxr-xr-x 1 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file1.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file2.html


/usr/share/nginx/html/folder2:
total 20
drwxr-xr-x 3 root root 4096 Jan 16 10:43 .
drwxr-xr-x 1 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file3.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file4.html
drwxr-xr-x 2 root root 4096 Jan 16 10:33 subfolder


/usr/share/nginx/html/folder2/subfolder:
total 16
drwxr-xr-x 2 root root 4096 Jan 16 10:33 .
drwxr-xr-x 3 root root 4096 Jan 16 10:43 ..
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file5.html
-rwxr-xr-x 1 root root    7 Jan 16 10:32 file6.html
Removing intermediate container face3cbc0031
---> 0e0062afab76
Successfully built 0e0062afab76

最简单的方法:

sudo docker cp path/on/your/machine adam_ubuntu:/root/path_in_container

注意,如果要复制需要被 root 用 ~ 拾取的内容,请放入 路径中。

FROM openjdk:8-jdk-alpine
RUN apk update && apk add wget openssl lsof procps curl
RUN apk update
RUN mkdir -p /apps/agent
RUN mkdir -p /apps/lib
ADD ./app/agent /apps/agent
ADD ./app/lib /apps/lib
ADD ./app/* /apps/app/
RUN ls -lrt /apps/app/
CMD sh /apps/app/launch.sh

在 Dockerfile 中,我将 ./apps/agent./apps/lib目录复制到 /apps/agent/apps/lib目录。

假设您希望将内容从拥有 docker 文件的文件夹复制到容器中。 使用添加剂:

RUN mkdir /temp
ADD folder /temp/Newfolder

it will add to your container with temp/newfolder

文件夹是一个文件夹/目录,你有 dockerfile,更具体地说,你把你的内容,并希望复制。

现在可以通过运行容器来检查复制/添加的文件夹,并使用 ls 查看内容