为什么要问这个问题?
发布此问答的原因是,有时需要某些软件才能在docker映像中编译软件。编译后,这些软件包是多余的,应删除以减小图像大小。在某些情况下,大于1.5GB的图像会减少到小于300MB。以下用例并不代表实际情况,而是提供了该用例的示例。
尝试解决此问题的方法在创建文件夹的同一层中定义了remove命令:
FROM alpine
RUN mkdir dir && cd dir && wget http://google.com && rm -rf dir
结果是: br />当目标是删除另一层中的目录时,此操作将失败: />
另一种尝试是使用workdir:
user@host$ docker build -t dir .
Sending build context to Docker daemon 1.336 MB
Step 1/2 : FROM alpine
---> 4a415e366388
Step 2/2 : RUN mkdir dir && cd dir && wget http://google.com && rm -rf dir
---> Using cache
---> c283805e687f
Successfully built c283805e687f
构建图像导致: />
#1 楼
mkdir dir && cd dir && wget http://google.com && rm -rf dir
并没有按照您的想象做。让我们分解一下:
mkdir dir
创建dir
。 /> cd dir
将目录更改到其中。wget http://google.com
在dir/
中下载google.com。rm -rf dir
尝试删除当前目录中的名为dir
的目录。问题是,当前目录中没有
dir
,因为您已经进入其中。并且由于添加了cd
标志,因此该命令不会产生错误。这是为什么在不确定是否需要强制标志的情况下不应该使用强制标志的原因之一。由于未使用
-f
命令,因此在更改结束时将放弃目录更改WORKDIR
。因此,下一行将在原始工作目录中执行,并尝试进入RUN
,但正如我们之前所讨论的,该目录仍然存在,其中包含wgetted内容。评论
当然可以删除目录;您刚刚指定了错误的路径。
–熊佳亚诺夫
17年4月2日在16:34
考虑到rm -r正是要解决的问题,这是一个奇怪的错误。在这种情况下,您可能可以添加-f,但是我将做进一步调查以查看该目录中的确切内容(例如,ls -A)。但是,此时您已经超越了最初的问题。
–熊佳亚诺夫
17年4月2日在18:59
#2 楼
最新的Dockerfile规范允许使用多个FROM语句。https://docs.docker.com/engine/userguide/eng-image/multistage-build/
使用这种方法,您可以将编译结果保留在纯运行时环境中。
评论
我的情况是-出于安全原因,我正在中间层下载软件包。然后,将它们添加到最终图像。接下来使用RUN命令安装软件包并删除软件包。我的目标是在RUN命令安装后删除已下载的软件包。有什么方法可以:a)将ADD和RUN合并为一层; b)删除ADD层?
–变量
20年6月3日,12:19
#3 楼
建立在Xiong Chiamiov的答案上,该答案正确地识别了问题的根本原因-尝试清空或删除该目录时,按相对路径引用dir
取决于当时的工作目录,在OP。因此有2种解决方案可用: br />
RUN mkdir dir && cd dir && wget http://google.com && cd .. %% rm -rf dir
而是使用指向该目录的
dir
完整路径引用。但是请谨慎使用(如果需要,请调整),以防类似情况,但与此情况不相同,因为这种方法假设初始工作目录为/dir
:RUN mkdir dir && cd dir && wget http://google.com && rm -rf /dir
评论
嗯为什么不使用rm -rf ../dir?这样就避免了绝对路径参考
– jpaugh
17年4月3日在17:28
@jpaugh可能有效,但感觉很奇怪(剪掉您坐在的树枝上吗?)
–丹·科尼莱斯库(Dan Cornilescu)
17年4月3日在18:29
确实如此;但是,当您指定绝对路径时,它的工作原理基本上相同。 FWIW,我之前是在交互式外壳中完成此操作的。 ls往往会失去其含义... ;-)您甚至可以使用rm -rf ../dir && mkdir ../dir && cd ../dir,这会将您放入新的空(有效)文件夹
– jpaugh
17-4-3在18:39
@jpaugh你是对的,这就是为什么我说感觉-这只是一种感觉:)
–丹·科尼莱斯库(Dan Cornilescu)
17年4月3日在20:06
#4 楼
一种解决方案是使用not empty directory
删除find
:评论
您那里有不必要的内容,我相信您错过了Xiong的答案的意思-问题不是rm cmd的-rf选项。
–丹·科尼莱斯库(Dan Cornilescu)
17年4月3日在14:11
如果我指定整个路径/ path / to / dir并从/运行,即使使用rf仍然失败。我必须从文件夹中删除所有内容。
– 030
17年4月4日在10:18
您是说rm -rf无效,并且必须在删除目录之前手动清空每个目录吗?很奇怪。
–丹·科尼莱斯库(Dan Cornilescu)
17年4月4日在12:21
rm -rf确实不起作用。我不得不使用find / path -delete
– 030
17年4月6日在8:07
评论
您当然可以在Dockerfile中拥有多个RUN语句。检查您的Dockerfile。看起来您复制粘贴同一行两次。如果您查看步骤2和3,它们都将执行相同的代码。这就是为什么找不到目录的原因。您已在第2步中将其删除