Dockerfile介绍
镜像的定制实际上就是定制每一层所添加的配置、文件,可以把每一层修改、安装、构建、操作都写入一个脚本, 这个脚本就是Dockerfile, Dockerfile是由一系列命令和参数构成的脚本,一个Dockerfile里面包含了构建整个image的完整命令。Docker通过docker build从上到下的顺序运行Dockerfile中的一系列命令自动构建image
一般包括:
基础镜像信息(FROM image)
维护者信息(MAINTAINER xxxx)
镜像操作指令(COPY, ADD, RUN, ENV等)
容器启动时执行指令(CMD, ENTRYPOINT)
分类 | 指令 | 说明 |
配置指令 | ARG | 定义创建镜像过程中使用的变量 |
FROM | 指定所创建镜像的基础镜像 | |
LABEL | 为生成的镜像添加元数据标签信息 | |
EXPOST | 声明镜像内服务监听的端口 | |
ENV | 指定环境变量 | |
ENTRYPOINT | 指定镜像的默认入口命令 | |
VOLUME | 创建一个数据卷挂载点 | |
USER | 指定运行容器时的用户名或UID | |
WORKDIR | 配置工作目录 | |
ONBUILD | 创建子镜像时指定自动执行的操作指令 | |
STOPSIGNAL | 指定退出的信号值 | |
HEALTHCHECK | 配置所启动容器如何进行健康检查 | |
SHELL | 指定默认的shell类型 | |
操作指令 | RUN | 运行指定命令 |
CMD | 启动容器时指定默认指定的命令 | |
ADD | 添加内容到镜像 | |
COPY | 复制内容到镜像 |
定义创建镜像过程中使用的变量
语法格式 |
示例 |
备注 |
ARG |
ARG image FROM $image |
docker build时,可以通过-build-arg[=]来为变量赋值,当镜像编译成功后,ARG指定的变量将不在存在(ENV指定的变量将在镜像中保留)
如: 创建dockerfile文件,内容如下
ARG image
FROM $image
RUN echo "helloworld"
CMD ["echo", "date"]
执行命令docker build --build-arg image=centos:7 --no-cache
为生成的镜像添加元数据标签信息,这些信息可以辅助过滤出特定镜像
语法格式 |
示例 |
备注 |
LABEL |
LABEL name=test |
一次设置一个 |
LABEL |
LABEL name=test age=10 |
一次设置多个 |
指定运行容器时的用户名或UID,后续RUN指令也会使用指定的用户身份
USER daemon
当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在Dockerfile中创建所需要的用户,临时获取管理员权限可以使用gosu命令
指定当基于所生成镜像创建子镜像时,自动执行的操作指令
语法格式 |
示例 |
备注 |
ONBUILD [INSTRUCTION] |
ONBUILD ADD . /app/src ONBUILD RUN /usr/local/python --dir /app/src...[] |
在创建专门用于自动编译、检查等操作的基础镜像时,十分有用 |
配置所启动容器如何进行健康检查(如何判断健康与否)
HEALTHCHECK [OPTIONS] CMD command 根据所执行命令返回值十分为0来判断
HEALTHCHECK NONE 禁止基础镜像中的健康检查
OPTION支持如下参数
-interval=DURATION(default:30s) 过多久检查一次
-timeout=DURATION(default:30s) 每次检查等待结果的超时
-retries=N(default:3) 如果失败,重试几次才最终确定失败
指定其他命令使用shell时的默认shell类型
语法格式 |
示例 |
备注 |
SHELL [“executable”, “parameters”] |
SHELL [“bin/sh”, “-c”] |
SHELL指令必须以json格式写入dockerfile
SHELL指令可以多次出现,每条SHELL指令都会覆盖所有先前的SHELL指令,并影响后续指令
指定基础镜像,必须为第一个命令,如果不以任何镜像为基础,则语法为FROM scratch,接下来所写的命令将作为镜像第一层开始
语法格式 |
示例 |
备注 |
FROM |
FROM centos |
|
FROM |
FROM centos:7 |
tag为可选项 |
FROM |
FROM mysql:xxxxxx |
digest为可选项 |
使用docker images --digests可以显示digests
tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
FROM可在同一个Dockerfile文件多次设置用来创建多个镜像,或者使用一个构建阶段作为另外一个构建阶段的依赖。只需要在每条新FROM前面提交输出的最后一个 镜像ID,每条FROM指令都会清除先前指令创建的任何状态
可以通过添加AS name到FROM指令,将名称赋予新的构建阶段。该名称可用于后续FROM和 COPY --from=
复制指令,将上下文的源路径下的文件或文件夹复制到新的一层镜像内的目标路径之下
语法格式 |
示例 |
备注 |
COPY <源路径> <目标路径> |
COPY hom* /mydir/ |
示例为通配、绝对路径 |
COPY不会自动解压文件,也不会访问网络资源
源路径为Dockerfile所在目录
和COPY指令格式和性质基本一致,支持远程URL,会自动将远程URL文件下载到目标路径下
如果源路径为压缩文件,ADD指令在复制到目标路径时会自动解压
将在当前镜像基础上执行指定命令,并提交为新的镜像,构建时执行,区别于CMD,CMD在容器启动的时候运行
语法格式 |
示例 |
备注 |
RUN |
RUN /bin/bash -c ‘source $HOME/.bashrc; echo $HOME’ |
shell执行,RUN后面直接跟shell命令 |
RUN [“executable”, “param1”, “param2”] |
RUN ["/bin/bash", “-c”, “echo hello”] |
exec执行,类似于函数调用 |
注意:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用,如果不想使用这些缓存镜像, 可以在构建时指定-no-cache参数
Dockerfile中每一个指令都会建立一层,多少个RUN就构建了多少层镜像,写多个RUN会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错,为使Dockerfile 更加易读,易懂和便于维护,复杂的 RUN 语句用反斜杠()分割成多行
设置环境变量,比如常见操作系统参数,Java启动参数等都可以通过ENV指令来设置
语法格式 |
示例 |
备注 |
ENV |
ENV name test |
一次设置一个 |
ENV |
ENV name=test age=10 |
一次设置多个 |
用来指定启动容器时默认执行的命令
语法格式 |
示例 |
备注 |
CMD [“executable”, “param1”, “param2”] |
CMD [“java”, “-version”] |
推荐方式 |
CMD command param1 param2 |
CMD echo “this is test” |
在默认的shell中执行,提供给需要交互的应用 |
CMD [“param1”, “param2”] |
CMD [“--help”] |
提供给ENTRYPOINT的默认参数 |
镜像默认入口指令,该指令会在启动容器时作为跟命令执行,所有传入值作为该指令的参数,支持两种格式
语法格式 |
示例 |
备注 |
ENTRYPOINT [“executable”, “param1”, “param2”] |
ENTRYPOINT [“java”, “-version”] |
exec调用执行推荐方式 |
ENTRYPOINT command param1 param2 |
ENTRYPONT echo “this is test” |
在默认的shell中执行,提供给需要交互的应用 |
RUN在镜像制作过程中运行指令
CMD和ENTRYPOINT
都在镜像启动时候默认入口命令,当Dockerfile中多次出现相同指令,都是只有最后一条生效,都可以采用exec和shell两种方式执行
不同之处,CMD [“param1”, “param2”]可以作为ENTRYPOINT参数使用,
docker run附加参数会覆盖CMD指令,但是会将附加参数传递给ENTRYPOINT
使用优先级为 ENTRYPOINT > Docker run命令参数 > CMD
类似cd命令,指定镜像内的工作目录,方便RUN、CMD、ENTRYPOINT、COPY、ADD等指令使用,如果不存在则会创建,也可以设置多次
语法格式 |
示例 |
备注 |
WORKDIR <文件目录> |
WORKDIR /home/root WORKDIR /application |
最后工作目录是/home/root/application |
指定外界交互的端口,即容器运行时监听的端口
语法格式 |
示例 |
备注 |
EXPOSE |
EXPOST 8081 8082 |
EXPOST并不会让容器的端口访问到主机,只是对外开放监听端口,需要在docker run运行容器时通过-p来发布监听端口,或通过-P参数来发布EXPOSE导出的所有端口
默认为TCP方式
用于指定持久化目录,实现挂载功能,授权访问从容器内到主机上的目录,用于容器之间共享目录,将本地文件夹或者其他容器中的文件夹挂载到当前容器中。此数据卷会随着容器的停止而消失,如果需要持久化则参考docker命令中,在run启动容器加-V参数
语法格式 |
示例 |
备注 |
VOLUME [“/home/root/usr/local”] |
VOLUME [“/var/log”] VOLUME /var/log VOLUME /var/log/db |
可以是一个jsonArray,也可以是多个值 |
容器使用的是AUFS,该文件系统不能持久化数据,当容器关闭所有更改就是消失,因此当数据持久化时使用该命令
一个卷可以存在于一个或多个容器的目录
卷可以在容器间共享和重用,参考参数--volumes-from
容器不一定要和其他容器共享卷
修改卷后会立即生效,对卷的修改不会对镜像造成英雄
卷会一直存在,直到没有容器使用