Dockerfile
什么是Dockerfile
A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
格式
1、 Dockerfile指令不区分大小写。但是,约定是将它们大写,以便更容易地将它们与参数区分开来。
2、 DockerDockerfile按顺序运行指令。一个Dockerfile 必须以FROM开始的指令。这可能在解析器指令、注释和全局范围的 ARG 之后。该FROM指令指定您正在构建的父镜像。FROM前面只能有一个或多个ARG指令
3、以 #开始作为注释,除非该行是一个有效的解析器指令。#在行中任何其他位置的标记都被视为参数。如
# Comment
RUN echo 'we are running some # of cool things'
4、注释中不支持换行符。
用法
1、首先要创建一个目录,在目录里面创建Dockerfile,不要直接使用根目录作为一个路径,它会导致构建将硬盘驱动器的全部内容传输到 Docker 守护程序。
2、开始构建镜像
在 Dockerfile 文件的存放目录下,执行构建动作。
docker build . # . 是上下文路径,当前目录
您可以使用 -f 指定docker build指向文件系统中任何位置的 Dockerfile(上下文路径)。
上下文路径:是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker
引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
Dockerfile指令说明
1、FROM(指定基础镜像)[构建指令]
FROM命令用来指定基础镜像,在基础镜像的基础上修改数据从而构建新的镜像。基础镜像可以是本地仓库也可以是远程仓库。格式有两种:
FROM image 【默认为latest版本】
FROM image:tag 【指定版本】
2、COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
指令有两种格式:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
[--chown=<user>:<group>]:
可选参数,用户改变复制到容器内文件的拥有者和属组
该COPY指令从中复制新文件或目录 ,(也可以是一个远程的文件url)并将它们添加到容器的文件系统中的绝对路径 。<dest>
<src>
可以指定多个资源,但文件和目录的路径将被解释为相对于构建上下文的源。
每个都可能包含通配符,匹配将使用 Go 的filepath.Match规则完成。例如:
添加所有以“hom”开头的文件:
COPY hom* /mydir/
3、ADD
ADD 指令和 COPY 的使用格类似(官方推荐使用 COPY)。功能也类似,不同之处如下:
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到
<目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
<dest>:
容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
4、RUN(安装软件用)[构建指令]
RUN在制作镜像(dockers build)的时候运行的,CMD在容器启动时运行
RUN可以运行任何被基础镜像支持的命令(即在基础镜像上执行一个进程),可以使用多条RUN指令,指令较长可以使用\来换行,避免生成多层。
指令有两种格式:
RUN command (the command is run in a shell - /bin/sh -c)
RUN [“executable”, “param1”, “param2” … ] (exec form)
指定使用其他终端实现,使用exec执行。
例子:RUN["/bin/bash","-c",“echo hello”]
注意:有的时候RUN后面会有set -eux
set指令能设置所使用shell的执行方式,可依照不同的需求来做设置。
语法
set [+-abCdefhHklmnpPtuvx]
参数说明:
-e 若指令传回值不等于0,则立即退出shell。
-u 当执行时使用到未定义过的变量,则显示错误信息。
-x 执行指令后,会先显示该指令的执行过程及所下的参数。
5、WORKDIR(切换目录)[设置指令]
相当于cd命令,可以多次切换目录,指定进入容器的时候,在哪个目录下,为RUN,CMD,ENTRYPOINT配置工作目录。可以使用多个WORKDIR的命令,后续命令如果是相对路径则是在上一级路径的基础上执行[类似cd的功能]。
格式:WORKDIR /path/to/workdir
6、ENV(用于设置环境变量)[构建指令]
在image中设置环境变量[以键值对的形式],设置之后RUN命令可以使用该环境变量,在容器启动后也可以通过docker inspect查看环境变量或者通过 docker run --env key=value设置或修改环境变量。
格式:ENV key value
ENV NGINX_VERSION 1.19.7
# 将1.19.7这个数值赋值NGINX_VERSION这个变量
7、CMD(设置container启动时执行的操作)[设置指令]
运行的第1个程序命令
用于容器启动时的指定操作,可以是自定义脚本或命令,只执行一次,多个默认执行最后一个。
指令有三种格式:
CMD [“executable”,“param1”,“param2”] (like an exec, this is the preferred form)
运行一个可执行文件并提供参数。
CMD command param1 param2 (as a shell)
直接执行shell命令,默认以/bin/sh -c执行。
CMD [“param1”,“param2”] (as default parameters to ENTRYPOINT)
和ENTRYPOINT配合使用,只作为完整命令的参数部分。
例如:
CMD ["nginx", "-g", "daemon off;"]
#在前台启动nginx程序 ,-g daemon off 将off值赋给daemon这个变量,告诉nginx不要在后台启动,在前台启动
daemon是守护进程--》默认在后台运行
nginx -g选项的作用是 设置一个全局的变量 ,给它赋值
为什么有些容器启动需要接 -it,而有些却不需要
答: centos7或者Ubuntu的基础镜像,在启动的时候,
FROM scratch
ADD ubuntu-focal-oci-amd64-root.tar.gz /
CMD ["bash"] --》容器启动的时候运行的程序是bash
运行程序:
在前台运行,容器就会一直运行 --》状态up
在后台运行或者程序运行完成后,容器就会退出 --》Exited
8、ENTRYPOINT(设置container启动时执行的操作)[设置指令]
指定容器启动时执行的命令,若多次设置只执行最后一次。
ENTRYPOINT翻译为“进入点”,它的功能可以让容器表现得像一个可执行程序一样。
例子:
ENTRYPOINT ["/bin/echo"]
那么docker build出来的镜像以后的容器功能就像一个/bin/echo程序,docker run -it dock “this is a test”,
就会输出对应的字符串。这个dock镜像对应的容器表现出来的功能就像一个echo程序一样。
指令有两种格式:
ENTRYPOINT [“executable”, “param1”, “param2”] (like an exec, the preferred form)
和CMD配合使用,CMD则作为完整命令的参数部分,ENTRYPOINT以JSON格式指定执行的命令部分。CMD可以为ENTRYPOINT提供可变参数,不需要变动的参数可以写在ENTRYPOINT里面。
例子:
ENTRYPOINT ["/usr/bin/ls","-a"]
CMD ["-l"]
ENTRYPOINT command param1 param2 (as a shell)
独自使用,即和CMD类似,如果CMD也是个完整命令
[CMD command param1 param2 (as a shell) ],
那么会相互覆盖,
只执行最后一个CMD或ENTRYPOINT
例子:ENTRYPOINT ls -l
9、VOLUME(指定挂载点)[设置指令]
创建一个可以从本地主机或其他容器挂载的挂载点,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用也可以被其他容器使用。
VOLUME /var/lib/mysql -》容器里的路径
会将容器里的/var/lib/mysql
在docker宿主机里创建一个匿名volume
,卷的名字是随机产生,卷的宿主机路径/var/lib/docker/volume/下
格式:VOLUME ["mountpoint"]
其他容器使用共享数据卷:docker run -t -i -rm -volumes-from container1 image2 bash
[container1为第一个容器的ID,image2为第二个容器运行image的名字。]
10、ARG:在制作镜像时传递参数
11、EXPOSE:暴露端口
12、STOPSIGNAL:用来设置系统调用的信号
RUN, COPY, ADD
增加层的数量