When using reqwest crate and building docker images with Dockerfile mentioned in this article, you will encounter openssl issues due to missing packages.
Error: could not find system library 'openssl' required by the 'openssl-sys' crate
It turns out that below line is the culprit:
FROM docker.io/rust:1-slim-bookworm AS build
#############################################
rust:1-slim-bookworm
misses lots of necessary package to run the application. It is suggested in official Rust docker image document that we should avoid using slim
image.
Simple but ugly solution
Well, the simplest approach is using a minimal Dockerfile which will always work:
FROM rust:bookworm
COPY . .
RUN cargo build --release
EXPOSE 8080
CMD ./target/release/your_package
However, it will generate a pretty large image which can take gigabytes of storage.
The better one
We can still use multi stage build to generate an optimal image with a little tweak (using default rust image version rust:bookworm
):
FROM docker.io/rust:bookworm AS build
## cargo package name: customize here or provide via --build-arg
ARG pkg=hello-world
WORKDIR /build
COPY . .
RUN --mount=type=cache,target=/build/target \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
set -eux; \
cargo build --release; \
objcopy --compress-debug-sections target/release/$pkg ./main
################################################################################
FROM docker.io/debian:bookworm-slim
WORKDIR /app
## copy the main binary
## add more files below if needed
COPY --from=build /build/main ./
EXPOSE 8080
CMD ./main
Now it builds fine, but you will get a runtime error when running reqwest
:
./main: error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory
Furthermore, after installing correct packages either vendored or automatic, you will still see error when sending https requests:
hyper_util::client::legacy::Error(Connect, Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 167772294, library: "SSL routines", function: "tls_post_process_server_certificate", reason: "certificate verify failed", file: "ssl/statem/statem_clnt.c", line: 2092 }]))) }, X509VerifyResult { code: 20, error: "unable to get local issuer certificate" }))
To solve these issues, I separately wrote an article for detailed explanation and solutions.