From 9285f7eafc9b2bf59be4c1e8a1514abe86615474 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 23 Jan 2026 21:14:55 +0000 Subject: [PATCH] ci: use depot for docker (#20380) Co-authored-by: Georgios Konstantopoulos --- .github/workflows/docker-git.yml | 54 ---------- .github/workflows/docker-nightly.yml | 65 ------------ .github/workflows/docker.yml | 145 ++++++++++++++------------- Dockerfile.depot | 86 ++++++++++++++++ docker-bake.hcl | 104 +++++++++++++++++++ 5 files changed, 264 insertions(+), 190 deletions(-) delete mode 100644 .github/workflows/docker-git.yml delete mode 100644 .github/workflows/docker-nightly.yml create mode 100644 Dockerfile.depot create mode 100644 docker-bake.hcl diff --git a/.github/workflows/docker-git.yml b/.github/workflows/docker-git.yml deleted file mode 100644 index 68bcdad0df..0000000000 --- a/.github/workflows/docker-git.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Publishes the Docker image, only to be used with `workflow_dispatch`. The -# images from this workflow will be tagged with the git sha of the branch used -# and will NOT tag it as `latest`. - -name: docker-git - -on: - workflow_dispatch: {} - -env: - REPO_NAME: ${{ github.repository_owner }}/reth - IMAGE_NAME: ${{ github.repository_owner }}/reth - OP_IMAGE_NAME: ${{ github.repository_owner }}/op-reth - CARGO_TERM_COLOR: always - DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/reth - OP_DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/op-reth - DOCKER_USERNAME: ${{ github.actor }} - GIT_SHA: ${{ github.sha }} - -jobs: - build: - name: build and push - runs-on: ubuntu-24.04 - permissions: - packages: write - contents: read - strategy: - fail-fast: false - matrix: - build: - - name: 'Build and push the git-sha-tagged reth image' - command: 'make PROFILE=maxperf GIT_SHA=$GIT_SHA docker-build-push-git-sha' - - name: 'Build and push the git-sha-tagged op-reth image' - command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME GIT_SHA=$GIT_SHA PROFILE=maxperf op-docker-build-push-git-sha' - steps: - - uses: actions/checkout@v6 - - uses: rui314/setup-mold@v1 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Install cross main - id: cross_main - run: | - cargo install cross --git https://github.com/cross-rs/cross - - name: Log in to Docker - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username ${DOCKER_USERNAME} --password-stdin - - name: Set up Docker builder - run: | - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 - docker buildx create --use --name cross-builder - - name: Build and push ${{ matrix.build.name }} - run: ${{ matrix.build.command }} diff --git a/.github/workflows/docker-nightly.yml b/.github/workflows/docker-nightly.yml deleted file mode 100644 index 67d276f094..0000000000 --- a/.github/workflows/docker-nightly.yml +++ /dev/null @@ -1,65 +0,0 @@ -# Publishes the nightly Docker image. - -name: docker-nightly - -on: - workflow_dispatch: - schedule: - - cron: "0 1 * * *" -env: - REPO_NAME: ${{ github.repository_owner }}/reth - IMAGE_NAME: ${{ github.repository_owner }}/reth - OP_IMAGE_NAME: ${{ github.repository_owner }}/op-reth - CARGO_TERM_COLOR: always - DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/reth - OP_DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/op-reth - DOCKER_USERNAME: ${{ github.actor }} - -jobs: - build: - name: build and push - runs-on: ubuntu-24.04 - permissions: - packages: write - contents: read - strategy: - fail-fast: false - matrix: - build: - - name: 'Build and push the nightly reth image' - command: 'make PROFILE=maxperf docker-build-push-nightly' - - name: 'Build and push the nightly edge profiling reth image' - command: 'make PROFILE=profiling docker-build-push-nightly-edge-profiling' - - name: 'Build and push the nightly profiling reth image' - command: 'make PROFILE=profiling docker-build-push-nightly-profiling' - - name: 'Build and push the nightly op-reth image' - command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=maxperf op-docker-build-push-nightly' - - name: 'Build and push the nightly edge profiling op-reth image' - command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=profiling op-docker-build-push-nightly-edge-profiling' - - name: 'Build and push the nightly profiling op-reth image' - command: 'make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=profiling op-docker-build-push-nightly-profiling' - steps: - - uses: actions/checkout@v6 - - name: Remove bloatware - uses: laverdet/remove-bloatware@v1.0.0 - with: - docker: true - lang: rust - - uses: rui314/setup-mold@v1 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Install cross main - id: cross_main - run: | - cargo install cross --git https://github.com/cross-rs/cross - - name: Log in to Docker - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username ${DOCKER_USERNAME} --password-stdin - - name: Set up Docker builder - run: | - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 - docker buildx create --use --name cross-builder - - name: Build and push ${{ matrix.build.name }} - run: ${{ matrix.build.command }} \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e922677225..3b8f5b4e9b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,9 @@ -# Publishes the Docker image. +# Publishes Docker images. +# +# Triggers: +# - Push tag v*: builds release (RC or latest) +# - Schedule: builds nightly + profiling +# - Manual: builds git-sha or nightly name: docker @@ -6,84 +11,82 @@ on: push: tags: - v* - -env: - IMAGE_NAME: ${{ github.repository_owner }}/reth - OP_IMAGE_NAME: ${{ github.repository_owner }}/op-reth - CARGO_TERM_COLOR: always - DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/reth - OP_DOCKER_IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/op-reth - DOCKER_USERNAME: ${{ github.actor }} + schedule: + - cron: "0 1 * * *" + workflow_dispatch: + inputs: + build_type: + description: "Build type" + required: true + type: choice + options: + - git-sha + - nightly + default: git-sha + dry_run: + description: "Skip pushing images (dry run)" + required: false + type: boolean + default: false jobs: - build-rc: - if: contains(github.ref, '-rc') - name: build and push as release candidate - runs-on: ubuntu-24.04 - permissions: - packages: write - contents: read - strategy: - fail-fast: false - matrix: - build: - - name: "Build and push reth image" - command: "make IMAGE_NAME=$IMAGE_NAME DOCKER_IMAGE_NAME=$DOCKER_IMAGE_NAME PROFILE=maxperf docker-build-push" - - name: "Build and push op-reth image" - command: "make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=maxperf op-docker-build-push" - steps: - - uses: actions/checkout@v6 - - uses: rui314/setup-mold@v1 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - - name: Install cross main - id: cross_main - run: | - cargo install cross --git https://github.com/cross-rs/cross - - name: Log in to Docker - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username ${DOCKER_USERNAME} --password-stdin - - name: Set up Docker builder - run: | - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 - docker buildx create --use --name cross-builder - - name: Build and push ${{ matrix.build.name }} - run: ${{ matrix.build.command }} - build: - if: ${{ !contains(github.ref, '-rc') }} - name: build and push as latest + name: Build Docker images runs-on: ubuntu-24.04 permissions: packages: write contents: read - strategy: - fail-fast: false - matrix: - build: - - name: "Build and push reth image" - command: "make IMAGE_NAME=$IMAGE_NAME DOCKER_IMAGE_NAME=$DOCKER_IMAGE_NAME PROFILE=maxperf docker-build-push-latest" - - name: "Build and push op-reth image" - command: "make IMAGE_NAME=$OP_IMAGE_NAME DOCKER_IMAGE_NAME=$OP_DOCKER_IMAGE_NAME PROFILE=maxperf op-docker-build-push-latest" + id-token: write steps: - uses: actions/checkout@v6 - - uses: rui314/setup-mold@v1 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 + + - name: Set up Depot CLI + uses: depot/setup-action@v1 + + - name: Log in to GHCR + uses: docker/login-action@v3 with: - cache-on-failure: true - - name: Install cross main - id: cross_main + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Determine build parameters + id: params run: | - cargo install cross --git https://github.com/cross-rs/cross - - name: Log in to Docker - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io --username ${DOCKER_USERNAME} --password-stdin - - name: Set up Docker builder - run: | - docker run --privileged --rm tonistiigi/binfmt --install arm64,amd64 - docker buildx create --use --name cross-builder - - name: Build and push ${{ matrix.build.name }} - run: ${{ matrix.build.command }} + REGISTRY="ghcr.io/${{ github.repository_owner }}" + + if [[ "${{ github.event_name }}" == "push" ]]; then + VERSION="${GITHUB_REF#refs/tags/}" + echo "targets=ethereum optimism" >> "$GITHUB_OUTPUT" + + # Add 'latest' tag for non-RC releases + if [[ ! "$VERSION" =~ -rc ]]; then + echo "ethereum_tags=${REGISTRY}/reth:${VERSION},${REGISTRY}/reth:latest" >> "$GITHUB_OUTPUT" + echo "optimism_tags=${REGISTRY}/op-reth:${VERSION},${REGISTRY}/op-reth:latest" >> "$GITHUB_OUTPUT" + else + echo "ethereum_tags=${REGISTRY}/reth:${VERSION}" >> "$GITHUB_OUTPUT" + echo "optimism_tags=${REGISTRY}/op-reth:${VERSION}" >> "$GITHUB_OUTPUT" + fi + + elif [[ "${{ github.event_name }}" == "schedule" ]] || [[ "${{ inputs.build_type }}" == "nightly" ]]; then + echo "targets=nightly" >> "$GITHUB_OUTPUT" + echo "ethereum_tags=${REGISTRY}/reth:nightly" >> "$GITHUB_OUTPUT" + echo "optimism_tags=${REGISTRY}/op-reth:nightly" >> "$GITHUB_OUTPUT" + + else + # git-sha build + echo "targets=ethereum optimism" >> "$GITHUB_OUTPUT" + echo "ethereum_tags=${REGISTRY}/reth:${{ github.sha }}" >> "$GITHUB_OUTPUT" + echo "optimism_tags=${REGISTRY}/op-reth:${{ github.sha }}" >> "$GITHUB_OUTPUT" + fi + + - name: Build and push images + uses: depot/bake-action@v1 + with: + project: ${{ vars.DEPOT_PROJECT_ID }} + files: docker-bake.hcl + targets: ${{ steps.params.outputs.targets }} + push: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }} + set: | + ethereum.tags=${{ steps.params.outputs.ethereum_tags }} + optimism.tags=${{ steps.params.outputs.optimism_tags }} diff --git a/Dockerfile.depot b/Dockerfile.depot new file mode 100644 index 0000000000..46b76d5473 --- /dev/null +++ b/Dockerfile.depot @@ -0,0 +1,86 @@ +# syntax=docker.io/docker/dockerfile:1.7-labs + +# Unified Dockerfile for reth and op-reth, optimized for Depot builds +# Usage: +# reth: --build-arg BINARY=reth +# op-reth: --build-arg BINARY=op-reth --build-arg MANIFEST_PATH=crates/optimism/bin + +FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef +WORKDIR /app + +LABEL org.opencontainers.image.source=https://github.com/paradigmxyz/reth +LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0" + +RUN apt-get update && apt-get install -y libclang-dev pkg-config + +# Install sccache for compilation caching +RUN cargo install sccache --locked +ENV RUSTC_WRAPPER=sccache +ENV SCCACHE_DIR=/sccache + +# Builds a cargo-chef plan +FROM chef AS planner +COPY --exclude=.git . . +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +COPY --from=planner /app/recipe.json recipe.json + +# Binary to build (reth or op-reth) +ARG BINARY=reth + +# Manifest path for the binary +ARG MANIFEST_PATH=bin/reth + +# Build profile, release by default +ARG BUILD_PROFILE=release +ENV BUILD_PROFILE=$BUILD_PROFILE + +# Extra Cargo flags +ARG RUSTFLAGS="" +ENV RUSTFLAGS="$RUSTFLAGS" + +# Extra Cargo features +ARG FEATURES="" +ENV FEATURES=$FEATURES + +# Build dependencies with cache mounts +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --locked --recipe-path recipe.json --manifest-path $MANIFEST_PATH/Cargo.toml + +# Build application with cache mounts +COPY --exclude=.git . . +RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ + --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ + --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \ + cargo build --profile $BUILD_PROFILE --features "$FEATURES" --locked --bin $BINARY --manifest-path $MANIFEST_PATH/Cargo.toml + +# Copy binary to a known location (ARG not resolved in COPY) +# Note: Custom profiles like maxperf/profiling output to target//, not target/release/ +RUN cp /app/target/$BUILD_PROFILE/$BINARY /app/binary || \ + cp /app/target/release/$BINARY /app/binary + +FROM ubuntu:24.04 AS runtime +WORKDIR /app + +# Binary name for entrypoint +ARG BINARY=reth + +# Install runtime dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates && \ + rm -rf /var/lib/apt/lists/* + +# Copy binary from build stage and create canonical symlink for entrypoint +COPY --from=builder /app/binary /usr/local/bin/ +RUN mv /usr/local/bin/binary /usr/local/bin/$BINARY && \ + ln -s /usr/local/bin/$BINARY /usr/local/bin/reth-binary && \ + chmod +x /usr/local/bin/$BINARY + +# Copy licenses +COPY LICENSE-* ./ + +EXPOSE 30303 30303/udp 9001 8545 8546 +ENTRYPOINT ["/usr/local/bin/reth-binary"] diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000000..6dcca621ae --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,104 @@ +// Docker Bake configuration for reth and op-reth images +// Usage: +// docker buildx bake ethereum # Build reth +// docker buildx bake optimism # Build op-reth +// docker buildx bake # Build all + +variable "REGISTRY" { + default = "ghcr.io/paradigmxyz" +} + +variable "TAG" { + default = "latest" +} + +variable "BUILD_PROFILE" { + default = "maxperf" +} + +variable "FEATURES" { + default = "jemalloc asm-keccak min-debug-logs" +} + +// Common settings for all targets +group "default" { + targets = ["ethereum", "optimism"] +} + +group "nightly" { + targets = ["ethereum", "ethereum-profiling", "ethereum-edge-profiling", "optimism", "optimism-profiling", "optimism-edge-profiling"] +} + +// Base target with shared configuration +target "_base" { + dockerfile = "Dockerfile.depot" + platforms = ["linux/amd64", "linux/arm64"] + args = { + BUILD_PROFILE = "${BUILD_PROFILE}" + FEATURES = "${FEATURES}" + } +} + +// Ethereum (reth) +target "ethereum" { + inherits = ["_base"] + args = { + BINARY = "reth" + MANIFEST_PATH = "bin/reth" + } + tags = ["${REGISTRY}/reth:${TAG}"] +} + +target "ethereum-profiling" { + inherits = ["_base"] + args = { + BINARY = "reth" + MANIFEST_PATH = "bin/reth" + BUILD_PROFILE = "profiling" + FEATURES = "jemalloc jemalloc-prof asm-keccak min-debug-logs" + } + tags = ["${REGISTRY}/reth:nightly-profiling"] +} + +target "ethereum-edge-profiling" { + inherits = ["_base"] + args = { + BINARY = "reth" + MANIFEST_PATH = "bin/reth" + BUILD_PROFILE = "profiling" + FEATURES = "jemalloc jemalloc-prof asm-keccak min-debug-logs edge" + } + tags = ["${REGISTRY}/reth:nightly-edge-profiling"] +} + +// Optimism (op-reth) +target "optimism" { + inherits = ["_base"] + args = { + BINARY = "op-reth" + MANIFEST_PATH = "crates/optimism/bin" + } + tags = ["${REGISTRY}/op-reth:${TAG}"] +} + +target "optimism-profiling" { + inherits = ["_base"] + args = { + BINARY = "op-reth" + MANIFEST_PATH = "crates/optimism/bin" + BUILD_PROFILE = "profiling" + FEATURES = "jemalloc jemalloc-prof asm-keccak min-debug-logs" + } + tags = ["${REGISTRY}/op-reth:nightly-profiling"] +} + +target "optimism-edge-profiling" { + inherits = ["_base"] + args = { + BINARY = "op-reth" + MANIFEST_PATH = "crates/optimism/bin" + BUILD_PROFILE = "profiling" + FEATURES = "jemalloc jemalloc-prof asm-keccak min-debug-logs edge" + } + tags = ["${REGISTRY}/op-reth:nightly-edge-profiling"] +}