Docker学习之路(四) Dockerfile
在第一天的学习中 此次尝试了 自己提交一个镜像 即commit命令
复习:如何根据一个容器 commit 为一个全新镜像
docker commit -m="提交信息" -a="作者信息" 使用的容器ID/容器名 要提交为的镜像名:Tag
DockerfIle 了解
Dockerfile 呢, 也是docker 构建镜像的一种方式,类似于一个构建镜像的脚本文件。
官方解释
我们查看官网的镜像仓库 随便搜索一个镜像,发现每一个镜像都是有很多版本号的 那么这些发布的镜像又是从哪里来的呢? 他们就是通过dockerfile文件来构建的一个个镜像。
我们点开 centos7 版本 发现来到了 github地址,果然 centos7 构建也是由一个dockerfile文件执行命令构建完成的。
看了 官网dockerfile的解释 ,是在文件中连续编写几个构建镜像的指令 最后才会成为一个完整的镜像,文件中 几个红色全大写的应该就是指令了 ,指令的意义以及dockerfile 文件内容以及 执行流程下边慢慢梳理。
DockerfIle指令
dockfile 文件 就是通过其中编写的一个个指令 ,我们执行dockerfile 文件中的指令 指令一层层叠加 最后就形成了咱的镜像。
Dockerfile由多条指令组成,每条指令在编译镜像时执行相应的程序完成某些功能,由指令+参数组成,以逗号分隔,#作为注释起始符,指令不区分大小写,但是一般指令使用大些,参数使用小写
dockerfile 指令初略说明
指令 | 参数 |
---|---|
FROM | 构建我们镜像所需的基础镜像 |
MAINTAINER | 构建镜像的作者信息 (官网最新已弃用) 采用LABEL |
RUN | 构建镜像时 需要运行的命令 |
CMD | 设置容器 启动时需要运行的命令 命令会被覆盖 |
LABEL | 设置镜像标签 |
EXPOSE | 申明镜像暴露的端口 类似命令 -p xxx:xxx |
VOLUME | 定义数据卷进进行挂载 类似命令 -v |
ENV | 设置镜像环境变量 命令 -e |
COPY | 编译镜像时 将文件复制到镜像中 docker cp 外路径 容器内路径 |
ADD | ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY) |
ENTRYPOINT | 类似于 CMD 指令 但命令不会被覆盖 |
WORKDIR | 指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在 |
ONBUILD | 用于延迟构建命令的执行。 |
HEALTHCHECK | 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。 |
dockerfile 指令详细说明
FROM
指令:FROM
功能描述:设置基础镜像
语法:FROM < image>[:< tag> | @< digest>]
示例:咱们上方的 centos7 镜像 设置的基础镜像为:FROM scratch
提示:镜像都是从一个基础镜像(操作系统或其他镜像)生成,可以在一个Dockerfile中添加多条FROM指令,一次生成多个镜像
注意:如果忽略tag选项,会使用latest镜像
MAINTAINER
指令:MAINTAINER
功能描述:构建镜像的作者信息 一般在设置作者信息的时候 采用 作者名+邮箱的形式 最新官网已弃用 建议使用 LABEL 示例:LABEL maintainer="SvenDowideit@home.org.au"
语法:MAINTAINER < name>
示例:MAINTAINER <lei.leileideve@163.com>
RUN
指令:RUN
功能描述:用于执行后面跟着的命令行命令
语法:
shell 格式: RUN <命令行命令>
示例:<命令行命令> 等同于,在终端操作的 shell 命令。 RUN ls -a
exec 格式 : RUN ["可执行文件", "参数1", "参数2"]
示例:RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
CMD
指令:CMD
功能描述:设置容器 启动时需要运行的命令
语法:
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
提示:类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
CMD 在docker run 时运行。
RUN 是在 docker build。
注意:构建镜像后,通过docker run 启动容器的时候 cmd命令会被覆盖,即Dockerfile中只能有一条CMD命令,如果写了多条则最后一条生效
ENTRYPOINT
指令:COPY
语法:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
示例:
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
功能描述:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
CMD 和ENTRYPONIT 区别
我们之前说了 cmd 命令 在 docker run 启动的时候 cmd 命令会被覆盖 而ENTRYPOINT 会进行追加
实战理解:
一个用 cmd 构建镜像
编写构建文件 dockerfilecmd
FROM centos
CMD echo "aaaa"
CMD ["ls","-a"]
docker build -f /docker/dockerfile/dockerfilecmd-t cmdcentos .
用ENTRYPOINT 执行shell命令构建镜像
添加 dockerfile-entrypoint 文件
FROM centos
ENTRYPOINT ["ls","-a"]
docker build -f /docker/dockerfile/dockerfile-entrypoint -t entrypiintcentos .
二者区别 cmd 在 docker run 命令后 加入 -l 运行报错 因为 之前的 ls -a 被覆盖为了 l ,l 命令是没有的,所以报错 entrypoint 在 docker run 命令后 加入 -l 其原生的 ls -a 追加了 l 变为了 ls -al,因而详细展示了目录。
WORKDIR
指令:WORKDIR
功能描述:设置RUN CMD ENTRYPOINT ADD COPY指令的工作目录 ,该WORKDIR指令可以解析先前使用设置的环境变量 ENV
语法:WORKDIR < Path>
示例:WORKDIR /a
提示:如果工作目录不存在,则Docker Daemon会自动创建
Dockerfile中多个地方都可以调用WORKDIR,如果后面跟的是相对位置,则会跟在上条WORKDIR指定路径后(如WORKDIR /A WORKDIR B WORKDIR C,最终路径为/A/B/C)
ONBUILD
LABEL
指令:LABEL
功能描述:设置镜像的标签
延伸:镜像标签可以通过docker inspect查看
格式:LABEL < key>=< value> < key>=< value>
示例:LABEL version="1.0"
提示:不同标签之间通过空格隔开
注意:镜像会继承基础镜像中的标签,如果存在同名标签则会覆盖
EXPOSE
指令:EXPOSE
功能描述:该EXPOSE指令通知Docker容器在运行时监听指定的网络端口。您可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。
语法:EXPOSE < port> < port> …
示例:
延伸:镜像暴露端口可以通过docker inspect查看
提示:容器启动时,Docker Daemon会扫描镜像中暴露的端口,如果加入-P参数,Docker Daemon会把镜像中所有暴露端口导出,并为每个暴露端口分配一个随机的主机端口(暴露端口是容器监听端口,主机端口为外部访问容器的端口)
注意:EXPOSE只设置暴露端口并不导出端口,只有启动容器时使用-P/-p才导出端口,这个时候才能通过外部访问容器提供的服务
VOLUME
指令:VOLUME
功能描述:设置容器的挂载点
语法:
VOLUME [“/data”]
VOLUME /data1 /data2
提示:启动容器时,Docker Daemon会新建挂载点,并用镜像中的数据初始化挂载点,可以将主机目录或数据卷容器挂载到这些挂载点 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
ENV
指令:ENV
功能描述:设置镜像中的环境变量
语法:ENV < key>=< value>…|< key> < value>
示例:ENV PASSWORD=123456
注意:环境变量在整个编译周期都有效,第一种方式可设置多个环境变量,第二种方式只设置一个环境变量
提示: ENV设置的变量值在整个编译过程中总是保持不变的
COPY
指令:COPY
功能描述:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
语法:COPY <源路径1>... <目标路径>
示例:COPY /leilei/home/* /mydir/
ADD
指令:COPY
功能描述:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
语法:ADD <源路径1>... <目标路径>
示例:ADD /leilei/home/* /mydir/
注意:
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
指令:ONBUILD
功能描述:用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
语法:ONBUILD [INSTRUCTION]
HEALTHCHECK
指令:HEALTHCHECK
功能描述:健康检查 用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
语法:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
实战: Dockerfile 文件生成镜像
我们在宿主机上 /docker/ 下创建一个文件
touch dockerfile
在文件中 编写咱们的指令
vim dockerfile
文件内容
#指定基础镜像
FROM centos
#指定挂载
VOLUME ["volumes"]
#指定版本
LABEL version="6.6.6"
#指定作者
LABEL author="leilei"
CMD '---build--success--'
CMD /bin/bash
使用 dokcer build 命令根据 Dockerfile 进行构建 -f 指定 Dockerfile 文件位置 -t 指定构建 镜像名:Tag 注意后边有个小 .
docker build -f /docker/dockerfile/dockerfile01 -t leileicentos:1.2 .
构建成功后 会有两个successfully 语句
查看镜像并运行
发现我们进入容器后 直接来到了所指定的功能合作目录 /usr/local/下,并且我们安装的 nginx 以及vim 命令可以使用了 还可以使用 docker inspect 查看运行容器的详细信息
特别注意:构建语句后边有个 . 符号
特别注意:构建语句后边有个 . 符号
特别注意:构建语句后边有个 . 符号
截止这里 dockerfile 的初步使用就完了 后续更新 开发项目 通过docker 构建镜像并运行