If you see below errors while running Rust app using Docker, this article is right for you:
error while loading shared libraries: libssl.so.3: cannot open shared object file: No such file or directory
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" }))
Anatomy
Reqwest document mentioned about requirements when running under Linux OS, where you need OpenSSL installed.
To supply OpenSSL, Rust official document provided 2 ways:
Vendored OpenSSL
Add below dependency to Cargo.toml
.
[dependencies]
openssl = { version = "0.10", features = ["vendored"] }
Automatic OpenSSL
Add below line to Dockerfile at stage of running app.
RUN apt-get update && apt-get install -y pkg-config libssl-dev
Either approach works fine and you can run the app successfully. However, when sending https requests, you will get below error:
unable to get local issuer certificate
A Debian image issue
This thread gives a good idea of what happens here. Essentially, the debian official image does not have ca certification package installed. To solve the issue, simply install the package in Dockerfile:
RUN apt-get update && apt-get install -y pkg-config libssl-dev && apt install -y ca-certificates
# or below if using vendored OpenSSL
# RUN apt-get update && apt install -y ca-certificates
Final Dockerfile
To build rust + actix-web + reqwest, below is what works for me:
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
reqwest = "0.12"
serde = { version = "1.0", features = ["derive"] }
openssl = { version = "0.10", features = ["vendored"] }
FROM 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
COPY --from=build /build/main ./
EXPOSE 8080
RUN apt-get update && apt install -y ca-certificates
CMD ./main
Leave a Reply