X
Popular Searches

How to Use Dockerfile ONBUILD to Run Triggers on Downstream Builds

Docker’s ONBUILD instruction lets you set up triggers within an image. Your triggers will be executed later, when the image is used as a base for another one. They’ll become part of the new downstream image context and won’t be filesystem layers in your initial docker build.

Adding ONBUILD Triggers

ONBUILD is an instruction you write into your Dockerfiles. It’s unique as it accepts another instruction as its argument. You can specify any Dockerfile operation, such as COPY or RUN, and have it be executed during a downstream image build.

ONBUILD RUN example-command

This example runs example-command in the child image at the time it’s built. Here’s another case where a file is copied from the downstream image’s build context into the filesystem:

ONBUILD COPY assets.json /app/assets.json

ONBUILD instructions have no effect whatsoever on the image produced by the Dockerfile they’re defined in. Building the above Dockerfile would not run example-command or include assets.json in the image:

# Does not include the extra instructions
docker build -t base-image:latest .

The triggers will be used when you write another Dockerfile that uses the first one as its base:

FROM base-image:latest
RUN my-binary
docker build -t downstream-image:latest .
Advertisement

Building this Dockerfile will run example-command, copy in assets.json, and finally run my-binary. The ONBUILD triggers are always executed first, immediately after the FROM instruction in the downstream Dockerfile.

How Does Docker Recognize Triggers?

ONBUILD doesn’t affect the base container’s filesystem but Docker still knows triggers are present when you create a downstream image. The build process tracks ONBUILD instructions it finds and records them in the image’s metadata.

Docker inspects the metadata of the images referenced in a FROM instruction. If the named image includes triggers in its metadata, those trigger instructions are effectively pasted to the top of the downstream Dockerfile before the build begins.

Triggers actually execute as part of the build’s FROM stage. They’ll be run in the order they were written in the upstream Dockerfile. If an ONBUILD instruction fails, Docker will cancel the build and it’ll look like the FROM stage was the cause.

Limitations

You can use any Dockerfile instruction as the argument to an ONBUILD trigger with three exceptions:

  • ONBUILD FROM – This isn’t allowed as it would override the base image used for the build. Each Dockerfile must inherit from a single base.
  • ONBUILD MAINTAINER – The MAINTAINER instruction is deprecated and should not be used; authorship information is best supplied as a label. The LABEL instruction is compatible with ONBUILD.
  • ONBUILD ONBUILD – Chaining of ONBUILD instructions is not supported. All triggers execute in the image immediately downstream of your Dockerfile. You cannot define triggers intended to execute in “grand-child” images two or more levels below the defining Dockerfile.

All instructions are defined in the same way as their regular uses. Writing an ordinary step in your Dockerfile, then prefixing it with ONBUILD, will move it out of the normal build flow and make it a downstream build trigger instead.

When Are ONBUILD Triggers Useful?

ONBUILD is most commonly used within utility images that automate tasks such as code compilation. This kind of procedure generally requires several steps to be executed in a specific sequence, with dependencies like your source code added at a particular point.

Advertisement

Consider a compilation image which looks for source code in a directory, then executes a command to build it. You can’t simply COPY and RUN within that image’s Dockerfile as the end user’s source wouldn’t exist inside your image’s build context.

Using ONBUILD lets you provide a boilerplate Dockerfile that your users can extend and docker build without reinventing common functionality:

ENV BUILD_ENV=production
RUN init-build.sh

ONBUILD COPY /src /build
ONBUILD RUN compile.sh --destination=/bin

This example demonstrates how a builder image could provide a preconfigured compilation environment. When used as a base image, code would be automatically compiled from the downstream build context. That image could interact with the compiled output in /bin within its own Dockerfile stages.

Summary

ONBUILD instructions in Dockerfiles give you a way to execute triggers as part of a downstream build. You can use any other Dockerfile instruction as an ONBUILD trigger, except for a few limitations.

Using ONBUILD lets you provide generic Docker images that define reusable sets of functionality. This is more efficient than having users copy the text of example Dockerfiles verbatim, then add their own instructions at the bottom. You can still modify and update the base image without requiring action from your users.

Advertisement

Adopting ONBUILD cuts down on repetition and facilitates extensible Docker base images. ONBUILD instructions are worth considering when you’re creating a boilerplate Dockerfile which will need to be customized by end users before the final container environment is considered complete.

James Walker James Walker
James Walker is a CloudSavvy IT contributor. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows with DevOps, CI/CD, Docker, and Kubernetes. Read Full Bio »

The above article may contain affiliate links, which help support CloudSavvy IT.