深入理解 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
标注镜像的一些说明信息
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3
RUN
RUN 指令在当前镜像层顶部的新层执行任何命令,并提交结果,生成新的镜像层 生成的提交映像将用于 Dockerfile 中的下一步。 分层运行 RUN 指令并生成提交符合 Docker 的核心概念,就像源代码控制一样。
RUN <command> ( shell 形式, /bin/sh -c 的方式运行,避免破坏shell字符串)
RUN ["executable", "param1", "param2"] ( exec 形式)
CMD 和 ENTRYPOINT
CMD 的三种写法:
- CMD ["executable","param1","param2"] ( exec 方式, 首选方式)
- CMD ["param1","param2"] (为 ENTRYPOINT 提供默认参数)
- CMD command param1 param2 ( shell 形式)
ENTRYPOINT 的两种写法:
- ENTRYPOINT ["executable", "param1", "param2"] ( exec 方式, 首选方式)
- ENTRYPOINT command param1 param2 (shell 形式)
Dockerfile 中只能有一条 CMD 指令。 如果您列出多个 CMD,则只有最后一个 CMD 才会生效。 CMD 的主要目的是为执行中的容器提供默认值。 这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定 ENTRYPOINT 指令。
ARG 和 ENV
- ARG
ARG 指令定义了一个变量,用户可以在构建时使用--build-arg = 传递,docker build 命令会将其传递给构建器。 --build-arg 指定参数会覆盖 Dockerfile 中指定的同名参数 如果用户指定了 未在 Dockerfile 中定义的构建参数 ,则构建会输出 警告 。 ARG 只在构建期有效,运行期无效
- ENV
在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。 引号和反斜杠可用于在值中包含空格。 ENV 可以使用 key value 的写法,但是这种不建议使用了,后续版本可能会删除
ADD 和 COPY
COPY 的两种写法
COPY 指令从 src 复制新文件或目录,并将它们添加到容器的文件系统中,路径为 dest 。
可以指定多个 src 资源,但是文件和目录的路径将被解释为相对于构建上下文的源。 每个 src 都可以包含通配符,并且匹配将使用 Go 的 filepath.Match 规则进行。
Dockerfile 最佳实践,多阶段构建
让镜像变小
# 第一阶段:环境构建;
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" ]