diff --git a/Cargo.toml b/Cargo.toml index 57794c2db1..86cca0a259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -298,5 +298,12 @@ lto = "fat" codegen-units = 1 incremental = false +[profile.reproducible] +inherits = "release" +debug = false +panic = "abort" +codegen-units = 1 +overflow-checks = true + [patch.crates-io] quick-protobuf = { git = "https://github.com/sigp/quick-protobuf.git", rev = "681f413312404ab6e51f0b46f39b0075c6f4ebfd" } diff --git a/Dockerfile.reproducible b/Dockerfile.reproducible new file mode 100644 index 0000000000..df57616874 --- /dev/null +++ b/Dockerfile.reproducible @@ -0,0 +1,44 @@ +# Define the Rust image as an argument with a default to x86_64 Rust 1.82 image based on Debian Bullseye +ARG RUST_IMAGE="rust:1.82-bullseye@sha256:ac7fe7b0c9429313c0fe87d3a8993998d1fe2be9e3e91b5e2ec05d3a09d87128" +FROM ${RUST_IMAGE} AS builder + +# Install specific version of the build dependencies +RUN apt-get update && apt-get install -y libclang-dev=1:11.0-51+nmu5 cmake=3.18.4-2+deb11u1 + +# Add target architecture argument with default value +ARG RUST_TARGET="x86_64-unknown-linux-gnu" + +# Copy the project to the container +COPY . /app +WORKDIR /app + +# Get the latest commit timestamp and set SOURCE_DATE_EPOCH (default it to 0 if not passed) +ARG SOURCE_DATE=0 + +# Set environment variables for reproducibility +ARG RUSTFLAGS="-C link-arg=-Wl,--build-id=none -C metadata='' --remap-path-prefix $(pwd)=." +ENV SOURCE_DATE_EPOCH=$SOURCE_DATE \ + CARGO_INCREMENTAL=0 \ + LC_ALL=C \ + TZ=UTC \ + RUSTFLAGS="${RUSTFLAGS}" + +# Set the default features if not provided +ARG FEATURES="gnosis,slasher-lmdb,slasher-mdbx,slasher-redb,jemalloc" + +# Set the default profile if not provided +ARG PROFILE="reproducible" + +# Build the project with the reproducible settings +RUN cargo build --bin lighthouse \ + --features "${FEATURES}" \ + --profile "${PROFILE}" \ + --locked \ + --target "${RUST_TARGET}" + +RUN mv /app/target/${RUST_TARGET}/${PROFILE}/lighthouse /lighthouse + +# Create a minimal final image with just the binary +FROM gcr.io/distroless/cc-debian12:nonroot-6755e21ccd99ddead6edc8106ba03888cbeed41a +COPY --from=builder /lighthouse /lighthouse +ENTRYPOINT [ "/lighthouse" ] diff --git a/Makefile b/Makefile index 03bf33a6d8..fe5dfbe551 100644 --- a/Makefile +++ b/Makefile @@ -82,6 +82,37 @@ build-lcli-aarch64: build-lcli-riscv64: cross build --bin lcli --target riscv64gc-unknown-linux-gnu --features "portable" --profile "$(CROSS_PROFILE)" --locked +# extracts the current source date for reproducible builds +SOURCE_DATE := $(shell git log -1 --pretty=%ct) + +# Default image for x86_64 +RUST_IMAGE_AMD64 ?= rust:1.82-bullseye@sha256:ac7fe7b0c9429313c0fe87d3a8993998d1fe2be9e3e91b5e2ec05d3a09d87128 + +# Reproducible build for x86_64 +build-reproducible-x86_64: + DOCKER_BUILDKIT=1 docker build \ + --build-arg RUST_TARGET="x86_64-unknown-linux-gnu" \ + --build-arg RUST_IMAGE=$(RUST_IMAGE_AMD64) \ + --build-arg SOURCE_DATE=$(SOURCE_DATE) \ + -f Dockerfile.reproducible \ + -t lighthouse:reproducible-amd64 . + +# Default image for arm64 +RUST_IMAGE_ARM64 ?= rust:1.82-bullseye@sha256:3c1b8b6487513ad4e753d008b960260f5bcc81bf110883460f6ed3cd72bf439b + +# Reproducible build for aarch64 +build-reproducible-aarch64: + DOCKER_BUILDKIT=1 docker build \ + --platform linux/arm64 \ + --build-arg RUST_TARGET="aarch64-unknown-linux-gnu" \ + --build-arg RUST_IMAGE=$(RUST_IMAGE_ARM64) \ + --build-arg SOURCE_DATE=$(SOURCE_DATE) \ + -f Dockerfile.reproducible \ + -t lighthouse:reproducible-arm64 . + +# Build both architectures +build-reproducible-all: build-reproducible-x86_64 build-reproducible-aarch64 + # Create a `.tar.gz` containing a binary for a specific target. define tarball_release_binary cp $(1)/lighthouse $(BIN_DIR)/lighthouse