使用未发布的包处理 Javascript/Typescript monorepo 中的 Docker 镜像

McF*_*iez 5 javascript docker microservices lerna monorepo

我一直试图找到这个问题的明确答案,但不幸的是我一直未能找到。有两个类似的问题涉及这个主题,

开发人员是否应该能够在其开发环境中从 lerna monorepo 创建 docker 工件?

如何在 lerna monorepo 中构建 docker 镜像而不发布

但他们没有明确回答,我认为需要添加更多背景才能得到更清晰的答案。

我正在使用 Next.js 和几个 Express 服务器建立一个业余爱好项目。我正在构建一组微服务,并且它们之间将有一个可以共享的公共资源。由于这是一个业余爱好项目,因此将所有这些都存在于单个 git 存储库中是有意义的。同样,作为一个业余爱好项目,不必将任何包发布到像 NPM 这样的注册表也是有意义的。

让我们想象一个类似于 lerna(JS monorepo 工具)文档展示的结构:

my-lerna-repo/
  package.json
  packages/
    package-1/
      package.json
    package-2/
      package.json
Run Code Online (Sandbox Code Playgroud)

使用像 Lerna 这样的工具,您可以拥有一个commons依赖的包,并让其他包引用它。Lerna 将提升这个commons包并简单地在包的node_modules.

这在开发时是有意义的,但是当您容器化服务时,这在生产中如何工作呢?例如,如果我们Dockerfile为每个服务创建一个并将其放入 Kubernetes 集群中,容器将会失败,因为commons依赖项不存在——它只是一个符号链接。

我研究过勒纳的“复制”论点,但不存在这样的论点。我知道还有其他 JS monorepo 工具(例如 Rush),但我知道 Lerna 是最受欢迎的。

如何解决容器化 monorepo 依赖包而不发布它们的问题?

McF*_*iez 0

对于在开发中遇到类似问题的人,我想提供我最终得到的解决方案。

首先,我使用纱线工作区在单一存储库的根目录中设置一个 package.json :

{
  "name": "ticketing",
  "private": true,
  "workspaces": [
    "common",
    "service-one",
    "service-two"
  ]
}
Run Code Online (Sandbox Code Playgroud)

然后,对于每个服务的 docker 文件,我将复制常见项目:

FROM node:alpine as builder
WORKDIR /app

COPY package.json .
COPY common ./common
COPY service-one./service-one


FROM builder as prod
WORKDIR /app
ENV NODE_ENV=production

RUN npm install --prod
CMD npm run prod -w @project/service-one


FROM builder as dev
WORKDIR /app
ENV CI=true

RUN npm install
CMD npm run dev -w @project/service-one
Run Code Online (Sandbox Code Playgroud)

通过此设置,我不再需要 npm 发布我的公共资源。