带有 yarn 工作区和 docker 没有 docker 文件的节点 monorepo

node monorepo with yarn workspaces and docker without dockerfiles

我正在尝试找到一个合适的设置来为 yarn workspaces monorepo 中的各个服务创建 docker 图像,例如这个:

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

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

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

我将能够从此构建映像中获取给定的包依赖项并将适当的构建工件复制到 运行 我的 services/apps.

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

我调查了在 repo 根目录下创建一个脚本

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

您知道如何使用 shell 脚本 create/commit 这张图片吗?

谢谢

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

#!/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"

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