Add Docker Hub workflow and optimize Dockerfile for size - #1886
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the project to version 0.24.0, including a detailed changelog and updated channel registry artifacts. The Dockerfile is migrated to an Alpine-based image for reduced size, and a 'dist' build profile is implemented with specific optimization flags. The MCP protocol now correctly supports camelCase deserialization for tool annotations. Review feedback recommends removing the heavy 'wasm-tools' dependency from the Docker build if it is not required and suggests moving build profile configurations from environment variables to Cargo.toml to ensure consistency and better visibility of panic behavior changes.
There was a problem hiding this comment.
Pull request overview
Introduces a Docker image publishing pipeline and Dockerfile optimizations to reduce the shipped container size, alongside a release/version bump and registry metadata updates.
Changes:
- Switches the Docker build/runtime to Alpine + musl and builds with the
distprofile to reduce image/binary size. - Adds a GitHub Actions workflow to build and push
nearaidev/ironclawto Docker Hub with tagging + Buildx cache. - Updates MCP tool annotation deserialization behavior and bumps release artifacts/versioning (Cargo + changelog + channel registry entries).
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
Dockerfile |
Moves builder/runtime to Alpine and uses --profile dist output for a smaller runtime image. |
.github/workflows/docker.yml |
New workflow to build/push Docker images with metadata-based tagging and GHA cache. |
src/tools/mcp/protocol.rs |
Ensures MCP tool annotation fields deserialize from camelCase; adds a regression test. |
registry/channels/slack.json |
Bumps Slack channel registry version and artifact URL/SHA. |
registry/channels/feishu.json |
Bumps Feishu channel registry version and artifact URL/SHA. |
registry/channels/discord.json |
Bumps Discord channel registry version and artifact URL/SHA. |
Cargo.toml |
Updates crate version to 0.24.0. |
Cargo.lock |
Updates lockfile entry for crate version 0.24.0. |
CHANGELOG.md |
Adds 0.24.0 release notes section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| && rm -rf /var/lib/apt/lists/* \ | ||
| RUN apk add --no-cache musl-dev pkgconfig cmake gcc g++ make perl \ | ||
| && rustup target add wasm32-wasip2 \ | ||
| && cargo install cargo-chef wasm-tools |
There was a problem hiding this comment.
cargo install cargo-chef wasm-tools without pinned versions makes the Docker build non-reproducible and can break unexpectedly when upstream releases new versions. Consider pinning versions (e.g., cargo install cargo-chef --version ...) or using prebuilt binaries/images for these tools.
| && cargo install cargo-chef wasm-tools | |
| && cargo install cargo-chef --version 0.1.76 \ | |
| && cargo install wasm-tools --version 1.221.0 |
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.
b3ef620 to
d145144
Compare
- 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
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| tags: | | ||
| # On default branch: latest | ||
| type=raw,value=latest,enable={{is_default_branch}} | ||
| # On version tags: extract semver (immutable) | ||
| type=match,pattern=(?:ironclaw-)?v(.*),group=1 | ||
| # Manual override | ||
| type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }} | ||
| # Short SHA for all builds | ||
| type=sha,prefix= |
There was a problem hiding this comment.
The workflow currently tags latest (default branch) and sha (all builds), but it does not add a Cargo.toml semver tag on pushes to main. This conflicts with the PR description (“latest + version on main”). If you want a version tag on main, add a tag rule that uses the extracted version output (or type=semver/type=raw based on it).
|
@claude review |
|
Trigger strategy — maybe you might want to consider making this release-only instead of firing on every main push. Replace push: branches/tags with workflow_call so release.yml can invoke it, and keep workflow_dispatch for on-demand pushes. Otherwise every staging promotion to main publishes a new image. |
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.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
* 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
* 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
Summary
nearaidev/ironclawon Docker Hubpanic=abort, andcodegen-units=1Dockerfile changes
libsslneeded (project uses rustls throughout)--profile dist: thin LTO eliminates dead code across crate boundariespanic=abort+codegen-units=1: removes unwinding tables, enables better whole-program optimizationWorkflow (
docker.yml)workflow_call(for release.yml integration) andworkflow_dispatch(on-demand)pushtrigger — avoids publishing on every staging→main promotionlatest+sha-<short>DOCKER_REGISTRY_USER(variable) andDOCKER_REGISTRY_TOKEN(secret) — same as ironclaw-dind repoTo wire into releases, add to
release.yml:Test plan
GET /api/health→{"status":"healthy"}/api/chat/events,/api/logs/events)POST /api/chat/send→{"status":"accepted"}