Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/docker-image-build-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,20 @@ jobs:
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.0.0
with:
context: .
target: debian
platforms: linux/amd64
push: true
tags: nethermindeth/juno:${{ needs.setup.outputs.tag }}

- name: Build and push AMD64 distroless
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.0.0
with:
context: .
target: distroless
platforms: linux/amd64
push: true
tags: nethermindeth/juno:${{ needs.setup.outputs.tag }}-distroless

build_and_push_docker_image_arm:
needs: setup
if: github.repository_owner == 'NethermindEth'
Expand All @@ -92,10 +102,20 @@ jobs:
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.0.0
with:
context: .
target: debian
platforms: linux/arm64
push: true
tags: nethermindeth/juno:${{ needs.setup.outputs.tag }}-arm64

- name: Build and push ARM64 distroless
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.0.0
with:
context: .
target: distroless
platforms: linux/arm64
push: true
tags: nethermindeth/juno:${{ needs.setup.outputs.tag }}-distroless-arm64

- name: Cleanup self-hosted
run: docker system prune -af

Expand Down Expand Up @@ -123,6 +143,13 @@ jobs:
nethermindeth/juno:${{ needs.setup.outputs.tag }}-arm64 \
--tag nethermind/juno:${{ needs.setup.outputs.tag }}

- name: Create and push distroless manifest using buildx
run: |
docker buildx imagetools create \
nethermindeth/juno:${{ needs.setup.outputs.tag }}-distroless \
nethermindeth/juno:${{ needs.setup.outputs.tag }}-distroless-arm64 \
--tag nethermind/juno:${{ needs.setup.outputs.tag }}-distroless

- name: Clean up Docker config
if: always()
run: rm -f ${HOME}/.docker/config.json
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/prepare-draft-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ jobs:
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Tag non-official image as latest
run: docker buildx imagetools create --tag nethermindeth/juno:latest nethermindeth/juno:${{ needs.docker-image.outputs.tag }}
- name: Tag non-official distroless image as latest-distroless
run: docker buildx imagetools create --tag nethermindeth/juno:latest-distroless nethermindeth/juno:${{ needs.docker-image.outputs.tag }}-distroless
- name: Clean up Docker config
if: always()
run: rm -f ${HOME}/.docker/config.json
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release-published.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
- name: Tag official image as latest
run: docker buildx imagetools create --tag nethermind/juno:latest nethermind/juno:${{ needs.build-official-docker-image.outputs.tag }}

- name: Tag official distroless image as latest-distroless
run: docker buildx imagetools create --tag nethermind/juno:latest-distroless nethermind/juno:${{ needs.build-official-docker-image.outputs.tag }}-distroless

- name: Clean up Docker config
if: always()
run: rm -f ${HOME}/.docker/config.json
54 changes: 52 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libjemalloc-dev libbz2-dev pkg-config \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

# Remove the shared jemalloc so that -ljemalloc links libjemalloc.a. The final image then needs
# no jemalloc package, and the Debian libjemalloc.so.2 does not pull in libstdc++.
RUN rm /usr/lib/$(gcc -dumpmachine)/libjemalloc.so

# Install Rust
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y --default-toolchain ${RUST_VERSION} --profile minimal
ENV PATH="/root/.cargo/bin:${PATH}"
Expand Down Expand Up @@ -40,8 +44,10 @@ COPY . .
# Build with make juno
RUN make juno

# --- Final stage ---
FROM debian:bookworm-slim AS final
# --- Debian image ---
# The earlier runtime image with a shell and utilities. Releases publish it as nethermind/juno:<tag>
# for users that cannot move to the distroless image yet. Build it with --target debian.
FROM debian:bookworm-slim AS debian
Comment thread
brbrr marked this conversation as resolved.
Resolved

RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
Expand All @@ -56,3 +62,47 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY --from=builder /app/build/juno /usr/local/bin/

ENTRYPOINT ["juno"]

# --- Runtime base stage ---
# Builds a Wolfi filesystem with glibc and no shell or package manager from the packages pinned in
# docker/apko.lock.json. It runs on the build platform, so a cross-arch build needs no emulation.
FROM --platform=$BUILDPLATFORM golang:1.27-bookworm AS base

# Keep in sync with APKO_VERSION in the Makefile.
ARG APKO_VERSION=v1.4.11
ARG TARGETARCH

# The golang image has python3 only as a dependency of mercurial. Install it explicitly for the
# manifest lookup below.
RUN apt-get update && apt-get install -y --no-install-recommends python3 \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

RUN go install chainguard.dev/apko@${APKO_VERSION}

WORKDIR /base
COPY docker/apko.yaml docker/apko.lock.json ./

# apko writes an image tarball with one layer. Extract that layer as the root filesystem.
RUN apko build --arch ${TARGETARCH} --lockfile apko.lock.json --sbom=false apko.yaml juno-base image.tar \
&& tar -xf image.tar \
&& layer="$(python3 -c 'import json, sys; m = json.load(open("manifest.json")); \
(len(m) == 1 and len(m[0]["Layers"]) == 1) or sys.exit("apko manifest.json: want 1 image with 1 layer"); \
print(m[0]["Layers"][0])')" \
&& mkdir /rootfs \
&& tar -xzf "$layer" -C /rootfs
Comment thread
brbrr marked this conversation as resolved.
Resolved

# --- Distroless image ---
# The default target. Releases publish it as nethermind/juno:<tag>-distroless.
FROM scratch AS distroless

COPY --from=base /rootfs/ /
COPY --from=builder /app/build/juno /usr/local/bin/

ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt

LABEL org.opencontainers.image.title="juno" \
org.opencontainers.image.vendor="Nethermind" \
org.opencontainers.image.source="https://github.com/NethermindEth/juno" \
org.opencontainers.image.licenses="Apache-2.0"

ENTRYPOINT ["juno"]
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ lint-diff:
tidy: ## Add missing and remove unused modules
go mod tidy

# Keep in sync with APKO_VERSION in the Dockerfile.
APKO_VERSION := v1.4.11

apko-lock: ## Pin the latest Wolfi packages for the Docker runtime image
go run chainguard.dev/apko@$(APKO_VERSION) lock -C docker apko.yaml --output apko.lock.json

rust-format-check: ## Check Rust formatting across all crates
$(MAKE) -C vm/rust format-check

Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
image: juno:latest
build: .
healthcheck:
test: ["CMD", "sleep", "4"]
test: ["CMD", "juno", "--help"]
interval: 4s
timeout: 10s
retries: 1
Expand Down
Loading
Loading