8i | 9i | 10g | 11g | 12c | 13c | 18c | 19c | 21c | 23ai | Misc | PL/SQL | SQL | RAC | WebLogic | Linux

Home » Articles » Linux » Here

Docker : Dockerfile Tips - Build in Stages

When you are learning to write Dockerfiles, or developing a complex new build, you may find it easier to take a staged approach to the build process.

Related articles.


What I'm going to suggest here is extremely wasteful of storage, but it will make development of a new Dockerfile much quicker when you are dealing with images containing large amounts of software, as you won't have to keep repeating slow steps in the build as you amend the process.

This is not supposed to be an example of the perfect build of Oracle on Docker. It is just an example I created while learning Docker. You might prefer to check out the Dockerfiles maintained by Oracle here.

If you are concerned about reducing storage usage, you should consider the --squash experimental feature described here. You can see how to enable experimental features in Oracle Linux here.

Building in Stages

You may want to end up with a single Dockerfile that does the complete build, but during the development of a new Dockerfile this can be an extremely inefficient way to work. Why? Because some of the steps of the build process can take a long time for large builds.

Imagine you are writing your own Dockerfile to build an image with Oracle database software in it. At minimum, you will have to do the following stages to prepare the image you are working with.

Each of these steps takes several minutes. As a result, each time you alter the Dockerfile, you may have to wait quite some time to see if your change has worked. The way Docker handles layers may save you some time, as some of the layers may already be present from a previous build, but at minimum you will be waiting for the first step to complete. This represents a large waste of time and it will drive you crazy when you have a large software stack.

Instead, it makes things easier to separate some sections of the build as a separate image, then keep extending with a new image, based on the previous image using the FROM operation in the Dockerfile. Once you get to the end of the process, you can decide if you want to merge everything back to a single Dockerfile, or keep the intermediate images. When you see how much space this separation wastes, you will probably end up merging it back together.

Example : Oracle Database Build Stages

The following example shows how I went about writing my first Dockerfile for an Oracle database image.

Stage 1

I started with a base image that performed the following actions.

None of these operations were particularly challenging, and once the image was built successfully I could then use it as the base for the next stages, without having to repeat all the previous steps.

Stage 2

The next image performed the following actions.

If you are used the silent installations there isn't really anything tricky here. At this point the software was installed and the image was ready to have a database configured on it.

Stage 3

The final stage didn't do much in the Dockerfile apart from expose the ports, calls the start script using the CMD operation and define the HEALTCHECK operation. This allowed me to play around with the "start.sh" and "healthcheck.sh" scripts without having to repeat all the previous steps.

This section is where I made all the mistakes, especially in the "start.sh" script. Being able to quickly reset to the previous image saved lots of time.

Keeping all these intermediate images can be very wasteful from a space perspective, but they will speed up the development of a new Dockerfile. Once you are happy, you will probably merge them back together into a single Dockerfile, such as the one below.

For more information see:

Hope this helps. Regards Tim...

Back to the Top.