From 3c109b1d9770cbc9e46540a771f7a1bd5d38db5b Mon Sep 17 00:00:00 2001 From: Yorick Downe Date: Sun, 26 Jul 2026 10:28:08 +0100 Subject: [PATCH] Support Ream --- .pre-commit-config.yaml | 1 + ream.yml | 172 ++++++++++++++++++++++++++++++++++++++++ ream/Dockerfile.source | 103 ++++++++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 ream.yml create mode 100644 ream/Dockerfile.source diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19b9b36d5..fc4d7c9a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -60,6 +60,7 @@ repos: rev: v2.4.1 hooks: - id: codespell + args: ["--ignore-words-list", "ream"] # Dockerfiles - repo: https://github.com/hadolint/hadolint diff --git a/ream.yml b/ream.yml new file mode 100644 index 000000000..9fab4cb67 --- /dev/null +++ b/ream.yml @@ -0,0 +1,172 @@ +x-logging: &logging + logging: + driver: ${LOG_DRIVER} + options: + max-size: ${LOG_MAX_SIZE} + max-file: ${LOG_MAX_FILE} + tag: ${LOG_TAG} + +services: + ream-builder: + restart: "no" + build: + context: ./ream + dockerfile: ${REAM_DOCKERFILE:-Dockerfile.source} + args: + - BUILD_TARGET=${REAM_SRC_BUILD_TARGET:-master} + - SRC_REPO=${REAM_SRC_REPO:-https://github.com/ReamLabs/ream} + - DOCKER_TAG=${REAM_DOCKER_TAG:-} + - DOCKER_REPO=${REAM_DOCKER_REPO:-} + image: ream:local + pull_policy: never + entrypoint: ["true"] + + consensus: + restart: "unless-stopped" + image: ream:local + pull_policy: never + user: ream + stop_grace_period: 1m + depends_on: + ream-builder: + condition: service_completed_successfully + environment: + - CL_EXTRAS=${CL_EXTRAS:-} + - LOG_LEVEL=${LOG_LEVEL:-info} + - NETWORK=${NETWORK} + volumes: + - ream-consensus-data:/var/lib/ream/beacon + - /etc/localtime:/etc/localtime:ro + - jwtsecret:/var/lib/ream/beacon/ee-secret + ports: + - ${HOST_IP:-}:${CL_P2P_PORT:-9000}:${CL_P2P_PORT:-9000}/tcp + - ${HOST_IP:-}:${CL_P2P_PORT:-9000}:${CL_P2P_PORT:-9000}/udp + networks: + default: + aliases: + - eth2 + # This allows multiple Eth Docker stacks all connected to the same bridge network + - ${CL_ALIAS:-default-consensus} + <<: *logging + entrypoint: +# - docker-entrypoint.sh + - ream + - --data-dir + - /var/lib/ream/beacon + - --verbosity + - $$VERBOSITY + - beacon_node + - --socket-address + - 0.0.0.0 + - --socket-port + - ${CL_P2P_PORT:-9000} + - --discovery-port + - ${CL_P2P_PORT:-9000} + - --http-address + - 0.0.0.0 + - --http-port + - ${CL_REST_PORT:-5052} + - --checkpoint-sync-url + - ${CHECKPOINT_SYNC_URL:?CHECKPOINT_SYNC_URL must be set in .env} + - --network + - ${NETWORK} # entrypoint would also support devnets + labels: + - metrics.scrape=false + - metrics.path=/metrics + - metrics.port=8008 + - metrics.instance=consensus + - metrics.network=${NETWORK} + - logs.collect=true + + validator: + restart: "unless-stopped" + image: ream:local + pull_policy: never + user: reamvalidator + depends_on: + consensus: + condition: service_started + ream-builder: + condition: service_completed_successfully + volumes: + - ream-vc-data:/var/lib/ream/validators + - /etc/localtime:/etc/localtime:ro + environment: + - MEV_BOOST=${MEV_BOOST} + - MEV_BUILD_FACTOR=${MEV_BUILD_FACTOR} + - BEACON_STATS_API=${BEACON_STATS_API} + - BEACON_STATS_MACHINE=${BEACON_STATS_MACHINE} + - DOPPELGANGER=${DOPPELGANGER} + - VC_EXTRAS=${VC_EXTRAS:-} + - GRAFFITI=${GRAFFITI:-} + - DEFAULT_GRAFFITI=${DEFAULT_GRAFFITI:-false} + - NETWORK=${NETWORK} + networks: + default: + aliases: + - ${VC_ALIAS:-vc} + <<: *logging + entrypoint: +# - docker-entrypoint-vc.sh + - ream + - --data-dir + - /var/lib/ream/validators + - validator_node + - --beacon-api-endpoint + - ${CL_NODE:-http://consensus:5052} + - --suggested-fee-recipient + - ${FEE_RECIPIENT} + - --key-manager-http-address + - 0.0.0.0 + - --key-manager-http-port + - ${KEY_API_PORT:-7500} + - --http-address + - 0.0.0.0 + - --network + - ${NETWORK} # entrypoint would also support devnets + labels: + - metrics.scrape=false + - metrics.path=/metrics + - metrics.port=8009 + - metrics.instance=validator + - metrics.network=${NETWORK} + - logs.collect=true + + validator-keys: + profiles: ["tools"] + restart: "no" + build: + context: ./vc-utils + image: vc-utils:local + pull_policy: never + # The API token has 640 permissions. Root copies it, + # then switches to the local user's UID or if not provided, + # 1000. The UID has to be able to write .eth/validator_keys + # for the "keys delete" command. + user: root + depends_on: + - validator + volumes: + - ream-vc-data:/var/lib/ream/validators + - ./.eth/validator_keys:/validator_keys + - ./.eth/exit_messages:/exit_messages + - /etc/localtime:/etc/localtime:ro + environment: + - KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD:-} + - KEY_API_PORT=${KEY_API_PORT:-7500} + - WEB3SIGNER=${WEB3SIGNER:-false} + - W3S_NODE=${W3S_NODE} + - CL_NODE=${CL_NODE} + entrypoint: + - keymanager.sh + - /var/lib/ream/validators/api-token.txt + - ${VC_ALIAS:-vc} + +volumes: + ream-consensus-data: + ream-vc-data: + jwtsecret: + +networks: + default: + enable_ipv6: ${IPV6:-false} diff --git a/ream/Dockerfile.source b/ream/Dockerfile.source new file mode 100644 index 000000000..f45dd9b04 --- /dev/null +++ b/ream/Dockerfile.source @@ -0,0 +1,103 @@ +# hadolint global ignore=DL3007,DL3008,DL3059,DL4006 +# Build ream in a stock rust container +FROM rust:trixie AS builder + +# Unused, this is here to avoid build time complaints +ARG DOCKER_TAG +ARG DOCKER_REPO + +RUN apt-get update && apt-get install -y --no-install-recommends \ + clang libclang-dev pkg-config libssl-dev build-essential + +RUN cargo install cargo-udeps --locked +RUN cargo install --git https://github.com/DevinR528/cargo-sort.git --rev 25a60ad860ce7cd0055abf4b69c18285cb07ab41 cargo-sort + +ARG BUILD_TARGET +ARG SRC_REPO + +WORKDIR /src + +ARG SRC_DIR=ream +ENV CC=clang +ENV CXX=clang++ +RUN --mount=type=cache,sharing=locked,id=ream-target,target=/src/target/ \ + --mount=type=cache,sharing=locked,target=/usr/local/cargo/git/db \ + --mount=type=cache,sharing=locked,target=/usr/local/cargo/registry/ \ + bash <<'EOF' +set -Eeuo pipefail +git clone "$SRC_REPO" "$SRC_DIR" +cd "$SRC_DIR" +git config advice.detachedHead false +git fetch --all --tags +CLEANED=$(echo "$BUILD_TARGET" | sed 's/\$\$(/$(/g') +TARGET=$(eval echo "$CLEANED") +if [[ "$TARGET" =~ ^pr-[1-9][0-9]*$ ]]; then + git fetch origin pull/${TARGET#pr-}/head:build-pr + git checkout build-pr +else + git checkout "$TARGET" +fi +CARGO_TARGET_DIR=/src/target make build +mkdir -p /src/bin +cp /src/target/release/ream /src/bin/ +EOF + + +# Pull all binaries into a second stage deploy debian container +FROM debian:trixie-slim + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y --no-install-recommends \ + ca-certificates \ + tzdata \ + adduser \ + bash \ + git \ + git-lfs \ + wget \ + jq \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +ARG USER=reamconsensus +ARG UID=10002 + +# See https://stackoverflow.com/a/55757473/12429735RUN +RUN adduser \ + --disabled-password \ + --gecos "" \ + --shell "/sbin/nologin" \ + --uid "${UID}" \ + "${USER}" + +RUN mkdir -p /var/lib/ream/beacon/ee-secret && chown -R ${USER}:${USER} /var/lib/ream/beacon && chmod -R 700 /var/lib/ream/beacon && chmod 777 /var/lib/ream/beacon/ee-secret + +# Cannot assume buildkit, hence no chmod +#COPY --chown=${USER}:${USER} ./docker-entrypoint.sh /usr/local/bin/ +# Belt and suspenders +RUN chmod -R 755 /usr/local/bin/* + +ARG USER=reamvalidator +ARG UID=10000 + +# See https://stackoverflow.com/a/55757473/12429735RUN +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + "${USER}" + +# Create data mount point with permissions +RUN mkdir -p /var/lib/ream/validators && chown ${USER}:${USER} /var/lib/ream/validators && chmod 700 /var/lib/ream/validators + +# Cannot assume buildkit, hence no chmod +COPY --from=builder --chown=${USER}:${USER} /src/bin/ream /usr/local/bin/ +#COPY --chown=${USER}:${USER} ./docker-entrypoint-vc.sh /usr/local/bin/ +# Belt and suspenders +RUN chmod -R 755 /usr/local/bin/* + +USER reamconsensus + +ENTRYPOINT ["ream"]