Skip to content
Latchkey

How to Build a Multi-Arch Docker Image in Bitbucket Pipelines

Enable the docker service, register QEMU, and drive Buildx to push a multi-platform image from one step.

Add the built-in docker service for a daemon, install QEMU emulators, create a Buildx builder, then docker buildx build --platform ... --push.

Buildx with the docker service

The docker service gives a daemon; QEMU plus Buildx build both platforms and push.

bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Build multi-arch
        image: atlassian/default-image:4
        services:
          - docker
        script:
          - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USER" --password-stdin
          - docker run --privileged --rm tonistiigi/binfmt --install all
          - docker buildx create --use
          - docker buildx build --platform linux/amd64,linux/arm64 -t myorg/app:$BITBUCKET_COMMIT --push .

Gotchas

  • You must add - docker to services: or the docker commands cannot reach a daemon.
  • QEMU registration plus emulated arm64 builds are memory-hungry - set a larger step size: 2x.
  • Buildx pushes the manifest directly; a multi-arch image cannot be loaded into the local daemon.

Verify it actually works

Bitbucket validates bitbucket-pipelines.yml on push, and a schema error disables the pipeline rather than failing a build, which can look like nothing happened at all.

Terminal
# validate before pushing
curl -X POST -H "Content-Type: application/x-yaml" \
  --data-binary @bitbucket-pipelines.yml \
  https://api.bitbucket.org/2.0/repositories/<workspace>/<repo>/pipelines/validate

# confirm which pipeline definition matched
# Pipelines -> the run -> "Configuration" tab

Constraints that catch people out

  • Each step runs in a fresh container. Nothing persists between steps unless it is declared as an artifact or a cache.
  • The default memory allocation per step is limited, and service containers share that budget, so adding a database service can push a previously passing build into an out-of-memory failure.
  • Only branches with a matching branches: definition run; a push to an unmatched branch silently runs nothing.
  • Artifacts are passed forward only to later steps in the same pipeline, not between pipelines.

Frequently asked questions

How do I build a Multi-Arch Docker Image in Bitbucket Pipelines?
Add the built-in docker service for a daemon, install QEMU emulators, create a Buildx builder, then docker buildx build --platform ... --push.
Buildx with the docker service?
The docker service gives a daemon; QEMU plus Buildx build both platforms and push.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card