语法
# 该命令以shell形式运行,Linux默认为/bin/sh -c, Windows默认为cmd /S /C
RUN <command>
或者
# exec格式,由于exec格式会被解析成为json数组,所以,必须使用双引号
RUN ["executable", "param1", "param2"]
使用RUN指令都会在当前镜像最顶层生成新的层,并提交到执行结果。Dockerfile中的后续步骤可以使用提交的结果。由于每次使用RUN指令都会生成新的层,所以建议多个Shell在同一个RUN指令中声明。例如:
Dockerfile
FROM alpine
# 由于RUN指令在liunx平台上默认以shell命令执行,所以可以省略/bin/sh -c
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache tini tzdata ttf-dejavu fontconfig
两个RUN指令会生成两个新层 (RootFS中显示由三个层级是因为其中有一个层级FROM引入的基础层)
再次构建的时候,就会直接从cache中获取
由于每次使用ADD、COPY、RUN指令都会生成新的层,会导致层数过多,镜像文件增大,所以上面的RUN指令,我们可以合并为一条,其中 \ 为换行符,多个shell命令之间用 && 连接
FROM alpine
# 由于RUN指令在liunx平台上默认以shell命令执行,所以可以省略/bin/sh -c
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache tini tzdata ttf-dejavu fontconfig
# 上面的语句等同于
RUN /bin/sh -c "sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache tini tzdata ttf-dejavu fontconfig"
这样我们可以看到总层数由原来的三层变为了两层
如果我们使用第二种命令格式,上面的Dockerfile我们可以写成:
FROM alpine
RUN ["/bin/sh","-c","sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache tini tzdata ttf-dejavu fontconfig"]
如果容器是以windows平台作为基础镜像,我们可以使用第二种命令格式,执行exe文件。
# 由于exec命令方式最终会解析成json格式,所以我们要将反斜杠转义
# 在windows的路径中经常出现反斜杠,这时候我们需要使用双反斜杠进行转义,否则可能出现意料之外的问题
RUN ["c:\\windows\\system32\\tasklist.exe"]