Builder builder pattern / multi multi stage builds?

My problem shouldn’t be too unfamiliar for those with web development. What i’m trying to achieve is simply a full build of our application, triggered from Jenkins.

  • Frontend:
    • NodeJs 10
    • Chromium
  • Backend:
    • Java 8
    • gradle

My plan consists of three images:

  1. Build-build image: Using FROM Java, installs NodeJs (and gradle) into that image
  2. Build-image: Installs npm packages and gradle dependencies, tests and compiles
  3. Image: Only consists of production software and build artifacts, like *.WAR, *.js.

The reasons for this plan is that there is no need to rebuild the base image (step 1) on every code change, only when we actually upgrade the Java, Node or Chromium version.

I see problems with bundling the steps into less stages.

  • A: Step 2 and 3 could maybe be bundled into a multi-stage build. Then, however, I would have mixed the builder pattern with a multi-stage pipeline on top, ouch!
  • B: I could do a clean rebuild FROM scratch. This, however, would needlessly install the full V8 engine into a Java image (or vice versa) no matter how late the build fails (think of a single unit test.)

The build is also planned to become more complicated in the future, sidecar-ing a mysql-container (with the step 2 image) to check if the Backend initialized the database correctly.

So is this a normal approach, best practice or straight out of hell?

I would avoid overloading the containers to have a single image at least for development. What you can do for development is create multiple images and have a docker-compose.yml .

That way the developers don’t have to hate you for making their local build cycles take forever.

For the final package you can build from scratch or some OS and copy the from the built images later so your production package is a single image.