node.js - 具有纱线工作区的节点单仓库和没有 dockerfiles 的 docker
问题描述
我正在尝试找到一个适当的设置来为纱线工作区 monorepo 中的单个服务创建 docker 映像,例如这个:
packages/
├─ svc1/
│ ├─ package.json
├─ svc2/
│ ├─ package.json
├─ .../
package.json
yarn.lock
尝试在每个服务包中使用 Dockerfile 时存在一个问题:锁定文件位于 repo 根目录,并且包可能使用workspace:
协议引用 repo 中的一些其他包。这将使install
步骤失败。
因此,我想创建一个保留 monorepo 布局的“构建”图像
- 1- 副本
package.json
和yarn.lock
- 1.1- 可选地挂载 .yarn/cache 目录(在构建时使用 docker 很难做到)
- 2-运行安装步骤
- 3-提交回购容器
我将能够从此构建映像中获取给定的包依赖项并复制适当的构建工件以运行我的服务/应用程序。
Dockerfile 在这里不是一个选项,因为目录布局:
- 不可能
COPY **/package.json
尊重目录 - 构建上下文很大(我知道 .dockerignore 可以提供帮助)
- 可以添加/删除项目我不想每次都编辑 dockerfile,只需按照 repo 布局即可
我调查了在 repo root 创建一个脚本
- 创建一个自定义 docker 容器(例如来自 node:alpine)
- 复制每个 package.json 尊重目录布局和锁文件(& 挂载 .yarn/cache?)
- 运行安装cmd
- 提交容器
我无法创建一个合适的脚本来做到这一点,我不能docker cp
在我刚刚创建的容器中文件,docker create
但我的 docker 技能可能很低。
您知道如何使用 shell 脚本创建/提交此图像吗?
谢谢
解决方案
经过多次试验和错误,我设法做到了:
#!/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"
这看起来很古怪,但确实有效。有没有更优雅的解决方案?
推荐阅读
- php - Laravel 原始总和查询到 laravel 查询构建器
- android - ViewModel 使用 BottomNavigationView 切换两次初始化
- ag-grid - 为树数据 ag 网格设置数据路径
- r - 在R中设置矩阵的最大值和最小值
- c++ - C++20 默认相等/不等式
- android - 在应用程序内购买。无法再次购买。项目响应:“7 项目已拥有”
- javascript - 如何使用 .toLocaleDateString() 以 2020 年 10 月 29 日等格式显示日期以供 en-us 使用?
- android - Motionlayout 文件太大
- r - 在 R Shiny flexdashboard 中单击带有 Plotly 的直方图栏上的超链接悬停文本
- python - 获取替换子字符串的所有可能组合