为了账号安全,请及时绑定邮箱和手机立即绑定

Docker镜像瘦身:让部署更快更省心

介绍.

几个月之前,在为客户进行关键部署时,我们碰到了一个意外的问题:部署过程特别慢。问题的根源在于臃肿的Docker镜像。这不仅令人沮丧,还带来了我们无法承受的停机时间。

这段经历让我学到了重要的一课:小改动可以产生大影响。通过优化 Docker 镜像,我们成功地将部署时间缩短了一半,节省了存储费用,并提高了 CI/CD 流水线的整体效率。今天,我将分享我们实现这一转变所采取的策略。

……

为什么我们要优化 Docker 镜像?

如果你曾经遇到过构建变慢、部署时间长或注册表空间中充斥着过大镜像的问题,你不是唯一一个遇到这种情况的人。那么,减少镜像大小的原因何其重要?

  1. 更快的构建: 开发周期变得更短,让您能够专注于重要的事情。
  2. 高效的存储: 更小的镜像占用的Docker注册表和机器上的磁盘空间更少。
  3. 更快的部署: 通过网络部署更小的镜像速度更快,更有效率。
  4. 增强的安全性: 组件更少,意味着潜在的安全漏洞也更少。

此处省略内容

那一天我们终于瘦身了Docker镜像

我记得我们优化之后第一次运行 docker images 的时候。看到“优化前”和“优化后”的大小变化,就像健身几周后上秤称重一样——能明显感觉到变化,感觉非常有成就感。这种感觉真的很棒。

以下是我们的确切步骤,以实现那个转变:

……

7 种有效优化 Docker 镜像的方法

1. 选择最小的基镜像

我们不再以 ubuntu:latest 或其他大型镜像为基础,而是切换到了 alpine。这一改动将镜像大小从 800MB 减少到不到 30MB。

例子:

FROM alpine:latest  # 从最新的 Alpine 镜像拉取基础镜像

点击全屏按钮,然后点击退出全屏按钮

……

2. 采用多阶段构建过程

在许多项目中,例如一个 React 应用程序,我们可能有一些构建所需的依赖项(如 Node.js 和 npm),这些依赖项仅在构建过程中需要,生产环境中则不需要。通过采用多阶段构建,我们可以将构建环境和运行时环境分开,从而生成更小的镜像。

示例:

在此示例中,我们将为一个 React 应用程序采用多阶段构建流程。

    # 构建阶段
    FROM node:16 AS builder
    WORKDIR /app
    COPY package.json package-lock.json ./
    # 复制 package.json 和 package-lock.json 到当前目录下
    RUN npm install
    COPY . .
    # 运行 npm 构建命令
    RUN npm run build

    # 运行时阶段
    FROM nginx:alpine
    # 从构建器阶段复制构建后的文件到 nginx 的 html 目录
    COPY --from=builder /app/build /usr/share/nginx/html
    # 启动 nginx 并设置守护进程为关闭状态
    CMD ["nginx", "-g", "daemon off;"]

全屏 退出全屏

上面的Dockerfile

  • 利用官方的 node:16 版本,安装所需的依赖,构建 React 应用,并生成静态内容。

  • 第二个阶段使用更小的 nginx:alpine 镜像来提供已构建的 React 应用。

这种逐步的方法保证了最终镜像中仅包含必要的构建产物(构建文件夹),从而使镜像尽可能小,同时优化生产环境。

此处为空白或仅包含格式符号,请参见原文。

3. 清理不必要的文件

调试时,我们常常在构建中包含临时文件。通过添加一个 .dockerignore 文件,我们确保这些文件就不会被误打包进镜像里。

例如 .dockerignore:

    node_modules  # 忽略node_modules文件夹
    *.log        # 忽略所有.log文件
    .git         # 忽略.git文件夹

这些行用于在版本控制系统中排除不需要跟踪的文件和文件夹。

切换到全屏 退出全屏

此处为空

4. 合并并减少图层

每个 Dockerfile 中的指令(例如 RUNCOPYADD)都会在 Docker 镜像中添加一个新的层。过多的层会导致镜像体积增大。通过将多个指令合并为一个 RUN 语句,这样可以减少层数并优化镜像。

示例:

不要写:

    RUN apt-get update  # 更新软件包列表
    RUN apt-get install -y curl vim  # 安装 curl 和 vim 工具
    RUN apt-get clean  # 清理 apt 缓存
    RUN rm -rf /var/lib/apt/lists/*  # 删除 apt 列表文件

切换到全屏模式 退出全屏

把它们合并成一个:

RUN apt-get update && apt-get install -y curl vim \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

点击进入全屏
点击退出全屏

这种方法尽量减少层数,并确保临时文件(如缓存)在同一层内被清除,从而使镜像文件更小且更整洁。

省略了部分内容

5. 避免安装不必要的依赖

最初,我们的Docker镜像包含了一些额外的库“以防万一”。随着时间的推移,我们意识到这导致了镜像变得过大以及不必要的安全隐患。通过只指定运行时实际需要的依赖项,我们让镜像变得更小和更安全。

例如,我们没有为每个项目安装许多库,而是关注最小的依赖,并避免安装不必要的包。


6. 这个步骤可以试试 docker-slim.

docker-slim 成为了我们过程中的一个变革者。这个工具能自动分析你的镜像,并通过移除未使用的文件、二进制文件和库等不必要的部分来减小镜像的大小,而不会影响其功能。

我们用 docker-slim 将图像大小减少了最多 80%,这使得 docker-slim 成为我们优化策略中的重要工具。

要缩小图像的命令:

使用 docker-slim build <image-name> 命令来构建镜像。将 <image-name> 替换为实际的镜像名称。

    docker-slim build <image-name>

点击这里进入全屏模式 点击这里退出全屏模式


7. 定期审查并修剪图像

Docker 镜像会随着时间的推移而积累,未使用的镜像或层会占据宝贵的磁盘空间。定期检查和清理未使用的镜像有助于保持环境整洁。

你可以通过运行下面的命令来删除多余的图片和图层:

清理未使用的镜像的命令示例:

docker system prune -f

这将强制删除Docker系统中未使用的资源。

进入全屏 退出全屏

删除所有未用图片的命令:

docker image prune -a -f  # 删除所有未使用的 Docker 镜像

进入全屏退出全屏

通过将定期剪枝纳入你的日常工作,你可以确保你的 Docker 环境始终保持简洁高效。


衡量成功

在实施了这些优化之后,我们用docker images命令来比较大小。结果令人惊讶。

  • 优化之前: 1.2GB
  • 优化之后: 250MB

不仅我们的部署更快了,云存储成本也降低了。


总结

优化 Docker 镜像可能看起来像是一个不重要的任务,但它能为你带来巨大的好处,特别是在工作流程上。不论你是独自开发还是在一个大团队中工作,这些策略都能带来真正的不同。

所以,你还等什么?跳进去看看你的 Dockerfile,开始优化工作,享受更快捷部署带来的好处吧。


参考文献
  1. Docker 官方文档页面
  2. Dockerfile 编写最佳实践

📖 喜欢这篇博客吗? 你也可以在我的 Hashnode 上阅读我的文章,也可以在那里关注我了解更多技术见解!🚀


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消