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 f6b28c73..aaf1158b 100644 --- a/examples/claude-code/Dockerfile +++ b/examples/claude-code/Dockerfile @@ -2,6 +2,3 @@ FROM docker.io/cloudflare/sandbox:0.5.4 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.4 diff --git a/examples/code-interpreter/Dockerfile b/examples/code-interpreter/Dockerfile index 62a13cb2..4017a67f 100644 --- a/examples/code-interpreter/Dockerfile +++ b/examples/code-interpreter/Dockerfile @@ -1,9 +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.4 -FROM cloudflare/sandbox-test:0.5.4 - -# 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.4 +FROM docker.io/cloudflare/sandbox:0.5.4 diff --git a/examples/minimal/Dockerfile b/examples/minimal/Dockerfile index 2a4a0cc9..54afe5a9 100644 --- a/examples/minimal/Dockerfile +++ b/examples/minimal/Dockerfile @@ -1,7 +1,4 @@ FROM docker.io/cloudflare/sandbox:0.5.4 -# On a Mac with Apple Silicon, you might need to specify the platform: -# FROM --platform=linux/arm64 docker.io/cloudflare/sandbox:0.5.4 - # Required during local development to access exposed ports EXPOSE 8080 diff --git a/examples/openai-agents/Dockerfile b/examples/openai-agents/Dockerfile index e13429ee..97372abf 100644 --- a/examples/openai-agents/Dockerfile +++ b/examples/openai-agents/Dockerfile @@ -1,12 +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.4 -# FROM cloudflare/sandbox-test:0.5.4 - -# 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.4 +FROM docker.io/cloudflare/sandbox:0.5.4 # Required during local development to access exposed ports EXPOSE 8080 diff --git a/examples/typescript-validator/Dockerfile b/examples/typescript-validator/Dockerfile index c976910a..18dc314b 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.4 -# 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.4 - - # Install esbuild for TypeScript bundling RUN npm install -g esbuild 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 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 diff --git a/packages/sandbox/package.json b/packages/sandbox/package.json index 3eaa7fe9..3071f3bd 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 fa552df0..1c7ca615 100644 --- a/tests/integration/Dockerfile +++ b/tests/integration/Dockerfile @@ -4,10 +4,6 @@ # FROM docker.io/cloudflare/sandbox:0.5.4 FROM cloudflare/sandbox-test:0.5.4 -# 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.4 - # Expose the ports you want to expose EXPOSE 8080 EXPOSE 3001