Skip to content

Add Docker Hub workflow and optimize Dockerfile for size - #1886

Merged
Evrard-Nil merged 5 commits into
stagingfrom
feat/docker-image-workflow
Apr 2, 2026
Merged

Evrard-Nil merged 5 commits into
stagingfrom
feat/docker-image-workflow

Conversation

@Evrard-Nil

@Evrard-Nil Evrard-Nil commented Apr 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Switch Dockerfile from Debian bookworm-slim to Alpine for both build and runtime stages, reducing image size from 162MB to 64MB (60% reduction)
  • Add GitHub Actions workflow to build and push to nearaidev/ironclaw on Docker Hub
  • Binary size reduced from 74MB to 53MB via thin LTO, panic=abort, and codegen-units=1

Dockerfile changes

  • Alpine + musl: runtime base drops from ~88MB to ~11MB; no libssl needed (project uses rustls throughout)
  • --profile dist: thin LTO eliminates dead code across crate boundaries
  • panic=abort + codegen-units=1: removes unwinding tables, enables better whole-program optimization
  • Pinned tool versions: cargo-chef@0.1.77, wasm-tools@1.246.1 for reproducible builds

Workflow (docker.yml)

  • Triggers via workflow_call (for release.yml integration) and workflow_dispatch (on-demand)
  • No push trigger — avoids publishing on every staging→main promotion
  • Tags: version from Cargo.toml + latest + sha-<short>
  • Uses Docker Buildx with GitHub Actions layer cache
  • Requires DOCKER_REGISTRY_USER (variable) and DOCKER_REGISTRY_TOKEN (secret) — same as ironclaw-dind repo

To wire into releases, add to release.yml:

docker:
  needs: [publish]
  uses: ./.github/workflows/docker.yml

Test plan

  • Built image locally on macOS (Docker Desktop, linux/amd64)
  • Built and tested on gpu07 (Ubuntu, native amd64)
  • Verified ~700ms startup time
  • Verified health endpoint: GET /api/health → {"status":"healthy"}
  • Verified web UI serves (HTML, CSS, JS — all 200)
  • Verified authenticated endpoints: gateway status, chat threads, tools list, memory tree, settings, profile, admin users, routines, extensions
  • Verified SSE streaming (/api/chat/events, /api/logs/events)
  • Verified chat send: POST /api/chat/send → {"status":"accepted"}
  • Verified DB migrations apply (libSQL, 4 incremental migrations)
Metric Before (Debian) After (Alpine) Change
Image size 162 MB 64 MB -60%
Binary size 74 MB 53 MB -28%
Compressed ~55 MB 24 MB -56%

Copilot AI review requested due to automatic review settings April 1, 2026 19:23
@github-actions github-actions Bot added scope: tool/mcp MCP client scope: sandbox Docker sandbox scope: ci CI/CD workflows scope: docs Documentation scope: dependencies Dependency updates size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: new First-time contributor labels Apr 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread Dockerfile Outdated
Comment thread Dockerfile

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 dist profile to reduce image/binary size.
  • Adds a GitHub Actions workflow to build and push nearaidev/ironclaw to 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.

Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
&& 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

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
&& cargo install cargo-chef wasm-tools
&& cargo install cargo-chef --version 0.1.76 \
&& cargo install wasm-tools --version 1.221.0

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/docker.yml Outdated
Comment thread Cargo.toml
@Evrard-Nil
Evrard-Nil changed the base branch from staging to main April 1, 2026 20:13
@Evrard-Nil
Evrard-Nil changed the base branch from main to staging April 1, 2026 20:13
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.
@Evrard-Nil
Evrard-Nil force-pushed the feat/docker-image-workflow branch from b3ef620 to d145144 Compare April 1, 2026 20:15
- 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
Copilot AI review requested due to automatic review settings April 1, 2026 21:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/docker.yml Outdated
Comment on lines +42 to +50
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=

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
@Evrard-Nil

Copy link
Copy Markdown
Contributor Author

@claude review

@Evrard-Nil
Evrard-Nil requested a review from henrypark133 April 2, 2026 01:00
@henrypark133

Copy link
Copy Markdown
Collaborator

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.
Copilot AI review requested due to automatic review settings April 2, 2026 01:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/docker.yml
Comment thread .github/workflows/docker.yml
@Evrard-Nil
Evrard-Nil merged commit a55aff9 into staging Apr 2, 2026
14 checks passed
@Evrard-Nil
Evrard-Nil deleted the feat/docker-image-workflow branch April 2, 2026 02:00
serrrfirat pushed a commit that referenced this pull request Apr 5, 2026
* 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
drchirag1991 pushed a commit to drchirag1991/ironclaw that referenced this pull request Apr 8, 2026
* 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
@ironclaw-ci ironclaw-ci Bot mentioned this pull request Apr 10, 2026
@ironclaw-ci ironclaw-ci Bot mentioned this pull request Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: new First-time contributor risk: medium Business logic, config, or moderate-risk modules scope: ci CI/CD workflows scope: dependencies Dependency updates scope: docs Documentation scope: sandbox Docker sandbox scope: tool/mcp MCP client size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants