mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-02 23:56:24 +08:00
* Add Docker Hub workflow and optimize Dockerfile for size Switch from Debian bookworm-slim to Alpine for both build and runtime stages, reducing image size from 162MB to 64MB (60% reduction): - Alpine + musl: runtime drops from ~88MB to ~11MB, no libssl needed (project uses rustls throughout) - Profile dist: thin LTO for smaller binary (74MB → 53MB) - panic=abort + codegen-units=1: eliminates unwinding tables and enables better whole-program optimization New docker.yml workflow builds and pushes to nearaidev/ironclaw on Docker Hub, triggered on push to main, version tags, or manual dispatch. Uses GitHub Actions cache for Docker layer caching. Tested locally (macOS) and on gpu07 (Ubuntu): gateway serves HTTP 200, SSE streams, chat API, memory/tools/settings endpoints all functional, ~700ms startup time. * Address review feedback - Fix image size comment (~30MB → remove specific number) - Add actions:write permission for GHA cache - Only push semver tag on version tag events (not on every main push) - Add comment explaining why panic=abort is set via env var * Make docker workflow release-only via workflow_call Replace push trigger with workflow_call so release.yml can invoke it, plus workflow_dispatch for on-demand builds. This prevents every staging promotion to main from publishing a new image. Simplified tag logic — always pushes version + latest + sha. * Pin cargo-chef and wasm-tools versions for reproducible builds
86 lines
2.2 KiB
Docker
86 lines
2.2 KiB
Docker
# Multi-stage Dockerfile for the IronClaw agent (cloud deployment).
|
|
#
|
|
# Uses cargo-chef for dependency caching — only rebuilds deps when
|
|
# Cargo.toml/Cargo.lock change, not on every source edit.
|
|
#
|
|
# Alpine-based build + runtime for a minimal image size.
|
|
# Statically links against musl; no glibc or libssl needed at runtime.
|
|
#
|
|
# Build:
|
|
# docker build --platform linux/amd64 -t ironclaw:latest .
|
|
#
|
|
# Run:
|
|
# docker run --env-file .env -p 3000:3000 ironclaw:latest
|
|
|
|
# Stage 1: Install cargo-chef
|
|
FROM rust:1.92-alpine AS chef
|
|
|
|
RUN apk add --no-cache musl-dev pkgconfig cmake gcc g++ make perl \
|
|
&& rustup target add wasm32-wasip2 \
|
|
&& cargo install cargo-chef@0.1.77 wasm-tools@1.246.1
|
|
|
|
WORKDIR /app
|
|
|
|
# Stage 2: Generate the dependency recipe (changes only when Cargo.toml/lock change)
|
|
FROM chef AS planner
|
|
|
|
COPY Cargo.toml Cargo.lock ./
|
|
COPY crates/ crates/
|
|
COPY build.rs build.rs
|
|
COPY src/ src/
|
|
COPY tests/ tests/
|
|
COPY benches/ benches/
|
|
COPY migrations/ migrations/
|
|
COPY registry/ registry/
|
|
COPY channels-src/ channels-src/
|
|
COPY wit/ wit/
|
|
COPY providers.json providers.json
|
|
|
|
RUN cargo chef prepare --recipe-path recipe.json
|
|
|
|
# Stage 3: Build dependencies (cached unless Cargo.toml/lock change)
|
|
FROM chef AS deps
|
|
|
|
# Docker-only overrides for the dist profile (not in Cargo.toml because
|
|
# cargo-dist uses dist for release binaries that need unwinding).
|
|
ENV CARGO_PROFILE_DIST_PANIC=abort \
|
|
CARGO_PROFILE_DIST_CODEGEN_UNITS=1
|
|
|
|
COPY --from=planner /app/recipe.json recipe.json
|
|
RUN cargo chef cook --profile dist --recipe-path recipe.json
|
|
|
|
# Stage 4: Build the actual binary (only recompiles ironclaw source)
|
|
FROM deps AS builder
|
|
|
|
COPY Cargo.toml Cargo.lock ./
|
|
COPY crates/ crates/
|
|
COPY build.rs build.rs
|
|
COPY src/ src/
|
|
COPY tests/ tests/
|
|
COPY benches/ benches/
|
|
COPY migrations/ migrations/
|
|
COPY registry/ registry/
|
|
COPY channels-src/ channels-src/
|
|
COPY wit/ wit/
|
|
COPY providers.json providers.json
|
|
|
|
RUN cargo build --profile dist --bin ironclaw
|
|
|
|
# Stage 5: Minimal runtime
|
|
FROM alpine:3.21
|
|
|
|
RUN apk add --no-cache ca-certificates
|
|
|
|
COPY --from=builder /app/target/dist/ironclaw /usr/local/bin/ironclaw
|
|
COPY --from=builder /app/migrations /app/migrations
|
|
|
|
# Non-root user
|
|
RUN adduser -D -u 1000 ironclaw
|
|
USER ironclaw
|
|
|
|
EXPOSE 3000
|
|
|
|
ENV RUST_LOG=ironclaw=info
|
|
|
|
ENTRYPOINT ["ironclaw"]
|