问题描述
在构建Docker镜像时,在Dockerfile中使用了一行指令,内容如下:
RUN ["echo", "'anything'", ">", "./a_file"]
然而这行指令没有生效,用户最终不得不使用以下形式才成功:
RUN ["sh", "-c", "echo 'anything' > ./a_file"]
在修复这个问题之前,用户使用了 dive 工具来查看这个指令在镜像中产生了什么改变。令人惊讶的是,a_file
并没有被创建,反而是一个空的 /etc/resolv.conf
文件被创建了。
解决方案
请注意以下操作可能受到Docker版本差异影响。
为什么会创建 /etc/resolv.conf
?
创建空的 /etc/resolv.conf
文件是Docker引擎通过绑定挂载在容器中注入的,其中的设置是与Docker引擎本身相关的。父文件系统中的空文件是这种绑定挂载的副作用,你可以安全地忽略它。
修复 a_file
未创建的问题
如果 a_file
没有被创建,需要检查该文件是否在一个卷(volume)中。在使用 RUN
命令中的临时(匿名)容器中创建的卷,对卷的更改不会包含在对容器文件系统的更改中。因此,如果 a_file
没有被创建,可能是因为它位于一个卷中。
为确保 a_file
被创建并包含在容器文件系统中,你可以尝试以下方法:
方法1:使用exec格式的echo指令
如果你希望继续使用exec格式的 echo
指令,可以尝试以下步骤:
- 确保
a_file
所在的目录在Dockerfile中是可写的,并且没有被定义为卷。 - 在
RUN
指令中,使用正确的语法来执行echo
指令,如下:
Dockerfile
RUN echo 'anything' > ./a_file
方法2:使用shell格式的echo指令
另一种方法是使用shell格式的 echo
指令,这通常更灵活。你可以通过以下步骤来实现:
- 确保
a_file
所在的目录在Dockerfile中是可写的,并且没有被定义为卷。 - 在
RUN
指令中使用shell格式的echo
指令,如下:
Dockerfile
RUN sh -c "echo 'anything' > ./a_file"
通过上述方法,你应该能够在Docker镜像中成功创建 a_file
文件。
总结
在使用Docker构建镜像过程中,遇到了使用exec格式的 echo
指令不按预期工作的问题。出现的 /etc/resolv.conf
文件是Docker引擎通过绑定挂载注入的一个副作用,不必过于担心。如果 a_file
没有被创建,你可以根据以上方法来进行修复,确保目录权限和文件路径设置正确,以便成功创建文件。