If you have ever used Docker to package your applications, you might already know about Dockerfiles. A Dockerfile is like a recipe that tells Docker how to build your container image.
However, there is a special instruction called ONBUILD that can sometimes be confusing if you have never tried it before.
In this blog, we will explain what ONBUILD is, how it works, and when you might want to use it in a real-world enterprise setting.
What Is Docker ONBUILD?
In simple terms, ONBUILD is an instruction you can put in a Dockerfile that tells Docker, “When another Dockerfile uses this image as its base, please run these extra steps.”
It means you can create a Docker image that has certain triggers that only run in the child image’s build process. These triggers do not run when you build the parent image itself. They only run later, when someone else uses your image as a base for another Docker image.
Why Is This Useful?
- Encapsulation: You can package certain build steps so that everyone who uses your base image will get those steps automatically.
- Simplicity: It makes your child Dockerfile simpler, since you do not have to repeat the same instructions again.
- Consistency: If many teams in your company rely on a standard base image, you can use ONBUILD to make sure all of them run certain steps (like installing packages, adding default configurations, or setting environment variables) without manually writing those steps over and over.
A Real-World Example
Let’s say you are part of a large enterprise that has many teams building microservices. Your company’s security policy requires that each microservice must have certain security patches and environment variables configured.
Instead of having each team remember to add these steps in their Dockerfiles, you can create a base image that uses ONBUILD to handle these tasks.
Below is an example base Dockerfile named Dockerfile.base
. It has steps to install some packages and set up default environment variables. We will also add ONBUILD instructions that copy and install application code when another Dockerfile builds on top of it.
# Dockerfile.base
FROM ubuntu:latest
# Install necessary packages in the base image
RUN apt-get update && apt-get install -y curl wget
# Set up a default environment variable
ENV APP_ENV=production
# Prepare a build step that will copy source code from child projects
# (This will happen only when the child Dockerfile uses this image as a base)
ONBUILD COPY . /usr/src/app
# Prepare a build step that will run an installation script
ONBUILD RUN cd /usr/src/app && ./install.sh
In the snippet above, notice these key points:
- We install packages before any ONBUILD steps. That means the base image is ready to go, but it will not copy any application code or run
install.sh
right now. - The
ONBUILD COPY
andONBUILD RUN
instructions will only take effect later, when a child Dockerfile uses this base image.
Now, let’s see what it looks like when your teams use this base image.
The Child Dockerfile
A developer in your company wants to build a microservice and decides to use the myorg/base:latest
image (which was built from the Dockerfile.base
above). Their Dockerfile might look like this:
# Dockerfile
FROM myorg/base:latest
# Now, thanks to ONBUILD, the base image automatically runs the COPY and RUN steps
# that were defined with ONBUILD in the base Dockerfile.
# Additional steps for your microservice
RUN echo "Extra steps for my microservice" && \
apt-get update && apt-get install -y nano
When the developer builds this Dockerfile, Docker will first pull the myorg/base:latest
image. Then it will detect that there are ONBUILD instructions in that base image. This triggers the extra steps:
COPY . /usr/src/app
RUN cd /usr/src/app && ./install.sh
Only after those steps have finished, Docker will run the child Dockerfile’s RUN echo "Extra steps..."
step. This ensures your company’s default patches, environment variables, and scripts are always applied, without each developer having to remember them.
Where It Can Be Used in Enterprises
- Standardizing Security: If your company needs each Docker container to have security checks or scanning tools installed, you can put those steps in an ONBUILD base image. Everyone who uses that image will automatically inherit these security requirements.
- Internal Tooling: Maybe your organization has a special CLI tool or library that must be included in all services. Instead of asking everyone to install it, you can just include it in the base image or trigger its installation using ONBUILD steps.
- Environment Setup: You might have environment variables or config files required by all applications. By using ONBUILD, your teams can skip some repetitive steps.
Things to Watch Out For
While ONBUILD can be helpful, it is not always the best solution:
- Hard to Override: Once you define an ONBUILD instruction, child images might not easily override it. Make sure this does not cause problems for teams with special requirements.
- Hidden Complexity: If new developers are not familiar with ONBUILD, they might be surprised when extra steps run. Good documentation helps.
- Version Control: If you change the ONBUILD steps in the base image, it affects all future builds that use that base image. Make sure you handle versioning carefully.
Conclusion
ONBUILD can be a powerful way to simplify Docker builds in an enterprise environment. It makes sure that crucial steps happen automatically whenever a child image builds on top of your base image. This can save time, reduce mistakes, and ensure consistency across multiple teams. However, use it wisely—if you are not careful, it can also introduce hidden steps that some developers might overlook.
By understanding how ONBUILD works and planning your Docker build process carefully, you can keep your microservices secure, standardized, and easy to maintain across all teams in your organization.