Search code examples
dockerdockerhubauto-build

Multiple Docker Hub builds by parameterization


I have a requirement to build the same Dockerfile on a (relatively large) number of flavours.

In particular, I am working on a customization of Apache Tomcat. With the same Dockerfile, applying some enhancements to base Tomcat, I need to build several customized Tomcats based on different versions (n particular at least the baselines 8.5 and 9 combined with JDKs 8 and 11).

As an exercise only, just o get more practice on Docker, I could even decide to build all Tomcat images, which come in a large number of flavours, as customized builds.

Given that I already have a Dockerfile...

ARG TOMCAT_VERSION
FROM tomcat:${TOMCAT_VERSION}
MAINTAINER Some One ([email protected])
ARG POSTGRES_JDBC_VERSION="42.2.16"
ARG ORACLE_JDBC_VERSION="19.7.0.0"
ARG LIFECYCLE_LISTENER_VERSION="1.0.1"
ENV MAX_MEMORY_SIZE 4096
ARG CONTEXT_NAME

ADD https://repo1.maven.org/maven2/net/aschemann/tomcat/tomcat-lifecyclelistener/${LIFECYCLE_LISTENER_VERSION}/tomcat-lifecyclelistener-${LIFECYCLE_LISTENER_VERSION}.jar /usr/local/tomcat/lib
ADD https://repo1.maven.org/maven2/org/postgresql/postgresql/${POSTGRES_JDBC_VERSION}/postgresql-${POSTGRES_JDBC_VERSION}.jar /usr/local/tomcat/lib
ADD https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/${ORACLE_JDBC_VERSION}/ojdbc8-${ORACLE_JDBC_VERSION}.jar /usr/local/tomcat/lib
COPY tomcat-${TOMCAT_MAJOR}/server.xml /usr/local/tomcat/conf/ #This enables AJP

EXPOSE 8009
EXPOSE 8080

VOLUME #some volume
# etc etc

What I need to achieve is, possibly using Docker Hub's auto-build is

for (tomcatVersion in "8.5", "9")
    for (javaVersion in "jd8-slim", "jdk11-slim", "jdk14")
        docker build --build-arg TOMCAT_VERSION=$tomcatVersion+"-"+$javaVersion -t examplebiz/tomcat:$tomcatVersion+"-"+$javaVersion .

Currently Docker Hub offers to me use multiple Github branches

Docker Hub Build Settings

But I don't like this, as a single Dockerfile is sufficient. I can combine the 6 versions and run the build manually from my pc

I haven't very well understood the build hooks. Maybe there lies the solution?

Can I get some advice on how to design the build?


Solution

  • In addition to BMitch's answer, I also found my own way in the meantime and I'd like to share my experience, possibly explaining.

    Docker Hub allows hooks automation. In particular, the build hook, as described in the docs, will override the entire build process. One can choose whether to change the variables passed to Docker, or to reinvent brand new ways of building!!

    I just had to translate my pseudo-code for cycle into a real bash for cycle

    #!/bin/bash
    
    for tomcatVersion in "8.5" "9" ; do
        for javaVersion in "jdk8-slim" "jdk11-slim" "jdk14" ; do
            imageVersion="$tomcatVersion-$javaVersion"
            echo "Building Tomcat $imageVersion"
            docker build --build-arg TOMCAT_VERSION=$imageVersion -t examplebiz/tomcat:$imageVersion .;
            docker push examplebiz/tomcat:$imageVersion
        done
    done
    
    docker tag examplebiz/tomcat:$imageVersion examplebiz/tomcat:latest
    

    There are just two caveats:

    1. Docker Hub won't ever push anything by itself. Whatever custom you build, you must push it. That is why I have the docker push line and I use the last value of the variable imageVersion in my code

    2. Docker Hub will push a repository:latest image after the build, so it demands its presence. Make your choice on who to promote latest, but make sure Docker has built a latest image, whether with a tag or a plain build