RavenClaws 1.0.0

Lightweight, secure Rust agent framework with multi-provider LLM support
Documentation
# RavenClaws — Multi-stage build for minimal production image
# Supports: linux/amd64, linux/arm64
# Usage: docker buildx build --platform linux/amd64,linux/arm64 -t ravenclaws:latest .
#        docker buildx build --build-arg INCLUDE_RAVENFABRIC=false -t ravenclaws:latest .
# syntax=docker/dockerfile:1

# Stage 1: Builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM

FROM --platform=$BUILDPLATFORM rust:1.86-slim-bookworm@sha256:57d415bbd61ce11e2d5f73de068103c7bd9f3188dc132c97cef4a8f62989e944 AS builder

WORKDIR /app

# Whether to include RavenFabric agent binary (adds ~15 MB)
ARG INCLUDE_RAVENFABRIC=true

# Map TARGETPLATFORM to Rust target triple and RavenFabric arch
ARG TARGETPLATFORM
RUN case "$TARGETPLATFORM" in \
        "linux/amd64")  echo "x86_64-unknown-linux-gnu" > /tmp/rust_target.txt \
                        && echo "amd64" > /tmp/rf_arch.txt ;; \
        "linux/arm64")  echo "aarch64-unknown-linux-gnu" > /tmp/rust_target.txt \
                        && echo "arm64" > /tmp/rf_arch.txt ;; \
        *)              echo "x86_64-unknown-linux-gnu" > /tmp/rust_target.txt \
                        && echo "amd64" > /tmp/rf_arch.txt ;; \
    esac

# Install dependencies, cross-compilation tools, and UPX
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
    pkg-config \
    libssl-dev \
    curl \
    ca-certificates \
    gcc-aarch64-linux-gnu \
    gcc-x86-64-linux-gnu \
    cmake \
    libc6-dev-arm64-cross \
    libc6-dev-amd64-cross \
    linux-libc-dev-arm64-cross \
    linux-libc-dev-amd64-cross \
    xz-utils \
    && rm -rf /var/lib/apt/lists/*

# Install UPX for binary compression
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN UPX_VERSION="5.2.0" && \
    curl -fsSL "https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-amd64_linux.tar.xz" \
      -o /tmp/upx.tar.xz && \
    tar xf /tmp/upx.tar.xz -C /tmp/ && \
    cp "/tmp/upx-${UPX_VERSION}-amd64_linux/upx" /usr/local/bin/ && \
    rm -rf /tmp/upx* && \
    upx --version

# Configure cargo for cross-compilation
RUN case "$TARGETPLATFORM" in \
        "linux/amd64")  \
            printf '[target.x86_64-unknown-linux-gnu]\nlinker = "x86_64-linux-gnu-gcc"\n' >> /usr/local/cargo/config.toml ;; \
        "linux/arm64")  \
            printf '[target.aarch64-unknown-linux-gnu]\nlinker = "aarch64-linux-gnu-gcc"\n' >> /usr/local/cargo/config.toml ;; \
    esac

# Download RavenFabric agent binary (optional runtime component)
ARG RAVENFABRIC_VERSION=v0.25.1
RUN if [ "$INCLUDE_RAVENFABRIC" = "true" ]; then \
      RF_ARCH=$(cat /tmp/rf_arch.txt) && \
      echo "Downloading RavenFabric ${RAVENFABRIC_VERSION} for ${RF_ARCH}..." && \
      curl -fsSL \
        "https://github.com/egkristi/RavenFabric-Published/releases/download/${RAVENFABRIC_VERSION}/ravenfabric-linux-${RF_ARCH}-agent" \
        -o /app/ravenfabric-agent && \
      curl -fsSL \
        "https://github.com/egkristi/RavenFabric-Published/releases/download/${RAVENFABRIC_VERSION}/SHA256SUMS" \
        -o /app/SHA256SUMS && \
      EXPECTED=$(grep "ravenfabric-linux-${RF_ARCH}-agent" /app/SHA256SUMS | cut -d' ' -f1) && \
      ACTUAL=$(sha256sum /app/ravenfabric-agent | cut -d' ' -f1) && \
      if [ "$EXPECTED" != "$ACTUAL" ]; then \
        echo "SHA256 mismatch: expected $EXPECTED, got $ACTUAL"; \
        exit 1; \
      fi && \
      echo "SHA256 match: $ACTUAL" && \
      chmod +x /app/ravenfabric-agent && \
      upx --best --lzma /app/ravenfabric-agent && \
      rm /app/SHA256SUMS; \
    else \
      echo "Skipping RavenFabric agent download (INCLUDE_RAVENFABRIC=false)"; \
      touch /app/ravenfabric-agent; \
    fi

# Copy manifests
COPY Cargo.toml Cargo.lock* ./
COPY src/ ./src/

# Build optimized release for the target platform
RUN TARGET=$(cat /tmp/rust_target.txt) && \
    rustup target add "$TARGET" && \
    cargo build --release --locked --target "$TARGET" && \
    cp "target/$TARGET/release/ravenclaws" /app/ravenclaws && \
    upx --best --lzma /app/ravenclaws

# Stage 2: Runtime (minimal)
FROM gcr.io/distroless/cc-debian12:nonroot@sha256:b0ae8e989418b458e0f25489bc3be523718938a2b70864cc0f6a00af1ddbd985

WORKDIR /app

# Copy RavenClaws binary (UPX-compressed)
COPY --from=builder /app/ravenclaws /app/ravenclaws

# Copy RavenFabric agent binary (optional — for swarm/supervisor modes)
COPY --from=builder /app/ravenfabric-agent /app/ravenfabric-agent

# Security: run as non-root, read-only filesystem
USER nonroot

# Environment variables (set via K8s/Docker)
ENV RAVENCLAW_CONFIG=/config/ravenclaws.toml
ENV RUST_LOG=info

# Health check (HTTP endpoint requires --serve mode)
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
    CMD ["/app/ravenclaws", "--version"]

ENTRYPOINT ["/app/ravenclaws"]
CMD ["--mode", "single"]