Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
0

Configure Feed

Select the types of activity you want to include in your feed.

ircd.rs / docker / Dockerfile.leveva
4.0 kB 89 lines
1# Build the `leveva` IRC daemon binary. 2# 3# leveva is a workspace member, so the whole workspace is copied in: cargo needs 4# every member manifest to resolve the lockfile, even though `-p leveva` only 5# compiles leveva and its path dependency (leveva-iauth). The build is pure Rust 6# (rustls/ring for TLS, no system OpenSSL), and we cross-compile to a fully 7# static musl target with cargo-zigbuild, so the runtime image needs nothing. 8# 9# The build stage pins itself to the native BUILDPLATFORM (no QEMU emulation); 10# cargo-zigbuild then cross-compiles to whichever musl triple matches the 11# requested TARGETARCH (amd64 -> x86_64, arm64 -> aarch64). Both ARGs are 12# populated automatically by `docker buildx`. 13 14FROM --platform=$BUILDPLATFORM rust:1-bookworm AS build 15WORKDIR /src 16 17# Install zig from ziglang.org rather than apt: Debian's package is far behind, 18# and leveva's cross-build path (cargo-zigbuild) wants a current toolchain. 19# The tarball is a self-contained static binary; just extract and symlink. 20ARG ZIG_VERSION=0.16.0 21RUN apt-get update \ 22 && apt-get install -y --no-install-recommends curl xz-utils ca-certificates \ 23 && rm -rf /var/lib/apt/lists/* \ 24 && case "$(dpkg --print-architecture)" in \ 25 amd64) ZIG_ARCH=x86_64 ;; \ 26 arm64) ZIG_ARCH=aarch64 ;; \ 27 riscv64) ZIG_ARCH=riscv64 ;; \ 28 ppc64le) ZIG_ARCH=powerpc64le ;; \ 29 *) echo "unsupported arch: $(dpkg --print-architecture)" >&2; exit 1 ;; \ 30 esac \ 31 && curl -fsSL "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" \ 32 | tar -xJ -C /opt \ 33 && ln -s "/opt/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}/zig" /usr/local/bin/zig \ 34 && cargo install cargo-zigbuild 35 36# Map the Docker TARGETARCH to a Rust musl triple, add the std component for it, 37# then cross-build. The artifact is copied to a stable path (/leveva) so the 38# runtime stage's COPY doesn't need to know the triple. 39ARG TARGETARCH 40 41# Copy the full workspace (path deps + lockfile) and build only leveva. 42COPY . . 43RUN set -eux; \ 44 case "$TARGETARCH" in \ 45 amd64) RUST_TARGET=x86_64-unknown-linux-musl ;; \ 46 arm64) RUST_TARGET=aarch64-unknown-linux-musl ;; \ 47 riscv64) RUST_TARGET=riscv64gc-unknown-linux-musl ;; \ 48 ppc64le) RUST_TARGET=powerpc64le-unknown-linux-musl ;; \ 49 ppc64) RUST_TARGET=powerpc64-unknown-linux-musl ;; \ 50 *) echo "unsupported TARGETARCH: $TARGETARCH" >&2; exit 1 ;; \ 51 esac; \ 52 rustup target add "$RUST_TARGET"; \ 53 cargo zigbuild --release --locked --target "$RUST_TARGET" -p leveva --bin leveva; \ 54 cp "target/$RUST_TARGET/release/leveva" /leveva 55 56# --- 57 58# A throwaway stage that supplies the two pieces of userland the scratch runtime 59# needs: the CA bundle and the unprivileged service account. Both are pure data 60# (PEM files / passwd entries), so we pin this to the native BUILDPLATFORM — it 61# never has to match the target arch, and the alpine image only needs to exist 62# for the builder. This is what lets the runtime work on ppc64 (big endian), 63# which has no official alpine/debian image of its own. 64FROM --platform=$BUILDPLATFORM alpine:3.24 AS rootfs 65RUN apk add --no-cache ca-certificates \ 66 && addgroup -g 10001 leveva \ 67 && adduser -S -u 10001 -G leveva -h /var/lib/leveva leveva 68 69# --- 70 71# The binary is a fully static musl build, so the runtime image needs nothing but 72# the binary itself plus the CA bundle and account skeleton from the rootfs stage. 73# scratch has no per-arch base image, so every target platform is satisfied. 74FROM scratch AS runtime 75 76COPY --from=rootfs /etc/ssl/certs /etc/ssl/certs 77COPY --from=rootfs /etc/passwd /etc/passwd 78COPY --from=rootfs /etc/group /etc/group 79COPY --from=rootfs --chown=10001:10001 /var/lib/leveva /var/lib/leveva 80COPY --from=build /leveva /usr/local/bin/leveva 81 82# Config lives in /etc/leveva; runtime state (none today) under /var/lib/leveva. 83WORKDIR /var/lib/leveva 84USER leveva 85 86# 6667 = clients, 6697 = TLS clients, 6067 = server-only (S2S) links. 87EXPOSE 6667 6697 6067 88 89CMD ["/usr/local/bin/leveva"]