0

I am trying to dockerise a simple server written in Rust using Rocket. I managed to get a simple image working but found the image size to be massive. When trying to shrink it I have tried two different things, both seems to result in the same issue. docker exec <name> exited with code 126 It seems like the arbdata.exe file is not being copied across properly.

working Dockerfile (big image)

FROM rust

COPY . /app

WORKDIR /app

RUN cargo build --release

CMD ["./target/release/arb_data"]

first attempt at smaller image

FROM rust as builder
WORKDIR /app
COPY ./ /app
RUN cargo build --release
# gcr.io/distroless/cc-debian11
# rust:slim-buster
# FROM gcr.io/distroless/cc
FROM gcr.io/distroless/cc
COPY --from=builder /app/target/release/arb_data .
CMD ["./arb_data"]

second attempt at a smaller image

ARG BINARY_NAME_DEFAULT=arbdata

FROM clux/muslrust:stable as builder
RUN groupadd -g 10001 -r dockergrp && useradd -r -g dockergrp -u 10001 dockeruser
ARG BINARY_NAME_DEFAULT
ENV BINARY_NAME=$BINARY_NAME_DEFAULT

# Build the project with target x86_64-unknown-linux-musl

# Build dummy main with the project's Cargo lock and toml
# This is a docker trick in order to avoid downloading and building 
# dependencies when lock and toml not is modified.
COPY Cargo.lock .
COPY Cargo.toml .
RUN mkdir src \
    && echo "fn main() {print!(\"Dummy main\");} // dummy file" > src/main.rs
RUN set -x && cargo build --target x86_64-unknown-linux-musl --release
RUN ["/bin/bash", "-c", "set -x && rm target/x86_64-unknown-linux-musl/release/deps/${BINARY_NAME//-/_}*"]

# Now add the rest of the project and build the real main
COPY src ./src
RUN set -x && cargo build --target x86_64-unknown-linux-musl --release
RUN mkdir -p /build-out
RUN set -x && cp target/x86_64-unknown-linux-musl/release/$BINARY_NAME /build-out/

# Create a minimal docker image 
FROM scratch

COPY --from=0 /etc/passwd /etc/passwd
USER dockeruser

ARG BINARY_NAME_DEFAULT
ENV BINARY_NAME=$BINARY_NAME_DEFAULT

ENV RUST_LOG="error,$BINARY_NAME=info"
COPY --from=builder /build-out/$BINARY_NAME /

# Start with an execution list (there is no sh in a scratch image)
# No shell => no variable expansion, |, <, >, etc 
# Hard coded start command
CMD ["/arbdata"]

here is a link to the github repo with the working api.

streetRAT
  • 23
  • 6
  • 1
    Great, so you started with glibc based distribution and tried to run your app on musl, it didn't work. So now you start with musl, and try to run on scratch? Choose one, just `FROM glibc`. – KamilCuk Jul 03 '22 at 22:56
  • Not really sure what you’re saying. Do you have any links that I could read please? What is glibc? Sorry I’m new to docker and not really understanding the finer details yet. Why are none of these images working? – streetRAT Jul 03 '22 at 23:03

2 Answers2

2

When you want to use a docker image without any libc available, you'll need to statically link your application. This can easily be done like this:

FROM rust:slim AS builder

ENV TARGET x86_64-unknown-linux-musl
RUN rustup target add "$TARGET"

# copy all your source files ...

RUN cargo build --release --locked --target "$TARGET"

# and then copy it to an empty docker image
FROM scratch
COPY --from=builder /path/to/binary/arb_data /bin/arb_data
RUN ["/bin/arb_data"]

You can find a full example here: https://github.com/msrd0/docker-element/blob/main/Dockerfile

I recommend you do not use rust:alpine image. It contains a broken version of the rust compiler that refuses dynamic linking not just for the final version but during the entire build process, resulting in the inability to use procedural macros (like serde_derive).

msrd0
  • 7,816
  • 9
  • 47
  • 82
  • thanks for your response, what is the purpose of the --locked flag? the compile is not passing that point (: as for the link, I really wish that made more sense to me. I am very new to docker. The when I do remove the --locked flag the compile stops at openssl-sys v0.9.74. any suggestions? I did try addidn `apk add --no-chache openssl-dev` which installed but the error persisted. thanks – streetRAT Jul 06 '22 at 10:22
  • @streetRAT openssl is very much incompatible with static linking. I'd recommend you try to use rustls instead, most crates offer feature flags for that – msrd0 Jul 06 '22 at 11:23
  • The --locked flag makes cargo use the Cargo.lock file as is and disallows editing/adjusting its contents. This is common practice for release builds – msrd0 Jul 06 '22 at 11:24
1

Rust docker image on ubuntu, you can't run executable from ubuntu on alpine. Try:

FROM rust
COPY . /app
WORKDIR /app
RUN cargo build --release
FROM glibc
COPY --from=builder /app/target/release/arb_data /
CMD ["/arb_data"]

Alternatively, compile and built on musl, we have alpine rust image https://registry.hub.docker.com/_/rust/ :

FROM rust:alpine
COPY . /app
WORKDIR /app
RUN cargo build --release
FROM alpine
COPY --from=builder /app/target/release/arb_data /
CMD ["/arb_data"]

You may want to read https://en.wikipedia.org/wiki/Glibc, https://en.wikipedia.org/wiki/Musl, Why can't I run a C program built on alpine on ubuntu?, Why can't I execute binary copied into a container?, https://en.wikipedia.org/wiki/Dynamic_linker, What is the role of libc(glibc) in our linux app? etc.

You could also statically link C runtime, in which case, you can scratch. How to generate statically linked executables? .

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Thank you for the great response. Is this the same reason gct.io/distroless/cc didn’t work? Also, why is there a “? I know nothing about rust” is that an error message? Thanks – streetRAT Jul 04 '22 at 07:25
  • `Is this the same reason gct.io/distroless/cc didn’t work?` No idea. `why is there a “? I know nothing about rust” is that an error message?` I do not know how to pass options to cargo, removed that part. – KamilCuk Jul 04 '22 at 07:29
  • thanks for the response. I can't get this to work and can't really see why. All the links you provided were definitely helpful for providing some context but as a windows user I don't really understand the finer points of linux. The bigger issue at the moment is that the rust image page example is completely over my head. – streetRAT Jul 04 '22 at 09:25