Docker | 缓存依赖
1. 简介
项目使用docker compose
,前端与后台都是使用二段构建,先安装依赖编译出文件,在将编译出来的文件,复制到新建构的镜像。然而每次构建镜像都要花大量时间去等待安装前端node.js依赖后台golang的依赖,后面找到解决方法缓存依赖,这样就省去了每次构建镜像时安装依赖的时间。
下面以golang安装依赖为例,/go/pkg/mod
为golang依赖的缓存目录。
2. 演示
2.1. 文件树
hello-go
├── Dockerfile
├── go.mod
└── main.go
2.2. 文件内容
Dockerfile
FROM golang:1.19.1-bullseye
WORKDIR hello-go/
COPY . .
# 无缓存依赖
#RUN go env -w GOPROXY=https://goproxy.cn,direct && \
# go mod tidy && \
# go build -o main
# 缓存依赖
RUN --mount=type=cache,mode=0777,id=go-mod,target=/go/pkg/mod \
go env -w GOPROXY=https://goproxy.cn,direct && \
go mod tidy && \
go build -o main
CMD ./main
main.go
package main
import (
"go.uber.org/zap"
)
func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("Hello world")
}
go.mod
module hello-go
go 1.19
require go.uber.org/zap v1.24.0
require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
)
2.3. 执行对比
无缓存依赖
docker build -f Dockerfile --no-cache -t hello-go:1.0.0 .
[+] Building 2.3s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.19.1-bullseye
=> [1/4] FROM docker.io/library/golang:1.19.1-bullseye 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 3.80kB 0.0s
=> CACHED [2/4] WORKDIR hello-go/ 0.0s
=> [3/4] COPY . . 0.0s
=> [4/4] RUN go env -w GOPROXY=https://goproxy.cn,direct && go mod tidy && go build -o main 2.0s
=> => # go: downloading github.com/stretchr/testify v1.8.0
=> => # go: downloading go.uber.org/goleak v1.1.11
=> => # go: downloading github.com/benbjohnson/clock v1.1.0
=> => # go: downloading gopkg.in/yaml.v3 v3.0.1
=> => # go: downloading github.com/davecgh/go-spew v1.1.1
=> => # go: downloading github.com/pmezard/go-difflib v1.0.0
...
有缓存依赖
有缓存依赖第一次也会下载,后续在执行,不会在重新下载依赖
docker build -f Dockerfile --no-cache -t hello-go:1.0.0 .
[+] Building 1.6s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 405B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.19.1-bullseye 0.0s
=> [stage-0 1/4] FROM docker.io/library/golang:1.19.1-bullseye 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 4.17kB 0.0s
=> CACHED [internal] settings cache mount permissions 0.0s
=> CACHED [stage-0 2/4] WORKDIR hello-go/ 0.0s
=> [stage-0 3/4] COPY . . 0.0s
=> [stage-0 4/4] RUN --mount=type=cache,mode=0777,id=go-mod,target=/go/pkg/mod go env -w GOPROXY=https://goproxy.cn,direct && go mod tidy && go build -o main 1.4s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:1d0eefea9bf2a1079782e1233119db73ded083ec399911ddee6720346f1f5502 0.0s
=> => naming to docker.io/library/hello-go:1.0.0
3. 注意
- 如果
hello-go:1.0.0
镜像不存在并且执行了docker system prune
,依赖缓存会被清理