Rust:用多阶段构建方式优化Docker镜像大小
使用 Docker 部署应用程序时,则需要遵循一些最佳实践。
每条指令Dockerfile大致翻译为一个层:
RUN apt-get update |
每条RUN指令都会创建一个新层。
优化目标是降低层数:
RUN apt-get update \ |
这样,层数就减少到一层。
Docker在 Docker 17.06 CE 中引入了多阶段构建。此功能可以帮助在容器化应用程序时优化 Docker 映像。
多阶段构建可以减少构建后文件大小。
如何实现多阶段构建?
将构建过程分为两个阶段:
- 在第一阶段,构建应用程序并获取二进制文件。除了二进制文件外,不需要生成依赖关系和任何其他文件。
- 在第二阶段,将构建最终镜像,二进制文件从第一阶段复制,是唯一包含的文件。
这就是多阶段编译的工作原理。每个 FROM 指令都可以使用不同的基础镜像。
FROM rust:latest AS builder |
在第一阶段:
- 以 rust:latest 镜像为基础,将阶段命名为 builder
- 工作目录设置为 /app
- 复制清单(Cargo.toml)
- 创建临时 src 目录和 main.rs 文件
- 启动构建进程,生成依赖项缓存
- 复制应用程序代码
- 将 main.rs 文件的访问和修改时间戳更新为当前时间
- 构建应用程序
- 删除二进制文件中不必要的信息,从而减小文件大小,并增加逆向工程的难度
在第二阶段:
- 以 alpine:latest 镜像为基础,将阶段命名为 release
- 工作目录设置为 /app
- 从第一阶段复制二进制文件
- 设置 ROCKET_ADDRESS 环境变量
- 设置 ROCKET_PORT 环境变量
- 暴露主机中的 8000 端口
- 指定容器启动时要运行的命令
上述多阶段构建可将镜像文件从2GB减小到11.2MB。这就是通过多阶段构建来优化 Rust 容器化应用程序的方法,并且此功能可以与任何编译的编程语言一起使用。