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
53 changes: 53 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/<docker-arch>/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:
# * <version> (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
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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/<docker-arch>/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"]
Loading