本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、简介
DockerFile 是用来构建 Docker 镜像的构建文件,是由一系列命令参数构成的脚本。
二、DockerFile 的一些规则
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令顺序执行,遵循从上到下原则
- 表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
三、docker 执行 DockerFile 的大致流程
- docker 从基础镜像运行一个容器
- 顺序执行一条指令对容器做出修改
- 执行类似 docker commit 的操作提交一个新的镜像层
- docker 基于刚才提交的镜像运行一个新的容器
- 执行 DockerFile 中下一条指令直到文件中的所有指令都执行完成
上述过程类似图:
四、使用 DockerFile 构建镜像的步骤
- 编写 DockerFile 文件
- docker build
- docker run
上述过程类似图:
五、DockerFile 的保留字指令
- FROM:指定基础镜像
- MAINTAINER:镜像维护者姓名及邮箱地址
- RUN:容器构建时需要运行的命令
- EXPOSE:当前容器对外暴露的端口号
- WORKDIR:指定在创建容器后,终端默认登录进来的工作目录
- ENV:用来在构建镜像过程中设置环境变量
- ADD:将宿主机目录下的文件拷贝进镜像,ADD 命令会自动处理 URL 和解压 tar 压缩包
- COPY:拷贝文件、目录到镜像中。具体是将从构建上下文目录中 <src 原路径>的文件或目录复制到新一层镜像的 <目标路径> 位置 ,有两种写法:
COPY src dest
或者COPY ["src", "dest"]
- VOLUME:容器数据卷,用于数据保存和持久化工作
- CMD:指定一个容器启动时要运行的命令
- 注意 DockerFile 中可以有多个 CMD 指令,但只有最后一个在启动时生效,CMD 会被 docker run 之后的命令或参数覆盖
- CMD 指令的格式和 RUN 相似,也是两种格式:
- shell 格式:CMD <命令>
- exec 格式:CMD [“可执行文件”, “参数 1”, “参数 2” …]
- 参数列表格式:CMD [“参数 1”, “参数 2”, …],在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
- ENTRYPOINT:指定一个容器启动时要运行的命令,与 CMD 一样都是在指定容器启动程序及参数(下面通过实例 2 将他们的区别)。
- ONBUILD:当构建一个被继承的 DockerFile 时运行命令, 父镜像在被子镜像继承后,父镜像的 ONBUILD 被触发。
六、实例
下面我们通过几个实际的案例来构建 DockerFile。
实例一:
-
需求:构建一个自己的 centos 镜像,使其具有登录后进入路径为 / etc 并且支持 vim 命令及 ifconfig 命令,运行生成容器时并暴露 5000 端口。
-
下面是具体的步骤,一步步跟着来实现
-
DockerFile 的内容:
FROM centos MAINTAINER lihongcheng<[email protected]> ENV ETCPATH /etc WORKDIR $ETCPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 5000 CMD echo "-----successful------" CMD /bin/bash 复制代码
上面内容中 FROM 父镜像为原生 centos,MAINTAINER 为作者邮箱名,ENV 设置了一个环境变量 ETCPATH ,WORKDIR 设置了容器运行后默认进入的路径为 ETCPATH 变量指定的路径,RUN 运行两条构建时运行的命令,分别是用 yum 安装 vim 编辑器和 net-tools 网络调试工具 (注意原生 centos 镜像具有 yum 指令),EXPOSE 指定了镜像生成运行实例容器对象时暴露的端口 5000。第一个 CMD 只是运行在控制台打印一句话 (不会最后启动生效,只是通常为了检测是否执行到这一步),第二个 CMD 表明运行时启动容器的 / bin/bash 终端。
-
build 命令来构建自己的 centos 镜像
- 命令:
docker build -f /path/DataFile -t 镜像名 [:TAG] .
- /path/DataFile 是 DataFile 文件的路径,例:/mydocker/datafile.txt
- 命令:
-
run 命令来启动运行这个镜像生成的实例容器
- 命令:
docker run -it 镜像名[:TAG]
- 命令:
-
查看 docker 镜像的运行历史(仅用于查看是如何运行的)
- 命令:
docker history
镜像名 [:TAG]
- 命令:
实例二(主要用来区分 CMD 和 ENTRYPOINT):
-
需求:构建一个 centos 镜像,通过 curl 命令在启动容器后输出 ip 地址,在启动时添加 -i 选项,可以查看详细的报文信息。
-
Dockerfile 内容两个版本
FROM centos MAINTAINER lihongcheng<[email protected]> RUN yum -y install curl CMD ["curl", "-s", "http://ip.cn"] 复制代码
构建镜像、运行容器如上例,在运行容器实例后会由 CMD 命令输出 ip 地址的信息。但当使用命令:
docker run -it 镜像名[:TAG] -i
来输出详细的报文时却显示错误,这是由于 CMD 关键字命令会被 docker run 之后的 -i 参数覆盖而并非在命令中添加一个 -i 选项。所以不满足上面需求。FROM centos MAINTAINER lihongcheng<[email protected]> RUN yum -y install curl ENTRYPOINT ["curl", "-s", "http://ip.cn"] 复制代码
将 CMD 关键字换成 ENTRYPOINT 后,使用命令:
docker run -it 镜像名[:TAG] -i
就可以输出详细信息,因为 ENTRYPOINT 关键字命令是可以将 docker run 之后 -i 选项加载到它的参数中执行,这就是 CMD 与 ENTRYPOINT 的区别。满足上面需求。