Compare commits

..

7 Commits

Author SHA1 Message Date
antondlr
24c1463338 Move appimagetool SHA256 pins to top-level env vars
All version pins are now visible at the top of their respective files:
- Dockerfile.reproducible: Rust image, apt packages, distroless runtime
- reproducible.yml: appimagetool SHA256s (APPIMAGETOOL_SHA256_AMD64/ARM64)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 14:44:38 +02:00
antondlr
9aa30e2f57 Fix reproducibility and CI correctness issues in reproducible.yml
- Pin appimagetool by SHA256 digest rather than floating 'continuous' tag.
  The tool has no stable releases; we verify the download hash before use.
  To update: download new binary, sha256sum it, bump the matrix value.
- Add --clobber to gh release upload to handle reruns cleanly.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 14:42:05 +02:00
antondlr
d8e8655754 Bump reproducible builder to Rust 1.95 (latest stable)
rust:1.95-bookworm@sha256:225aa827...

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 14:28:19 +02:00
antondlr
d1078c02af Update reproducible build to Debian Bookworm (stable)
- Rust builder: rust:1.88-bookworm (multi-arch index digest)
- Runtime: distroless/cc-debian12:nonroot (Bookworm, pinned by index digest)
- Build deps bumped to Bookworm versions:
    libclang-dev 1:14.0-55.7~deb12u1
    cmake         3.25.1-1
    libjemalloc-dev 5.3.0-1
- libz.so.1 search path updated /lib → /usr/lib (moved in Bookworm)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 13:44:55 +02:00
antondlr
f0500a01ee Fix reproducible image runtime deps: copy libz from builder, drop libssl COPY
ldd on the built binary shows only libz.so.1 is missing from distroless/cc-debian11;
libssl/libcrypto are statically linked by this build and do not need to be copied.
libstdc++.so.6 and libgcc_s.so.1 are already present in the distroless/cc variant.

Also consolidates the mv + mkdir into a single RUN layer.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 12:49:30 +02:00
antondlr
1c635f57a0 Fix reproducible image: switch to distroless/cc-debian11, copy libssl from builder
The previous final stage used distroless/cc-debian12 (Bookworm) which carries
no libssl and uses OpenSSL 3, making the Bullseye-built binary non-functional.

- Switch to distroless/cc-debian11:nonroot (pinned by index digest) — same
  Bullseye ABI as the builder, already includes libc and libgcc
- Copy libssl.so.1.1 and libcrypto.so.1.1 from the builder stage into /usr/lib/
  so no package manager is invoked in the final image (stays fully pinned)
- Normalise the arch-specific triplet lib path via a `find` into /libs/ so the
  COPY instructions work identically for both amd64 and arm64 builds

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 11:25:18 +02:00
antondlr
b647e22861 Simplify reproducible builds: single version tag, add binary tarball + AppImage outputs
- Replace docker-reproducible.yml with reproducible.yml which produces
  three artifacts per arch: Docker image, binary tarball, and AppImage
- Use a single multi-arch index digest in Dockerfile.reproducible as the
  sole version tag to maintain; Makefile and CI no longer carry their own
  per-arch image references
- Add packaging/appimage/ template (AppRun, .desktop, lighthouse.svg)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-20 10:55:27 +02:00
7 changed files with 344 additions and 197 deletions

View File

@@ -1,183 +0,0 @@
name: docker-reproducible
on:
push:
branches:
- unstable
tags:
- v*
workflow_dispatch: # allows manual triggering for testing purposes and skips publishing an image
env:
DOCKER_REPRODUCIBLE_IMAGE_NAME: >-
${{ github.repository_owner }}/lighthouse-reproducible
DOCKER_PASSWORD: ${{ secrets.DH_KEY }}
DOCKER_USERNAME: ${{ secrets.DH_ORG }}
jobs:
extract-version:
name: extract version
runs-on: ubuntu-22.04
steps:
- name: Extract version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
# It's a tag (e.g., v1.2.3)
VERSION="${GITHUB_REF#refs/tags/}"
elif [[ "${{ github.ref }}" == refs/heads/unstable ]]; then
# unstable branch -> latest-unstable
VERSION="latest-unstable"
else
# For manual triggers from other branches and will not publish any image
VERSION="test-build"
fi
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
id: extract_version
outputs:
VERSION: ${{ steps.extract_version.outputs.VERSION }}
verify-and-build:
name: verify reproducibility and build
needs: extract-version
strategy:
matrix:
arch: [amd64, arm64]
include:
- arch: amd64
rust_target: x86_64-unknown-linux-gnu
rust_image: >-
rust:1.88-bullseye@sha256:8e3c421122bf4cd3b2a866af41a4dd52d87ad9e315fd2cb5100e87a7187a9816
platform: linux/amd64
runner: ubuntu-22.04
- arch: arm64
rust_target: aarch64-unknown-linux-gnu
rust_image: >-
rust:1.88-bullseye@sha256:8b22455a7ce2adb1355067638284ee99d21cc516fab63a96c4514beaf370aa94
platform: linux/arm64
runner: ubuntu-22.04-arm
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Verify reproducible builds (${{ matrix.arch }})
run: |
# Build first image
docker build -f Dockerfile.reproducible \
--platform ${{ matrix.platform }} \
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
--build-arg RUST_IMAGE="${{ matrix.rust_image }}" \
-t lighthouse-verify-1-${{ matrix.arch }} .
# Extract binary from first build
docker create --name extract-1-${{ matrix.arch }} lighthouse-verify-1-${{ matrix.arch }}
docker cp extract-1-${{ matrix.arch }}:/lighthouse ./lighthouse-1-${{ matrix.arch }}
docker rm extract-1-${{ matrix.arch }}
# Clean state for second build
docker buildx prune -f
docker system prune -f
# Build second image
docker build -f Dockerfile.reproducible \
--platform ${{ matrix.platform }} \
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
--build-arg RUST_IMAGE="${{ matrix.rust_image }}" \
-t lighthouse-verify-2-${{ matrix.arch }} .
# Extract binary from second build
docker create --name extract-2-${{ matrix.arch }} lighthouse-verify-2-${{ matrix.arch }}
docker cp extract-2-${{ matrix.arch }}:/lighthouse ./lighthouse-2-${{ matrix.arch }}
docker rm extract-2-${{ matrix.arch }}
# Compare binaries
echo "=== Comparing binaries ==="
echo "Build 1 SHA256: $(sha256sum lighthouse-1-${{ matrix.arch }})"
echo "Build 2 SHA256: $(sha256sum lighthouse-2-${{ matrix.arch }})"
if cmp lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }}; then
echo "Reproducible build verified for ${{ matrix.arch }}"
else
echo "Reproducible build FAILED for ${{ matrix.arch }}"
echo "BLOCKING RELEASE: Builds are not reproducible!"
echo "First 10 differences:"
cmp -l lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }} | head -10
exit 1
fi
# Clean up verification artifacts but keep one image for publishing
rm -f lighthouse-*-${{ matrix.arch }}
docker rmi lighthouse-verify-1-${{ matrix.arch }} || true
# Re-tag the second image for publishing (we verified it's identical to first)
VERSION=${{ needs.extract-version.outputs.VERSION }}
FINAL_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
docker tag lighthouse-verify-2-${{ matrix.arch }} "$FINAL_TAG"
- name: Log in to Docker Hub
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Push verified image (${{ matrix.arch }})
if: ${{ github.event_name != 'workflow_dispatch' }}
run: |
VERSION=${{ needs.extract-version.outputs.VERSION }}
IMAGE_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
docker push "$IMAGE_TAG"
- name: Clean up local images
run: |
docker rmi lighthouse-verify-2-${{ matrix.arch }} || true
VERSION=${{ needs.extract-version.outputs.VERSION }}
docker rmi "${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}" || true
- name: Upload verification artifacts (on failure)
if: failure()
uses: actions/upload-artifact@v4
with:
name: verification-failure-${{ matrix.arch }}
path: |
lighthouse-*-${{ matrix.arch }}
create-manifest:
name: create multi-arch manifest
runs-on: ubuntu-22.04
needs: [extract-version, verify-and-build]
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Create and push multi-arch manifest
run: |
IMAGE_NAME=${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}
VERSION=${{ needs.extract-version.outputs.VERSION }}
# Create manifest for the version tag
docker manifest create \
${IMAGE_NAME}:${VERSION} \
${IMAGE_NAME}:${VERSION}-amd64 \
${IMAGE_NAME}:${VERSION}-arm64
docker manifest push ${IMAGE_NAME}:${VERSION}
# For version tags, also create/update the latest tag to keep stable up to date
# Only create latest tag for proper release versions (e.g. v1.2.3, not v1.2.3-alpha)
if [[ "${GITHUB_REF}" == refs/tags/* ]] && [[ "${VERSION}" =~ ^v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}$ ]]; then
docker manifest create \
${IMAGE_NAME}:latest \
${IMAGE_NAME}:${VERSION}-amd64 \
${IMAGE_NAME}:${VERSION}-arm64
docker manifest push ${IMAGE_NAME}:latest
fi

297
.github/workflows/reproducible.yml vendored Normal file
View File

@@ -0,0 +1,297 @@
name: reproducible
# Produces three artifacts per architecture: Docker image, binary tarball, AppImage.
# The Docker image is the single build artifact; the binary and AppImage are extracted from it.
# Only one version tag to maintain: the RUST_IMAGE ARG in Dockerfile.reproducible.
on:
push:
branches:
- unstable
tags:
- v*
workflow_dispatch:
env:
DOCKER_REPRODUCIBLE_IMAGE_NAME: ${{ github.repository_owner }}/lighthouse-reproducible
DOCKER_PASSWORD: ${{ secrets.DH_KEY }}
DOCKER_USERNAME: ${{ secrets.DH_ORG }}
# appimagetool has no stable release tags; pin by SHA256 of the continuous binary.
# To update: curl the new binary, run sha256sum, replace the values below.
APPIMAGETOOL_SHA256_AMD64: a6d71e2b6cd66f8e8d16c37ad164658985e0cf5fcaa950c90a482890cb9d13e0
APPIMAGETOOL_SHA256_ARM64: 1b00524ba8c6b678dc15ef88a5c25ec24def36cdfc7e3abb32ddcd068e8007fe
jobs:
extract-version:
name: extract version
runs-on: ubuntu-22.04
steps:
- name: Extract version
id: extract_version
run: |
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
elif [[ "${{ github.ref }}" == refs/heads/unstable ]]; then
VERSION="latest-unstable"
else
VERSION="test-build"
fi
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
outputs:
VERSION: ${{ steps.extract_version.outputs.VERSION }}
build:
name: build and verify (${{ matrix.arch }})
needs: extract-version
strategy:
matrix:
arch: [amd64, arm64]
include:
- arch: amd64
rust_target: x86_64-unknown-linux-gnu
platform: linux/amd64
runner: ubuntu-22.04
appimage_arch: x86_64
- arch: arm64
rust_target: aarch64-unknown-linux-gnu
platform: linux/arm64
runner: ubuntu-22.04-arm
appimage_arch: aarch64
runs-on: ${{ matrix.runner }}
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
# ── Step 1: Build twice and verify bit-for-bit reproducibility ──────────
- name: Build image (pass 1)
run: |
docker build -f Dockerfile.reproducible \
--platform ${{ matrix.platform }} \
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
-t lighthouse-verify-1 .
- name: Extract binary (pass 1)
run: |
docker create --name extract-1 lighthouse-verify-1
docker cp extract-1:/lighthouse ./lighthouse-1
docker rm extract-1
- name: Clean Docker state between builds
run: |
docker buildx prune -f
docker system prune -f
- name: Build image (pass 2)
run: |
docker build -f Dockerfile.reproducible \
--platform ${{ matrix.platform }} \
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
-t lighthouse-verify-2 .
- name: Extract binary (pass 2)
run: |
docker create --name extract-2 lighthouse-verify-2
docker cp extract-2:/lighthouse ./lighthouse-2
docker rm extract-2
- name: Verify reproducibility
run: |
echo "Pass 1 SHA256: $(sha256sum lighthouse-1)"
echo "Pass 2 SHA256: $(sha256sum lighthouse-2)"
if cmp lighthouse-1 lighthouse-2; then
echo "Reproducible build verified for ${{ matrix.arch }}"
else
echo "BLOCKING RELEASE: builds are not reproducible!"
echo "First 10 differing bytes:"
cmp -l lighthouse-1 lighthouse-2 | head -10
exit 1
fi
# ── Step 2: Tag the verified image and push ──────────────────────────────
- name: Tag verified image
run: |
VERSION=${{ needs.extract-version.outputs.VERSION }}
docker tag lighthouse-verify-2 \
${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}
- name: Log in to Docker Hub
if: ${{ github.event_name != 'workflow_dispatch' }}
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Push Docker image
if: ${{ github.event_name != 'workflow_dispatch' }}
run: |
VERSION=${{ needs.extract-version.outputs.VERSION }}
docker push ${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}
# ── Step 3: Binary tarball ───────────────────────────────────────────────
- name: Create binary tarball
env:
VERSION: ${{ needs.extract-version.outputs.VERSION }}
run: |
cp lighthouse-2 lighthouse
tar -czf lighthouse-${VERSION}-${{ matrix.rust_target }}.tar.gz lighthouse
sha256sum lighthouse-${VERSION}-${{ matrix.rust_target }}.tar.gz \
> lighthouse-${VERSION}-${{ matrix.rust_target }}.tar.gz.sha256
# ── Step 4: AppImage ─────────────────────────────────────────────────────
- name: Download appimagetool
run: |
curl -fsSL \
"https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${{ matrix.appimage_arch }}.AppImage" \
-o appimagetool
# Verify against pinned SHA256 (see APPIMAGETOOL_SHA256_* env vars at top of file)
EXPECTED="APPIMAGETOOL_SHA256_$(echo '${{ matrix.appimage_arch }}' | tr '[:lower:]' '[:upper:]')"
echo "${!EXPECTED} appimagetool" | sha256sum --check
chmod +x appimagetool
- name: Assemble AppDir
run: |
mkdir -p AppDir/usr/bin
cp lighthouse-2 AppDir/usr/bin/lighthouse
cp packaging/appimage/AppRun AppDir/AppRun
chmod +x AppDir/AppRun
cp packaging/appimage/lighthouse.desktop AppDir/lighthouse.desktop
cp packaging/appimage/lighthouse.svg AppDir/lighthouse.svg
- name: Build AppImage
env:
VERSION: ${{ needs.extract-version.outputs.VERSION }}
# Deterministic squashfs: fixed modification times, no extra metadata
SOURCE_DATE_EPOCH: 0
run: |
./appimagetool \
--comp xz \
AppDir \
lighthouse-${VERSION}-${{ matrix.appimage_arch }}.AppImage
sha256sum lighthouse-${VERSION}-${{ matrix.appimage_arch }}.AppImage \
> lighthouse-${VERSION}-${{ matrix.appimage_arch }}.AppImage.sha256
# ── Step 5: GPG sign and upload artifacts (tags only) ────────────────────
- name: Sign artifacts
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
VERSION: ${{ needs.extract-version.outputs.VERSION }}
run: |
echo "$GPG_SIGNING_KEY" | gpg --batch --import
for f in \
lighthouse-${VERSION}-${{ matrix.rust_target }}.tar.gz \
lighthouse-${VERSION}-${{ matrix.appimage_arch }}.AppImage; do
echo "$GPG_PASSPHRASE" | gpg --passphrase-fd 0 \
--pinentry-mode loopback --batch -ab "$f"
done
- name: Upload binary tarball
uses: actions/upload-artifact@v4
with:
name: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.rust_target }}.tar.gz
path: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.rust_target }}.tar.gz
compression-level: 0
- name: Upload binary tarball signature
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: actions/upload-artifact@v4
with:
name: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.rust_target }}.tar.gz.asc
path: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.rust_target }}.tar.gz.asc
compression-level: 0
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.appimage_arch }}.AppImage
path: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.appimage_arch }}.AppImage
compression-level: 0
- name: Upload AppImage signature
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: actions/upload-artifact@v4
with:
name: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.appimage_arch }}.AppImage.asc
path: lighthouse-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.appimage_arch }}.AppImage.asc
compression-level: 0
- name: Upload verification artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: verification-failure-${{ matrix.arch }}
path: |
lighthouse-1
lighthouse-2
- name: Clean up
if: always()
run: |
docker rmi lighthouse-verify-1 lighthouse-verify-2 || true
VERSION=${{ needs.extract-version.outputs.VERSION }}
docker rmi ${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }} || true
manifest:
name: create multi-arch manifest
needs: [extract-version, build]
runs-on: ubuntu-22.04
if: ${{ github.event_name != 'workflow_dispatch' }}
steps:
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Create and push multi-arch manifest
run: |
IMAGE=${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}
VERSION=${{ needs.extract-version.outputs.VERSION }}
docker manifest create ${IMAGE}:${VERSION} \
${IMAGE}:${VERSION}-amd64 \
${IMAGE}:${VERSION}-arm64
docker manifest push ${IMAGE}:${VERSION}
# Tag latest only for stable release versions (e.g. v1.2.3, not v1.2.3-alpha)
if [[ "${GITHUB_REF}" == refs/tags/* ]] && \
[[ "${VERSION}" =~ ^v[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}$ ]]; then
docker manifest create ${IMAGE}:latest \
${IMAGE}:${VERSION}-amd64 \
${IMAGE}:${VERSION}-arm64
docker manifest push ${IMAGE}:latest
fi
publish:
name: publish to GitHub release
needs: [extract-version, build]
runs-on: ubuntu-22.04
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
VERSION: ${{ needs.extract-version.outputs.VERSION }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Upload to GitHub release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# The release draft is created by release.yml's draft-release job which runs in parallel.
# --clobber allows re-runs to overwrite previously uploaded assets without error.
run: |
gh release upload ${VERSION} \
lighthouse-${VERSION}-x86_64-unknown-linux-gnu.tar.gz/lighthouse-${VERSION}-x86_64-unknown-linux-gnu.tar.gz \
lighthouse-${VERSION}-x86_64-unknown-linux-gnu.tar.gz.asc/lighthouse-${VERSION}-x86_64-unknown-linux-gnu.tar.gz.asc \
lighthouse-${VERSION}-aarch64-unknown-linux-gnu.tar.gz/lighthouse-${VERSION}-aarch64-unknown-linux-gnu.tar.gz \
lighthouse-${VERSION}-aarch64-unknown-linux-gnu.tar.gz.asc/lighthouse-${VERSION}-aarch64-unknown-linux-gnu.tar.gz.asc \
lighthouse-${VERSION}-x86_64.AppImage/lighthouse-${VERSION}-x86_64.AppImage \
lighthouse-${VERSION}-x86_64.AppImage.asc/lighthouse-${VERSION}-x86_64.AppImage.asc \
lighthouse-${VERSION}-aarch64.AppImage/lighthouse-${VERSION}-aarch64.AppImage \
lighthouse-${VERSION}-aarch64.AppImage.asc/lighthouse-${VERSION}-aarch64.AppImage.asc \
--clobber \
--repo ${{ github.repository }}

View File

@@ -1,9 +1,15 @@
# Define the Rust image as an argument with a default to x86_64 Rust 1.88 image based on Debian Bullseye
ARG RUST_IMAGE="rust:1.88-bullseye@sha256:8e3c421122bf4cd3b2a866af41a4dd52d87ad9e315fd2cb5100e87a7187a9816"
# Single version tag to maintain for reproducible builds.
# This multi-arch index digest resolves to the correct arch-specific image at build time.
# To update: run `docker buildx imagetools inspect rust:X.Y-bookworm` and replace the digest below.
# rust:1.95-bookworm
ARG RUST_IMAGE="rust:1.95-bookworm@sha256:225aa827d55fae9816a0492284592827e794a5247c6c6a961c3b471b344295ec"
FROM ${RUST_IMAGE} AS builder
# Install specific version of the build dependencies
RUN apt-get update && apt-get install -y libclang-dev=1:11.0-51+nmu5 cmake=3.18.4-2+deb11u1 libjemalloc-dev=5.2.1-3
# Install pinned versions of the build dependencies
RUN apt-get update && apt-get install -y \
libclang-dev=1:14.0-55.7~deb12u1 \
cmake=3.25.1-1 \
libjemalloc-dev=5.3.0-1
ARG RUST_TARGET="x86_64-unknown-linux-gnu"
@@ -14,11 +20,21 @@ WORKDIR /app
# Build the project with the reproducible settings
RUN make build-reproducible
# Move the binary to a standard location
RUN mv /app/target/${RUST_TARGET}/release/lighthouse /lighthouse
# Move the binary and runtime libs to fixed paths for arch-independent copying below.
# ldd shows the binary dynamically requires: libz.so.1, libstdc++.so.6, libgcc_s.so.1,
# and glibc — the latter three are already in distroless/cc; only libz needs to be copied.
# libssl/libcrypto are statically linked by this build (no dynamic dep on them).
# libz lives under an arch-specific triplet dir; normalise to /libs/ for a clean COPY below.
RUN mv /app/target/${RUST_TARGET}/release/lighthouse /lighthouse \
&& mkdir /libs \
&& find /usr/lib -maxdepth 3 -name "libz.so.1" -exec cp {} /libs/ \;
# Create a minimal final image with just the binary
FROM gcr.io/distroless/cc-debian12:nonroot-6755e21ccd99ddead6edc8106ba03888cbeed41a
# Final image: distroless/cc-debian12 (Bookworm) — matches builder OS for ABI compatibility.
# The cc variant already includes libc, libgcc, and libstdc++.
# gcr.io/distroless/cc-debian12:nonroot
FROM gcr.io/distroless/cc-debian12:nonroot@sha256:e2d29aec8061843706b7e484c444f78fafb05bfe47745505252b1769a05d14f1
COPY --from=builder /libs/libz.so.1 /usr/lib/
COPY --from=builder /lighthouse /lighthouse
ENTRYPOINT [ "/lighthouse" ]

View File

@@ -118,10 +118,6 @@ JEMALLOC_OVERRIDE = /usr/lib/$(JEMALLOC_LIB_ARCH)-linux-gnu/libjemalloc.a
# Default target architecture
RUST_TARGET ?= x86_64-unknown-linux-gnu
# Default images for different architectures
RUST_IMAGE_AMD64 ?= rust:1.88-bullseye@sha256:8e3c421122bf4cd3b2a866af41a4dd52d87ad9e315fd2cb5100e87a7187a9816
RUST_IMAGE_ARM64 ?= rust:1.88-bullseye@sha256:8b22455a7ce2adb1355067638284ee99d21cc516fab63a96c4514beaf370aa94
.PHONY: build-reproducible
build-reproducible: ## Build the lighthouse binary into `target` directory with reproducible builds
SOURCE_DATE_EPOCH=$(SOURCE_DATE) \
@@ -132,11 +128,13 @@ build-reproducible: ## Build the lighthouse binary into `target` directory with
JEMALLOC_OVERRIDE=${JEMALLOC_OVERRIDE} \
cargo build --bin lighthouse --features "$(FEATURES_REPRODUCIBLE)" --profile "$(PROFILE)" --locked --target $(RUST_TARGET)
# Rust image digest is the single source of truth in Dockerfile.reproducible.
# These targets pass no --build-arg RUST_IMAGE so Docker uses the ARG default from that file.
.PHONY: build-reproducible-x86_64
build-reproducible-x86_64: ## Build reproducible x86_64 Docker image
DOCKER_BUILDKIT=1 docker build \
--build-arg RUST_TARGET="x86_64-unknown-linux-gnu" \
--build-arg RUST_IMAGE=$(RUST_IMAGE_AMD64) \
-f Dockerfile.reproducible \
-t lighthouse:reproducible-amd64 .
@@ -145,7 +143,6 @@ build-reproducible-aarch64: ## Build reproducible aarch64 Docker image
DOCKER_BUILDKIT=1 docker build \
--platform linux/arm64 \
--build-arg RUST_TARGET="aarch64-unknown-linux-gnu" \
--build-arg RUST_IMAGE=$(RUST_IMAGE_ARM64) \
-f Dockerfile.reproducible \
-t lighthouse:reproducible-arm64 .

View File

@@ -0,0 +1,9 @@
#!/bin/sh
# AppRun - AppImage entry point for Lighthouse
# Resolves the real location of the AppImage and executes the bundled binary.
set -e
SELF=$(readlink -f "$0")
HERE=$(dirname "$SELF")
exec "$HERE/usr/bin/lighthouse" "$@"

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Name=Lighthouse
Comment=Ethereum consensus client
Exec=lighthouse
Icon=lighthouse
Type=Application
Categories=Network;
Terminal=true

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 47 51" fill="#fff">
<path d="M34.6763 27.5954C34.4546 29.842 33.6617 30.8785 32.2989 32.5242L37.3878 37.603L35.6756 39.3118L30.5867 34.233C28.8745 35.593 26.9251 36.4012 24.7371 36.6533V43.8204H22.3597V36.6533C20.1409 36.3998 18.1901 35.593 16.5101 34.233L11.4184 39.3131L9.70623 37.6044L14.7951 32.5256C14.0976 31.7035 13.5587 30.8014 13.1784 29.8196C12.798 28.8391 12.5286 27.7943 12.37 26.6863H5.18854V24.3137H12.37C12.5286 23.2057 12.798 22.1777 13.1784 21.228C13.5587 20.2476 14.0976 19.3288 14.7951 18.4744L9.70623 13.3956L11.4184 11.6869L16.5073 16.7656C18.1564 15.4056 20.1058 14.6142 22.3569 14.3929V7.17818H24.7343V14.3929C26.9532 14.6464 28.904 15.4378 30.5839 16.7656L35.6728 11.6869L37.385 13.3956L32.2961 18.4744C33.6588 20.1509 34.4518 21.1888 34.6735 23.4032H46.9972C45.9376 11.4081 35.844 2 23.547 2C10.5427 2 0 12.5216 0 25.5C0 38.4784 10.5427 49 23.547 49C35.844 49 45.9376 39.5919 47 27.5954H34.6763Z"/>
</svg>

After

Width:  |  Height:  |  Size: 986 B