一、Dockerfile 介绍
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
基于 Dockerfile 构建镜像可以使用 docker build 命令。docker build 命令中使用-f 可以指定具体的
dockerfile 文件示例:
FROM centos
MAINTAINER xianchao
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum install wget -y
RUN yum install nginx -y
COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
dockerfile 构建镜像过程
1、从基础镜像运行一个容器
2、执行一条指令,对容器做出修改
3、执行类似 docker commit 的操作,提交一个新的镜像层
4、再基于刚提交的镜像运行一个新的容器
5、执行 dockerfile 中的下一条指令,直至所有指令执行完毕
二、dockerfile中关键字介绍
(1)FROM
基础镜像,必须是可以下载下来的,定制的镜像都是基于 FROM 的镜像,这里的 centos 就是定制需要的
基础镜像。后续的操作都是基于 centos 镜像。
(2)MAINTAINER
指定镜像的作者信息
(3)RUN
指定在当前镜像构建过程中要运行的命令
包含两种模式
1、Shell
RUN (shell 模式,这个是最常用的,需要记住)
RUN echo hello
2、exec 模式
RUN [“executable”,“param1”,“param2”](exec 模式)
RUN [“/bin/bash”,”-c”,”echo hello”]
等价于/bin/bash -c echo hello
(4)EXPOSE
仅仅只是声明端口。
作用:
1、帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
2、在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
3、可以是一个或者多个端口,也可以指定多个 EXPOSE
格式:EXPOSE [...]
(5)CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
1、CMD 在 docker run 时运行。执行docker run指令的时候
2、RUN 是在 docker build 构建镜像时运行的
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被docker run 命令行参数中指定要运行的程序所覆盖。
CMD[“executable”,“param1”,“param2”](exec 模式)
CMD command (shell 模式)
CMD [“param1”,”param2”](作为 ENTRYPOINT 指令的默认参数)
(6)ENTERYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 entrypoint 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTERYPOINT [“executable”,“param1”,“param2”](exec 模式) ENTERYPOINT command (shell 模式)
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下,示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
1、不传参运行
$ docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
2、传参运行
$ docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf
(7)COPY
COPY <src> <dest>
复制指令,从上下文目录中<宿主机的上下文>复制文件或者目录到容器里指定路径。
COPY hom* /mydir/
COPY hom?.txt /mydir/
:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
(8)ADD
ADD <src> <dest>
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
ADD 的优点:在执行 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到dest。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
ADD vs COPY
ADD 包含类似 tar 的解压功能
如果单纯复制文件,dockerfile 推荐使用 COPY
(9)VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
1、避免重要的数据,因容器重启而丢失,这是非常致命的。
2、避免容器不断变大。
格式:
VOLUME ["", ""...]
VOLUME
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
VOLUME [“/data”]
(10)WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR /path/to/workdir
(填写绝对路径)
(11 )ENV
设置环境变量
ENV key = value
以下示例设置 NODE_VERSION =6.6.6, 在后续的指令中可以通过 $NODE_VERSION 引用:
ENV NODE_VERSION 6.6.6
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"