3

I am packaging a rust app to a docker image to deploy to my server. I found the rust docker image size to be more than 1GB (larger than any other app using java and python). Why is the rust docker image so huge? I checked the layer and found the cargo build command takes more than 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"]

Is it possible to make the rust docker image smaller?

Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
Dolphin
  • 29,069
  • 61
  • 260
  • 539
  • 1
    Does this answer your question? [Why are Docker container images so large?](https://stackoverflow.com/questions/24394243/why-are-docker-container-images-so-large) – Stargateur Sep 11 '21 at 16:44

1 Answers1

20

The rust image is definitely not 1GB. From Dockerhub we can see that the images are far smaller. Your image is 1GB, because it contains all intermediate build artifacts which are not necessary for the functioning of the application - just check the size of the target folder on your PC

Rust image sizes:

+---------------+----------------+------------------+
|    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        |
+---------------+----------------+------------------+

The rust docker image contains the compiler, which you need to build your app, but you don;t have to package it with your final image. Nor you have to package all the temporary artifacts generated by the build process.

Solution

In order to reduce the final, production image, you have to use a multi-stage docker build:

  1. The first stage builds the image
  2. The second stage discards all irrelevant stuff and gets only the built application:
# 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"]

kmdreko
  • 42,554
  • 6
  • 57
  • 106
Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
  • 1
    They may have been looking at the output of `docker images`, which will indeed show the Rust image as being somewhere around `1.25 GB`. The `slim` variant shows as `602 MB`. – Herohtar Sep 13 '21 at 16:40
  • 2
    @Herohtar no, he is using `cargo run` which builds the app before running the debug build and generates a ton of build artifacts, which are not needed at all, but consume space. And neither is rustc, nor cargo. A distroless image, containing only the necessary app binaries is just several megabytes! – Svetlin Zarev Sep 13 '21 at 16:44
  • I'm not talking about the generated image, I'm talking about the actual Rust image (`rust:1.54`); it is large to begin with. But yes, building will definitely increase the size even more, and you are correct that multi-stage builds should be used to create an image containing the compiled program, as they will be much smaller. – Herohtar Sep 13 '21 at 16:47
  • He is correct. The 1.70.0 Rust Image is about 1.4G if you use `docker image ls` to see it and if you `docker save` it will cost about 1.4G disk space. Hence the compressed size does confuse me. But It should not be used as the base image for your rust program. That is for sure. – runzhi xiao Aug 02 '23 at 08:44
  • This multi-stage docker build reduced my image from 6GB to 36MB. – Jan Aug 09 '23 at 10:13