Why should I use docker ONBUILD?

1. Scenario with ONBUILD

Base Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install python3

ONBUILD COPY test.py test.py

Obliviously, when we build above Dockerfile(test-image:latest), the COPY wont affected.(The test.py not copied)

Now onbuild Dockerfile

FROM test-image:latest

Now, when we build above Dockerfile, the COPY will affect, copies test.py

2. Scenario without ONBUILD

I achieve same thing without use ONBUILD

Base Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install python3

Above Dockerfile build docker image which has python3 (test-image2:latest)

Now child docker image Dockerfile

FROM test-image2:latest
COPY test.py /test.py

So, my question is, why should I use ONBUILD or when should use? is there any performance difference


I think that the answer is simple: you want to use ONBUILD when your parent image has to be used in various children images, so you

  1. avoid repetitions
  2. contstrain the user of the image to have test.py copied

In general you shouldn't use ONBUILD at all. Having a later Dockerfile FROM line do something other than simply incorporate its contents violates the principle of least surprise.

If the thing you're trying to do ONBUILD is something like a RUN or ENV instruction, semantically it makes no difference whether you do it in the base image or the derived image. It will be more efficient if you do it in the base image (once ever, as opposed to once each time a derived image is built).

If you're trying to ONBUILD COPY ... then you're trying to force a specific file to be on the host system at the point you run docker build, which is a little strange as a consumer. Docker's Best practices for writing Dockerfiles notes

Be careful when putting ADD or COPY in ONBUILD. The “onbuild” image fails catastrophically if the new build’s context is missing the resource being added. Adding a separate tag, as recommended above, helps mitigate this by allowing the Dockerfile author to make a choice.

As that page notes, if you must use ONBUILD, you should call it out in the image tag so it's clear when you build a Dockerfile FROM that image, something strange is going on. Most current Docker Hub images don't have -onbuild variants at all, even for things like tomcat that generally have extremely formulaic uses.