Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile ONBUILD instruction

Tags:

docker

I read on the docker documentation how ONBUILD instruction can be used, but it is not clear at all.
Can someone please explain it to me?

like image 839
softshipper Avatar asked Jan 18 '16 20:01

softshipper


People also ask

What is Workdir in Dockerfile?

WORKDIR instruction is used to set the working directory for all the subsequent Dockerfile instructions. Some frequently used instructions in a Dockerfile are RUN, ADD, CMD, ENTRYPOINT, and COPY. If the WORKDIR is not manually created, it gets created automatically during the processing of the instructions.

What is && in Dockerfile?

Each RUN command in a Dockerfile creates a new layer to the Docker image. In general, each layer should try to do one job and the fewer layers in an image the easier it is compress. This is why you see all these '&& 's in the RUN command, so that all the shell commands will take place in a single layer.


2 Answers

The ONBUILD instruction is very useful for automating the build of your chosen software stack.

Example

The Maven container is designed to compile java programs. Magically all your project's Dockerfile needs to do is reference the base container containing the ONBUILD intructions:

FROM maven:3.3-jdk-8-onbuild CMD ["java","-jar","/usr/src/app/target/demo-1.0-SNAPSHOT-jar-with-dependencies.jar"] 

The base image's Dockerfile tells all

FROM maven:3-jdk-8  RUN mkdir -p /usr/src/app WORKDIR /usr/src/app  ONBUILD ADD . /usr/src/app  ONBUILD RUN mvn install 

There's a base image that has both Java and Maven installed and a series of instructions to copy files and run Maven.

The following answer gives a Java example

  • How to build a docker container for a java app
like image 93
Mark O'Connor Avatar answered Sep 23 '22 18:09

Mark O'Connor


As stated by the docker docs:

The ONBUILD instruction adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile.

So what does that mean? Let's take this Nodejs Dockerfile:

FROM node:0.12.6  RUN mkdir -p /usr/src/app WORKDIR /usr/src/app  ONBUILD COPY package.json /usr/src/app/ ONBUILD RUN npm install ONBUILD COPY . /usr/src/app  CMD [ "npm", "start" ] 

In your own Dockerfile, when you do FROM node:0.12.6-onbuild you're getting an image, which means the build command has already been run, so the instructions have ALREADY been executed as well, however all but those starting with ONBUILD. These have been deferred to another time, when the downstream build (when your image is getting built from your own Dockerfile) uses this image as the base (FROM node:0.12.6-onbuild).

You can’t just call ADD and RUN now, because you don’t yet have access to the application source code, and it will be different for each application build.

That's right! The image containing onbuild instructions wasn't built on your machine, so it doesn't yet have access to package.json.

Then when you build your own Dockerfile, before executing any instruction in your file, the builder will look for ONBUILD triggers, which were added to the metadata of the parent image when it was built.

That spares you the hassle of executing these commands yourself, it really is as though these commands were written in your own Dockerfile.

Finally, they add:

You could simply provide application developers with a boilerplate Dockerfile to copy-paste into their application, but that is inefficient, error-prone and difficult to update because it mixes with application-specific code.

The thing is that if these instructions are modified in the boilerplate Dockerfile, you will have to modify them as well in your Dockerfile. But thanks to the ONBUILD instruction, we don't have to worry about it.

like image 22
jperl Avatar answered Sep 22 '22 18:09

jperl