6-2 如何自封装公共镜像,简化&加速镜像打包过程
为什么要封装公共基础镜像
在项目的 Dockerfile 中,每次构建都需要重复执行以下操作:
- 从 GitHub 下载 pnpm 的 Linux 安装文件
- 配置 pnpm 的执行权限
- 设置 pnpm 的缓存目录和存储路径
这些操作属于环境准备阶段,与项目业务无关。将其提取为独立的基础镜像,可以:
- 消除每次构建时的重复下载和安装
- 减少构建时间,提升 CI/CD 效率
- 统一团队的基础环境配置
创建 pnpm 基础镜像
在项目根目录下创建 Dockerfile-pnpm:
FROM node:18-alpine
# 记录维护者信息
LABEL maintainer="admin <admin@example.com>"
# 安装 wget 并下载 pnpm
RUN apk add --no-cache wget \
&& wget -qO /bin/pnpm "https://github.com/pnpm/pnpm/releases/latest/download/pnpm-linuxstatic-x64" \
&& chmod +x /bin/pnpm \
&& apk del wget
# 清理安装过程中产生的缓存
RUN rm -rf /var/cache/apk/* /tmp/*
# 配置 pnpm 缓存目录和存储路径
RUN pnpm config set store-dir /home/node/.local/share/pnpm/store
# 设置工作目录
WORKDIR /home/node/app
dockerfile
关键要点:
apk add --no-cache:安装 wget 时不缓存索引apk del wget:安装完 pnpm 后立即卸载 wget,减小镜像体积- 清理
/var/cache/apk/*和/tmp/*:删除安装过程中产生的临时文件 - 设置
store-dir:指定 pnpm 的全局存储路径,便于后续构建时复用缓存
构建并推送基础镜像
# 构建基础镜像
docker build \
-f Dockerfile-pnpm \
-t your-registry/node:18-alpine-pnpm \
.
# 查看镜像大小
docker images | grep node
# your-registry/node 18-alpine-pnpm 约 180MB(比原始 Alpine 镜像大 54MB 左右)
# 推送到 Docker Hub
docker push your-registry/node:18-alpine-pnpm
bash
除了 Docker Hub,团队也可以使用私有 Registry:
- Harbor:企业级私有镜像仓库,支持 RBAC、镜像扫描、镜像签名
- GitHub Container Registry (ghcr.io):与 GitHub Actions 集成良好
- 阿里云容器镜像服务 (ACR):国内访问速度快
改造项目 Dockerfile 使用基础镜像
使用自定义基础镜像后,项目 Dockerfile 可以大幅简化:
改造前(需要手动安装 pnpm):
FROM node:18-alpine AS builder
USER node
WORKDIR /home/node/app
# 每次都要重复安装 pnpm
RUN apk add --no-cache wget \
&& wget -qO /bin/pnpm "..." \
&& chmod +x /bin/pnpm
dockerfile
改造后(直接使用基础镜像):
# 使用包含 pnpm 的自定义基础镜像
FROM your-registry/node:18-alpine-pnpm AS builder
USER node
WORKDIR /home/node/app
# 无需安装 pnpm,直接使用
COPY --chown=node:node package*.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
dockerfile
不再需要 ARG NODE_VERSION 定义、RUN wget 下载命令和权限配置。
工作目录权限问题
构建时可能遇到 pnpm install cannot open 错误,原因是工作目录权限不足。解决方法是在安装依赖前设置目录权限:
FROM your-registry/node:18-alpine-pnpm AS builder
# 设置工作目录权限
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
USER node
WORKDIR /home/node/app
COPY --chown=node:node package*.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
dockerfile
验证构建结果
# 使用新的 Dockerfile 构建项目镜像
docker build -t nest-starter:1.1 .
# 构建速度明显提升
# 原因:跳过了 pnpm 下载安装步骤
bash
小结
- 将 pnpm 安装和环境配置提取为独立的基础镜像
- 基础镜像约增加 54MB(包含 pnpm 二进制文件和配置)
- 推送到 Docker Hub 或私有 Registry 后,团队成员可直接拉取使用
- 项目 Dockerfile 简化后,构建速度提升、维护成本降低
- 注意设置工作目录权限,避免安装依赖时报权限错误
↑