如何优化Docker镜像的大小详解

 更新时间:2025年03月07日 09:59:21   作者:Student Li  
本文详细介绍了Docker的定义和优点,以及如何通过优化Docker镜像来提高其轻量化和便携性,通过使用轻量化基础镜像和多阶段构建,可以显著减小Docker镜像的大小,从而提高部署和运行效率

什么是Docker

Docker是一个开源的虚拟化平台,可以让开发人员将应用程序和依赖项打包在轻量级容器中,然后可以轻松地在任何环境中运行。这样,开发人员可以将容器作为独立的可移植单元在不同的环境中部署和运行应用程序,而不用担心环境的差异会对应用程序的行为产生影响。例如,您可以使用Docker在开发环境中测试应用程序,然后将容器部署到生产环境中运行。总之,Docker可以让开发人员更轻松地创建、部署和运行应用程序。

  • 灵活性:即使是最复杂的应用程序也可以容器化。
  • 轻量化:容器共享主机内核,使得它们远比虚拟机高效。
  • 便携性:可以做到本地编译,到处运行。松耦合:容器自我封装,一个容器被替换或升级不会打断别的容器。
  • 安全性:容器对进程进行了严格的限制和隔离,而无需用户进行任何配置。

在这篇文章中,我将重点讨论如何优化 Docker 镜像以使其轻量化。

优化过程

让我们从一个示例开始,在该示例中,我们构建了一个 React 应用程序并将其容器化。运行 npx 命令并创建 Dockerfile 之后,我们得到了如图 1 所示的文件结构。

npx create-react-app app --template typescript

如果我们构建一个基础的 Dockerfile(如下所示),我们最终会得到一个 1.16 GB 的镜像:

FROM node:10   
WORKDIR /app  
COPY app /app  
RUN npm install -g webserver.local  
RUN npm install && npm run build   
EXPOSE 3000  
CMD webserver.local -d ./build

第一步优化:使用轻量化基础镜像

在 Docker Hub(公共 Docker 仓库)中,有一些镜像可供下载,每个镜像都有不同的特征和大小。

通常,相较于基于其他 Linux 发行版(例如 Ubuntu)的镜像,基于 Alpine 或 BusyBox 的镜像非常小。这是因为 Alpine 镜像和类似的其他镜像都经过了优化,其中仅包含最少的必须的软件包。

在下面的图片中,你可以看到 Ubuntu、Alpine、Node 和基于 Alpine 的 Node 镜像之间的大小比较。

通过修改 Dockerfile 并使用 Alpine 作为基础镜像,我们的镜像最终大小为 330MB:

FROM node:10-alpine   
WORKDIR /app  
COPY app /app  
RUN npm install -g webserver.local  
RUN npm install && npm run build   
EXPOSE 3000  
CMD webserver.local -d ./build

第二步优化:多阶段构建

通过多阶段构建,我们可以在 Dockerfile 中使用多个基础镜像,并将编译成品、配置文件等从一个阶段复制到另一个阶段,这样我们就可以丢弃不需要的东西。

我们部署 React 应用程序需要的是编译后的代码,我们不需要源文件,也不需要 node_modules 目录和 package.json 文件等。

通过将 Dockerfile 修改为如下内容,我们最终得到的镜像大小为 91.5MB。请记住,来自第一阶段(第 1-4 行)的镜像不会被自动删除,Docker 将它保存在 cache 中,如果我们在另一个构建镜像过程中执行了相同的阶段,就可以使镜像构建更快。所以你必须手动删除第一阶段镜像。

FROM node:10-alpine AS build  
WORKDIR /app  
COPY app /app  
RUN npm install && npm run build    
FROM node:10-alpineWORKDIR /app  
RUN npm install -g webserver.local  
COPY --from=build /app/build ./build  
EXPOSE 3000  
CMD webserver.local -d ./build

现在我们有了一个 Dockerfile,它有两个阶段:在第一个阶段中,我们编译项目,在第二个阶段中,我们在 web 服务器上部署应用程序。

然而,Node 容器并不是提供网页(HTML、CSS 和 JavaScript 文件、图片等)服务的最佳选择,最好的选择是使用像 Nginx 或 Apache 这样的服务。在本例中,我将使用 Nginx。

通过将 Dockerfile 修改为如下内容,我们的镜像最终大小是 22.4MB,如果我们运行这个容器,我们可以看到网页可以正常工作,没有任何问题。

FROM node:10-alpine AS build  
WORKDIR /app  
COPY app /app  
RUN npm install && npm run build    
FROM nginx:stable-alpine  
COPY --from=build /app/build /usr/share/nginx/html  
EXPOSE 80  
CMD ["nginx", "-g", "daemon off;"]

最终容器的运行结果

总结

您可以使用多种方法来优化Docker镜像大小。

这里列举几种常用的方法:

  1. 使用基础镜像:选择一个较小的基础镜像来作为您的应用程序的镜像。这样,您的镜像就不会包含多余的文件和依赖项。
  2. 使用多个镜像:将您的应用程序拆分成多个镜像,每个镜像只包含一个特定的功能。这样,您就可以在运行时动态加载镜像,而不需要在每个镜像中都包含所有功能。
  3. 压缩镜像:使用压缩工具对镜像进行压缩,可以节省镜像的空间。
  4. 清理无用文件:在构建镜像时,确保只包含必需的文件和依赖项。在构建过程中,可以使用命令来清理缓存和无用的文件。
  5. 使用 alpine 版本的镜像:alpine 版本的镜像比普通版本的镜像要小得多,因为它们只包含基本的 Linux 系统功能。因此,您可以使用 alpine 版本的镜像来构建您的应用程序。
  6. 删除不必要的依赖项:在构建镜像时,确保只安装必需的依赖

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • docker images导入导出方式

    docker images导入导出方式

    这篇文章主要介绍了docker images导入导出方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • docker实现buildx构建多平台(x86,arm64)构架镜像

    docker实现buildx构建多平台(x86,arm64)构架镜像

    这篇文章主要介绍了docker实现buildx构建多平台(x86,arm64)构架镜像,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-09-09
  • docker安装RabbitMQ详细步骤

    docker安装RabbitMQ详细步骤

    大家好,本篇文章主要讲的是docker安装RabbitMQ详细步骤,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • docker容器资源限制与容器内的dotnet应用线程限制

    docker容器资源限制与容器内的dotnet应用线程限制

    文章指出因docker-compose资源限制配置错误(如误将cpu设为0.5导致线程过多),引发redis超时问题,同时微服务中大key、热key等不合理操作加剧redis性能瓶颈,需优化代码和容器参数设置
    2025-09-09
  • Docker构建Java镜像并部署Java项目的完整步骤

    Docker构建Java镜像并部署Java项目的完整步骤

    这篇文章主要给大家介绍了关于Docker构建Java镜像并部署Java项目的完整步骤,Docker是一种容器化技术,可以帮助开发者轻松打包应用程序和依赖项,并在任何地方运行它们,需要的朋友可以参考下
    2023-10-10
  • Docker 网络模式及配置方式

    Docker 网络模式及配置方式

    这篇文章主要介绍了Docker 网络模式及配置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Docker使用编写dockerfile启动node.js应用

    Docker使用编写dockerfile启动node.js应用

    这篇文章主要介绍了Docker使用编写dockerfile启动node.js应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • docker 连接宿主Mysql操作

    docker 连接宿主Mysql操作

    这篇文章主要介绍了docker 连接宿主Mysql操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • docker迁移数据目录的方法步骤

    docker迁移数据目录的方法步骤

    本文主要介绍了docker迁移数据目录的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • docker容器挂载宿主主机目录的操作方法

    docker容器挂载宿主主机目录的操作方法

    这篇文章主要介绍了docker容器挂载宿主主机目录的操作方法,本文给大家介绍的非常详细,具有参考借鉴价值,需要的朋友参考下吧
    2018-01-01

最新评论