diff --git a/Dockerfile b/Dockerfile index d3c2aec..bcb36d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,34 @@ -FROM --platform=$BUILDPLATFORM rust:1.84 AS rust_fetcher +# This is the example Dockerfile for building the multi arch Envoy image with the Rust dynamic module. -WORKDIR /app +# Use https://github.com/rust-cross/cargo-zigbuild to cross-compile the Rust library for both x86_64 and aarch64 architectures. +# We need it because bindgen relies on the sysroot of the target architecture which makes it +# a bit hairy to cross-compile. +# +# If you don't need multi-arch support, you can use simply `FROM rust:x.y.z` and `cargo build` on the host architecture or, +# compile the shared library on each architecture separately and copy the shared library to the final image. +FROM --platform=$BUILDPLATFORM ghcr.io/rust-cross/cargo-zigbuild:0.19.8 AS rust_builder -# Cache dependencies by copying only the Cargo files and fetching them on the build platform. +WORKDIR /build + +# bindgen requires libclang-dev. +RUN apt update && apt install -y clang + +# Fetch the dependencies first to leverage Docker cache. COPY ./rust/Cargo.toml ./rust/Cargo.lock ./ RUN mkdir src && echo "" > src/lib.rs RUN cargo fetch RUN rm -rf src -FROM rust:1.84 AS rust_builder - -# We need libclang to do the bindgen. -RUN apt update && apt install -y clang - -# Copy the dependencies from the previous stage. -WORKDIR /app -COPY --from=rust_fetcher /usr/local/cargo/git /usr/local/cargo/git -COPY --from=rust_fetcher /usr/local/cargo/registry /usr/local/cargo/registry - -# Then, copy the entire source code and build. +# Then copy the rest of the source code and build the library. COPY ./rust . -RUN cargo build +RUN cargo zigbuild --target aarch64-unknown-linux-gnu +RUN cargo zigbuild --target x86_64-unknown-linux-gnu + +RUN cp /build/target/aarch64-unknown-linux-gnu/debug/librust_module.so /build/arm64_librust_module.so +RUN cp /build/target/x86_64-unknown-linux-gnu/debug/librust_module.so /build/amd64_librust_module.so # Finally, copy the built library to the final image. FROM envoyproxy/envoy-dev:4a113b5118003682833ba612202eb68628861ac6 AS envoy +ARG TARGETARCH ENV ENVOY_DYNAMIC_MODULES_SEARCH_PATH=/usr/local/lib -COPY --from=rust_builder /app/target/debug/librust_module.so /usr/local/lib/librust_module.so +COPY --from=rust_builder /build/${TARGETARCH}_librust_module.so /usr/local/lib/librust_module.so diff --git a/README.md b/README.md index fe473a1..fe5ea31 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ cargo clippy -- -D warnings cargo fmt --all -- --check ``` -### Build Envoy + Rust Dynamic Module Docker Image +### Build Envoy + Example Rust Dynamic Module Docker Image To build the example modules and bundle them with Envoy, simply run @@ -41,7 +41,7 @@ docker buildx build . -t envoy-with-dynamic-modules:latest [--platform linux/amd where `--platform` is optional and can be used to build for multiple platforms. -### Run Envoy + Rust Dynamic Module Docker Image +### Run Envoy + Example Rust Dynamic Module Docker Image The example Envoy configuration yaml is in [`integration/envoy.yaml`](integration/envoy.yaml) which is also used to run the integration tests. Assuming you built the Docker image with the tag `envoy-with-dynamic-modules:latest`, you can run Envoy with the following command: