Skip to content

Run Dockerfile SDK stages on the build platform and publish for the target - #735

Merged
rockfordlhotka merged 1 commit into
mainfrom
dockerfiles-buildplatform
Oct 24, 2026
Merged

rockfordlhotka merged 1 commit into
mainfrom
dockerfiles-buildplatform

Conversation

@rockfordlhotka

Copy link
Copy Markdown
Member

Summary

  • All 14 remaining .NET Dockerfiles (deploy/Dockerfile.*, Dockerfile.scripts-manager, the five src/McpServer.*, src/RockBot.UserProxy.Blazor) run their SDK stage on --platform=$BUILDPLATFORM and pass -a $TARGETARCH to restore/build/publish.
  • src/ClaudeCodeProxy/Dockerfile: the build stage (emits only dist/ JavaScript) moves to $BUILDPLATFORM; the final stage is unchanged.
  • RockBot.Llm.Copilot.csproj: <IsRidAgnostic>false</IsRidAgnostic> so the referencing app's RID reaches it.

Companion to #734, which does the same for Dockerfile.browser.

Why

Building any of these images for linux/amd64 on an ARM64 host ran the .NET SDK under QEMU, where dotnet restore aborts (qemu: uncaught target signal 6). With the SDK stage native and -a $TARGETARCH, only the final stage's small RUN steps (useradd, chown) are emulated.

The Copilot CLI catch

GitHub.Copilot.SDK 0.2.0 bundles a native copilot binary and chooses its platform from RuntimeIdentifier, falling back to NETCoreSdkPortableRuntimeIdentifier (the build host). Its targets are in build/, not buildTransitive/, so they run only in RockBot.Llm.Copilot, which the agent consumes as a RID-agnostic project reference, and the .NET SDK strips RuntimeIdentifier from those. The first pass of this change therefore produced an amd64 agent image carrying runtimes/linux-arm64/native/copilot. Today's images are correct only because they're built on x64 hosts. IsRidAgnostic=false lets the RID flow through; RID-less builds (local dotnet build, tests, dotnet pack) keep the build-host fallback exactly as before.

Test plan

Run on an ARM64 Windows host (Docker Desktop, BuildKit):

  • All 15 images build for linux/arm64 and linux/amd64, except claude-code-proxy amd64: its unchanged final stage runs Claude's install.sh, whose x64 binary aborts under QEMU. That image still needs an x64 host to build for amd64.
  • Every amd64 image's native binaries are x86-64 and every arm64 image's are aarch64 (apphosts, and the agent's runtimes/linux-*/native/copilot).
  • amd64 agent image's file list (172 files) is identical to the deployed rockylhotka/rockbot-agent:0.16.14-pr732-2.
  • dotnet build RockBot.slnx (SDK 10), RockBot.Llm.Copilot.Tests 12/12 passing, dotnet pack src/RockBot.Llm.Copilot succeeds.
  • Not run: the amd64 images under emulation beyond file inspection; first real check is the next cluster deploy.

🤖 Generated with Claude Code

…arget

Every .NET Dockerfile now runs its SDK stage on $BUILDPLATFORM and passes
-a $TARGETARCH to restore/build/publish, so building an image for another
architecture no longer runs the .NET SDK under QEMU, where dotnet restore
aborts. ClaudeCodeProxy's build stage (it only emits dist/ JavaScript)
moves too; its final stage stays on the target platform.

RockBot.Llm.Copilot sets IsRidAgnostic=false. GitHub.Copilot.SDK's targets
live in build/, so they run only in this library, and pick the native
CLI from its RuntimeIdentifier or else the build host. As a RID-agnostic
project reference it had the agent's RID stripped, so a cross-arch
publish bundled the host's Copilot CLI (an amd64 agent image built on
arm64 shipped runtimes/linux-arm64/native/copilot).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rockfordlhotka
rockfordlhotka merged commit f4257b6 into main Oct 24, 2026
2 checks passed
@rockfordlhotka
rockfordlhotka deleted the dockerfiles-buildplatform branch October 24, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant