1. 简介
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。 步骤:
- 编写Dockerfile文件
- docker build
- docker run
1.1 DockerFile的基础知识
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
1.3 Dockerfile、镜像、容器三者关系
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

**Dockerfile**,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;**Docker镜像**,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;**Docker容器**,容器是直接提供服务的。
2. DockerFile体系结构(保留字指令)
2.1 指令
2.1.1 FROM
基础镜像,当前新镜像是基于哪个镜像的
2.1.2 MAINTAINER
镜像维护者的姓名和邮箱地址
2.1.3 RUN
镜像build构建时需要运行的命令,和CMD、ENTRYPOINT的区别,参考:2.3 RUN、CMD和ENTRYPOINT的区别
2.1.4 EXPOSE
当前容器对外暴露出的端口
2.1.5 WORKDIR
指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
2.1.6 ENV
用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest# 这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;# 也可以在其它指令中直接使用这些环境变量,# 比如:WORKDIR $MY_PATH
2.1.7 ADD
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包。 和COPY的区别,参考:2.2 ADD和COPY的区别
2.1.8 COPY
类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置 和ADD的区别,参考:2.2 ADD和COPY的区别
# 两种用法COPY src destCOPY ["src", "dest"]
2.1.9 VOLUME
容器数据卷,用于数据保存和持久化工作 参考:六、Docker容器数据卷 3. 数据卷 3.2 DockerFile添加
2.1.10 CMD
指定一个容器使用
**docker run**启动时要运行的命令Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,且CMD 会被 docker run 之后的参数替换
2.1.11 ENTRYPOINT
指定一个容器
**docker run**启动时要运行的命令 ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,区别参考:2.3 RUN、CMD和ENTRYPOINT的区别
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
2.1.12 ONBUILD
触发器,当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承(
FROM xxxxxx)后父镜像的onbuild被触发
ONBUILD RUN echo "father image onbuild------success"
2.2 ADD和COPY的区别
ADD和COPY:COPY就是拷贝;ADD更强大,等于COPY+tar解压缩
2.3 RUN、CMD和ENTRYPOINT的区别
RUN、CMD和ENTRYPOINT:
- RUN———是在执行
docker build构建时执行,而CMD和ENTRYPOINT是在docker run时执行- CMD———Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,且如果docker run之后传递了参数,CMD会被替换
- ENTRYPOINT———docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
- 并且ENTRYPOINT可以和CMD结合使用,ENTRYPOINT指定指令,CMD指定参数
- 可以参考Docker:Dockerfile 中 RUN, CMD, ENTRYPOINT 的区别
3. 案例
- Base镜像(scratch),Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的

- 自定义镜像mycentos
- Hub默认CentOS镜像什么情况(上图)

- 准备编写DockerFile文件

- myCentOS内容DockerFile
# 继承自哪个镜像 FROM centos:7 # 镜像维护者的姓名和邮箱 MAINTAINER JShawn<shwawn@163.com> # 声明环境变量 ENV MYPATH /user/local # 落脚点,终端登录进来后的工作目录 WORKDIR $MYPATH # 容器构建时执行的命令,yum源有问题,暂时不装 #RUN yum -y install vim # 容器构建时执行的命令,yum源有问题,暂时不装 #RUN yum -y install net-tools # 容器对外暴露出的端口 EXPOSE 80 # docker run时执行的命令 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
build构建镜像
docker build -f dockerfile_mycentos -t jshawn/centos:2.0 .
查看镜像

run运行镜像
docker run -it 29cb3440c55b查看WORKDIR的落脚点
4. 自定义Tomcat9镜像(略)
5. 总结

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,且CMD 会被 docker run 之后的参数替换


