使用 Lerna 在 mono 存储库中 Docker 化多个 Node 应用程序

Mus*_*eed 7 node.js npm docker reactjs lerna

我的单一存储库和 Docker 项目设置遇到一些问题。

\n\n

我想使用 Lerna 进行单一存储库设置,并使用 Docker 进行项目构建。

\n\n

在我集成 Lerna 之前,一切都工作得很好,但现在我集成了 Lerna,我不知道我必须调用哪个部分/步骤,lerna bootstrap因为调用此命令后,我node_modules将自动构建,我不再需要npm install在每个中单独运行Dockerfile。我不明白的是这一切会是什么样子,我是否必须Dockerfile为根文件夹创建另一个?如果是,那么我的docker-compose.yml文件会是什么样子?一切都还不清楚。

\n\n

这就是我的项目树的样子:

\n\n

后端文件夹具有基本的 Nestjs 设置,客户端文件夹具有基本的 Gatsby 设置。

\n\n
\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 backend\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 nest-cli.json\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.controller.spec.ts\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.controller.ts\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.module.ts\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.service.ts\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.ts\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 test\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.e2e-spec.ts\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 jest-e2e.json\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 tsconfig.build.json\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tsconfig.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 client\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gatsby-browser.js\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gatsby-config.js\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gatsby-node.js\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gatsby-ssr.js\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 LICENSE\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 components\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 header.js\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 image.js\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 layout.css\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 layout.js\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 seo.js\n\xe2\x94\x82       \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 images\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gatsby-astronaut.png\n\xe2\x94\x82       \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 gatsby-icon.png\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 pages\n\xe2\x94\x82           \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 404.js\n\xe2\x94\x82           \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 page-2.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 docker-compose.yml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lerna.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tslint.json\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

客户端文件夹中的 Dockerfile:

\n\n
FROM node:12\n\nEXPOSE 8000 9929 9230\n\nWORKDIR /usr/src/app/client\n\nRUN npm install -g gatsby-cli\n\nCOPY package*.json ./\n\nCOPY . .\n\nRUN npm install\n\nCMD ["gatsby", "develop", "-H", "0.0.0.0" ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

后端文件夹中的 Dockerfile:

\n\n
FROM node:12-alpine\n\nWORKDIR /usr/src/app/backend\n\nCOPY package*.json ./\n\nRUN npm install\n\nCOPY . .\n\nEXPOSE 3000\n\nCMD [ "npm", "start" ]\n
Run Code Online (Sandbox Code Playgroud)\n\n

根文件夹中的 docker-compose.yml 文件:

\n\n
version: "3"\n\nservices:\n  backend:\n    image: docker-nestjs-backend\n    build: ./backend\n    command: npm run start:dev\n    volumes:\n      - ./backend:/usr/src/app/backend\n      - /usr/src/app/backend/node_modules\n    ports:\n      - 3002:3000\n\n  client:\n    image: docker-gatsby-client\n    build: ./client\n    volumes:\n      - ./client:/usr/src/app/client\n      - /usr/src/app/client/node_modules\n    ports:\n      - "8000:8000"\n      - "9929:9929"\n      - "9230:9230"\n    environment:\n      - NODE_ENV=development\n      - GATSBY_WEBPACK_PUBLICPATH=/\n    depends_on:\n      - backend\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

任何帮助表示赞赏。

\n

gol*_*und 4

我曾经参与过的一个开源项目就是这样做的。他们有一个由多个包组成的单一存储库(每个包都有一个 Dockerfile)。他们使用 CircleCI 作为 CI 管道,并使用 IIRC 将所有包依赖项分配到一个虚拟 Nodejs 映像中,该映像的存在只是为了提供所有其他映像的依赖项。这涉及到将 NodeJS 映像置于根级别,并使用 Yarn 的工作区功能将所有包级别依赖项“提升”到单个根级别映像中。

我希望我能提供更全面的例子,但已经很长时间了,我找不到这个项目。不过,你会做这样的事情:

  1. 在根目录创建 Dockerfile,使用 Yarn 提升所有 deps
  2. 在每个包 Dockerfile 中,挂载持久的、共享的 deps 卷而不是安装它们
  3. 在 CI 管道或 Docker-Compose 中,您首先构建根级映像并在其中运行yarn bootstrap等yarn coverage。您需要确保此容器在构建其他容器之前处于活动状态 - 您可以使用wait-for-it等脚本来执行此操作(这里是 Docker 特定的使用信息)

再次,我希望能为您提供更详细的答案,但我希望这至少能给您一些想法有所帮助。