RUN
RUN有2种形式:
RUN (shell形式,该命令在shell中运行,在Linux上默认为/bin/sh -c,在Windows上默认为cmd /S/C)
RUN ["executable", "param1", "param2"](exec 形式)
RUN指令在当前镜像顶部的新层(new layer)中执行任何命令,并提交结果。生成的提交的(committed)镜像将用于Dockerfile构建过程中的下一步。
分层运行RUN指令并生成提交(committed)符合Docker的核心概念,在Docker中,提交(committed)很廉价,并且可以从镜像历史记录的任何位置创建容器,特别像源代码控制。
exec形式可以避免破坏shell字符串,并使用不包含指定shell executable的基本镜像运行RUN命令。
可以使用SHELL命令更改shell形式的默认shell。
在shell形式中,可以使用\(反斜杠)将一条RUN指令继续到下一行。例如,考虑以下两行:
它们在一起等价于以下这一行:
要使用/bin/sh以外的其他shell,请使用exec形式传入所需的shell。例如:
NOTE:
exec形式的指令被解析为JSON数组,这意味着对于单词,我们必须使用双引号包围,而不是单引号。
与shell形式不同,exec形式不会调用命令行shell。这意味着正常的shell处理不会发生。例如,RUN ["echo","$HOME"]不会对$HOME进行变量替换。如果要进行shell处理,可以使用shell形式或直接执行shell,例如:RUN ["sh","-c","echo $HOME"]。当使用exec形式并直接执行shell时(例如在shell形式中),是由shell进行环境变量扩展,而不是docker。
Dockerfile:
示例一:shell形式
示例二: exec形式
示例三:直接执行shell
上面我直接将三种形式放在了一个Dockerfile中,便于比较。
NOTE:
在JSON形式中,必须转义反斜杠。这在Windows中特别有用,在Windows中反斜杠是路径分隔符。由于无效的JSON,以下几行将被视为shell形式,并以意外的方式执行失败:
正确的语法示例:
在下一次构建中,RUN指令的缓存不会自动失效。诸如RUN apt-get dist-upgrade -y之类的指令的缓存将在下一次构建中重用。可以使用--no-cache使RUN指令的缓存无效,例如docker build --no-cache。
可以通过ADD和COPY指令使RUN指令的缓存无效。
Last updated