Skip to content

深入理解 Dockerfile

Dockerfile 是每一行是一条命令语句,支持以#开头的注释 通常一个标准的 Dockerfile 包含 4 部分信息:基础镜像信息, 维护者信息,镜像操作指令, 启动执行指令

常用指令详解

指令说明
FROM指定基础镜像
MAINTAINER已过时,可以使用 LABEL maintainer=xxx 来替代
RUN运行命令
CMD指定启动容器时默认的命令
ENTRYPOINT指定镜像的默认入口.运行命令
EXPOSE声明镜像内服务监听的端口
ENV指定环境变量,可以在 docker run 的时候使用-e 改变 v
ADD复制指定的 src 路径下的内容到容器中的 dest 路径下,src 可以为 url 会自动下载,可以为 tar 文件,会自动解压
COPY复制本地主机的 src 路径下的内容到镜像中的 dest 路径下,但不会自动解压等
LABEL指定生成镜像的元数据标签信息
VOLUME创建数据卷挂载点
USER指定运行容器时的用户名或 UID
WORKDIR配置工作目录,为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录
ARG指定镜像内使用的参数(如版本号信息等),可以在 build 的时候,使用--buildargs 改变

FROM

FROM 指定基础镜像于多阶段构建 Java 应用当然是 java 基础镜像(SpringBoot 应用)或者 Tomcat 基础镜像(War 应用) JS 模块化应用一般用 nodejs 基础镜像 其他各种语言用自己的服务器或者基础环境镜像,如 python、golang、java、php 等

LABEL

标注镜像的一些说明信息

bash
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3

RUN

RUN 指令在当前镜像层顶部的新层执行任何命令,并提交结果,生成新的镜像层 生成的提交映像将用于 Dockerfile 中的下一步。 分层运行 RUN 指令并生成提交符合 Docker 的核心概念,就像源代码控制一样。

BASH
RUN <command> ( shell 形式, /bin/sh -c 的方式运行,避免破坏shell字符串)
RUN ["executable", "param1", "param2"] ( exec 形式)

CMD 和 ENTRYPOINT

CMD 的三种写法:

  1. CMD ["executable","param1","param2"] ( exec 方式, 首选方式)
  2. CMD ["param1","param2"] (为 ENTRYPOINT 提供默认参数)
  3. CMD command param1 param2 ( shell 形式)

ENTRYPOINT 的两种写法:

  1. ENTRYPOINT ["executable", "param1", "param2"] ( exec 方式, 首选方式)
  2. ENTRYPOINT command param1 param2 (shell 形式)

Dockerfile 中只能有一条 CMD 指令。 如果您列出多个 CMD,则只有最后一个 CMD 才会生效。 CMD 的主要目的是为执行中的容器提供默认值。 这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定 ENTRYPOINT 指令。

ARG 和 ENV

  1. ARG

ARG 指令定义了一个变量,用户可以在构建时使用--build-arg = 传递,docker build 命令会将其传递给构建器。 --build-arg 指定参数会覆盖 Dockerfile 中指定的同名参数 如果用户指定了 未在 Dockerfile 中定义的构建参数 ,则构建会输出 警告 。 ARG 只在构建期有效,运行期无效

  1. ENV

在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。 引号和反斜杠可用于在值中包含空格。 ENV 可以使用 key value 的写法,但是这种不建议使用了,后续版本可能会删除

ADD 和 COPY

COPY 的两种写法

  1. COPY 指令从 src 复制新文件或目录,并将它们添加到容器的文件系统中,路径为 dest 。

  2. 可以指定多个 src 资源,但是文件和目录的路径将被解释为相对于构建上下文的源。 每个 src 都可以包含通配符,并且匹配将使用 Go 的 filepath.Match 规则进行。

Dockerfile 最佳实践,多阶段构建

让镜像变小

bash
# 第一阶段:环境构建;
FROM maven:3.5.0-jdk-8-alpine AS builder
WORKDIR /app
ADD ./ /app
RUN mvn clean package -Dmaven.test.skip=true
# 第二阶段,最小运行时环境,只需要jre
FROM openjdk:8-jre-alpine
# 修改时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo
'Asia/Shanghai' >/etc/timezone
LABEL maintainer="534096094@qq.com"
# 从上一个阶段复制内容
COPY --from=builder /app/target/*.jar /app.jar
ENV JAVA_OPTS=""
ENV PARAMS=""
# 运行jar包
ENTRYPOINT [ "sh", "-c", "java  $JAVA_OPTS -jar /app.jar $PARAMS" ]

Released under the MIT License.