为什么Rust Docker镜像如此庞大

4

我正在将一个 Rust 应用程序打包成 Docker 镜像,以部署到我的服务器。我发现 Rust 的 Docker 镜像大小超过了 1GB(比使用 Java 和 Python 的任何其他应用程序都要大)。为什么 Rust 的 Docker 镜像这么大?我检查了层,并发现 cargo build 命令占用了 400MB 以上的空间。

FROM rust:1.54

LABEL maintainer="jiangtingqiang@gmail.com" 

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=11014 

WORKDIR /app
COPY . .

RUN rustup default stable
RUN cargo build

CMD ["cargo", "run"]

有可能让 Rust Docker 镜像变小吗?


1
这个回答解决了你的问题吗?为什么Docker容器镜像如此庞大? - Stargateur
1个回答

21

Rust镜像绝对不是1GB。从Dockerhub上我们可以看到其镜像要小得多。你的镜像有1GB,因为它包括了所有中间构建产物,这些都不是应用程序运行所必需的 - 只需检查PC上的target文件夹的大小即可。

Rust镜像大小:

+---------------+----------------+------------------+
|    Digest     |     OS/ARCH    |  Compressed Size |
+---------------+----------------+------------------+
| 99d3d924303a  | linux/386      | 265.43 MB        |
| 852ba83a6e49  | linux/amd64    | 196.74 MB        |
| 6eb0fe2709a2  | linux/arm/v7   | 256.59 MB        |
| 2a218d86ec85  | linux/arm64/v8 | 280.22 MB        |
+---------------+----------------+------------------+

Rust Docker镜像中包含编译器,您需要用它来构建应用程序,但您不必将其与最终镜像打包在一起。您也不必打包构建过程中生成的所有临时文件。

解决方案

为了减少最终生产镜像的大小,您需要使用多阶段Docker构建:

  1. 第一阶段构建图像
  2. 第二个阶段放弃所有无关紧要的内容,仅获取已构建的应用程序:
# Build stage
FROM rust:1.54 as builder
WORKDIR /app
ADD . /app
RUN cargo build --release

# Prod stage
FROM gcr.io/distroless/cc
COPY --from=builder /app/target/release/app-name /
CMD ["./app-name"]


1
他们可能一直在查看 docker images 的输出,这确实会显示 Rust 镜像的大小约为 1.25 GB。而 slim 变体则显示为 602 MB - Herohtar
2
@Herohtar 不是的,他正在使用 cargo run 命令,在运行调试构建之前构建应用程序并生成大量的构建产物,这些产物完全不需要,但会占用空间。而且既不需要 rustc,也不需要 cargo。一个只包含必要应用程序二进制文件的 distroless 镜像只有几兆字节大小! - Svetlin Zarev
我说的不是生成的图像,而是实际的 Rust 镜像 (rust:1.54);它本来就很大。但是,构建肯定会使大小增加更多,你正确地指出了应该使用多阶段构建来创建包含编译程序的镜像,因为它们会更小。 - Herohtar
他是正确的。如果你使用docker image ls来查看,1.70.0版的Rust镜像大约有1.4G大小,并且如果你使用docker save命令保存它,将会占用大约1.4G的磁盘空间。因此,压缩后的大小让我感到困惑。但是这绝对不应该作为你的Rust程序的基础镜像来使用,这一点是确定的。 - runzhi xiao
这个多阶段的Docker构建将我的镜像从6GB减小到了36MB。 - Jan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接