Fez*_*sta 13 docker dockerfile yarnpkg
我有一个由Yarn管理的monorepo,我想利用Docker缓存层来加速我的构建,这样做我想首先复制package.json
和yarn.lock
文件,运行yarn install
然后复制其余的文件.
这是我的回购结构:
packages/one/package.json
packages/one/index.js
packages/two/package.json
packages/two/index.js
package.json
yarn.lock
Run Code Online (Sandbox Code Playgroud)
这是Dockerfile的感兴趣部分:
COPY package.json .
COPY yarn.lock .
COPY packages/**/package.json ./
RUN yarn install --pure-lockfile
COPY . .
Run Code Online (Sandbox Code Playgroud)
问题是第3个COPY
命令没有复制任何东西,我怎样才能达到预期的效果?
mbe*_*sky 19
有一个基于多阶段构建功能的解决方案:
FROM node:12.18.2-alpine3.11
WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]
# Step 2: Copy whole app
COPY packages packages
# Step 3: Find and remove non-package.json files
RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
# Step 4: Define second build stage
FROM node:12.18.2-alpine3.11
WORKDIR /app
# Step 5: Copy files from the first build stage.
COPY --from=0 /app .
RUN yarn install --frozen-lockfile
COPY . .
# To restore workspaces symlinks
RUN yarn install --frozen-lockfile
CMD yarn start
Run Code Online (Sandbox Code Playgroud)
在Step 5
该层高速缓存,即使在任何文件将被重用packages
目录已经更改。
Joo*_*ost 19
使用 Docker 的新 BuildKit 执行器,可以使用绑定挂载到 Docker 上下文中,然后您可以根据需要从中复制任何文件。
例如,以下代码片段将 Docker 上下文中的所有 package.json 文件复制到映像的目录/app/
(以下示例中的 workdir)
不幸的是,更改挂载中的任何文件仍然会导致层缓存未命中。这可以使用@mbelsky 提出的多阶段方法来解决,但这次不再需要显式删除。
# syntax = docker/dockerfile:1.2
FROM ... AS packages
WORKDIR /app/
RUN --mount=type=bind,target=/docker-context \
cd /docker-context/; \
find . -name "package.json" -mindepth 0 -maxdepth 4 -exec cp --parents "{}" /app/ \;
FROM ...
WORKDIR /app/
COPY --from=packages /app/ .
Run Code Online (Sandbox Code Playgroud)
指定mindepth
/maxdepth
参数是为了减少要搜索的目录数量,可以根据您的用例进行调整/删除。
可能需要使用环境变量启用 BuildKit 执行器DOCKER_BUILDKIT=1
,因为传统执行器会默默地忽略绑定安装。
有关 BuildKit 和绑定边界的更多信息可以在此处找到。
要跟进@FezVrasta对我的第一个答案的评论,如果您无法枚举Dockerfile中所有受威胁的子目录,但是想要分两步复制所有文件以利用Docker缓存功能,则可以尝试以下解决方法:
package.json
格式),将所需文件复制到.deps/
具有类似层次结构的单独目录(例如)中,然后调用docker build …
yarn install --pure-lockfile
…所有东西放在一起,这可能会导致以下文件:
### ./build.bash ###
#!/bin/bash
tag=copy-example:latest
rm -f -r .deps # optional, to be sure that there is
# no extraneous "package.json" from a previous build
find . -type d \( -path \*/.deps \) -prune -o \
-type f \( -name "package.json" \) \
-exec bash -c 'dest=".deps/$1" && \
mkdir -p -- "$(dirname "$dest")" && \
cp -av -- "$1" "$dest"' bash '{}' \;
# instead of mkdir + cp, you may also want to use
# rsync if it is available in your environment...
sudo docker build -t "$tag" .
Run Code Online (Sandbox Code Playgroud)
和
### ./Dockerfile ###
FROM ...
WORKDIR /usr/src/app
# COPY package.json . # subsumed by the following command
COPY .deps .
# and not "COPY .deps .deps", to avoid doing an extra "mv"
COPY yarn.lock .
RUN yarn install --pure-lockfile
COPY . .
# Notice that "COPY . ." will also copy the ".deps" folder; this is
# maybe a minor issue, but it could be avoided by passing more explicit
# paths than just "." (or by adapting the Dockerfile and the script and
# putting them in the parent folder of the Yarn application itself...)
Run Code Online (Sandbox Code Playgroud)
如官方Dockerfile参考中所述COPY <src> <dest>
COPY指令从中复制新文件或目录
<src>
,并将它们添加到路径中容器的文件系统中<dest>
。
对于你的情况
每个都可能包含通配符,并且将使用Go的
filepath.Match
规则进行匹配。
这是规则。它们包含以下内容:
'*'匹配任何非分隔符字符序列
因此,请尝试在您的模式中使用*
而不是**
。
归档时间: |
|
查看次数: |
11985 次 |
最近记录: |