【问题标题】:node monorepo with yarn workspaces and docker without dockerfiles带有纱线工作空间的节点单仓库和没有 dockerfiles 的 docker
【发布时间】:2021-04-22 08:40:09
【问题描述】:

我正在尝试找到一个合适的设置来为纱线工作区 monorepo 中的单个服务创建 docker 映像,例如这个:

packages/
├─ svc1/
│  ├─ package.json
├─ svc2/
│  ├─ package.json
├─ .../
package.json
yarn.lock

尝试在每个服务包中使用 Dockerfile 时会出现问题:锁定文件位于 repo 根目录,并且包可能使用 workspace: 协议引用 repo 中的一些其他包。 这将使install 步骤失败。

因此,我想创建一个保留 monorepo 布局的“构建”图像

  • 1- 复制 package.jsons 和 yarn.lock
  • 1.1- 可选地挂载 .yarn/cache 目录(在构建时使用 docker 很难做到)
  • 2- 运行安装步骤
  • 3- 提交 repo 容器

我将能够从此构建映像中获取给定的包依赖项并复制适当的构建工件以运行我的服务/应用程序。

Dockerfile 在这里不是一个选项,因为目录布局:

  • 不可能COPY **/package.json 尊重目录
  • 构建上下文非常庞大(我知道 .dockerignore 可以提供帮助)
  • 可以添加/删除项目我不想每次都编辑 dockerfile,只需按照 repo 布局即可

我研究了在 repo 根目录下创建一个脚本

  • 创建自定义 docker 容器(例如从 node:alpine)
  • 根据目录布局和锁定文件复制每个 package.json(并挂载 .yarn/cache?)
  • 运行安装cmd
  • 提交容器

我无法创建适当的脚本来执行此操作,我无法在我刚刚使用 docker create 创建的容器中 docker cp 文件,但我的 docker 技能可能很低。

您知道如何使用 shell 脚本创建/提交此图像吗?

谢谢

【问题讨论】:

    标签: node.js docker yarnpkg


    【解决方案1】:

    经过多次尝试和错误,我设法做到了:

    #!/usr/bin/env sh
    
    set -eo pipefail
    
    echo "pulling node:alpine..."
    # find . -name node_modules -prune -false -o -name package.json
    
    workdir="/opt/myrepo"
    
    mountpath="$(pwd)/.yarn/cache"
    container=$(docker create --tty --workdir "${workdir}" --mount type=bind,source=${mountpath},target=${workdir}/.yarn/cache,readonly node:alpine sh)
    echo "container id=\"${container}\""
    echo "docker start \"${container}\""
    docker start "${container}"
    
    find . -name node_modules -prune -false -o -name package.json | while IFS= read file; do
      path=$(dirname "${file}")
      echo "docker exec \"${container}\" mkdir -p \"${path}\""
      docker exec "${container}" mkdir -p "${path}"
      echo "docker cp \"${file}\" \"${container}:${file}\""
      docker cp "${file}" "${container}:${workdir}/${file}"
    done
    docker cp .yarnrc.yml "${container}":${workdir}/
    docker cp yarn.lock "${container}":${workdir}/
    docker cp .yarn/plugins "${container}":${workdir}/.yarn/
    docker cp .yarn/releases "${container}":${workdir}/.yarn/
    docker exec --workdir "${workdir}" "${container}" yarn workspaces focus --all --production
    docker commit "${container}" "myrepo:latest"
    docker stop "${container}"
    
    echo "done"
    

    这看起来很古怪,但确实有效。有没有更优雅的解决方案?

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 1970-01-01
      • 2021-06-03
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      相关资源
      最近更新 更多