Dockerfile详解

FROM

  1. 指定基础镜像,必须是第一条指令

  2. 如果没有基础镜像,则以 FROM scratch 开头

  3. 这条指令写入的东西为镜像首层

写法FROM <images>:<tag>

USER

  1. 设置容器启动用户,可以是用户名或UID

  2. 如果容器以daemon用户运行,那么RUN, CMD, ENTRYPOINT 都会以这个用户运行

语法

USER daemo
USER UID

ENV 指令

  1. 设置容器环境变量

语法

ENV <key> <value>
ENV <key>=<value> ... // 可以设置多个

WORKDIR

  1. 设置工作目录,对 RUN, CMD, ENTRYPOINT, COPY, ADD 生效。

  2. 如果不存在则会创建, 也可以设置多次

  3. 可以指定绝对路径和相对路径,这里的路径是指容器中的路径

  4. WORKDIR 会解析环境变量

  5. 可以理解为cd 命令

语法

RUN

  1. RUN命令在容器的可写入层执行命令,并commit容器为新的镜像。

  2. 上一步RUN命令生成的镜像被接下来RUN使用,每次RUN命令都会重新生成一个新的镜像

  3. 可以通过链式输入命令以减少创建镜像层的数量

  4. 镜像层过多,会导致镜像过大

  5. 可以通过docker history 镜像名称 查看镜像层

  6. CMD 命令通常在文件最末尾处

写法RUN <command> 或者 RUN ["executable", "param1", "param2"]

第二种方式类似函数调用,在linux下,自动使用脚本解析器: /bin/sh -c ,windows下则是 cmd /S /C

为了减少镜像层数,可以使用链式命令 RUN command1&& command2 并且,可以使用 \反斜线 换行。

CMD

  1. CMD 命令用于指定启动容器时的命令

  2. 如果不指定CMD命令,则将使用基础镜像提供的默认命令

  3. 因为是启动命令,所以在创建容器时不会执行,只有启动容器时才会执行

  4. 也可以使用exec形式指定要执行的命令

  5. 可以使用docker run -ti centos:7 echo "hello world" 的方式,替换默认命令

  6. 写法:CMD ["echo", "hello"]

  7. 只可以写一条,如果写多条,只有最后一条有效

ENTRYPOINT

功能是启动时默认命令,与CMD类似

语法

相同点

  1. 只可以写一条,如果有多条,只有最后一条有效

  2. 容器启动时相同

不同点

  1. ENTRYPOINT 指令不会被运行时command覆盖

COPY

  1. COPY 指令从build上下文复制文件或者文件夹到容器文件系统

  2. 例如: COPY xxx.jar /data/jar/

ADD

  1. ADD指令和COPY指令类似,可以将文件复制到容器中

  2. 也可以从Internet下载文件并复制到容器中

  3. 并且,ADD命令可以自动解压压缩文件

  4. 通常使用COPY指令,除非明确需要ADD指令

VOLUME

  1. 可实现挂载

  2. 容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失

  3. 数据资源推荐挂载

语法

LABEL

LABEL 指令为镜像指定标签, 一个镜像可以拥有多个标签

语法

可以使用 反斜杠换行,或者多个LABEL 标签

MAINTAINER

指定作者:

ARG

  1. 设置变量命令

  2. ARG命令定义一个变量,在docker build 使用Dockerfile构建镜像时,使用 --build-arg <varname>=<value> 来指定变量值

  3. 可以给变量设置默认值

  4. 如果用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个Warning[Warning] One or more build-args [foo] were not consumed.

语法

HEALTHCHECK

语法

OPTIONS 支持如下三个选项:

CMD命令的返回值,决定了本次健康检查是否成功:

比如:

HEALTHCHECK 指令只可以出现一次,如果出现多次,最后一个生效。

ONBUILD

  1. 只对当前镜像的子镜像生效

比如当前镜像为A,在Dockerfile种添加: ONBUILD RUN ls -al 这个 ls -al 命令不会在A镜像构建或启动的时候执行

此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

语法

STOPSIGNAL 指令

语法

命令是的作用是当容器推出时给系统发送什么样的指令

使用Dockerfile构建image

cd 到 Dockerfile 文件所在路径执行 docker build -t 镜像名称:版本 . 即可构建镜像

镜像构建缓存

file

如果新的构建版本中,某些指令与之前的版本一致,则会使用缓存。

造成的问题

  1. 如果是yum update -y 命令,则不会执行,导致yum仓库源不是最新的

解决办法

  1. 保证命令前后不一致,可以使用链式命令

  2. 使用 –no-cache=truedocker build -t centos . --no-cache=true

上传镜像至 DockerHub

  1. docker login

  2. docker push [OPTIONS] NAME[:TAG]

构建多CPU架构image

创建以下dockerfile:

安装buildx:

在mac与win的docker-desktop自带buildx,而linux需要安装:https://github.com/docker/buildx

创建并使用一个新的builder(默认builder可构建的cpu架构类型少):

查看所有的builder列表:

查看当前使用的builder:

使用buildx构建多cpu架构的镜像:

**成果:**https://hub.docker.com/repository/docker/yangsx95/gitclient

多阶段构建

可以使用Dockerfile拉取环境镜像,分阶段构建最终镜像。比如一个java应用,依次经过三个阶段:

  1. git clone 拉取代码

  2. mvn clean package 打包

  3. 放入tomcat容器

--from可以指定名称,也可以指定索引,比如引用第一个阶段的结果,使用--from=0

将上述内容保存到Dockerfile文件中,使用下面的命令构建镜像:

测试:

最后更新于

这有帮助吗?