Dockerfile
Dockerfile
指令 | 说明 |
---|---|
FROM | 指定基础镜像 |
MAINTAINER | 指定维护者信息,已经过时,可以使用 LABEL maintainer=xxx 来替代 |
RUN | 运行命令 |
CMD | 指定启动容器时默认的命令 |
ENTRYPOINT | 指定镜像的默认入口,运行命令 |
EXPOSE | 声明镜像内服务监听的端口 |
ENV | 指定环境变量,可以在 docker run 的时候使用 -e 改变,会被固化到 image 的 config 里面 |
ADD | 复制指定的 src 路径下的内容到容器中的 dest 路径下,src 可以为 url 会自动下载,可以为 tar 文件,会自动解压 |
COPY | 复制本地主机的 src 路径下的内容到镜像中的 dest 路径下,但不会自动解压等 |
LABEL | 指定生成镜像的元数据标签信息 |
VOLUME | 创建数据卷挂载点 |
USER | 指定运行容器时的用户名或 UID |
WORKDIR | 配置工作目录,为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录 |
ARG | 指定镜像内使用的参数(如版本号信息等),可以在 build 的时候,使用 –buildargs 改变 |
OBBUILD | 配置当创建的镜像作为其他镜像的基础镜像是,所指定的创建操作指令 |
STOPSIGNAL | 容器退出的信号值 |
HEALTHCHECK | 健康检查 |
SHELL | 指定使用 shell 时的默认 shell 类型 |
FROM
FROM 指定基础镜像,最好挑一些 apline,slim 之类的基础小镜像,scratch 镜像是一个空镜像,常用于多阶段构建
LABEL
标注镜像的一些说明信息
1 | LABEL multi.label1="value1" multi.label2="value2" other="value3" |
RUN
RUN 指令在当前镜像层顶部的新层执行任何命令,并提交结果,生成新的镜像层
生成的提交映像将用于 Dockerfile 中的下一步,分层运行 RUN 指令并生成提交符合 Docker 的核心概念,就像源代码控制一样
exec 形式可以避免破坏 shell 字符串,并使用不包含指定 shell 可执行文件的基本映像运行 RUN 命令,可以使用 SHELL 命令更改 shell 形式的默认 shell,在 shell 形式中,您可以使用 \ 将一条 RUN 指令继续到下一行
RUN
(shell 形式, /bin/sh -c 的方式运行,避免破坏 shell 字符串)
RUN [“executable”, “param1”, “param2”] (exec 形式)
1 | RUN /bin/bash -c 'source $HOME/.bashrc; \ |
1 | # 测试案例 |
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 形式)
1 | # 一个示例 |
只能有一个 CMD
Dockerfile 中只能有一条 CMD 指令,如果您列出多个 CMD,则只有最后一个 CMD 才会生效。
CMD 的主要目的是为执行中的容器提供默认值,这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定 ENTRYPOINT 指令
CMD 为 ENTRYPOINT 提供默认参数
如果使用 CMD 为 ENTRYPOINT 指令提供默认参数,则 CMD 和 ENTRYPOINT 指令均应使用 JSON 数组格式指定
docker run 启动参数会覆盖 CMD 内容
1 | # 一个示例 |
ARG 和 ENV
ARG
ARG 指令定义了一个变量,用户可以在构建时使用 –build-arg = 传递,docker build 命令会将其传递给构建器
–build-arg 指定参数会覆盖 Dockerfile 中指定的同名参数
如果用户指定了“未在 Dockerfile 中定义的构建参数”,则构建会输出“警告”
ARG 只在构建期有效,运行期无效
不建议使用构建时变量来传递诸如 github 密钥,用户凭据等机密,因为构建时变量值使用 dockerhistory 是可见的
ARG 变量定义从 Dockerfile 中定义的行开始生效
使用 ENV 指令定义的环境变量始终会覆盖同名的 ARG 指令
ENV
在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换
引号和反斜杠可用于在值中包含空格
ENV 可以使用 key value 的写法,但是这种不建议使用了,后续版本可能会删除
1 | ENV MY_MSG hello |
docker run –env 可以修改这些值
容器运行时 ENV 值可以生效
ENV 在 image 阶段就会被解析并持久化(docker inspect image 查看),参照下面示例
1 | FROM alpine |
综合测试示例
1 | FROM alpine |
ADD 和 COPY
COPY
COPY 的两种写法
1 | COPY [--chown=<user>:<group>] <src>... <dest> |
–chown 功能仅在用于构建 Linux 容器的 Dockerfiles 上受支持,而在 Windows 容器上不起作用
COPY 指令从 src 复制新文件或目录,并将它们添加到容器的文件系统中,路径为 dest
可以指定多个 src 资源,但是文件和目录的路径将被解释为相对于构建上下文的源
每个 src 都可以包含通配符,并且匹配将使用 Go 的 filepath.Match 规则进行
1 | COPY hom* /mydir/ # 当前上下文,以 home 开始的所有资源 |
ADD
同 COPY 用法,不过 ADD 拥有自动下载远程文件和解压的功能。
注意:
src 路径必须在构建的上下文中,不能使用 ../something /something 这种方式,因为 docker 构建的第一步是将上下文目录(和子目录)发送到 docker 守护程序
如果 src 是 URL,并且 dest 不以斜杠结尾,则从 URL 下载文件并将其复制到 dest
如果 dest 以斜杠结尾,将自动推断出 url 的名字(保留最后一部分),保存到 dest
如果 src 是目录,则将复制目录的整个内容,包括文件系统元数据
WORKDIR 和 VOLUME
WORKDIR
WORKDIR 指令为 Dockerfile 中跟随它的所有 RUN,CMD,ENTRYPOINT,COPY,ADD 指令设置工作目录。 如果 WORKDIR 不存在,即使以后的 Dockerfile 指令中未使用它也将被创建
WORKDIR 指令可在 Dockerfile 中多次使用,如果提供了相对路径,则它将相对于上一个 WORKDIR 指令的路径,例如:
1 | WORKDIR /a |
也可以用到环境变量
1 | ENV DIRPATH=/path |
VOLUME
作用:把容器的某些文件夹映射到主机外部
写法:
1 | VOLUME ["/var/log/"] # 可以是 JSON 数组 |
注意:用 VOLUME 声明了卷,那么以后对于卷内容的修改会被丢弃,所以一定在 volume 声明之前修改内容
USER
写法:
1 | USER <user>[:<group>] |
USER 指令设置运行映像时要使用的用户名(或 UID)以及可选的用户组(或 GID),以及 Dockerfile 中 USER 后面所有 RUN,CMD 和 ENTRYPOINT 指令
EXPOSE
EXPOSE 指令通知 Docker 容器在运行时在指定的网络端口上进行侦听,可以指定端口是侦听 TCP 还是 UDP,如果未指定协议,则默认值为 TCP
EXPOSE 指令实际上不会发布端口,它充当构建映像的人员和运行容器的人员之间的一种文档,即有关打算发布哪些端口的信息,要在运行容器时实际发布端口,请在 docker run 上使用 -p 标志发布并映射一个或多个端口,或使用 -P 标志发布所有公开的端口并将其映射到高阶端口
1 | EXPOSE <port> [<port>/<protocol>...] |
multi-stage builds
1 | # 以下所有前提 保证 Dockerfile 和项目在同一个文件夹 |
示例
1 | FROM openjdk:8-jre-alpine |