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
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
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 .
Building this Dockerfile will run
example-command, copy in
assets.json, and finally run
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.
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
MAINTAINERinstruction is deprecated and should not be used; authorship information is best supplied as a label. The
LABELinstruction is compatible with
ONBUILD ONBUILD– Chaining of
ONBUILDinstructions 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.
Consider a compilation image which looks for source code in a directory, then executes a command to build it. You can’t simply
RUN within that image’s Dockerfile as the end user’s source wouldn’t exist inside your image’s build context.
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.
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.
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.
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.