Best way to organize Docker image definitions to support CentOS AND RHEL?

For various reasons we need to support our product distribution using both CentOS and RHEL image based containers.

I’ve already built two sets of container files, however the ONLY difference between the two is one line in each Dockerfile. Is there “best practice” way to organize this? It seems very cumbersome to have to manage 2 sets of Dockerfiles where the only difference is the FROM line.

Is there a way to:

  1. import a partial Dockerfile from master Dockerfile?
  2. can you use variables in the FROM? If yes, how does this work? and how do you know what the variable value was when the image was build?
  3. some other way to have a single definition that can handle multiple container image (I’m not sure if this is what Manifests do or not)

Note I’m not looking for different cpu architecture to support however supporting something like Ubuntu, CentOS, RHEL, etc all with a single Dockerfile would be ideal.

1 Like

have you had a look at multi stage dockerfiles?
it does not solve your problem well, but at least it keeps everything you need to know about your Docker deployment inside one file.

If you compile/bundle also upfront then your RHEL and CentOS stages will be quite short I guess without much Copy&Paste.

I’m not sure how that helps exactly. I could possibly see how it would be helpful for making a singular production build, but in my instance where I actually need a CentOS and RHEL version through the whole build pipeline (DoD/NIST requirements), I’m not sure I could build the base pieces with CentOS and then use a Multi-Stage build to convert the image to RHEL.

Also RHEL 7 stable is far behind on Docker support (we’re talking 12.x). If multi-stage support doesn’t show up until 17.05, this just doesn’t work.

Some of the multi-arch solutions like https://eyskens.me/multiarch-docker-images/ looks closest to what might work in concept, but even that shares the same base image.

I’ve considered writing the Dockerfiles as mustache templates, and then generating the Dockerfile on the fly for the specific OS, but it just feel brittle since there’s not really good protection to prevent someone from using an incompatible base image.

How about this idea?

FROM centos:1.2.3

COPY . /
RUN ./build.sh

FROM rhel:3.2.1

COPY . /
RUN ./build.sh

And within your build.sh you have an if centos; then foo; else; bar; fi;

Unfortunately no.

Our DoD client can’t have CentOS present during the build process. RHEL has to be present through the entire build pipeline. Conversely, our non-DoD clients don’t want to pay to license RHEL just to build so flip-flopping the order doesn’t help.

I also don’t like scripting outside the Dockerfile because changes in the script are not picked up as a layer change. Docker needs some sort of optional manifest declaration to watch for those kind of changes.