diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3eecc2..b348b56 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,3 +72,56 @@ jobs: artifacts/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # The Docker image bundles the release binaries (built above) + # into a debian-slim base and pushes a multi-arch manifest to + # GHCR. Downstream consumers (merobox#256+) pull this image + # at runtime so they don't have to keep a Dockerfile bundled + # in their own tree. + # + # Layout for buildx context: COPY in the Dockerfile expects + # binaries under `artifacts//boot-node`, so we + # restage the GitHub-release-named binaries into the + # docker-arch directory layout before invoking buildx. + - name: Stage binaries for Docker build + run: | + mkdir -p artifacts/amd64 artifacts/arm64 + cp artifacts/boot-node-x86_64-unknown-linux artifacts/amd64/boot-node + cp artifacts/boot-node-aarch64-unknown-linux artifacts/arm64/boot-node + chmod +x artifacts/amd64/boot-node artifacts/arm64/boot-node + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Tags published per release: + # * (e.g. 0.7.0) — immutable, pinned by consumers + # * latest — current published release + # * edge — also tracks latest, matches the + # naming convention merod uses + # (`ghcr.io/calimero-network/merod:edge`) + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ghcr.io/calimero-network/boot-node:${{ needs.metadata.outputs.version }} + ghcr.io/calimero-network/boot-node:latest + ghcr.io/calimero-network/boot-node:edge + labels: | + org.opencontainers.image.source=https://github.com/calimero-network/boot-node + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=${{ needs.metadata.outputs.version }} + org.opencontainers.image.licenses=Apache-2.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d31b3f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +# Multi-stage Dockerfile for the calimero-network boot-node. +# +# Building from the binary that was just produced by the release +# CI (release.yml). The binary is platform-specific, so the +# release workflow does the cross-builds and passes the right +# artifact in via `--build-arg BOOT_NODE_BINARY=...`. The image +# itself is multi-arch via buildx (linux/amd64 + linux/arm64); +# each platform variant copies the matching binary from the +# release artifacts. +# +# `debian:bookworm-slim` keeps the runtime image small (~80MB) +# without going to `scratch` — boot-node is a glibc binary built +# via standard `cargo build`, and `scratch` would force a musl +# rebuild. The ca-certificates package is required for any +# rendezvous-bootstrap-peer that uses TLS. + +FROM debian:bookworm-slim + +# The binary is copied in from the release artifacts. The release +# workflow runs `cargo build --release` (x86_64) + `cross build` +# (aarch64), then renames the outputs to predictable names that +# match this ARG default. buildx picks the right one for the +# target platform via TARGETARCH. +ARG TARGETARCH + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# Copy the platform-matching binary. The release workflow stages +# both architectures under `artifacts//boot-node` +# (amd64 ← x86_64-unknown-linux build, arm64 ← aarch64-unknown- +# linux build) so this COPY can use TARGETARCH directly without +# any shell-side mapping inside the Dockerfile. +COPY artifacts/${TARGETARCH}/boot-node /usr/local/bin/boot-node +RUN chmod +x /usr/local/bin/boot-node + +# 4001 is the default libp2p listen port (the boot-node binary's +# `--port` flag defaults to it too). Single port covers TCP and +# QUIC — libp2p listens on both with the same number. +EXPOSE 4001/tcp 4001/udp + +# `--dev` generates an ephemeral keypair on each startup, so the +# container is usable with no extra setup. Operators that need a +# stable peer id should mount a keypair and override with +# `--private-key /path`. +CMD ["boot-node", "--dev"]