From 855aa8d3d320a28e43fb60f1f382fcce143da85e Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 25 Nov 2025 17:27:39 +0000 Subject: [PATCH 1/4] Remove multi-arch Docker image support Production only supports linux/amd64. Publishing ARM64 images caused Docker to automatically select the ARM variant on ARM hosts, creating dev/prod architecture mismatch and potential platform-specific bugs. ARM Mac users will use emulation automatically, ensuring local dev matches production deployment. --- .changeset/remove-multi-arch.md | 5 +++++ .github/workflows/pkg-pr-new.yml | 4 +--- .github/workflows/release.yml | 18 ++---------------- CLAUDE.md | 3 ++- examples/claude-code/Dockerfile | 3 --- examples/code-interpreter/Dockerfile | 4 ---- examples/minimal/Dockerfile | 3 --- examples/openai-agents/Dockerfile | 6 +----- examples/typescript-validator/Dockerfile | 5 ----- packages/sandbox/package.json | 6 +++--- tests/integration/Dockerfile | 4 ---- 11 files changed, 14 insertions(+), 47 deletions(-) create mode 100644 .changeset/remove-multi-arch.md diff --git a/.changeset/remove-multi-arch.md b/.changeset/remove-multi-arch.md new file mode 100644 index 00000000..d00670df --- /dev/null +++ b/.changeset/remove-multi-arch.md @@ -0,0 +1,5 @@ +--- +'@cloudflare/sandbox': patch +--- + +Publish Docker images for linux/amd64 only to ensure dev/prod parity. ARM Mac users will automatically use emulation, matching production deployment behavior. This prevents architecture-specific bugs caused by Docker automatically selecting ARM64 variants on ARM hosts. diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml index c601a6a8..696644b5 100644 --- a/.github/workflows/pkg-pr-new.yml +++ b/.github/workflows/pkg-pr-new.yml @@ -82,13 +82,11 @@ jobs: with: context: . file: packages/sandbox/Dockerfile - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 push: true tags: cloudflare/sandbox:${{ steps.package-version.outputs.version }} cache-from: | type=gha,scope=preview-pr-${{ github.event.pull_request.number }} - type=gha,scope=pr-${{ github.event.pull_request.number }}-amd64 - type=gha,scope=release-amd64 type=gha,scope=release cache-to: type=gha,mode=max,scope=preview-pr-${{ github.event.pull_request.number }} build-args: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9a0396c4..c1353bd2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -177,29 +177,15 @@ jobs: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - name: Build and cache single-arch image (for PR cache reuse) - uses: docker/build-push-action@v6 - with: - context: . - file: packages/sandbox/Dockerfile - platforms: linux/amd64 - push: false # Don't push, just cache - cache-from: type=gha,scope=release-amd64 - cache-to: type=gha,mode=max,scope=release-amd64 - build-args: | - SANDBOX_VERSION=${{ needs.unit-tests.outputs.version }} - - name: Build and push Docker image uses: docker/build-push-action@v6 with: context: . file: packages/sandbox/Dockerfile - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64 push: true tags: cloudflare/sandbox:${{ needs.unit-tests.outputs.version }} - cache-from: | - type=gha,scope=release-amd64 - type=gha,scope=release + cache-from: type=gha,scope=release cache-to: type=gha,mode=max,scope=release build-args: | SANDBOX_VERSION=${{ needs.unit-tests.outputs.version }} diff --git a/CLAUDE.md b/CLAUDE.md index f2381a32..67e76768 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -385,9 +385,10 @@ Note: Container isolation is handled at the Cloudflare platform level (VMs), not - **Beta releases**: Published automatically on every push to main (`@beta` tag on npm) - **Stable releases**: When changesets exist, the "Version Packages" PR is auto-created. Merging it triggers: 1. Version bump in `package.json` - 2. Docker image build and push to Docker Hub (multi-arch: amd64, arm64) + 2. Docker image build and push to Docker Hub (linux/amd64 architecture only to match production) 3. npm package publish with updated version - **Version synchronization**: Docker image version always matches npm package version (enforced via `ARG SANDBOX_VERSION` in Dockerfile) +- **Architecture**: Images are built for linux/amd64 only, matching Cloudflare's production container runtime. ARM Mac users will automatically use emulation (Rosetta/QEMU) for local development, ensuring perfect dev/prod parity. **SDK version tracked in**: `packages/sandbox/src/version.ts` diff --git a/examples/claude-code/Dockerfile b/examples/claude-code/Dockerfile index 8b7bdf0a..875e5c8d 100644 --- a/examples/claude-code/Dockerfile +++ b/examples/claude-code/Dockerfile @@ -2,6 +2,3 @@ FROM docker.io/cloudflare/sandbox:0.5.3 RUN npm install -g @anthropic-ai/claude-code ENV COMMAND_TIMEOUT_MS=300000 EXPOSE 3000 - -# On a Mac with Apple Silicon, you might need to specify the platform: -# FROM --platform=linux/arm64 docker.io/cloudflare/sandbox:0.5.3 diff --git a/examples/code-interpreter/Dockerfile b/examples/code-interpreter/Dockerfile index 28a1a46c..5ef3c558 100644 --- a/examples/code-interpreter/Dockerfile +++ b/examples/code-interpreter/Dockerfile @@ -3,7 +3,3 @@ # you should use the official image instead: # FROM docker.io/cloudflare/sandbox:0.5.3 FROM cloudflare/sandbox-test:0.5.3 - -# On a mac, you might need to actively pick up the -# arm64 build of the image. -# FROM --platform=linux/arm64 cloudflare/sandbox-test:0.5.3 diff --git a/examples/minimal/Dockerfile b/examples/minimal/Dockerfile index b8037828..486d8b7c 100644 --- a/examples/minimal/Dockerfile +++ b/examples/minimal/Dockerfile @@ -1,7 +1,4 @@ FROM docker.io/cloudflare/sandbox:0.5.3 -# On a Mac with Apple Silicon, you might need to specify the platform: -# FROM --platform=linux/arm64 docker.io/cloudflare/sandbox:0.5.3 - # Required during local development to access exposed ports EXPOSE 8080 diff --git a/examples/openai-agents/Dockerfile b/examples/openai-agents/Dockerfile index 22f639a6..9e2fa45d 100644 --- a/examples/openai-agents/Dockerfile +++ b/examples/openai-agents/Dockerfile @@ -2,11 +2,7 @@ # Whenever you're integrating with sandbox SDK in your own project, # you should use the official image instead: # FROM docker.io/cloudflare/sandbox:0.5.3 -# FROM cloudflare/sandbox-test:0.5.3 - -# On a mac, you might need to actively pick up the -# arm64 build of the image. -FROM --platform=linux/arm64 cloudflare/sandbox-test:0.5.3 +FROM cloudflare/sandbox-test:0.5.3 # Required during local development to access exposed ports EXPOSE 8080 diff --git a/examples/typescript-validator/Dockerfile b/examples/typescript-validator/Dockerfile index 2f93a7af..88cd266c 100644 --- a/examples/typescript-validator/Dockerfile +++ b/examples/typescript-validator/Dockerfile @@ -1,11 +1,6 @@ # Use Cloudflare sandbox as base FROM docker.io/cloudflare/sandbox:0.5.3 -# On a mac, you might need to actively pick up the -# arm64 build of the image. -# FROM --platform=linux/arm64 cloudflare/sandbox-test:0.5.3 - - # Install esbuild for TypeScript bundling RUN npm install -g esbuild diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json index 72e93f53..15891389 100644 --- a/packages/sandbox/package.json +++ b/packages/sandbox/package.json @@ -34,9 +34,9 @@ "check": "biome check && npm run typecheck", "fix": "biome check --fix && npm run typecheck", "typecheck": "tsc --noEmit", - "docker:local": "cd ../.. && docker build -f packages/sandbox/Dockerfile --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox-test:$npm_package_version .", - "docker:publish": "cd ../.. && docker buildx build --platform linux/amd64,linux/arm64 -f packages/sandbox/Dockerfile --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox:$npm_package_version --push .", - "docker:publish:beta": "cd ../.. && docker buildx build --platform linux/amd64,linux/arm64 -f packages/sandbox/Dockerfile --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox:$npm_package_version-beta --push .", + "docker:local": "cd ../.. && docker build -f packages/sandbox/Dockerfile --platform linux/amd64 --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox-test:$npm_package_version .", + "docker:publish": "cd ../.. && docker buildx build --platform linux/amd64 -f packages/sandbox/Dockerfile --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox:$npm_package_version --push .", + "docker:publish:beta": "cd ../.. && docker buildx build --platform linux/amd64 -f packages/sandbox/Dockerfile --build-arg SANDBOX_VERSION=$npm_package_version -t cloudflare/sandbox:$npm_package_version-beta --push .", "test": "vitest run --config vitest.config.ts \"$@\"", "test:e2e": "cd ../.. && vitest run --config vitest.e2e.config.ts \"$@\"" }, diff --git a/tests/integration/Dockerfile b/tests/integration/Dockerfile index a54f9629..92ab56b9 100644 --- a/tests/integration/Dockerfile +++ b/tests/integration/Dockerfile @@ -4,10 +4,6 @@ # FROM docker.io/cloudflare/sandbox:0.5.3 FROM cloudflare/sandbox-test:0.5.3 -# On a mac, you might need to actively pick up the -# arm64 build of the image. -# FROM --platform=linux/arm64 cloudflare/sandbox-test:0.5.3 - # Expose the ports you want to expose EXPOSE 8080 EXPOSE 3001 From 4d9f282948feaa65ed9a32fe257f106b16c3afe6 Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 25 Nov 2025 17:30:26 +0000 Subject: [PATCH 2/4] Fix pre-commit hook for package.json files Remove json from biome-fix glob since biome ignores package.json files. Prettier in the format command already handles JSON formatting. --- lefthook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lefthook.yml b/lefthook.yml index 55c7f886..abfa41f4 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -4,7 +4,7 @@ pre-commit: commands: biome-fix: - glob: '{packages,examples,sites}/**/*.{js,ts,tsx,json,astro}' + glob: '{packages,examples,sites}/**/*.{js,ts,tsx,astro}' run: npx biome check --write {staged_files} stage_fixed: true From 5edb6e3763a10c1a2deecf5ba9cd190c2460ec27 Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 25 Nov 2025 18:27:46 +0000 Subject: [PATCH 3/4] Fix base images in examples --- examples/code-interpreter/Dockerfile | 6 +----- examples/openai-agents/Dockerfile | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/examples/code-interpreter/Dockerfile b/examples/code-interpreter/Dockerfile index 5ef3c558..1caebe95 100644 --- a/examples/code-interpreter/Dockerfile +++ b/examples/code-interpreter/Dockerfile @@ -1,5 +1 @@ -# This image is unique to this repo, and you'll never need it. -# Whenever you're integrating with sandbox SDK in your own project, -# you should use the official image instead: -# FROM docker.io/cloudflare/sandbox:0.5.3 -FROM cloudflare/sandbox-test:0.5.3 +FROM docker.io/cloudflare/sandbox:0.5.3 diff --git a/examples/openai-agents/Dockerfile b/examples/openai-agents/Dockerfile index 9e2fa45d..d8ce8a96 100644 --- a/examples/openai-agents/Dockerfile +++ b/examples/openai-agents/Dockerfile @@ -1,8 +1,4 @@ -# This image is unique to this repo, and you'll never need it. -# Whenever you're integrating with sandbox SDK in your own project, -# you should use the official image instead: -# FROM docker.io/cloudflare/sandbox:0.5.3 -FROM cloudflare/sandbox-test:0.5.3 +FROM docker.io/cloudflare/sandbox:0.5.3 # Required during local development to access exposed ports EXPOSE 8080 From f5954157d9b3c27f329e17a96a0bb9ba283bfad0 Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 25 Nov 2025 18:32:13 +0000 Subject: [PATCH 4/4] Add Docker setup guide link to README Link to official docs setup guide in prerequisites for Docker installation and troubleshooting. --- packages/sandbox/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sandbox/README.md b/packages/sandbox/README.md index f1b9deaa..d17e1fbc 100644 --- a/packages/sandbox/README.md +++ b/packages/sandbox/README.md @@ -15,7 +15,7 @@ Perfect for AI code execution, interactive development environments, data analys ### Prerequisites 1. Install [Node.js](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) (version 16.17.0 or later) -2. Ensure Docker is running locally +2. Ensure Docker is running locally ([see setup guide](https://developers.cloudflare.com/sandbox/get-started/#ensure-docker-is-running-locally)) 3. For deploying to production, sign up for a [Cloudflare account](https://dash.cloudflare.com/sign-up/workers-and-pages) ### 1. Create a new project