Skip to content

Commit 83bcf27

Browse files
authored
Add Dockerfile with multi-platform support (#14)
1 parent 888f9e2 commit 83bcf27

File tree

10 files changed

+395
-0
lines changed

10 files changed

+395
-0
lines changed

.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# exclude everything
2+
*
3+
4+
# include source files
5+
!/src
6+
!Cargo.lock
7+
!Cargo.toml
8+
!rustfmt.toml
9+
10+
# include for vergen constants
11+
!/.git
12+
13+
# include licenses
14+
!LICENSE
15+
16+
# include scripts
17+
!/scripts

.github/workflows/docker-build.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Reusable Docker Build
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
make-target:
7+
description: 'Makefile target to run'
8+
required: true
9+
type: string
10+
profile:
11+
description: 'Cargo profile to use'
12+
required: false
13+
type: string
14+
default: 'release'
15+
16+
env:
17+
IMAGE_NAME: ${{ github.repository_owner }}/bera-reth
18+
DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/bera-reth
19+
DOCKER_USERNAME: ${{ github.actor }}
20+
21+
jobs:
22+
docker-build:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout sources
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Docker Buildx
29+
uses: docker/setup-buildx-action@v3
30+
31+
- name: Set up QEMU
32+
uses: docker/setup-qemu-action@v3
33+
34+
- name: Set up Docker builder
35+
run: |
36+
docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64
37+
docker buildx create --use --name cross-builder
38+
39+
- name: Login to GitHub Container Registry
40+
uses: docker/login-action@v3
41+
with:
42+
registry: ghcr.io
43+
username: ${{ env.DOCKER_USERNAME }}
44+
password: ${{ secrets.GITHUB_TOKEN }}
45+
46+
- name: Set up Rust toolchain
47+
uses: dtolnay/rust-toolchain@stable
48+
49+
- name: Set up Rust cache
50+
uses: Swatinem/rust-cache@v2
51+
with:
52+
cache-on-failure: true
53+
54+
- name: Install cross
55+
run: cargo install cross --git https://github.com/cross-rs/cross
56+
57+
- name: Build and push Docker image
58+
run: DOCKER_IMAGE_NAME=${{ env.DOCKER_IMAGE_NAME }} PROFILE=${{ inputs.profile }} make ${{ inputs.make-target }}

.github/workflows/docker-git.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Docker Git SHA
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
docker-git:
8+
uses: ./.github/workflows/docker-build.yml
9+
with:
10+
make-target: docker-build-push-git-sha

.github/workflows/docker-nightly.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Docker Nightly
2+
3+
on:
4+
schedule:
5+
# Run at 1:00 AM UTC every day
6+
- cron: "0 1 * * *"
7+
workflow_dispatch:
8+
9+
jobs:
10+
docker-nightly:
11+
uses: ./.github/workflows/docker-build.yml
12+
with:
13+
make-target: docker-build-push-nightly
14+
profile: maxperf
15+
16+
docker-nightly-profiling:
17+
uses: ./.github/workflows/docker-build.yml
18+
with:
19+
make-target: docker-build-push-nightly-profiling
20+
profile: profiling

.github/workflows/docker.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
tags:
6+
- v*
7+
8+
jobs:
9+
docker-release-candidate:
10+
if: contains(github.ref, '-rc')
11+
uses: ./.github/workflows/docker-build.yml
12+
with:
13+
make-target: docker-build-push
14+
15+
docker-latest:
16+
if: ${{ !contains(github.ref, '-rc') }}
17+
uses: ./.github/workflows/docker-build.yml
18+
with:
19+
make-target: docker-build-push-latest

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ log = "0.4.27"
3333
serde = { version = "1.0", features = ["derive"], default-features = false }
3434
thiserror = "2.0"
3535

36+
[profile.maxperf]
37+
inherits = "release"
38+
lto = "fat"
39+
codegen-units = 1
40+
incremental = false
41+
42+
[profile.profiling]
43+
inherits = "release"
44+
debug = "full"
45+
strip = "none"
3646

3747
[patch.crates-io]
3848
#alloy-consensus = { git = "https://github.com/rezbera/alloy", branch ="BRIP-0002"}

Dockerfile

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# syntax=docker.io/docker/dockerfile:1.7-labs
2+
3+
# Support setting various labels on the final image
4+
ARG COMMIT=""
5+
ARG VERSION=""
6+
ARG BUILDNUM=""
7+
8+
FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef
9+
WORKDIR /app
10+
11+
LABEL org.opencontainers.image.source=https://github.com/berachain/bera-reth
12+
LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"
13+
14+
# Install system dependencies
15+
RUN apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config
16+
17+
# Builds a cargo-chef plan
18+
FROM chef AS planner
19+
COPY --exclude=.git --exclude=target . .
20+
RUN cargo chef prepare --recipe-path recipe.json
21+
22+
FROM chef AS builder
23+
COPY --from=planner /app/recipe.json recipe.json
24+
25+
# Build profile, release by default
26+
ARG BUILD_PROFILE=release
27+
ENV BUILD_PROFILE=$BUILD_PROFILE
28+
29+
# Extra Cargo flags for optimization and multi-platform support
30+
ARG RUSTFLAGS=""
31+
ARG TARGETPLATFORM
32+
ENV RUSTFLAGS="$RUSTFLAGS"
33+
34+
# Extra Cargo features
35+
ARG FEATURES=""
36+
ENV FEATURES=$FEATURES
37+
38+
# Configure target architecture based on platform
39+
RUN case "$TARGETPLATFORM" in \
40+
"linux/amd64") echo "x86_64-unknown-linux-gnu" > /tmp/target.txt ;; \
41+
"linux/arm64") echo "aarch64-unknown-linux-gnu" > /tmp/target.txt ;; \
42+
"linux/arm/v7") echo "armv7-unknown-linux-gnueabihf" > /tmp/target.txt ;; \
43+
*) echo "x86_64-unknown-linux-gnu" > /tmp/target.txt ;; \
44+
esac
45+
46+
# Install target for cross-compilation if needed
47+
RUN TARGET=$(cat /tmp/target.txt) && \
48+
if [ "$TARGET" != "x86_64-unknown-linux-gnu" ]; then \
49+
rustup target add $TARGET; \
50+
fi
51+
52+
# Builds dependencies
53+
RUN TARGET=$(cat /tmp/target.txt) && \
54+
cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --target $TARGET --recipe-path recipe.json
55+
56+
# Build application
57+
COPY --exclude=target . .
58+
RUN TARGET=$(cat /tmp/target.txt) && \
59+
cargo build --profile $BUILD_PROFILE --features "$FEATURES" --target $TARGET --locked --bin bera-reth
60+
61+
# ARG is not resolved in COPY so we have to hack around it by copying the
62+
# binary to a temporary location
63+
RUN TARGET=$(cat /tmp/target.txt) && \
64+
cp /app/target/$TARGET/$BUILD_PROFILE/bera-reth /app/bera-reth
65+
66+
# Use Ubuntu as the release image
67+
FROM ubuntu:22.04 AS runtime
68+
WORKDIR /app
69+
70+
# Install runtime dependencies
71+
RUN apt-get update && \
72+
apt-get install -y ca-certificates libssl-dev && \
73+
rm -rf /var/lib/apt/lists/*
74+
75+
# Copy bera-reth over from the build stage
76+
COPY --from=builder /app/bera-reth /usr/local/bin/
77+
RUN chmod +x /usr/local/bin/bera-reth
78+
79+
# Copy licenses
80+
COPY LICENSE ./
81+
82+
# Expose standard Ethereum execution client ports
83+
EXPOSE 30303 30303/udp 9001 8545 8546 8551
84+
85+
# Add metadata labels to help programmatic image consumption
86+
ARG COMMIT=""
87+
ARG VERSION=""
88+
ARG BUILDNUM=""
89+
LABEL commit="$COMMIT" version="$VERSION" buildnum="$BUILDNUM"
90+
91+
ENTRYPOINT ["/usr/local/bin/bera-reth"]

Dockerfile.cross

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# This image is meant to enable cross-architecture builds.
2+
# It assumes the bera-reth binary has already been compiled for `$TARGETPLATFORM` and is
3+
# locatable in `./dist/bin/$TARGETARCH`
4+
FROM --platform=$TARGETPLATFORM ubuntu:22.04
5+
6+
LABEL org.opencontainers.image.source=https://github.com/berachain/bera-reth
7+
LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"
8+
9+
# Filled by docker buildx
10+
ARG TARGETARCH
11+
12+
# Install runtime dependencies
13+
RUN apt-get update && \
14+
apt-get install -y ca-certificates libssl-dev && \
15+
rm -rf /var/lib/apt/lists/*
16+
17+
COPY ./dist/bin/$TARGETARCH/bera-reth /usr/local/bin/bera-reth
18+
RUN chmod +x /usr/local/bin/bera-reth
19+
20+
EXPOSE 30303 30303/udp 9001 8545 8546 8551
21+
ENTRYPOINT ["/usr/local/bin/bera-reth"]

Makefile

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,86 @@
11
#!/usr/bin/make -f
22

3+
###############################################################################
4+
### Variables ###
5+
###############################################################################
6+
7+
GIT_SHA ?= $(shell git rev-parse HEAD)
8+
GIT_TAG ?= $(shell git describe --tags --abbrev=0 2>/dev/null || echo "dev")
9+
BIN_DIR = "dist/bin"
10+
CARGO_TARGET_DIR ?= target
11+
PROFILE ?= release
12+
# Features: jemalloc (memory allocator), asm-keccak (optimized hashing), min-debug-logs (reduce log overhead)
13+
FEATURES ?= jemalloc asm-keccak min-debug-logs
14+
DOCKER_IMAGE_NAME ?= bera-reth
15+
16+
###############################################################################
17+
### Docker ###
18+
###############################################################################
19+
20+
# Note: This requires a buildx builder with emulation support. For example:
21+
#
22+
# `docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64`
23+
# `docker buildx create --use --driver docker-container --name cross-builder`
24+
.PHONY: docker-build-push
25+
docker-build-push: ## Build and push a cross-arch Docker image tagged with the latest git tag.
26+
$(call docker_build_push,$(GIT_TAG),$(GIT_TAG))
27+
28+
.PHONY: docker-build-push-latest
29+
docker-build-push-latest: ## Build and push a cross-arch Docker image tagged with the latest git tag and `latest`.
30+
$(call docker_build_push,$(GIT_TAG),latest)
31+
32+
.PHONY: docker-build-push-git-sha
33+
docker-build-push-git-sha: ## Build and push a cross-arch Docker image tagged with the latest git sha.
34+
$(call docker_build_push,$(GIT_SHA),$(GIT_SHA))
35+
36+
.PHONY: docker-build-local
37+
docker-build-local: ## Build a Docker image for local use.
38+
docker build --tag $(DOCKER_IMAGE_NAME):local \
39+
--build-arg COMMIT=$(GIT_SHA) \
40+
--build-arg VERSION=$(GIT_TAG) \
41+
--build-arg BUILD_PROFILE=$(PROFILE) \
42+
.
43+
44+
.PHONY: docker-build-push-nightly
45+
docker-build-push-nightly: ## Build and push cross-arch Docker image tagged with nightly.
46+
$(call docker_build_push,nightly,nightly)
47+
48+
.PHONY: docker-build-push-nightly-profiling
49+
docker-build-push-nightly-profiling: ## Build and push cross-arch Docker image with profiling profile tagged with nightly-profiling.
50+
$(call docker_build_push,nightly-profiling,nightly-profiling)
51+
52+
# Create a cross-arch Docker image with the given tags and push it
53+
define docker_build_push
54+
$(MAKE) build-x86_64-unknown-linux-gnu
55+
mkdir -p $(BIN_DIR)/amd64
56+
cp $(CARGO_TARGET_DIR)/x86_64-unknown-linux-gnu/$(PROFILE)/bera-reth $(BIN_DIR)/amd64/bera-reth
57+
58+
$(MAKE) build-aarch64-unknown-linux-gnu
59+
mkdir -p $(BIN_DIR)/arm64
60+
cp $(CARGO_TARGET_DIR)/aarch64-unknown-linux-gnu/$(PROFILE)/bera-reth $(BIN_DIR)/arm64/bera-reth
61+
62+
docker buildx build --file ./Dockerfile.cross . \
63+
--platform linux/amd64,linux/arm64 \
64+
--tag $(DOCKER_IMAGE_NAME):$(1) \
65+
--tag $(DOCKER_IMAGE_NAME):$(2) \
66+
--build-arg COMMIT=$(GIT_SHA) \
67+
--build-arg VERSION=$(GIT_TAG) \
68+
--provenance=false \
69+
--push
70+
endef
71+
72+
# Cross-compilation targets
73+
build-x86_64-unknown-linux-gnu:
74+
cargo install cross --git https://github.com/cross-rs/cross || true
75+
RUSTFLAGS="-C link-arg=-lgcc -Clink-arg=-static-libgcc" \
76+
cross build --bin bera-reth --target x86_64-unknown-linux-gnu --features "$(FEATURES)" --profile "$(PROFILE)"
77+
78+
build-aarch64-unknown-linux-gnu: export JEMALLOC_SYS_WITH_LG_PAGE=16
79+
build-aarch64-unknown-linux-gnu:
80+
cargo install cross --git https://github.com/cross-rs/cross || true
81+
RUSTFLAGS="-C link-arg=-lgcc -Clink-arg=-static-libgcc" \
82+
cross build --bin bera-reth --target aarch64-unknown-linux-gnu --features "$(FEATURES)" --profile "$(PROFILE)"
83+
384
###############################################################################
485
### Tests & Simulation ###
586
###############################################################################

0 commit comments

Comments
 (0)