Docker 为我们提供的一个用于自定义构建镜像的一个配置文件:描述如何构建一个对象
利用 Docker 提供的 build 命令,指定 Dockerfile 文件,就可以按照配置的内容将镜像构建出来
作为开发者需要将自己开发好的项目打包成 Docker 镜像,便于后面直接作为 Docker 容器运行
作为运维人员需要构建更精简的基础设施服务镜像,满足公司的需求以及尽可能减少冗余的功能占用过多的资源
基于一个现有的容器,构建一个新的镜像
bashdocker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
bashdocker commit -a="gyc" -m="first image" centos7 mycentos:7
docker build
命令用于从 Dockerfile 构建 Docker 镜像。
bashdocker build [OPTIONS] PATH
常用参数说明:
-t
或 --tag
:指定镜像的标签(名字),例如 my-image:latest
。-f
或 --file
:指定 Dockerfile 的路径(默认为当前目录下的 Dockerfile
)。--no-cache
:在构建过程中不使用缓存。--build-arg
:设置构建时的变量。示例:
bashdocker build -t my-image:latest .
这个命令将在当前目录(.
)下查找 Dockerfile 并构建镜像,镜像名称为 my-image
,标签为 latest
。
如果你有一个自定义路径的 Dockerfile,可以这样使用:
bashdocker build -t my-image:latest -f /path/to/Dockerfile .
指定以什么镜像作为基础镜像,在改进项的基础之上构建新的镜像。
如果不想以任何镜像作为基础:FROM scratch
语法:
以上为三种写法,后两者为指定具体版本,第一种则使用 latest 也就是最新版
指定该镜像的作者
为镜像设置标签,一个 Dockerfile 中可以配置多个 LABEL
语法:
如:
PS:LABEL 指令会继承基础镜像(FROM)中的 LABEL,如果当前镜像 LABEL 的 key 与其相同,则会将其覆盖
设置容器的环境变量,可以设置多个
语法:
两种语法的区别为第一种一次只能设置一个环境变量,第二种可以一次设置多个
构建镜像的过程中要执行的命令
语法:
第一种写法就是直接写 Shell 脚本即可
第二种写法类似函数调用,第一个参数为可执行文件,后面的都是参数
复制命令,把 src 的文件复制到镜像的 dest 位置
语法:
设置工作目录,可以简单理解为 cd 到指定目录,如果该目录不存在会自动创建,对 RUN、CMD、ENTRYPOINT、COPY、ADD 生效,可以设置多次 WORKDIR
如:
表示在容器内创建了 dir 目录,并且当前目录已经是 dir 目录了
设置挂载目录,可以将主机中的指定目录挂载到容器中
语法:
以上三种写法都可
改镜像运行容器后,需要暴露给外部的端口,但仅仅表示该容器想要暴露某些端口,并不会与主机端口有映射关系,如果想将容器暴露的端口与主机映射则需要使用 -p 或 -P 参数来映射,可以暴露多个端口
该镜像启动容器时默认执行的命令或参数
语法:
以上为该命令的三种写法,第三种与普通 Shell 命令类似,第一、二两种都是可执行文件 + 参数的形式,另外数组内的参数必须使用双引号。
案例:
第一种:CMD ["sh", "-c", "echo $HOME"] 等同于 sh -c "echo $HOME"
第二种:CMD ["echo", "$HOME"] 等同于 echo $HOME
运行容器时的启动命令,感觉与 CMD 命令会很像,实际上还是有很大区别,简单对比一下:
相同点: 在整个 Dockerfile 中只能设置一次,如果写了多次则只有最后一次生效
不同点:
如果同时设置了这两个指令,且 CMD 仅仅是选项而不是参数,CMD 中的内容会作为 ENTRYPOINT 的参数(一般不这么做)
如果两个都是完整命令,那么只会执行最后一条
语法:
设置变量,在镜像中定义一个变量,当使用 docker build 命令构建镜像时,带上 --build-arg <name>=<value> 来指定参数值,如果该变量名在 Dockerfile 中不存在则会抛出一个警告
设置容器的用户,可以是用户名或 UID,如果容器设置了以 daemon 用户去运行,那么 RUN、CMD 和 ENTRYPOINT 都会以这个用户去运行,一定要先确定容器中有这个用户,并且拥有对应的操作权限。
表示在构建镜像时做某操作,不过不对当前 Dockerfile 的镜像生效,而是对以当前 Dockerfile 镜像作为基础镜像的子镜像生效
语法:
例:
当前镜像为 A,设置了如下指令
ONBUILD RUN ls -al
镜像 B:
FROM 镜像A
......
构建镜像 B 时,会执行 ls -al 命令
STOPSIGNAL 指令设置将发送到容器的系统调用信号以退出。此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如 9,或 SIGNAME 格式的信号名,例如 SIGKILL。
默认的stop-signal是SIGTERM,在docker stop的时候会给容器内PID为1的进程发送这个signal,通过--stop-signal可以设置自己需要的signal,主要的目的是为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s。
bashSTOPSIGNAL \<signal>
容器健康状况检查,可以指定周期检查容器当前的健康状况,该命令只能出现一次,如果有多次则只有最后一次生效。
语法:
第一种:在容器内部按照指定周期运行指定命令来检测容器健康状况
第二种:取消在基础镜像
OPTIONS 选项:
ENTRYPOINT
ENTRYPOINT
指定了容器启动时要执行的主要命令,并且这个命令不能被覆盖。DockerfileENTRYPOINT ["executable", "param1", "param2"]
DockerfileENTRYPOINT executable param1 param2
CMD
CMD
提供了容器启动时的默认参数,这些参数可以被 docker run
命令行中指定的参数覆盖。DockerfileCMD ["param1", "param2"]
DockerfileCMD executable param1 param2
ENTRYPOINT
和 CMD
的组合假设您要创建一个容器,它启动时会运行一个 Python 脚本,并且您希望能够覆盖脚本的参数。
Dockerfile# Dockerfile FROM python:3.9-slim # 将 Python 脚本复制到容器中 COPY script.py /usr/src/app/script.py # 设置 ENTRYPOINT ENTRYPOINT ["python", "/usr/src/app/script.py"] # 提供默认参数 CMD ["default_arg1", "default_arg2"]
解释:
ENTRYPOINT
指定了容器启动时始终运行 python /usr/src/app/script.py
。CMD
提供了默认参数 default_arg1
和 default_arg2
,这些参数可以在 docker run
命令中被覆盖。运行:
使用默认参数:
bashdocker run myimage
这将运行 python /usr/src/app/script.py default_arg1 default_arg2
。
使用自定义参数:
bashdocker run myimage custom_arg1 custom_arg2
这将运行 python /usr/src/app/script.py custom_arg1 custom_arg2
。
ENTRYPOINT
如果您希望容器总是执行一个固定的命令,并且不希望在 docker run
中覆盖该命令,可以仅使用 ENTRYPOINT
:
Dockerfile# Dockerfile FROM ubuntu:latest # 设置 ENTRYPOINT ENTRYPOINT ["/bin/echo", "Hello"]
运行:
这将输出bashdocker run myimage World
Hello World
。ENTRYPOINT
中的 /bin/echo
是固定的,而 docker run
中提供的 World
是传递给 echo
命令的参数。CMD
如果您不需要指定固定的命令,只是提供默认参数,可以仅使用 CMD
:
Dockerfile# Dockerfile FROM ubuntu:latest # 设置 CMD CMD ["echo", "Hello World"]
运行:
使用默认命令:
bashdocker run myimage
这将输出 Hello World
。
使用自定义命令:
bashdocker run myimage "Custom Message"
这将输出 Custom Message
。
ENTRYPOINT
:用于指定容器启动时始终执行的主要命令。如果 ENTRYPOINT
和 CMD
都定义了,CMD
提供的参数将作为 ENTRYPOINT
中命令的默认参数。CMD
:用于提供容器启动时的默认参数,这些参数可以被 docker run
命令中的参数覆盖。选择使用 ENTRYPOINT
、CMD
还是两者结合取决于您是否需要固定的执行命令或提供默认参数并允许覆盖。
本文作者:GYC
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!