Error while executing rust in docker

I have Debian 12 on my server and running a Docker container with my Rust binary. But after changing nothing relevant I got the following error:

error while loading shared libraries: 
libz.so.1: cannot open shared object file: No such file or directory

I already tried to install the required file but that did not help.

What base image is your container using? Alpine uses musl instead of glibc so you'd have to change target

rust:slim-buster at Build Stage and gcr.io/distroless/cc at Production Stage

The binary you're running that gives the error - what target was it compiled for? By default, Cargo will use Glibc, which means the binary will only be able to run on systems that have Glibc installed. Alpine images don't have Glibc for example. To get more self-sufficient binaries, build them for musl:

$ rustup target add x86_64-unknown-linux-musl
$ cargo build --release --target=x86_64-unknown-linux-musl

Then the only dependency of your binary will be on the minimal Linux kernel version. Not only is this a good approach to be able to run on Alpine, but it's also good to avoid requiring a specific Glibc version even if the system has Glibc installed.

At the same time, keep in mind Musl can be either buggy or limited in functionality compared to Glibc, in particular recently they fixed a problem in Musl that broke DNS in some cases. Just - be aware.

rust:slim-buster is Debian IMHO

I ran it on my local machine again and that works well

The error indicates that your program depends on libz, but the container doesn't have libz installed. This dynamic library is a common C implementation of the gzip compression format.

But I installed it
Here is my Dockerfile:

# Build stage, TODO: actix middleware logger einbauen
FROM rust:slim-buster as builder

RUN apt-get update && \
  # here zlib1g
  apt-get install -y pkg-config make g++ libssl-dev cmake libmariadb-dev-compat zlib1g && \
  rustup target add x86_64-unknown-linux-gnu

WORKDIR /var/www/app

COPY . .

RUN cargo build --release --bin app

# Prod stage, removing the Rust toolchain
FROM gcr.io/distroless/cc

COPY --from=builder /var/www/app/config /config
COPY --from=builder /var/www/app/.env /.env
COPY --from=builder /var/www/app/target/release/app /

CMD ["./app"]

The problem isn't your build image, but the production one. distroless/cc doesn't have libz installed.

2 Likes

But I also used it before the error appeared

I assume you added a dependency to your Cargo.toml (or added a feature for an already existing one) that needs libz installed. Anything that enables compression.

But it is correct to install libz in Docker as far as I know and on my local machine is no problem but on the server. And it is installed on my host machine and on the server with the same Dockerfile

As @jofas said, you installed the package on the builder stage but not on the prod stage. libz is dynamically linked in your app so the shared lib must be present on the prod container as well. You should add something like this to the prod stage:

COPY --from=builder /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/libz.so.1
3 Likes

I will try it. But why does is work on my local machine without doing this step. Thats my confusion.

Because your local machine already has libz installed.

So that step is more a prevention to install in every machine manually I see

I'm not sure I understand what you mean. Containers run a different execution environment than your machine, and the distroless image you're using doesn't have libz bundled. Most distros (and even most container base images) do bundle it, it's the specific one you're using that doesn't. But in general, when linking with shared libraries you have to make sure they are installed in your target environment.

1 Like

Maybe that's the point.

Because your local machine already has libz installed.

My local machine has installed libz but distroless does not using it? This should mean that it will not work on my host machine because distroless does not get libz from my host machine. It should only work if I install or copy it to distroless. But it worked without installing or copying.

But this is the wrong Forum to discuss.

COPY --from=builder /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/libz.so.1

That did not solve the problem

We solved the problem by changing to rust:slim-buster in our production stage