How to build docker images in a lerna monorepo without publishing How to build docker images in a lerna monorepo without publishing docker docker

How to build docker images in a lerna monorepo without publishing


For my own project, the solution is to use docker BuildKit to first build all the workspace and then build a docker image for the project workspace reusing the previous built files.

In details you have copy in the docker file the top package.json with yarn lock and then cherrypicking the package.json of the needed workspace.Then running a yarn install and a yarn build to get everything working.

Here is my project:

# base imageFROM @myscope/base:latest as base# set working directoryWORKDIR /app# add `/app/node_modules/.bin` to $PATHENV PATH /app/node_modules/.bin:$PATH# install and cache app dependenciesCOPY ["package.json","yarn.lock", "./"]COPY ./packages/server/package.json ./packages/server/COPY ./packages/shared/package.json ./packages/shared/COPY ./packages/app/package.json ./packages/app/RUN yarn install --frozen-lockfile --non-interactive --production=false --ignore-scriptsCOPY . /appRUN yarn buildFROM nodejs:14.15 as serverappWORKDIR /appCOPY ["package.json","yarn.lock", "./"]COPY ./packages/server/package.json ./packages/server/COPY ./packages/shared/package.json ./packages/shared/RUN yarn install --frozen-lockfile --non-interactive --production=true --ignore-scripts# copy artifact build from the 'build environment'COPY --from=base /app/packages/shared/dist /app/packages/shared/distCOPY ["./packages/server/", "./packages/server/"]WORKDIR /app/packages/serverVOLUME ["/app/packages/server/logs", "/app/packages/server/uploads"]EXPOSE $PORTCMD ["yarn", "start"]

shared is a private workspace that is a dependency of the server workspace.


Due no answer was satisfying for me i have built an npm package, which generates a Dockerfile for lerna projects. It uses the stage feature of Docker and creates stages for each package.

You simply need at least two Dockerfiles:

The base Dockerfile which contains the global setup

Dockerfile.base:

FROM node:14 as baseCOPY ./package.json ./RUN npm iCOPY ./lerna.json ./

and a template for the packages

Dockerfile.template:

FROM base as buildCOPY ./package.json ./RUN npm installRUN --if-exists npm run build

you can also have custom Dockerfiles for packages by simply adding your own Dockerfile inside the package. This will replace the template by the custom Dockerfile.

afterwards you can run the command over npx to generate your dockerfile:

npx lerna-dockerize