Musayyab Naveed
Musayyab Naveed

Reputation: 365

Dockerizing multiple Node apps with Lerna in mono repository

I am having some problems with my mono-repository and Docker project setup.

I want to use Lerna for my mono-repository setup, and Docker for project building.

Before I integrated Lerna things were working just fine, but now I have Lerna integrated and I don't have any idea in what part/step I have to call lerna bootstrap because after calling this command my node_modules will be built automatically and I no more have to individually run npm install in each Dockerfile. What I do not understand is how this all will look like and will I have to create another Dockerfile for root folder? if yes then how will my docker-compose.yml file look like? It is all unclear.

This is how my project tree looks like:

The backend folder has basic nestjs setup and the client folder has basic Gatsby setup.


.
├── backend
│   ├── Dockerfile
│   ├── nest-cli.json
│   ├── package.json
│   ├── README.md
│   ├── src
│   │   ├── app.controller.spec.ts
│   │   ├── app.controller.ts
│   │   ├── app.module.ts
│   │   ├── app.service.ts
│   │   └── main.ts
│   ├── test
│   │   ├── app.e2e-spec.ts
│   │   └── jest-e2e.json
│   ├── tsconfig.build.json
│   └── tsconfig.json
├── client
│   ├── Dockerfile
│   ├── gatsby-browser.js
│   ├── gatsby-config.js
│   ├── gatsby-node.js
│   ├── gatsby-ssr.js
│   ├── LICENSE
│   ├── package.json
│   ├── README.md
│   └── src
│       ├── components
│       │   ├── header.js
│       │   ├── image.js
│       │   ├── layout.css
│       │   ├── layout.js
│       │   └── seo.js
│       ├── images
│       │   ├── gatsby-astronaut.png
│       │   └── gatsby-icon.png
│       └── pages
│           ├── 404.js
│           ├── index.js
│           └── page-2.js
├── docker-compose.yml
├── lerna.json
├── package.json
├── README.md
└── tslint.json

Dockerfile in the client folder:

FROM node:12

EXPOSE 8000 9929 9230

WORKDIR /usr/src/app/client

RUN npm install -g gatsby-cli

COPY package*.json ./

COPY . .

RUN npm install

CMD ["gatsby", "develop", "-H", "0.0.0.0" ]

Dockerfile in the backend folder:

FROM node:12-alpine

WORKDIR /usr/src/app/backend

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD [ "npm", "start" ]

docker-compose.yml file in the root folder:

version: "3"

services:
  backend:
    image: docker-nestjs-backend
    build: ./backend
    command: npm run start:dev
    volumes:
      - ./backend:/usr/src/app/backend
      - /usr/src/app/backend/node_modules
    ports:
      - 3002:3000

  client:
    image: docker-gatsby-client
    build: ./client
    volumes:
      - ./client:/usr/src/app/client
      - /usr/src/app/client/node_modules
    ports:
      - "8000:8000"
      - "9929:9929"
      - "9230:9230"
    environment:
      - NODE_ENV=development
      - GATSBY_WEBPACK_PUBLICPATH=/
    depends_on:
      - backend

Any help appreciated.

Upvotes: 7

Views: 5704

Answers (1)

struensee
struensee

Reputation: 606

One of the open-source projects I used to work on did this. They had a monorepo of several packages (each a Dockerfile). They used CircleCI for a CI pipeline and IIRC all package dependencies were allocated into a single dummy nodejs image that existed solely to serve the dependencies to all the other images. This involved having the nodejs image at the root level, and using Yarn's Workspaces feature to 'hoist' all the package-level deps into a single, root-level image.

I wish I could offer more thorough examples of this, but it has been a long time and I cannot find the project. You would do something like this, though:

  1. Create Dockerfile at root that hoists all deps with Yarn
  2. In each package Dockerfile, mount persistent, shared deps volume in lieu of installing them
  3. In your CI pipeline or Docker-Compose, you build the root-level image first and run yarn bootstrap, yarn coverage etc therein. You'll need to make sure this container is live before the other containers are built - you can do this using a script like wait-for-it (here is Docker-specific usage info)

Again, I wish I could offer you a more detailed answer but I hope this was at least helpful in giving you some ideas.

Upvotes: 5

Related Questions