Skip to content

Wrangler Containers deploy should respect configured Docker Buildx builders #14375

Description

@jahands

Note: This issue was written by OpenAI Codex (gpt-5.5-high) on behalf of the reporter.

What versions & operating system are you using?

Reproduction project CI environment:

wrangler: 4.103.0
@cloudflare/containers: 0.0.30
Node.js: v24.13.0
Bun: 1.3.13
Docker Engine: 28.0.4
Docker Buildx: v0.23.0
BuildKit: v0.29.3-blacksmith
OS: Ubuntu 24.04.3 LTS on GitHub Actions / Blacksmith runner blacksmith-4vcpu-ubuntu-2404

Equivalent package versions from the repro:

{
  "packageManager": "bun@1.3.13",
  "dependencies": {
    "@cloudflare/containers": "0.0.30",
    "hono": "4.11.1"
  },
  "devDependencies": {
    "wrangler": "^4.103.0",
    "typescript": "5.9.3"
  }
}

Please provide a link to a minimal reproduction

https://github.com/uuid-rocks/workers-containers-blacksmith-demo

Relevant Actions runs:

Describe the Bug

wrangler deploy for a Worker with containers builds the configured Dockerfile internally. In CI, this makes it hard to use a Buildx-backed remote/persistent builder cache.

In the repro, the workflow sets up Blacksmith's Docker builder before running wrangler deploy:

- name: Setup Docker builder
  uses: useblacksmith/setup-docker-builder@v1

- name: Deploy Worker
  run: bun run deploy

The Blacksmith setup succeeds and creates a remote BuildKit builder, sets it as the default Buildx builder, and reports that the builder is ready. However, the subsequent wrangler deploy container build does not populate that BuildKit cache. The successful seed run completed an expensive Docker build, but the post-action cleanup showed:

Build cache contents:
ID  RECLAIMABLE  SIZE  LAST ACCESSED  USAGE COUNT
Reclaimable: 0B
Total:       0B

A second run then rebuilt the expensive dependency compilation step instead of hitting cache. In particular, the Dockerfile step running uv sync rebuilt scikit-learn and opencv-python-headless again:

#15 [builder 6/6] RUN --mount=type=cache,target=/root/.cache/uv ... uv sync --frozen --no-dev --compile-bytecode ...
#15 0.724    Building scikit-learn==1.6.1
#15 1.986    Building opencv-python-headless==4.11.0.86
#15 121.5       Built scikit-learn==1.6.1

Looking at the installed Wrangler bundle, the Containers build path appears to construct a plain Docker build command roughly like:

docker build --load -t <tag> --platform linux/amd64 --provenance=false -f - <context>

That works functionally, but it does not appear to use the Buildx remote builder/cache configured by docker buildx use ... in this CI setup. The result is that users cannot take advantage of CI provider BuildKit/sticky-disk caching for expensive Container image builds through wrangler deploy.

Expected behavior:

Wrangler Containers deploy should either:

  1. Use docker buildx build when Buildx is available / configured, respecting the selected Buildx builder, or
  2. Provide a supported Wrangler config/flag/env var to opt into Buildx and pass cache-related options, or
  3. Document a supported extension point for using CI-managed BuildKit builders with Containers.

Actual behavior:

Users have to wrap Wrangler's Docker binary and rewrite only the docker build invocation to docker buildx build while passing through docker login, docker tag, docker push, docker image inspect, etc. Example workaround required in the repro workflow:

- name: Setup Docker builder
  uses: useblacksmith/setup-docker-builder@v1
  with:
    nofallback: "true"

- name: Route Wrangler Docker builds through Buildx
  run: |
    cat > "$RUNNER_TEMP/docker-buildx-wrapper" <<'EOF'
    #!/usr/bin/env bash
    set -euo pipefail

    if [[ "${1:-}" == "build" ]]; then
      shift
      exec docker buildx build "$@"
    fi

    exec docker "$@"
    EOF
    chmod +x "$RUNNER_TEMP/docker-buildx-wrapper"
    echo "WRANGLER_DOCKER_BIN=$RUNNER_TEMP/docker-buildx-wrapper" >> "$GITHUB_ENV"

- name: Deploy Worker
  run: bun run deploy

This is brittle because it depends on Wrangler's internal Docker CLI shape and rewrites a subcommand externally.

Please provide any relevant error logs

From the successful seed run after a full 7+ minute Docker dependency build:

Blacksmith builder is ready for use by Docker
...
$ wrangler deploy
Building image workers-containers-blacksmith-demo-mycontainer:3878a2fc
...
#15 [builder 6/6] RUN --mount=type=cache,target=/root/.cache/uv ... uv sync --frozen --no-dev --compile-bytecode ...
#15 0.918    Building scikit-learn==1.6.1
#15 2.122    Building opencv-python-headless==4.11.0.86
#15 445.6       Built opencv-python-headless==4.11.0.86
#15 DONE 447.7s
...
Build cache contents:
ID  RECLAIMABLE  SIZE  LAST ACCESSED  USAGE COUNT
Reclaimable: 0B
Total:       0B
Successfully committed sticky disk

From the follow-up run:

Blacksmith builder is ready for use by Docker
...
Building image workers-containers-blacksmith-demo-mycontainer:bbc6dbd4
...
#15 [builder 6/6] RUN --mount=type=cache,target=/root/.cache/uv ... uv sync --frozen --no-dev --compile-bytecode ...
#15 0.724    Building scikit-learn==1.6.1
#15 1.986    Building opencv-python-headless==4.11.0.86
...
Build cache contents:
ID  RECLAIMABLE  SIZE  LAST ACCESSED  USAGE COUNT
Reclaimable: 0B
Total:       0B

Metadata

Metadata

Assignees

No one assigned

    Labels

    product:containersRelating to Cloudflare Containers: https://developers.cloudflare.com/containers/

    Fields

    No fields configured for Feature.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions