确保拥有轻量级的 Docker 镜像可以加快 Docker 容器的构建和部署。在构建 Docker 镜像时,你可以使用一些方法,在不影响性能的情况下减小其大小。本文将向你传授瘦身 Docker 镜像的最佳策略和技巧。如果你正在寻找一种更简单的方法来管理你的 Docker 镜像,那么本文就是为你量身定制的。
Docker 镜像可以让你轻松地将应用程序部署到不同的基础设施,如 Kubernetes 集群、云平台和 CI/CD 管道。在部署和管理应用程序时,这些 Docker 镜像的大小很重要。大的镜像会带来限制,必须扩大存储容量,从而导致费用增加。应用程序的 Docker 镜像大小会影响性能、可扩展性、可移植性等关键方面,并可能导致安全漏洞。
2.具备使用 Docker 的基本知识。
优化 Docker 镜像并将其缩小到最小尺寸,可以大大减少构建和推送镜像所需的成本和时间。在本节中,我们将讨论缩小 Docker 镜像并减小其大小的不同策略。在此之前,你需要创建一个可以使用的 Docker 镜像。
FROM node:19 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 4000 CMD npm start运行以下命令来构建应用程序镜像:
# 堆代码 duidaima.com docker build -t node_example .使用以下命令检查镜像是否创建成功:
docker images node_example为该应用程序创建的镜像大小如下:
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest a10aa8869a21 39 seconds ago 1.16GB要运行这么小的应用程序,这个镜像实在是太大了。让我们为这个 Docker 镜像瘦身吧。
基础镜像是创建 Docker 镜像的起点,通常包括底层操作系统以及任何必要的软件和软件包。Docker 的常用基础镜像包括 Alpine Linux、Ubuntu、Debian、CentOS 和 Fedora。在 Docker 中运行 Node.js 应用程序时,一个常见的基础镜像是 Docker Hub 上提供的 Node.js 官方镜像。不过,Node.js 还提供其他带有不同标签的变体镜像发行版,从而使 Docker 基础镜像更加精简。
这些标签包括:
Bullseye:提供 Debian 发行版,以减少镜像需要安装的软件包数量,从而减小自定义镜像的整体大小。FROM node:19-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 4000 CMD npm start将此应用到 Dockerfile 中,可减少镜像大小,如下所示:
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest a10aa8869a21 39 seconds ago 338.7MB你使用的每个基础镜像都会提供其发行版。请确保你经常检查提供小型镜像构建的基础镜像标签。
仔细观察,Docker 并不需要复制所有这些文件夹和文件。例如,DockerFile 中的 RUN npm run build 命令将创建应用程序构建文件夹,而 RUN npm install 命令将创建 node_modules 文件夹。因此,在构建 Docker 镜像时不需要复制这些文件。复制的每个文件夹和文件都会增加镜像的大小。最好避免不必要的复制。
node_modules Dockerfile build重建镜像并检查大小:
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest c1b36fb72af3 12 seconds ago 264MB因此,在 .dockerignore 文件中添加不必要的文件可以创建更小的 Docker 镜像。至此,最初 1.16GB 的镜像已减至 264MB。
FROM node:19-alpine WORKDIR /app COPY package*.json ./ COPY . . RUN yarn install RUN npm run build RUN rm -rf node_modules RUN npm install --production EXPOSE 4000 CMD npm start这将创建以下大小的图像,以备使用:
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest fbebed577ab2 2 minutes ago 266.34MB这些新命令为 Docker 镜像添加了更多层。
FROM node:19-alpine WORKDIR /app COPY package*.json ./ COPY . . RUN npm install && \ npm run build && \ rm -rf node_modules && \ npm install --production EXPOSE 4000 CMD npm start
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest bd92d29f12ff 2 minutes ago 194MB使用多阶段构建来精简 Docker 镜像
Dockerfile 是构建 Docker 镜像的基础。它们为 Docker 打包应用程序指定了必要的指令。传统上,应用程序遵循构建模式来捆绑其资源,这意味着你需要构建应用程序代码,以确定如何在生产环境中提供服务。在遵循构建模式的同时使用 Docker 意味着你必须创建两个 Dockerfile 才能完全打包应用程序。因此,最终会创建两个镜像,每个镜像都占用各自的磁盘空间。
以本指南中使用的 TypeScript 应用程序为例。TypeScript 必须编译成 JavaScript 后才能执行。因此,你需要两个 Dockerfile 用于开发和生产。一个 Dockerfile 用于打包编译阶段的应用程序,另一个 Dockerfile 用于在生产环境中运行编译后的代码。此外,在许多情况下,生产环境所需的依赖关系与开发环境所需的依赖关系不同。因此,通常使用单独的 Dockerfile 来指定这些依赖关系。
#Stage One: Build FROM node:19-alpine AS builder WORKDIR /app COPY . . RUN npm install RUN npm run build #Stage Two: Final FROM node:19-alpine AS final WORKDIR /app COPY --from=builder ./app/build ./build COPY package*.json ./ RUN npm install --production CMD npm start在本例中,第一阶段创建了应用程序构建。第二阶段将复制该构建,以创建最终镜像。生成器阶段将在第一阶段创建镜像。使用 COPY --from=builder 后,最后阶段将复制第一阶段的结果,并将其用于打包生产中的最终镜像。
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest b066d92ab741 2 minutes ago 181MB
多阶段构建并不局限于使用同一基础镜像的相同 FROM 语句。它可用于同时对多个应用程序进行 dockerize,以最大限度地降低总体资源利用率。这个多阶段构建示例使用 Node。js 和 Nginx 基本镜像的两个 FROM 语句来实现多阶段构建概念。
docker build --target builder -t node_example:dev . docker build --target final -t node_example:prod .使用工具缩小 Docker 镜像大小
docker build . -t node_example --squash这将把最终镜像压缩为一个层。在运行 --squash 之前,请确保 experimental 设置为 true。这是因为 --squash 功能是 Docker 的一项实验性功能。它并不完全受支持,可能会导致与某些 Docker 注册表或工具的兼容性问题。
REPOSITORY TAG IMAGE ID CREATED SIZE node_example latest b066d92ab741 1 minutes ago 162MB你可以查看如何使用 DockerSlim 将当前镜像大小(162MB)进一步缩小到约 91.5%。
5.减少 Docker 镜像大小的工具