前端容器化实践( 二 )


为解决这个问题,进一步的我们可以设想一个类似 数据卷 的功能,在镜像构建时把 node_modules 文件夹挂载上去,在构建完成后,这个 node_modules 文件夹会自动卸载,实际的镜像中并不包含 node_modules 这个文件夹,这样我们就省去了每次获取依赖的时间,大大增加了镜像构建效率,同时也避免了生成了大量的中间层镜像 。
此处课代表总结一下:就是尽量减少中间层镜像的可能,最小化docker映像大小和构建时间
由于我使用的是pnpm进行npm包管理,所以我去翻阅了pnpm官方文档关于此优化如下:
FROM node:20-slim AS baseENV PNPM_HOME="/pnpm"ENV PATH="$PNPM_HOME:$PATH"RUN corepack enableCOPY . /appWORKDIR /appFROM base AS prod-depsRUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfileFROM base AS buildRUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfileRUN pnpm run buildFROM baseCOPY --from=prod-deps /app/node_modules /app/node_modulesCOPY --from=build /app/dist /app/distEXPOSE 8000CMD [ "pnpm", "start" ]于是本着依葫芦画瓢的精神,还有使用生产化的nginx配置,我找了同事写的nginx包装镜像,同样你可以执行docker build、docker run进行验证,然后我改造后的代码如下:
FROM node:17-buster AS builderENV PNPM_HOME="/pnpm"ENV PATH="$PNPM_HOME:$PATH"RUN corepack enableWORKDIR /srcCOPY ./ /srcRUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked--mount=type=cache,target=/pnpm/store,id=pnpm_cachepnpm installRUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=lockedpnpm run buildFROM ghcr.io/zboyco/webrunner:0.0.7COPY --from=builder /src/dist /app4.4 如何利用buildx制作多架构镜像docker buildx的工具,说白了就是给你提供一个能力,当你的宿主机是x86 64的架构时,你想构建镜像为ARM64的架构,就需要这个工具,给人的感觉有点类似交叉编译,诸如:go build的交叉编译,在win10下编译可执行程序,可用于特定linux平台
buildx本质上调用了 buildkit 的 api,构建是在 buildkit 的环境中进行的 。是否支持多架构,取决于 buildkit 的环境,如果需要 buildkit支持多架构,需要在宿主机执行(当然这个不是必须的,按构建的需求进行控制,Docker桌面版无需进行此项设置):
docker run --privileged --rm tonistiigi/binfmt --install all我们这里改造上面Dockerfile代码,使它支持多架构,由于platform是实验性质,所以需要先执行docker pull docker/dockerfile 拉取镜像
# syntax = docker/dockerfile:experimental# --platform, 会让 builder 只会有一份,且 arch 与宿主机一致FROM --platform=${BUILDPLATFORM:-linux/amd64} node:17-buster AS builderENV PNPM_HOME="/pnpm"ENV PATH="$PNPM_HOME:$PATH"RUN corepack enableWORKDIR /srcCOPY ./ /srcRUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=locked--mount=type=cache,target=/pnpm/store,id=pnpm_cachepnpm installRUN --mount=type=cache,target=/src/node_modules,id=myapp_pnpm_module,sharing=lockedpnpm run buildFROM ghcr.io/zboyco/webrunner:0.0.7COPY --from=builder /src/dist /app在执行打包镜像命令之前,我们先查看下我们机器默认的 builder 实例
docker buildx lsNAME/NODEDRIVER/ENDPOINT STATUSBUILDKITPLATFORMSdefaultdockerdefaultdefaultrunning v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6desktop-linux * dockerdesktop-linux desktop-linuxrunning v0.11.7-0.20230525183624-798ad6b0ce9f linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6使用buildx执行上面的脚本打包镜像会报错如下
【前端容器化实践】docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t webapp-official-website:v1 .ERROR: Multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")由于 Docker 默认的 builder 实例不支持同时指定多个 --platform,我们必须首先创建一个新的 builder 实例 。同时由于国内拉取镜像较缓慢,我们可以使用配置了镜像加速地址的 dockerpracticesig/buildkit:master 镜像替换官方镜像 。

如果你有私有的镜像加速器,可以基于 https://github.com/docker-practice/buildx 构建自己的 buildkit 镜像并使用它 。
# 适用于国内环境$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master# 适用于腾讯云环境(腾讯云主机、coding.NET 持续集成)$ docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master-tencent# $ docker buildx create --name mybuilder --driver docker-container$ docker buildx use mybuilder


推荐阅读