# 原理

当我们基于 Dockerfile 构建一个镜像的时候,不可避免的会遇到错误或失败,这个时候,通常我们会核查对应步骤执行的指令,然后调整指令,再次构建镜像,这是一种常规的方法。

其实,因为 Docker 底层存储的机制,我们可以直接进入到失败之前成功的那次状态中,然后二次调试我们的指令,从而做到有的放矢地验证。

docker 基于 Dockerfile 构建一个镜像的流程大致如下:

  1. 基于 FROM 的基础镜像运行一个临时容器
  2. 在临时容器当中,执行 Dockerfile 中定义的指令
  3. 然后执行类似 docker commit 的操作,生成一个全新的镜像层
  4. Docker 会再基于刚刚提交的镜像运行一个新容器
  5. 接着重复 2 ~ 4 步,直到 Dockerfile 中的所有指令执行完毕。

因此,当我们遇到构建失败的时候,只需要复原出错前一步的 Docker 容器,即可回溯到出错前的环境,然后再手动执行出错的命令来分析出错的原因即可。

申明

原创文章eryajf,未经授权,严禁转载,侵权必究!此乃文中随机水印,敬请读者谅解。

# 实践

有如下 Dockerfile 文件:

$ cat Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/eryajf/centos:7.5
RUN echo 'aaa' > /opt/test
RUN ehco 'bbb' >> /opt/test

1
2
3
4

这里可以看到,第三行指令的 echo 命令拼写有误,此时镜像构建日志如下:

$ docker build -t test .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM registry.cn-hangzhou.aliyuncs.com/eryajf/centos:7.5
 ---> a290d4e5c19d
Step 2/3 : RUN echo 'aaa' > /opt/test
 ---> Running in 706e69349e9a
Removing intermediate container 706e69349e9a
 ---> ad3fb6309109
Step 3/3 : RUN ehco 'bbb' >> /opt/test
 ---> Running in bec27c733f58
/bin/sh: ehco: command not found
The command '/bin/sh -c ehco 'bbb' >> /opt/test' returned a non-zero code: 127

1
2
3
4
5
6
7
8
9
10
11
12

可以看到步骤 3 执行有异常,但是步骤 2 是正常执行的,我们可以执行如下命令拉起一个步骤 2 的环境:

$ docker run -it ad3fb6309109 cat "/opt/test"
aaa

1
2

如上命令可以看到第二行的 echo 指令已经正常执行,而且环境也是当时的现场,这个时候我们就可以基于当时的现场,进行后续指令的调试。