pnpm fetch
lockfile에서 가상 저장소로 패키지를 가져오면 패키지 매니페스트 파일이 무시됩니다.
사용 시나리오#
이 명령은 도커 이미지 빌드를 향상하기 위해 특별히 설계되었습니다.
Node.js 앱용 Dockerfile 작성에 관한 official guide를 읽어보셨을 수도 있습니다. 아직 읽지 않았다면 먼저 읽어보는 것이 좋습니다.
이 가이드에서 pnpm을 사용하여 프로젝트에 최적화된 Dockerfile을 작성하는 방법을 배웁니다.
FROM node:20
WORKDIR /path/to/somewhere
RUN corepack enable pnpm && corepack install -g pnpm@latest-11
# Files required by pnpm install
COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml .pnpmfile.mjs ./
# If you patched any package, include patches before install too
COPY patches patches
RUN pnpm install --frozen-lockfile --prod
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
.npmrc, package.json, pnpm-lock.yaml, pnpm-workspace.yaml, .pnpmfile.mjs에 변경 사항이 없는 한, docker 빌드 캐시는 docker 이미지 빌드 시간의 대부분을 차지하는 RUN pnpm install --frozen-lockfile --prod 레이어까지 계속 유효합니다.
그러나 package.json은 종속성뿐만 아니라 버전 번호, 스크립트, 기타 도구에 대한 임의의 설정도 포함할 수 있기 때문에, 예상보다 훨씬 자주 수정될 수 있습니다.
monorepo 프로젝트를 빌드하는 Dockerfile을 유지 관리하는 것도 어렵습니다. 다음과 같이 보일 수 있습니다.
FROM node:20
WORKDIR /path/to/somewhere
RUN corepack enable pnpm && corepack install -g pnpm@latest-11
# Files required by pnpm install
COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml .pnpmfile.mjs ./
# If you patched any package, include patches before install too
COPY patches patches
# for each sub-package, we have to add one extra step to copy its manifest
# to the right place, as docker have no way to filter out only package.json with
# single instruction
COPY packages/foo/package.json packages/foo/
COPY packages/bar/package.json packages/bar/
RUN pnpm install --frozen-lockfile --prod
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
보시다시피 하위 패키지를 추가하거나 제거할 때 Dockerfile을 업데이트해야 합니다.
pnpm fetch는 lockfile과 설정 파일(pnpm-workspace.yaml)의 정보만 사용하여 가상 스토어에 패키지를 불러오는 기능을 제공함으로써 위의 문제를 완벽하게 해결합니다.
FROM node:20
WORKDIR /path/to/somewhere
RUN corepack enable pnpm && corepack install -g pnpm@latest-11
# pnpm fetch does require only lockfile
COPY pnpm-lock.yaml pnpm-workspace.yaml ./
# If you patched any package, include patches before running pnpm fetch
COPY patches patches
RUN pnpm fetch --prod
COPY . ./
RUN pnpm install -r --offline --prod
EXPOSE 8080
CMD [ "node", "server.js" ]
이는 단순한 프로젝트와 모노레포 프로젝트 모두에서 작동하며, 필요한 모든 패키지가 이미 가상 스토어에 있으므로 --offline은 pnpm이 패키지 레지스트리와 통신하지 않도록 강제합니다.
기존 lockfile이 변경되지 않는 한 빌드 캐시는 해당 레이어까지 유효하므로, RUN pnpm install -r --offline --prod로 많은 시간을 절약할 수 있습니다.
참고
로컬 file: 프로토콜 종속성은 fetch 시점에 사용할 수 없는 디렉터리를 참조할 수 있으므로(예: Docker 빌드에서) pnpm fetch 중에는 건너뜁니다.
옵션#
--dev, -D#
개발 패키지만 가져옵니다.
--prod, -P#
개발 패키지를 가져오지 않습니다.