Building a docker image of a "Hello World" Rust app

To practice Rust, I wanted to first have a simple Rust app in a container to begin.
I managed to build the binary without issue, but once built, it doesn't run with the following message :

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found

Below are the details

My current Rust version is :

> cargo --version
cargo 1.78.0 (54d8815d0 2024-03-26)

I make a new Rust project :

> cargo new testing
    Creating binary (application) `testing` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

I add some dependencies in the toml file :

[package]
name = "testing"
version = "0.1.0"
edition = "2021"

[dependencies]
diesel = "2.1.6"
serde = { version = "1.0.202", features = ["derive"] }

I make the following dockerfile :

# Use a Rust base image with Cargo installed
FROM rust:1.78.0 AS builder

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy the Cargo.toml and Cargo.lock files
COPY Cargo.toml Cargo.lock ./

# Create an empty src directory to trick Cargo into thinking it's a valid Rust project
RUN mkdir src && echo "fn main() {}" > src/main.rs

# Build the dependencies without the actual source code to cache dependencies separately
RUN cargo build --release

# Now copy the source code
COPY ./src ./src

# Build your application
RUN cargo build --release

# Start a new stage to create a smaller image without unnecessary build dependencies
FROM debian:buster-slim

# Set the working directory
WORKDIR /usr/src/app

# Copy the built binary from the previous stage
COPY --from=builder /usr/src/app/target/release/testing./

# Command to run the application
CMD ["./testing"]

I build the image and everything seems fine :

> docker build -t my-rust-app -f .\.dockerfile .
[+] Building 0.7s (12/12) FINISHED                                                                       docker:default
 => [internal] load build definition from .dockerfile-testing                                                      0.0s
 => => transferring dockerfile: 638B                                                                               0.0s
 => [internal] load metadata for docker.io/library/rust:1.78.0                                                     0.4s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [1/7] FROM docker.io/library/rust:1.78.0@sha256:5907e96b0293eb53bcc8f09b4883d71449808af289862950ede9a0e3cca44  0.0s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 115B                                                                                  0.0s
 => CACHED [2/7] WORKDIR /usr/src/app                                                                              0.0s
 => CACHED [3/7] COPY Cargo.toml Cargo.lock ./                                                                     0.0s
 => CACHED [4/7] RUN mkdir src && echo "fn main() {}" > src/main.rs                                                0.0s
 => CACHED [5/7] RUN cargo build --release                                                                         0.0s
 => CACHED [6/7] COPY ./src ./src                                                                                  0.0s
 => CACHED [7/7] RUN cargo build --release                                                                         0.0s
 => exporting to image                                                                                             0.2s
 => => exporting layers                                                                                            0.2s
 => => writing image sha256:8a66f914a8036fca1c91796e786b1de3da13cbe2be9d8cf4bfae4992604ac916                       0.0s
 => => naming to docker.io/library/my-rust-app                                                                     0.0s

What's Next?
  View a summary of image vulnerabilities and recommendations → docker scout quickview

Then open an interactive terminal inside it :

> docker run -it my-rust-app /bin/bash

Now when I start the binary called testing and I get some errors :

> ./testing
./testing: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./testing)
./testing: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./testing)
./testing: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./testing)

I probably forgot something very obvious ?
Which step you think I should add of modify here ?
Any suggestion is welcomed.

Debian buster is too old. Use debian:bookworm-slim instead.

1 Like

I replaced buster by bookworm as you suggested.

Now I don't have the error anymore, thanks.

Although, now I have nothing in my output after I execute the binary inside the final container, when I was actually expecting a "Hello World" printed.

> ./testing

/* empty output instead of Hello World */

Try to remove that step and try again. Whenever you are debugging anything, you should try to reduce the error surface as much as possible.

1 Like

You were right again.
Thank you.

I don't remember where I saw the recommendation to execute a cargo build once before adding the project code, but it seems it only made things harder for me.

Now, the app does print Hello World as expected.
:slight_smile:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.