我最近开始使用lerna来管理monorepo,并且在开发中效果很好。

Lerna在我的各种软件包之间创建符号链接(symbolic link),因此'tsc --watch'或nodemon之类的工具可以很好地检测其他软件包中的更改。

但是我在这种环境下创建docker镜像时遇到了一个问题。

假设我们有一个具有以下结构的项目:

root
  packages
     common → artifact is a private npm package, this depends on utilities, something-specific
     utilities → artifact is a public npm package
     something-specific -> artifact is a public npm package
     frontend → artifact is a docker image, depends on common
     backend → artifact is a docker image, depends on common and utilities

在这种情况下,在开发中,一切都很好。我正在运行某种实时重新加载服务器,并且符号链接(symbolic link)可以正常运行,从而使依赖项正常工作。

现在假设我要从后端创建一个docker镜像。

我将介绍一些场景:
  • 我在Dockerfile中添加了ADD package.json,然后运行npm install。

    不起作用,因为通用和实用程序包未发布。
  • 我在后端运行我的构建命令,在docker文件中添加/build和/node_modules。

    不起作用,因为我的内置后端具有require('common')require('utilities')命令,这些命令位于node_modules(符号链接(symbolic link))中,但是Docker只会忽略这些符号链接(symbolic link)的文件夹。

    解决方法:使用cp --dereference“取消符号链接(symbolic link)”节点模块起作用。看到这个AskUbuntu question
  • 步骤1,但在构建docker镜像之前,我发布了npm软件包。

    这行得通,但是对于正在检查代码库并对commonutilities进行修改的人来说,它将无法工作,因为他们没有发布npm软件包的特权。
  • 我将buildbackend命令配置为不将commonutilities视为外部,而common则不将something-specific视为外部。

    我认为首先要构建something-specific,然后构建common,再构建utilities,再构建backend

    这样,当进行构建时,并将此技术与webpack一起使用,捆绑软件将包含something-specfic,common和utilities的所有代码。

    但这麻烦管理。

  • 我想在这里解决似乎很简单的问题。我的机器上当前正在运行的代码,我想拉出并放入docker容器中。

    请记住,我们希望在此处实现的关键是,使某人能够从其开发环境中 check out 代码库,修改任何软件包,然后构建docker镜像。

    我是否在这里缺少一种明显的lerna技术,或者我可以用来思考解决此问题的发展引用框架?

    最佳答案

    我们遇到了一个类似的问题,这是我们所做的事情:将Dockerfile放在monorepo的根目录(lerna.json所在的位置)中。

    原因是:您确实将整个存储库视为单个事实来源,并且您希望对整个存储库的任何修改都反射(reflect)在Docker镜像中,因此为各个软件包使用单独的Dockerfile显得没有意义。

    Docker文件

    FROM node:12.13.0
    
    SHELL ["/bin/bash", "-c"]
    
    RUN mkdir -p /app
    WORKDIR /app
    
    # Install app dependencies
    COPY package.json /app/package.json
    COPY yarn.lock /app/yarn.lock
    COPY packages/frontend/package.json /app/packages/frontend/package.json
    COPY packages/backend/package.json /app/packages/backend/package.json
    COPY lerna.json /app/lerna.json
    RUN ["/bin/bash", "-c", "yarn install"]
    
    # Bundle app source
    COPY . /app
    RUN ["/bin/bash", "-c", "yarn bootstrap"]
    RUN ["/bin/bash", "-c", "yarn build"]
    
    EXPOSE 3000
    
    CMD [ "yarn", "start" ]
    
    

    package.json
    {
      "private": true,
      "workspaces": [
        "packages/*"
      ],
      "scripts": {
        "bootstrap": "lerna clean --yes && lerna bootstrap",
        "build": "lerna run build --stream",
        "start": "cross-env NODE_ENV=production node dist/backend/main",
      },
      "devDependencies": {
        "lerna": "^3.19.0",
        "cross-env": "^6.0.3"
      },
    }
    
    

    09-25 18:55
    查看更多