首页 > 解决方案 > 具有纱线工作区的节点单仓库和没有 dockerfiles 的 docker

问题描述

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

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

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

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

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

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

我调查了在 repo root 创建一个脚本

我无法创建一个合适的脚本来做到这一点,我不能docker cp在我刚刚创建的容器中文件,docker create但我的 docker 技能可能很低。

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

谢谢

标签: node.jsdockeryarnpkg

解决方案


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

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

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


推荐阅读