Docker Dockerfile
什么是
Dockerfile
?
Dockerfile
是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
构建镜像
由于
docker
的运行模式是C/S
。我们本机是C
,docker
引擎是S
。
实际的构建过程是在docker
引擎下完成的,所以这个时候无法用到我们本机的文件。
这就需要把我们本机的指定目录下的文件一起打包提供给docker
引擎使用。
-
如果未说明最后一个参数,那么默认上下文路径就是。Dockerfile
所在的位置 -
实际操作如下图所示,忘记上下文路径将执行报错
-
注意:上下文路径下不要放无用的文件,因为会一起打包发送给
docker
引擎,如果文件过多会造成过程缓慢。- 这里给出两个错误的打包结果与一个正确的打包结果来理解上下文路径
-
- 由于无用文件太多导致的打包失败
-
- 下面是
由于docker上下文路径设置错误,造成添加文件失败,导致脚本执行错误,最终无法打包
的错误
- 下面是
-
- 正确的命令。
dockerfile(文件夹)
包含了index.html(文件)
与dockerfile(文件)
.
将dockerfile(文件夹)
作为docker build 的上下文
通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)
docker build -t nginx:v3 .
- 最后的
.
代表本次执行的上下文路径 - 上下文路径,是指
docker
在构建镜像时,将上下文路径中的所有内容打包。(docker build 命令得知这个路径后,会将路径下的所有内容打包)
Dockerfile:构建文件,定义了一切的步骤,源代码。
Dockermages:通过Dockerfile 构建生成的镜像,最终发布和运行的产品。 docker images | docker ps
Docker容器:容器就是镜像运行起来提供服务器。 docker run | docker exec
构建镜像示例
这里的构建镜像要是理解上面描述的上下文内容
- 编辑 dockerfile
FROM centos:8
MAINTAINER robertchao<xxxxxxx@qq.com>
ENV MYPATH /usr/local
RUN echo `pwd`
RUN ls ./
WORKDIR $MYPATH
RUN echo `pwd`
RUN ls ./
COPY ./index.html $MYPATH/temp/
EXPOSE 80
CMD `pwd`
CMD echo "----end----"
CMD /bin/bash
- 构建成功后如图所示
- 使用
docker images
查看
- 由于当前项目没有运行项目,需要通过
docker run -it dockertest
进行访问- 进入目录为
/usr/local
COPY
复制上下文中的文件到指定文件目录(自动创建)
- 进入目录为
上面那个我们只看到了使用过程中上下文文件的添加,下面我们启动 tomcat 为例
- tomcat docker file 内容如下
FROM tomcat:8.5
MAINTAINER xx@mail.com
#将webapp下的全部删除
RUN rm -rf /usr/local/tomcat/webapps/*
WORKDIR /usr/local/tomcat/webapps
#将target下的xx.war拷贝到/usr/local/tomcat/webapps/下
ADD docker-web ./docker-web
RUN chmod 777 /usr/local/tomcat/bin/catalina.sh
#端口
EXPOSE 8080
#设置启动命令
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
- 具体的问题需要排查,我这里添加权限就可以运行了,如下图
- 通过
docker ps -a
查看启动中的容器
- 验证过程,服务能够访问到,服务目录能够查询到添加的项目文件
Docker File 指令
- 每个保留关键字(指令)都是必须是大写字母
- 执行从上到下顺序执行
# 表示注释
- 每一个指令都会创建一个新的镜像层,并提交
指令简述
- FROM 构建镜像基于哪个镜像
- MAINTAINER 镜像维护者姓名或邮箱地址
- RUN 构建镜像时运行的指令
- CMD 运行容器时执行的shell环境
- VOLUME 指定容器挂载点到宿主机自动生成的目录或其他容器
- USER 为RUN、CMD、和 ENTRYPOINT 执行命令指定运行用户
- WORKDIR 为 RUN、CMD、ENTRYPOINT、COPY 和 ADD 设置工作目录,就是切换目录
- HEALTHCHECH 健康检查
- ARG 构建时指定的一些参数
- EXPOSE 声明容器的服务端口(仅仅是声明)
- ENV 设置容器环境变量
- ADD 拷贝文件或目录到容器中,如果是URL或压缩包便会自动下载或自动解压
- COPY 拷贝文件或目录到容器中,跟ADD类似,但不具备自动下载或解压的功能
- ENTRYPOINT 运行容器时执行的shell命令
指令使用
-
FROM
:定制的镜像都是基于FROM
的镜像 -
RUN
:用于执行后面跟着的命令行命令。有以下俩种格式:RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
RUN ["可执行文件", "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
-
COPY
:复制指令,从上下文目录中复制文件或者目录到容器里指定路径[--chown=<user>:<group>]
:可选参数,用户改变复制到容器内文件的拥有者和属组。- <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足
Go
的filepath.Match
规则。 - <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
-
ADD
: ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)- 在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>
- 在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
-
CMD
:类似于RUN
指令,用于运行程序- 二者运行的时间点不同:
CMD
在docker run
时运行RUN
是在docker build
- 为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
- 如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
- 二者运行的时间点不同:
-
ENTRYPOINT
:类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖- 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序
- 在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数
- 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,
仅最后一个生效
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
docker run nginx:test
# 容器默认执行 nginx -c /etc/nginx/nginx.conf
docker run nginx:test -c /etc/nginx/new.conf
# 容器内会默认运行以下命令 nginx -c /etc/nginx/new.conf ,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
-
ENV
: 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量 -
ARG
: 构建参数,与 ENV 作用一致。不过作用域不一样。- ARG 设置的环境变量仅对 Dockerfile 内有效
- 只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量
- 构建命令 docker build 中可以用
--build-arg <参数名>=<值>
来覆盖
-
VOLUME
:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。- 避免重要的数据,因容器重启而丢失,这是非常致命的
- 避免容器不断变大
- 在启动容器
docker run
的时候,我们可以通过-v
参数修改挂载点
-
EXPOSE
:仅仅只是声明端口- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
- 运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
-
WORKDIR
: 指定工作目录。- 用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在
- 以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
- docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在
-
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 -
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。 -
ONBUILD
用于延迟构建命令的执行 -
LABEL
用来给镜像添加一些元数据(metadata),以键值对的形式LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL org.opencontainers.image.authors="runoob"
-
执行会创建 3 层镜像
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
- 以
&&
符号连接命令,这样执行后,只会创建 1 层镜像
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz