Dockerfile详细解析(三)——解析器指令

解析器指令(Parser directives)

解析器指令是可选的,并影响对Dockerfile中后续行的处理方式。解析器指令不会增加层到构建,也不会展示在构建步骤。解析器指令是一种以特殊形式的注释编写的 # directive=value。一个指令只可以用一次。
一旦一个注释,空的行和构建指令被执行,Docker 不再查找解析器指令,相反docker把任何格式作为一个解析器指令的内容当作注释而且不会尝试去验证他是否可能是一个解析器指令。因此,全部的解析器指令必须放在Dockerfile最顶部。
解析器指令是不区分大小写的。然而,约定用小写的形式约定上也总会去加上一句空白行再任何的解析器指令后面。解析器指令不支持行连续字符。
根据以上的规则,下面的例子都是不合法:
不合法,由于连续多行:

# direc \
tive=value

不合法,由于一个解析器指令出现2次:

# directive=value1
# directive=value2

FROM ImageName

被当作注释由于出现再构建指令后面:

FROM ImageName
# directive=value

被当作注释由于出现再一个注释后面而不是解释器命令:

# About my dockerfile
# directive=value
FROM ImageName

未知的指令会被当作注释由于无法辨认。另外,当它出现再一个不解析器指令的注释后面,已知的指令也会被当成注释:

# unknowndirective=value
# knowndirective=value

不分行的空白是允许在解析器命令里。因此,以下的命令行都一样作用。

#directive=value
# directive =value
#	directive= value
# directive = value
#	  dIrEcTiVe=value

以下的解析器指令已被支持:

  • escape

escape

# escape=\ (backslash)

# escape=` (backtick)

escape 指令设置Dockerfile里默认的转义符。如果没有指定,默认的转义符是 \ 。

转义符既用于转义行中字符,也用于转义换行符。这里允许一个Dockerfile 指令行分跨越多行。需要注意的是不管escape解析器指令是否包含在一个Dockerfile 里,转义是不可以在RUN命令中执行,除非在行末。

把转义符设置成 是主要用于Windows中,当 \ 作为目录路径的分隔符。` 跟Windows PowerShell保持一致。

考虑到接下来的例子将会在Windows中非显式失败。第二个 \ 在第二行末会被解释成换行符,而不是从第一个 \ 转义过来的目标。类似地,第三行末尾的 \ , 假设实际它被当作一个指令,这就是它被当作行连续的原因。结果就是Dockerfile 把第二行和第三行合成单独的一个指令:

FROM microsoft/nanoserver
COPY testfile.txt c:\\
RUN dir c:\

结果如下:

PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/2 : COPY testfile.txt c:\RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>

对于上面的其中一个解决方案是使用 / 作为 COPY指令的目标和 dir。然而,这个符号,最好的情况,也会是是人迷惑,因为在Windows上它不是正式的路径符号,最坏的情况,容易出错,因为不是所有的命令在Windows上都支持 / 作为路径分隔符。

通过添加 escape 解析器指令,下面的Dockerfile可以成功执行出Windows文件路径原生平台语法期望的结果:

# escape=`

FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\

结果如下:

PS C:\John> docker build -t succeeds --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1/3 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/3 : COPY testfile.txt c:\
 ---> 96655de338de
Removing intermediate container 4db9acbb1682
Step 3/3 : RUN dir c:\
 ---> Running in a2c157f842f5
 Volume in drive C has no label.
 Volume Serial Number is 7E6D-E0F7

 Directory of c:\

10/05/2016  05:04 PM             1,894 License.txt
10/05/2016  02:22 PM    <DIR>          Program Files
10/05/2016  02:14 PM    <DIR>          Program Files (x86)
10/28/2016  11:18 AM                62 testfile.txt
10/28/2016  11:20 AM    <DIR>          Users
10/28/2016  11:20 AM    <DIR>          Windows
           2 File(s)          1,956 bytes
           4 Dir(s)  21,259,096,064 bytes free
 ---> 01c7f3bef04f
Removing intermediate container a2c157f842f5
Successfully built 01c7f3bef04f
PS C:\John>

你可能感兴趣的:(Docker,devops)