构建缓存在镜像的构建过程中,Docker会根据Dockerfile指定的顺序执行每个指令 。Dockerfile的每条指令都会将结果提交为新的镜像 。然后,下一条指令基于上一条指令的镜像进行构建 。
在执行每条指令之前,Docker都会在缓存中查找是否已经存在可重用的镜像,如果存在就使用现存的镜像,不再重复创建 。
因此,为了有效地利用缓存,尽量保持Dockerfile一致 , 并且尽量在末尾修改:
FROM ubuntuMAINTAINER author <somebody@company.com>RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe"RUN apt-get updateRUN apt-get upgrade -y
更改MAINTAINER指令会使Docker强制执行run指令来更新apt,而不是使用缓存 。
如不希望使用缓存,在执行 docker build 时需加上参数--no-cache=true 。
Docker中 , 构建缓存遵循的基本规则如下:
- 从缓存中存在的基础镜像(FROM指令指定)开始,下一条指令将和该基础镜像的所有子镜像进行匹配,检查这些子镜像被创建时使用的指令是否和被检查的指令完全一样 。如果不是,则缓存失效 。
- 多数情况中,使用其中一个子镜像来比较Dockerfile中的指令是足够的 。然而 , 特定的指令需要做更多的判断 。
- 对于ADD和COPY指令 , 镜像中对应文件的内容也会被检查,每个文件都会计算出一个校验值 , 通常是检查文件的校验和(checksum) 。在缓存的查找过程中,会将这些校验和已存在镜像中的文件校验值进行对比 。如果文件有任何改变,则缓存失效 。
- 除了ADD和COPY指令,缓存匹配检查并不检查临时容器中的文件 。例如,当使用RUN apt-get -y update命令更新了容器中的文件 , 并不会被缓存检查策略作为缓存匹配的依据 。
- 一旦缓存失效,所有后续的Dockerfile指令都将产生新的镜像,缓存不会被使用 。
例如,如果构建包含多个层,则可以将它们从变化频率较低(以确保生成缓存可重用)到变化频率较高的顺序排序:
- 安装构建应用程序所需的依赖工具
- 安装或更新依赖项
- 构建你的应用
FROM golang:1.11-alpine AS build# 安装项目需要的工具# 运行 `docker build --no-cache .` 来更新依赖RUN apk add --no-cache gitRUN go get Github.com/golang/dep/cmd/dep# 通过 Gopkg.toml 和 Gopkg.lock 获取项目的依赖# 仅在更新 Gopkg 文件时才重新构建这些层COPY Gopkg.lock Gopkg.toml /go/src/project/WORKDIR /go/src/project/# 安装依赖库RUN dep ensure -vendor-only# 拷贝整个项目进行构建# 当项目下面有文件变化的时候该层才会重新构建COPY . /go/src/project/RUN go build -o /bin/project# 将打包后的二进制文件拷贝到 scratch 镜像下面,将镜像大小降到最低FROM scratchCOPY --from=build /bin/project /bin/projectENTRYPOINT ["/bin/project"]CMD ["--help"]
使用标签除非是在用Docker做实验,否则你应当通过 -t 选项来 docker build 新的镜像以便于标记构建的镜像 。一个简单可读的标签可以帮助管理每个创建的镜像 。docker build -t="tuxknight/luckyPython/ target=_blank class=infotextkey>Python"
始终通过 -t 标记来构建镜像 。公开端口Docker的核心概念是可重复和可移植,镜像应该可以运行在任何主机上并运行尽可能多的次数 。在Dockerfile中可以映射私有和公有端口,但永远不要通过Dockerfile映射公有端口 。这样运行多个镜像的情况下会出现端口冲突的问题 。
EXPOSE 80:8080# 80映射到host的8080,不提倡这种用法 EXPOSE 80 # 80会被docker随机映射一个端口
EXPOSE指令用于声明容器将监听的端口 。在EXPOSE指令中,端口号的格式为<容器端口>/<协议> 。其中,容器端口是指在容器内部应用程序监听的端口,而协议是可选的,默认为TCP 。示例中,EXPOSE 80:8080表示容器将监听容器端口80 , 而宿主机可以使用端口8080来访问容器的80端口 。也就是,容器的80端口映射到了宿主机的8080端口 。
推荐阅读
- 曙光王妃小说 曙光王妃
- 新鲜竹笋的做法,鲜毛竹笋的处理及做法?
- 远志的功效与作用及食用方法
- 车前子的功效与作用及食用方法
- 国标螺丝型号及尺寸规格表 国标螺丝
- Spring Boot中实现订单30分钟自动取消的策略思路及源代码
- 苹果iPhone电池健康异常:原因揭秘及解决方案
- 花胶的功效与作用及食用方法,花胶的正确炖法和吃法秋季?
- 用友T3如何备份账套,哪位知道用友T3普及版如何进行账套备份
- 打耳洞发炎要及时就医,打耳洞发炎要去医院吗