蛋黄派碎冰冰

pnpm-store几种缓存方式

分别介绍在Gitlab CI、Docker、Gitlab CI中使用Docker构建镜像等多种情况下,如何将pnpm-store缓存下来。

2024-04-3 11:55:00

pnpm-store几种缓存方式

Gitlab CI

这种是官方文档中推荐的写法,适用于直接在Gitlab CI的Stage中直接使用pnpm

.gitlab-ci.yml 文件:

stages:
  - build

build:
  stage: build
  image: node:18.17.1
  before_script:
    - corepack enable
    - corepack prepare pnpm@latest-8 --activate
    - pnpm config set store-dir .pnpm-store
  script:
    - pnpm install # install dependencies
  cache:
    key:
      files:
        - pnpm-lock.yaml
    paths:
      - .pnpm-store

Docker

在docker构建镜像时,没办法在容器内部和宿主机设置任何软连接和硬链接,只能通过BuildKit的缓存挂载来在多次build之间共享缓存

Dockerfile文件:

FROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY . /app
WORKDIR /app

FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile

FROM base AS build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build

FROM base
COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
EXPOSE 8000
CMD [ "pnpm", "start" ]

docker默认带了两种缓存存储方式,inline和local

  1. inline inline模式会像构建镜像层级一样将cache存储到镜像中,在下一次构建时声明cache-from,即可以将远程镜像拉取下来并使用其中的缓存层。

inline cache 的构建指令:

docker buildx build --push -t <registry>/<image> \
  --cache-to type=inline \
  --cache-from type=registry,ref=<registry>/<image> .
  1. local

顾名思义local模式即是将cache存储到宿主机某一个目录下

local cache 的构建指令:

docker buildx build --push -t <registry>/<image> \
  --cache-to type=local,dest=path/to/local/dir[,parameters...] \
  --cache-from type=local,src=path/to/local/dir .

Gitlab CI + Docker

为了让项目的构建和部署可以更好的兼容不同的CI平台或云平台,我通常会尽量让Dockerfile文件足以描述整个构建过程,简化CI脚本下执行指令的复杂度。

在Gitlab CI中执行镜像构建,每次build都在一个全新的容器中执行,因此需要结合BuildKit cache的local模式和Gitlab CI的cache能力,Gitlab CI可以将当前构建环境中某个目录缓存下来,供下次构建使用,因此只需要将BuildKit cache local模式下的缓存目录缓存到Gitlab CI的cache中即可。

.gitlab-ci.yaml文件:

stages:
  - build-img

build-img:
  image: docker:20.10.16-dind
  stage: build-img
  cache:
    paths:
      - pnpm-store
  script:
    - until docker info; do sleep 1; done
    - docker login -u $HARBOR_USERNAME -p $HARBOR_PASSWORD ...
    - mkdir -p pnpm-store
    - docker context create tls-environment
    - docker buildx create --name multiarch-builder --use tls-environment --driver docker-container --driver-opt image=moby/buildkit:master,network=host
    - docker buildx build ---cache-to type=local,dest=pnpm-store --cache-from type=local,src=pnpm-store --cache-from=<registry>/<image:latest> --tag <registry>/<image:tag> --tag <registry>/<image:latest> --load .
    - docker push <registry>/<image:tag>
    - docker push <registry>/<image:latest>

构建时声明了两个cache-from:

  • --cache-from type=local,src=pnpm-store: 指使用缓存的pnpm-store
  • --cache-from=<registry>/<image:latest>: 指将最近一个镜像拉到当前环境下,使用docker的layer缓存