From 23fea1482a0a620af006e9e3a79615f5665b43bb Mon Sep 17 00:00:00 2001 From: Francesco Guardiani Date: Mon, 4 May 2020 14:38:59 +0200 Subject: [PATCH] Rust MUSL support (#526) * Rust MUSL support Signed-off-by: Francesco Guardiani * Changed version Signed-off-by: Francesco Guardiani * Added sccache usage to speedup builds Signed-off-by: Francesco Guardiani * Modified path in launch.json Signed-off-by: Francesco Guardiani * Changed APPSODY_RUN_ON_CHANGE Signed-off-by: Francesco Guardiani * Production image uses user nobody Signed-off-by: Francesco Guardiani Co-authored-by: Sandy Koh --- experimental/rust/README.md | 4 ++- experimental/rust/image/Dockerfile-stack | 16 ++++++---- experimental/rust/image/project/Dockerfile | 30 +++++++++++-------- experimental/rust/stack.yaml | 2 +- .../rust/templates/simple/.vscode/launch.json | 2 +- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/experimental/rust/README.md b/experimental/rust/README.md index b4c62dd47..dc6a50630 100644 --- a/experimental/rust/README.md +++ b/experimental/rust/README.md @@ -2,7 +2,9 @@ The Rust stack provides a consistent way of developing [Rust](https://rust-lang.org/) applications. -This stack is based on the `Rust v1.37` runtime and allows you to develop new or existing Rust applications using Appsody. +This stack is based on the `Rust v1.39` runtime and allows you to develop new or existing Rust applications using Appsody. + +The Rust stack uses [Rust MUSL support](https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/musl-support-for-fully-static-binaries.html) to build fully static binaries with statically linked libc, making the built images really small. ## Templates diff --git a/experimental/rust/image/Dockerfile-stack b/experimental/rust/image/Dockerfile-stack index e78220820..770546afe 100644 --- a/experimental/rust/image/Dockerfile-stack +++ b/experimental/rust/image/Dockerfile-stack @@ -1,22 +1,26 @@ -FROM rust:1.37 +FROM rust:1.39 -RUN apt-get update && apt-get install -y lldb +RUN apt-get update && apt-get install -y lldb musl-tools +RUN rustup target add x86_64-unknown-linux-musl +RUN cargo install sccache ENV CARGO_HOME=/usr/local/cargo/deps +ENV SCCACHE_DIR=/project/sccache +ENV RUSTC_WRAPPER=sccache -ENV APPSODY_MOUNTS=.:/project/user-app +ENV APPSODY_MOUNTS=.:/project/user-app;~/.cache/sccache:/project/sccache ENV APPSODY_DEPS=$CARGO_HOME ENV APPSODY_WATCH_DIR="/project/user-app" ENV APPSODY_WATCH_REGEX="^(Cargo.toml|.*.rs)$" -ENV APPSODY_RUN="cargo run" -ENV APPSODY_RUN_ON_CHANGE="cargo run" +ENV APPSODY_RUN="cargo run --target x86_64-unknown-linux-musl" +ENV APPSODY_RUN_ON_CHANGE="$APPSODY_RUN" ENV APPSODY_RUN_KILL=true ENV APPSODY_TEST="cargo test" -ENV APPSODY_DEBUG="cargo build && lldb-server platform --listen '*:1234' --min-gdbserver-port 5000 --max-gdbserver-port 5001 --server" +ENV APPSODY_DEBUG="cargo build --target x86_64-unknown-linux-musl && lldb-server platform --listen '*:1234' --min-gdbserver-port 5000 --max-gdbserver-port 5001 --server" ENV APPSODY_DEBUG_ON_CHANGE="$APPSODY_DEBUG" ENV APPSODY_DEBUG_KILL=true diff --git a/experimental/rust/image/project/Dockerfile b/experimental/rust/image/project/Dockerfile index 17a2657fe..8732b35a8 100644 --- a/experimental/rust/image/project/Dockerfile +++ b/experimental/rust/image/project/Dockerfile @@ -1,4 +1,8 @@ -FROM rust:1.37 as builder +FROM rust:1.39 as builder + +# Install musl +RUN apt-get update && apt-get install -y musl-tools +RUN rustup target add x86_64-unknown-linux-musl WORKDIR "/project/user-app" @@ -12,25 +16,27 @@ RUN cargo fetch COPY /user-app/src ./src # build for release -RUN cargo build --release \ - && echo "#!/bin/bash" > run.sh \ - && bin=$(find ./target/release -maxdepth 1 -perm -111 -type f| head -n 1) \ - && echo ./${bin##*/} >> run.sh \ - && chmod 755 run.sh +RUN cargo build --release --target x86_64-unknown-linux-musl \ + && cp $(find ./target/x86_64-unknown-linux-musl/release -maxdepth 1 -perm -111 -type f| head -n 1) ./target/app \ + && chmod 755 ./target/app -FROM rust:1.37-slim-stretch +# Create a "nobody" non-root user for the next image by crafting an /etc/passwd +# file that the next image can copy in. This is necessary since the next image +# is based on scratch, which doesn't have adduser, cat, echo, or even sh. +RUN echo "nobody:x:65534:65534:Nobody:/:" > /etc_passwd -RUN useradd rust +FROM scratch WORKDIR "/project/user-app" # get files and built binary from previous image -COPY --from=builder /project/user-app/run.sh /project/user-app/Cargo.toml /project/user-app/target/release/ ./ - -USER rust +COPY --from=builder /project/user-app/target/app ./ +COPY --from=builder /etc_passwd /etc/passwd ENV PORT 8000 +USER nobody + EXPOSE 8000 -CMD ["./run.sh"] \ No newline at end of file +CMD ["./app"] \ No newline at end of file diff --git a/experimental/rust/stack.yaml b/experimental/rust/stack.yaml index fa01d247d..883b3a70a 100644 --- a/experimental/rust/stack.yaml +++ b/experimental/rust/stack.yaml @@ -1,5 +1,5 @@ name: Rust -version: 0.1.6 +version: 0.2.0 description: Runtime for Rust applications license: Apache-2.0 language: rust diff --git a/experimental/rust/templates/simple/.vscode/launch.json b/experimental/rust/templates/simple/.vscode/launch.json index 02fed8c97..2be9c4f02 100644 --- a/experimental/rust/templates/simple/.vscode/launch.json +++ b/experimental/rust/templates/simple/.vscode/launch.json @@ -9,7 +9,7 @@ "initCommands": [ "platform select remote-linux", "platform connect connect://localhost:1234", - "platform settings -w /project/user-app/target/debug" + "platform settings -w /project/user-app/target/x86_64-unknown-linux-musl/debug" ], "targetCreateCommands": [ "file rust-simple"