指令失败时呢?
之前大致介绍了一下指令失败时的执行过程,下面来看一个例子:假设我们在上面的 Dockerfile 中把 nginx 拼成了 ngnx ,再来构建一遍
我们可以看到,程序出错了,这个时候我们希望去调试一下这次失败。我们使用 docker run 命令来基于这次构建到目前为止已经成功的最后一步创建一个容器,这里它的ID 是 dee85a65a396
,我们可以使用如下命令
docker run -t -i dee85a65a396 /bin/bash
,来恢复到出错之前的镜像,然后重新运行出错的指令apt-get install -y ngnx
,可以看到哪里出错了
但是感觉这个步骤是多余了一些,如果 Dockerfile 中出现了错误,那么 Docker 就会给你提示,用不着重新运行命令来找出问题原因。
Dockerfile 和构建缓存
由于每一步的结果都会作为下一步的基础镜像,所以Docker 构建镜像的过程非常聪明,它会将之前的镜像层作为缓存。
正如上面 Dockerfile 来举例,比如,在我们调试过程中,不需要在第一步和第三步之间做任何修改,因此 Docker 会将之前构建时创建的镜像当作缓存并作为新的开始点。再次构建时,Docker 会直接从第四步开始。当之前的构建步骤没有变化时,这会节省大量的时间。如果第一步到第三步之间有什么变化,则回到第一步开始。
然而,有的时候不希望有缓存的功能,这个时候你需要使用 apt-get update
,那么 Docker 将不会刷新 APT 包的缓存,要想略过缓存,可以使用 docker build
的 --no-cache 标志。
基于构建缓存的 Dockerfile 模版
构建缓存的一个好处就是,我们可以实现简单的 Dockerfile 模版,一般会在 Dockerfile 文件顶部使用相同的指令集模版,比如对 ubuntu ,使用下面的模版
FROM ubuntu:14.04 MAINTAINER James Turnbull "james@example.com" ENV REFRESHED_AT 2019-08-15 RUN apt-get -qq update
我们来分析一下这个新的 Dockerfile :
- 首先,通过 FROM 指令为新镜像设置了一个基础镜像 ubuntu:14.04。
- 接着,使用 MAINTAINER 指令添加了自己的详细信息
- 然后,通过 ENV 指令设置了一个名为 REFRESHED_AT 的环境变量,用来表示最后一次的更新时间
- 最后,使用 RUN 指令运行 apt-get -qq update 命令,该指令会刷新 APT 包的缓存,用来确保每个安装的软件包都在最新版本。
查看新镜像
现在来看一下新构建的镜像,使用 docker images 命令来完成
如果想要了解镜像是如何构建出来的,可以使用 docker history 命令,如下
从结果可以看出镜像构建的每一层都是哪些指令构成的
从新镜像启动容器
我们可以基于新构建的镜像启动新容器,来检查我们的构建工作是否正常
在这里,我们使用 docker run 命令,启动一个 static_web 的容器, -d
表示的是以分离(detached) 的方式在后台运行。这种方式适合 nginx守护进程 这种需要长时间运行的进程。我们也指定了需要在 容器中运行的命令: nginx -g "daemon off;"
,将以前台方式运行 nginx 作为我们的服务器。
我们这里也使用了一个新的 -p 标志,用来控制 Docker 再运行时应该给外部开放哪些端口
- Docker 可以在宿主机上随机选择 49153 --- 65535 之间的一个比较大的端口映射到 80 端口上
- 可以在 Docker 宿主机指定一个具体的端口来映射到 80 端口上
使用 docker ps
查看一下端口分配情况
Docker 把 32769 端口映射到了 80 端口上
也可以通过 docker port
查看端口的映射情况
Dockerfile 指令
Dockerfile 指令比较多,这里我们会对 Dockerfile 单独列一个章节进行说明
将镜像推送至 Docker Hub
镜像构建完毕之后,我们也可以将它上传到 Docker Hub 上面去,这样其他人就能使用这个镜像了。
Docker Hub 的私有仓库是需要收费的
我们可以使用 docker push 命令将镜像推送至 Docker Hub。命令如下
为什么推送不上去?
网上搜索了一下,大概是镜像标签的问题,重新为镜像设置一个标签
然后把这个标签推送上去,相当于就是把镜像推送上去
我们可以在 Docker Hub 上看到我们推送的镜像了
删除镜像
如果不再需要一个镜像了,也可以将它删除,使用 docker rmi
命令来删除一个镜像
该操作只能删除本地镜像,如果你已经推送至 Docker Hub 上,那么你还需要在 Docker Hub 上将其删除
登录 Docker Hub ,直接点下面的链接删除
docker rmi 删除多个容器的方式直接在后面枚举容器即可,中间用空格隔开
总结
本篇文章主要讲述了 Docker 中的镜像和仓库的一些概念和基本用法,那么你是否能回顾起来下面这些内容呢?
- 什么是镜像
- 如何列出Docker中的镜像,tag标签是干什么用的
- 如何拉取远程仓库中的镜像
- 如何查找镜像
- 对于镜像构建,你能想到哪些内容
- 如何推送镜像至 Docker Hub
- 如何删除镜像