使用 Dockerfile 构建镜像时,如果出错了怎么办?怎么调试?
以构建 Nginx 镜像为例子来说明吧。这是一个 Dockerfile
1 | # 以 ikutarian/new_ubuntu 为基础镜像 |
输入以下命令进行构建
1 | docker build -t ikutarian/static_web . |
控制台输出
1 | root@ikutarian:~/docker/static_web# docker build -t ikutarian/static_web . |
可以看到到了 Step 2/4 : RUN apt-get install -y ngin
这一步时出问题了,提示 E: Unable to locate package ngin
,找不到 ngin,原来是 Nginx 的名字写错了,改一下 Dockerfile 文件
1 | # 以 ikutarian/new_ubuntu 为基础镜像 |
然后重新构建
1 | docker build -t ikutarian/static_web . |
现在控制台输出
1 | root@ikutarian:~/docker/static_web# docker build -t ikutarian/static_web . |
可以看到镜像创建成功了,输入 docker images
可以看到刚刚创建好的镜像
1 | root@ikutarian:~/docker/static_web# docker images |
启动容器
1 | docker run --rm -d -p 80:80 ikutarian/static_web |
然后访问宿主机的 IP 应该就能看到 Nginx 的页面了。但是却没有看到页面,而且执行 docker ps
也没有看到有容器在运行。应该是哪一个步骤出问题了,从 Dockerfile 文件和镜像构建时输出的信息来看,应该是在最后一步 CMD ["nginx", "-g", "daemon off"]
出了问题
由于镜像是分层的,Dockerfile 中的一行指令会生成一层,可以在 CMD ["nginx", "-g", "daemon off"]
的前一行指令输出如下
1 | Step 3/4 : EXPOSE 80 |
执行 EXPOSE 80
时,输出的 ID 是 4bd0d0dc619f
,于是可以执行如下命令进入容器内部看一下
1 | docker run -it -p 80:80 --rm 4bd0d0dc619f |
然后执行一下 CMD
要执行的命令
1 | root@9942a1275763:/# nginx -g daemon off |
可以看到提示,Nginx 提示命令不合法,所以就是这一行的 Nginx 启动命令错了。查了一下文档,正确的应该是
1 | nginx -g "daemon off;" |
现在知道问题在那里了,改一下 Dockerfile 文件
1 | # 以 ikutarian/new_ubuntu 为基础镜像 |
重新构建并运行容器
1 | docker build -t ikutarian/static_web . |
总结
由于镜像是分层的,Dockerfile 中的一行指令会生成一层。所以可以在出错的指令前一层进入到容器内部调试