我试图优化我的Azure DevOps流水线中的构建时间,但是我的Dockerfile中的npm install
阶段无法缓存。为什么?
这是我的Dockerfile。我已经将复制package*.json文件和npm install分开成一个层,然后再复制其余的源代码,因为这是最佳实践,并且应该使npm install层在构建之间可缓存。
FROM node:12-alpine3.12 AS builder
WORKDIR /app
ARG VERSION
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
...
FROM node:12-alpine3.12
COPY --from=builder /dist .
...
这是我的构建流程。由于Azure每次都在干净的虚拟机上构建,我尝试拉取现有镜像以利用先前的构建缓存(参考:如何在Azure DevOps中启用Docker层缓存)。
- script: |
registry=myregistry.azurecr.io
image=${registry}/myApp:$(Build.SourceBranchName)
# Pull in previously built builder image because cache
docker pull ${image}-builder
# Build the builder target
docker build \
--target builder \
--cache-from ${image}-builder \
-t ${image}-builder \
--build-arg VERSION=$(Build.BuildNumber) \
-f apps/myApp/Dockerfile .
# Pull in previously built image because cache
docker pull ${image}
docker build \
--cache-from ${image}-builder \
--cache-from ${image} \
-t ${image} \
--build-arg VERSION=$(Build.BuildNumber) \
-f apps/myApp/Dockerfile .
docker push ${image}
docker push ${image}-builder
displayName: Build and push an image
正如你所看到的,我已经将 Dockerfile 中的每个阶段与管道中的各自阶段分开。一个用于构建“builder”阶段,另一个用于构建生成的镜像。每个阶段的 docker 镜像都被推送到我的容器注册表中。
在重新构建或 package.json 未更改的构建中,我期望 npm install
层会输出 ---> Using cache
,但在运行“builder”阶段时它从未这样做。
Step 1/8 : FROM node:12-alpine3.12 AS builder
12-alpine3.12: Pulling from library/node
188c0c94c7c5: Already exists
c4e63f2c1114: Already exists
74bf6ceff101: Already exists
1f6472fc624b: Already exists
Digest: sha256:f2e453020045d7d93790777bc3ce2c992f097ce9a6d577d73490093df93b0702
Status: Downloaded newer image for node:12-alpine3.12
---> ccd680d0b809
Step 2/8 : WORKDIR /app
---> Using cache
---> 9f88e2fda996
Step 3/8 : ARG VERSION
---> Using cache
---> 707e936abbc5
Step 4/8 : COPY package.json ./
---> Using cache
---> 034785fd08a7
Step 5/8 : COPY package-lock.json ./
---> Using cache
---> ab778dbabb01
Step 6/8 : RUN npm install
---> Running in df1dc4b5bf91
...
Removing intermediate container df1dc4b5bf91
---> 4ee43e4f6095
Step 7/8 : COPY . .
---> 9ea6540727f2
Step 8/8 : RUN npm run build
---> Running in bd65f90191a5
请注意上面的
Removing intermediate container df1dc4b5bf91
。这可能与问题有关?尽管我尝试过docker build --rm=false
,但在重新构建时仍然没有使用缓存层。
然而,在构建我的流水线的最后一个阶段时,它确实从缓存中运行:Step 1/16 : FROM node:12-alpine3.12 AS builder
---> ccd680d0b809
Step 2/16 : WORKDIR /app
---> Using cache
---> 9f88e2fda996
Step 3/16 : ARG VERSION
---> Using cache
---> 707e936abbc5
Step 4/16 : COPY package.json ./
---> Using cache
---> 034785fd08a7
Step 5/16 : COPY package-lock.json ./
---> Using cache
---> ab778dbabb01
Step 6/16 : RUN npm install
---> Using cache
---> 4ee43e4f6095
我错过了什么?