Dockerfile
本文最后更新于 2024年12月1日
Dockerfile概述
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
从应用软件的角度来看,Dockerfile,Docker镜像,Docker容器分别代表软件的三个不同阶段
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器可以认为是软件的运行态
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及运维和部署,合力充当Docker体系的基石。
Dockerfile定义了进程需要的一切东西,Dockerfile涉及的内容包括执行代码或者文件,环境变量,依赖包,运行时环境,动态链接库,操作系统发行版,服务进程和内核进程(当应用程序需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。
Docker镜像,在用Dockerfile定义了一个构建文件之后,docker build
时会产生一个Docker镜像,当运行Docker镜像时,会开始真正的提供服务。
Docker容器,是直接提供服务的进程。
Dockerfile构建过程:
- docker从基础镜像运行一个容器
- 执行一条指令,并对容器进行修改
- 执行类似
docker commit
的操作,提交一个新的镜像层 - docker再基于刚刚提交的镜像运行一个新容器
- 继续执行Dockerfile的下一条指令,直到所有指令都执行完成
Dockerfile的保留字指令
Dockerfile每个保留字指令均为大写,且后面至少跟随一个参数,指令从上到下顺序执行,用#
表示注释。
FROM
基本出现在第一行,意思是要构建的新镜像继承于或者说基于哪个已存在的镜像。
MAINTAINR
维护者信息(姓名和邮箱地址)
ENV
用于在构建镜像的过程中设置环境变量,这个环境变量可以在后续的任何RUN
指令中使用,就像在命令前面指定了环境变量一样,也可以在其他指令中直接使用这些环境变量,比如WORKDIR $JAVA_HOME
RUN
容器构建(docker build)时需要运行的命令,分为shell
和exec
两种格式
shell
exec
EXPOSE
声明容器运行时应该开放的端口。它不会自动开启端口,但为外部用户或其他容器提供信息
WORKDIR
指定在创建容器后,终端默认登录进来的工作目录,当执行docker run -it 镜像ID /bash
进入容器内部的时候,会默认落脚在哪个目录里
USER
指定镜像以什么用户去执行,如果不指定,默认是root
VOLUME
容器数据卷,用于数据的保存和持久化。
ADD
ADD
功能相比COPY
更加强大,将宿主机内的文件拷贝进镜像,如果源文件是.tar
、.tar.gz
等压缩格式的文件,ADD
会自动解压到目标路径。ADD
还可以从指定的URL下载文件并复制到容器内。
COPY
仅仅执行文件的复制,不支持自动解压或下载
CMD
指定容器启动后要做的事情,支持shell
和exec
两种格式,还支持参数列表格式,如果指定了ENTRYPOINT
指令,CMD
就会被用来指定具体的运行参数
注意事项
1.RUN
和CMD
的区别: RUN
是构建镜像时执行,CMD
是docker run
容器启动时执行
2.Dockerfile中可以有多个CMD
指令,但只有最后一个生效,CMD
会被docker run
之后的参数替换
例如:tomcat的Dockerfile的最后一行是CMD ["catalina.sh", "run"]
,那么使用docker run -it tomcat /bin/bash
命令启动这个镜像时,容器会启动,但是tomcat就不会被启动,因为被run
后的命令/bin/bash
替换掉了,故容器启动后会运行/bin/bash
ENTRYPOINT
类似于CMD
命令,但是不会被docker run
后的命令覆盖,而且还会把docker run
后的命令当作命令行参数传递给ENTRYPOINT
指令指定的程序
ENTRYPOINT
可以和CMD
一起用,一般是变参才会使用到CMD
,这里的CMD
等同于是在给ENTRYPOINT
传参,当指定了ENTRYPOINT
后,CMD
的含义就发生了变化,不再是直接运行其命令而是将CMD
的内容作为参数传递给ENTRYPOINT
指令,它们两个组合后会变成<ENTRYPOINT> "<CMD>"
案例:
按照Dockerfile原样执行 | 传参运行 | |
---|---|---|
Docker命令 | docker run nginx | docker run nginx -c /etc/nginx/kms.conf |
容器实际执行 | nginx -c /etc/nginx/nginx.conf | nginx -c /etc/nginx/kms.conf |
编写运行一个Dockerfile
未完待续