microservices - 开发人员是否应该能够在他们的开发环境中从 lerna monorepo 创建一个 docker 工件?

标签 microservices docker devops monorepo

我最近开始使用 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 镜像。

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

    不起作用,因为未发布公共(public)和实用程序包。
  • 我在后端运行构建命令,在 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 中使用这种技术,bundle 将包含来自 something-specfic 、 common 和 utilities 的所有代码。

    但这管理起来很麻烦。

  • 这似乎是我试图在这里解决的一个非常简单的问题。当前在我的机器上运行的代码,我想拉出并放入一个 docker 容器中。

    请记住,我们在这里想要实现的关键是让某人能够检查代码库,修改任何包,然后构建 docker 镜像,所有这些都来自他们的开发环境。

    是否有我在这里遗漏的明显 lerna 技术,或者我可以用来考虑解决这个问题的 devops 引用框架?

    最佳答案

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

    原因:您确实将整个 repo 视为单一事实来源,并且您希望对整个 repo 的任何修改都反射(reflect)在 docker 镜像中,因此为单个包使用单独的 Dockerfile 就没有意义了。

    Dockerfile

    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" ]
    
    

    包.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"
      },
    }
    
    

    关于microservices - 开发人员是否应该能够在他们的开发环境中从 lerna monorepo 创建一个 docker 工件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56294568/

    相关文章:

    java - 我们可以避免将所有字段都映射到springdata中用于Elasticsearch的实体类,因为json文档中有100多个字段吗?

    java - 微服务和 Rest 服务部署为 jar 文件?

    java - 我总是得到 "{"状态“:504 ,"error" :"Gateway Timeout" ,"message" :"com.netflix.zuul.exception.ZuulException: Hystrix Readed time out"}"?

    docker - 使用Neo4j和docker-compose配置环境变量

    docker - docker "instance"可以完全在 ram 中运行吗?

    testing - 在生产中运行端到端测试是否值得?

    tfs - DevOps 中的分支策略

    amazon-web-services - 使用 AWS Api Gateway 进行 Api 组合

    powershell - 如何为Set-Content调用提供唯一的凭据

    docker - 从位于 docker 中的应用程序连接到 Redis 服务器