Docker 学习 3. 编写 Dockerfile

目录

书写注意点

  1. 指定对大小写不敏感,但惯例是全为大写。
  2. 指定之后至少携带一个参数。
  3. # 开头的行为注释。
  4. 一条指定能完成的动作不要分成两条。因为指令越多,分层就越多,效率越低。
  5. 如果一条指令较长,可以使用 \ 分割。例如
1
2
3
4
5
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2"

FROM

scratch 镜像

scratch 镜像是一个空镜像,是所有镜像的 Base Image(相当于面向对象编程中的 Object 类)。scratch 镜像只能在 Dockerfile 中被继承,不能通过 pull 命令拉取,不能 run,也没有 tag。 并且它也不会生成镜像中的文件系统层。在 Docker 中,scratch 是一个保留字,用户不能作为自己的镜像名称使用。

MAINTAINER 维护者

【语法】 MAINTAINER
【解析】 MAINTAINER 指令的参数填写的一般是维护者姓名和信箱。不过,该指令官方已**不建议使用**,而是使用 LABEL 指令代替。

LABEL 标签

【语法】LABEL < key >=< value > < key >=< value >··…·.
【解析】LABEL 指令中可以以键值对的方式包含任意镜像的元数据信息,用于替代 MAINTAINER 指令。通过 docker inspect 可查看到 LABEL 与 MAINTAINER 的内容。

ENV 环境变量

【语法 1】ENV < key > < value >.
【解析】用于指定环境变量,这些环境变量,后续可以被 RUN 指令使用容器运行起来之 后,也可以在容器中获取这些环境变量。

【语法 2】ENV < key1 >=< value1 > < key2 >=< value2 >....
【解析】可以设置多个变量,每个变量为一对< key >=< value >指定。

ARG 变量

【语法】ARG < varname >[=< default value >]
【解析】定义一个变量,该变量将会使用于镜像构建运行时。若要定义多个变量,则需要定义多个 ARG 指令。

ENV 和 ARG 区别

ARG 定义的变量可以在 docker build 的使用用–build-arg 重新指定,ENV 不可以。

WORKDIR 工作目录

【语法】WORKDIR path.
【解析】容器打开后默认进入的目录,一般在后续的 RUN、CMD、ENTRYPOINT、ADD 等指令中会引用该目录。可以设置多个 WORKDIR 指令。后续 WORKDIR 指令若用的是相对路径,则会基于之前 WORKDIR 指令指定的路径。在使用 docker run 运行容器时,可以通过—w 参数覆盖构建时所设置的工作目录。

RUN 运行

【语法 1】 RUN
【解析】这里的就是 shell 命令。docker build 执行过程中,会使用 shell 运行指定的 command。

【语法 2】 RUN [“EXECUTABLE”,”PARAM1”,”PARAM2”, …].
【解析】在 docker build 执行过程中,会调用第一个参数“EXECUTABLE”指定的应用程序运行,并使用后面第二、三等参数作为应用程序的运行参数。

CMD 执行命令

【语法 1】 CMD [“EXECUTABLE”,”PARAM1”,”PARAM2”, ..].
【解析】在容器启动后,即在执行完 docker run 后会立即调用执行“EXECUTABLE”指定的可执行文件,并使用后面第二、三等参数作为应用程序的运行参数。

【语法 2】 CMD command param1 param2, .
【解析】这里的 command 就是 shell 命令。在容器启动后会立即运行指定的 shell 命令。

【语法 3】 CMD [“PARAM1”,“PARAM2”, …].
【解析】提供给 ENTERYPOINT 的默认参数。.

ENTRYPOINT 入口

【语法 1】 ENTRYPOINT [“EXECUTABLE”, “PARAM1”, “PARAM2” …]
【解析】在容器启动过程中,即在执行 docker run 时,会调用执行“EXECUTABLE”指定的应用程序,并使用后面第二、三等参数作为应用程序的运行参数。

【语法 2】ENTRYPOINT command param1 param2,…
【解析】这里的 command 就是 shell 命令。在容器启动过程中,即在执行 docker run 时,会运行指定的 shell 命令。

CMD 和 ENTRYPOINT 区别

CMD ENTRYPOINT
docker run 的 COMMAND 可以替换 CMD 内容。 docker run 的 COMMAND 不可以替换 ENTRYPOINT 的内容。
docker run 如果没有 COMMAND, 只有 ARG。CMD 会报错,因为 CMD 没有拼接 ARG 的作用。 docker run 如果没有 COMMAND, 只有 ARG, 并且 ENTRYPOINT 用[“EXECUTABLE”, “PARAM1”, “PARAM2” …]的形式使用 ARG 会被拼接。

结论:无论是 RUN 还是 ENTRYPOINT,使用[“EXECUTABLE”, “PARAM1”, “PARAM2” …]的**通用性**会更强。

EXPOSE 暴露

【语法】RUN[]
【解析】指定容器准备对外暴露的端口号,但该端口号并不会真正的对外暴露。若要真正暴
露,则需要在执行 docker run 命令时使用-p(小 p)来指定说要真正暴露出的端口号。给人看的

ADD 添加

【语法 1】ADD < src > < dest >.
【语法 2】ADD["< src >","< dest >"]#路径中存在空格时使用双引号引起来
【解析】该指令将复制当前宿主机中指定文件 src 到容器中的指定目录 dest 中。src 可以是宿主机中的绝对路径,也可以时相对路径。但相对路径是相对于 docker build 命令所指定的路径的。src 指定的文件可以是一个压缩文件,压缩文件复制到容器后会**自动解压**为目录;src 也可以是一个 URL,此时的 ADD 指令相当于 wget 命令;src 最好不要是目录,其会将该目录中所有内容复制到容器的指定目录中。dest 是一个绝对路径,其最后面的路径必须要加上斜杠,否则系统会将最后的目录名称当做是文件名的。

COPY 复制

功能与 ADD 指令相同,只不过 src 不能是 URL。若 src 为压缩文件,复制到容器后不会自动解压。

ONBUILD 子镜像编译时的操作

【语法】ONBUILD[INSTRUCTION]
【解析】该指令用于指定当前镜像的子镜像进行构建时要执行的指令。

构建新镜像的方法总结

  • docker build
  • docker commit
  • docker import(注意,docker load 并没有构建新镜像,其与原镜像是同一个镜像。)
  • docker compose
  • docker hub 中 Automated Builds