Docker之Dockerfile语法
1. FROM
指定基础镜像,并且必须是第一条指令,语法如下:
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
- 三种写法,其中 < tag>和< digest> 是可选项,如果没有选择,那么默认值为latest;
- 尽量使用官方的image作为base image;
- 如果不以任何镜像为基础,那么写法为:FROM scratch;
- FROM可以在一个Dockerfile中出现多次,以便于创建混合的images。
2. LABEL
镜像指定标签,语法如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号,如下:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
说明:①LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖;②metadata不可少
3. WORKDIR
用于为Dockerfile中所有RUN、CMD、ENTRYPOINT、COPY和ADD指令设定工作目录,类似cd,语法为:
WORKDIR <dirpath>
1.在Dockerfile文件中,WORKDIR指令可以出现多次,
2. 其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径,尽量使用绝对路径。
3.用WORKDIR,不要用RUN cd。
4. ADD and COPY
都是复制命令,把本地文件天骄到image中。
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
1.<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径。
2.ADD命令的<src>可以是一个本地文件或者是一个本地压缩文件,还可以是一个url,COPY的只能是本地文件。
3.ADD命令的<src>若是压缩文件,可以解压缩。
4.大部分情况,COPY优于ADD,添加远程文件/目录请使用curl或者wget
5. ENV
功能为设置环境变量,定义常量,语法为:
ENV <key> <value>
ENV <key>=<value> ...
两者的区别就是第一种是一次设置一个,第二种是一次设置多个。
尽量使用ENV增加可维护性。
6. RUN
运行指定的命令,执行命令并创建新的Image Layer,RUN命令有两种格式:
RUN <command>
RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令
- 在linux操作系统上默认 /bin/sh -c
- 在windows操作系统上默认 cmd /S /C
第二种是类似于函数调用。可将executable理解成为可执行文件,后面就是两个参数。
多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层。多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。如太长需要换行的话则使用\符号。
7. CMD
设置容器启动后默认执行的命令和参数。语法有三种写法:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
8. ENTRYPOINT
设置容器启动时运行的命令。语法如下:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
RUN、CMD and ENTRYPOINT的区别
- RUN是构建Image时就运行的命令以及提交运行结果
- CMD是容器启动时执行的命令,在构建Image时并不运行。
- 如果docker run 指定了其他命令,CMD命令会被忽略
- 如果定义了多个CMD,只有最后一个会执行
- ENTRYPOINT不会被docker run命令指定的参数所覆盖,一定会执行
- 如果同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指令的内容将会作为ENTRYPOINT的参数
- 如果同时写了ENTRYPOINT和CMD,并且CMD是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效
9. EXPOSE
为暴露容器运行时的监听端口给外部,使容器内的应用可以通过端口和外界交互。语法:
EXPOSE <port> [<port>...]
告诉Docker服务端容器对外映射的本地端口,需要在docker run 的时候使用-p 或者 -P 选项生效。
10. MAINTAINER
作者信息,写在FROM后。语法:
MAINTAINER <name>