先回顾一下通过 Dockerfile 构建镜像的过程:
- 从 base 镜像运行一个容器。
- 执行一条指令,对容器做修改。
- 执行类似 docker commit 的操作,生成一个新的镜像层。
- Docker 再基于刚刚提交的镜像运行一个新容器。
- 重复 2-4 步,直到 Dockerfile 中的所有指令执行完毕
一、调试 Dockerfile
包括 Dockerfile 在内的任何脚本和程序都会出错。有错并不可怕,但必须有办法排查;
来看一个调试的例子,Dockerfile 内容如下:
第一步:准备Dockerfile文件
第二步:执行docker build命令:
命令如下所示:
docker build -t image-debug .
具体结果如下所示:
可以看到,Dockerfile 在执行第三步 RUN 指令时失败,我们可以利用第二步创建的镜像 be460bb201e1进行调试,方式是通过 docker run -it
启动镜像的一个容器;
命令如下所示:
docker run -it be460bb201e1
具体结果如下所示:
二、Dockerfile常用指令
FROM 指定 base 镜像
MAINTAINER 设置镜像的作者,可以是任意字符串
COPY 将文件从 build context 复制到镜像,注意COPY 支持两种形式:COPY src dest或者COPY ["src", "dest"]
注意:src 只能指定 build context 中的文件或目录。
ADD 与 COPY 类似,从 build context 复制文件到镜像;
ENV 设置环境变量,环境变量可被后面的指令使用;
EXPOSE指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来;
VOLUME将文件或目录声明为 volume
WORKDIR为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录
RUN在容器中运行指定的命令
CMD容器启动时运行指定的命令,Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效;
ENTRYPOINT设置容器启动时运行的命令。Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效;
再举一个例子来练习一下Dockerfile:
第一步,准备Dockerfile文件
第二步:执行命令:
docker build -t my-image .
具体结果如下:
说明:build context说白了,就是Dockerfile所在的目录以及子目录;
最佳实践
RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包;
CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run
后面跟的命令行参数替换;
ENTRYPOINT 配置容器启动时运行的命令