这是我的Dockerfile本地开发:
FROM node:12-alpine
WORKDIR /usr/app
ENV __DEV__ 1
COPY package.json ./
COPY yarn.lock ./
RUN yarn --frozen-lockfile
COPY tsconfig.json ./
COPY nodemon.json ./
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD [ "yarn", "dev" ]
Run Code Online (Sandbox Code Playgroud)
这就是我构建它的方式:
docker build --rm -f Dockerfile.dev --tag my-app .
Run Code Online (Sandbox Code Playgroud)
这就是我运行它的方式:
docker run --rm -it --volume $(pwd)/src:/usr/app/src -p 3000:3000 my-app
Run Code Online (Sandbox Code Playgroud)
仅当文件夹外部的内容发生更改时,我才需要构建它src。例如,当我安装节点模块时。如何yarn在某处缓存模块,这样就不会在每个构建上提取所有模块。
Ste*_*oob 31
使用 Docker 构建下一代容器是使用Buildkit。我建议使用它,特别是因为它对缓存问题有一个优雅的解决方案。目前在普通 Docker 中确实没有一个好的解决方案;虽然你可以解决这个问题,但它非常麻烦。
我将在这里列出这两种解决方案:
塔伦的答案是正确的,但有一种更简洁的方法。Buildkit 支持将安装指定为缓存。一旦你设置了 Docker 使用 Buildkit,我们需要做的就是:
...
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install
...
Run Code Online (Sandbox Code Playgroud)
这将自动提取上一次运行的缓存,如果尚不存在或已过期,则创建它。就是这么简单。
或者,如果无法使用 Buildkit,则可以使用 vanilla Docker。我们在这里可以做的最好的事情是使用COPY指令复制位于构建上下文中的某种“缓存”。例如,如果我们.yarn_cache在构建上下文的根目录中创建一个目录,那么我们可以提供一个缓存:
...
COPY .yarn_cache /root/.yarn
RUN yarn --frozen-lockfile
...
Run Code Online (Sandbox Code Playgroud)
当你的镜像构建时,这个外部缓存不会被更新,它需要在你的镜像之外进行初始化和定期更新。您可以使用以下 shell 命令来执行此操作(在第一次运行时清除任何本地命令node_modules以强制其预热缓存):
$ YARN_CACHE_FOLDER=.yarn_cache yarn install
Run Code Online (Sandbox Code Playgroud)
虽然这可行,但它非常 hack-y 并且有一些缺点:
.yarn_cache目录需要包含在构建上下文中,这可能会非常慢,更不用说它必须在每次构建时执行此操作,即使没有任何更改。由于这些原因,前一种解决方案是优选的。
额外的专业提示:在上述任一情况下包含纱线缓存仍会将其保留在最终图像中,从而增加其大小。如果您使用多阶段构建,则可以缓解此问题:
# syntax = docker/dockerfile:1.2
FROM node:12-alpine as BUILDER
WORKDIR /usr/app
COPY package.json ./
COPY yarn.lock ./
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn --frozen-lockfile
FROM node:12-alpine
WORKDIR /usr/app
COPY --from=BUILDER node_modules ./node_modules
COPY package.json ./
COPY yarn.lock ./
COPY tsconfig.json ./
COPY nodemon.json ./
RUN apk add --no-cache tini
ENTRYPOINT [ "/sbin/tini", "--" ]
ENV __DEV__=1
CMD [ "yarn", "dev" ]
Run Code Online (Sandbox Code Playgroud)
Tarun Lalwani和SteveGoob的答案很棒,但他们忽略了一个重要的细节,人们在并行构建许多容器时可能会面临这一细节。
在我的例子中,我使用命令并行地为两种架构构建了包含许多容器的 docker compose 文件buildx bake:
docker buildx bake -f ./docker-compose.yml --set *.platform=linux/amd64,linux/arm64/v8 --pull --push
Run Code Online (Sandbox Code Playgroud)
如果我--mount按照建议插入参数,构建将会失败,因为 buildx 将尝试并行执行几个yarn install,这会使缓存不一致并完全破坏它。
所以我稍微改变了 RUN 命令。这是一个新版本:
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn/v6,sharing=locked yarn install
Run Code Online (Sandbox Code Playgroud)
首先,我决定不创建自己的缓存目录,而是挂载到默认目录。我怎么得到默认的呢?我只是跑
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn/v6,sharing=locked yarn install
Run Code Online (Sandbox Code Playgroud)
它打印了纱线缓存目录的当前路径。就我而言(也可能是大多数其他人),它将是/usr/local/share/.cache/yarn/v6。因此不需要创建任何额外的文件夹并将其作为环境变量传递。
接下来的事情是添加sharing=locked参数到--mount. 使用此参数,它将按顺序等待每个并行安装。第一个(对于第一个容器和第一个架构)将拉取所有包,将它们保存到缓存中,所有接下来的yarn install将重用该缓存。
如果您不喜欢它们互相等待,您可以使用sharing=private一些冗余,这将为每个容器+架构对创建自己的缓存。文档中的原始信息
| 归档时间: |
|
| 查看次数: |
17753 次 |
| 最近记录: |