In PNPM repositories, node_modules
have many hard links(not symbolic links) of packages to the local .pnpm store.
Now I need to make a Dockerfile
with a multi-stage building process for my SveltKit repo,
and I am stuck with copying node_modules
folder from my builder
to my deployer
docker image below:
FROM node:18.16.0-alpine AS builder
RUN npm install -g pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
RUN pnpm prune --prod
FROM node:18.16.0-alpine AS deployer
WORKDIR /app
COPY --from=builder /app/build build/
COPY --from=builder /app/node_modules ./node_modules
COPY package.json .
EXPOSE 5173
CMD [ "node", "build" ]
Because PNPM is not like NPM. Direct copying the node_modules
folder will not work.
I have tried to convert the pnpm-lock.yaml
into package-lock.json
by npm i --package-lock-only
, but it took a very long time then failed with this error message: Cannot set properties of null (setting 'dev')
.
What is the proper solution or workaround?
I was thinking about use Linux cp -rL
command to deal with hard links/symbolic links:
RUN cp -rL node_modules node_modules2
RUN rm -r node_modules
RUN mv node_modules2 node_modules
But that is not an efficient way to solve it.
Thanks for @DavidMaze. PNPM does use hard links and it seems to work fine with Docker COPY command. Here is a very contrived Dockerfile I tried and it works!
FROM node:18.16.0-alpine AS base
RUN npm install -g pnpm
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
FROM node:18.16.0-alpine
WORKDIR /app
COPY . .
COPY --from=base /app/node_modules ./node_modules
EXPOSE 5173
CMD [ "npm", "run", "dev" ]
As the above Dockerfile is not a proper way to build a SvelteKit image, you have to comment out those below in your .dockerignore:
#.svelte-kit
#**/.env
To build the image:
docker build . -t project1:v2
docker run -p5173:5173 -p 24678:24678 project1:v2