Choosing a Docker image for Bitbucket Pipelines: default vs custom
Decide between Atlassian’s default Docker image and a custom image for Bitbucket Pipelines. Compare startup time, security, reproducibility and maintenance, with a concrete pipeline example and validation steps.
01 Jul 2026, 10:03 UTC

The problem: tool missing or version drift in a pipeline step
A Bitbucket Pipelines build fails because the tool you need is not present in the runner, or the version is wrong. The decision is which Docker image to run the step in: Atlassian’s default image or a custom image you control.
Useful takeaway: start with the default image for simple, standard builds. Move to a custom image when you need a pinned tool version, OS packages, or reproducible environment that the default image does not provide.
Decision constraints
Image choice trades off startup speed against environment control.
- Build startup time. Larger images take longer to pull on first use and consume runner storage.
- Image size and pull cost. Default images are cached on Atlassian runners; custom images are pulled per pipeline.
- Security patching. The default image is maintained by Atlassian. A custom image is your responsibility.
- Reproducibility. A custom image pins OS, language and tool versions. The default image can change with tags.
- Maintenance overhead. Custom images require Dockerfile maintenance, registry access, and credential management.
Supported options
| Option | Typical image | Setup | Pull behavior | Tool availability |
|---|---|---|---|---|
| Default Atlassian image | atlassian/default-image:2 | Minimal. No image declaration needed. | Fast, pre-cached on runners | Base utilities only. Add tools via script installs. |
| Custom public image | e.g. maven:3.8-openjdk-11 | Declare image at pipeline or step level | Pull on first use, then cached | Full control over tool versions and OS packages |
| Custom private image | registry.example.com/team/ci-image:1.4.0 | Image + docker credentials in repository variables | Pull requires auth; risk of pull failure | Controlled and auditable environment |
Trade-offs
Default image reduces configuration and ensures the base OS receives updates from Atlassian. It is suitable for builds that only need git, bash and common package managers. The downside is limited tools and non-pinned versions if you install them at runtime.
Custom image guarantees environment consistency across branches and runners. You pin Maven, Node, Python, etc., and avoid install steps. The cost is longer initial pull times, larger storage use, and the need to patch the image yourself. Outdated images can introduce vulnerabilities.
Private registry images add credential management. You must store a username and password as secured repository variables and reference them in bitbucket-pipelines.yml. A missing or expired credential causes a pull failure and a blocked pipeline.
Concrete implementation
Example pipeline that uses a custom Maven image and caches the local repository. Run in the repository root as bitbucket-pipelines.yml. No permissions beyond normal pipeline execution are required. If using a private registry, add docker credentials via repository variables.
image: maven:3.8-openjdk-11
definitions:
caches:
maven: ~/.m2
pipelines:
default:
- step:
name: Build and test
caches:
- maven
script:
- mvn -v
- mvn -B clean verify
To override only one step while keeping the default image for others:
pipelines:
default:
- step:
name: Lint
script:
- npm ci
- npm run lint
- step:
name: Build
image: maven:3.8-openjdk-11
script:
- mvn -B package
Risks: a large custom image increases queue‑to‑start time. Pinned tags like 3.8-openjdk-11 reduce drift but still require periodic rebuilding for security updates. Do not embed secrets in the image.
Validation
Confirm the pipeline actually runs in the intended image.
- Run the pipeline from Bitbucket UI and open the step logs. Look for the Docker pull line that names the exact image tag used for the step.
- In the same step script, print tool versions to verify the environment. Example:
mvn -vornode -v. The log output should show the version you pinned in the image. - If you need to verify the image identifier, add a debug step that runs
cat /proc/self/cgroupor prints environment variables. Do not assumedocker inspectis available inside the normal step; it requires privileged access.
Limitations: image pull failures are silent until the step starts. Ensure the image is publicly accessible or that repository variables provide valid docker credentials for a private registry. Cache mounts are per‑image and do not transfer between different images.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.