From 75e7d9e89fd7e8ea7d15bc27e909eb446918c315 Mon Sep 17 00:00:00 2001 From: Carl Wilson Date: Thu, 5 Sep 2024 14:51:19 +0100 Subject: [PATCH 1/3] FEAT: Slimline and templated Dockerfile - moved to an all Alpine stack for build and the final image; - now two Dockerfiles: - `Dockerfile` builds a tag by cloning the GitHub repo; - `Dockerfile_dev` builds a copy of the local project; - added templated versions of both the above that are so that they are updated automatically as part of the Maven build; and - updated the main `pom.xml` with a `resource` plugin to copy the `Dockerfile` and `Dockerfile_dev` to the base directory. --- Dockerfile | 24 ++++++++------ Dockerfile_dev | 53 +++++++++++++++++++++++++++++++ pom.xml | 51 ++++++++++++++++++++++-------- templates/docker/Dockerfile | 56 +++++++++++++++++++++++++++++++++ templates/docker/Dockerfile_dev | 53 +++++++++++++++++++++++++++++++ 5 files changed, 214 insertions(+), 23 deletions(-) create mode 100644 Dockerfile_dev create mode 100644 templates/docker/Dockerfile create mode 100644 templates/docker/Dockerfile_dev diff --git a/Dockerfile b/Dockerfile index fcdd093c3..123c7c548 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,22 @@ # See https://docs.docker.com/engine/userguide/eng-image/multistage-build/ # First build the app on a maven open jdk 11 container -FROM maven:3-eclipse-temurin-11-focal as dev-builder +ARG JHOVE_VERSION=1.33.0-SNAPSHOT +FROM maven:3-eclipse-temurin-11-alpine AS dev-builder ARG JHOVE_VERSION -ENV JHOVE_VERSION=${JHOVE_VERSION:-1.32.0-RC1} +ENV JHOVE_VERSION=${JHOVE_VERSION} -# Copy the current dev source branch to a local build dir -COPY . /build/jhove/ -WORKDIR /build/jhove +RUN apk add --no-cache git +WORKDIR /build + +# Clone the repo, checkout the revision and build the application +RUN git clone https://github.com/openpreserve/jhove.git -RUN mvn clean package && java -jar jhove-installer/target/jhove-xplt-installer-${JHOVE_VERSION}.jar docker-install.xml +WORKDIR /build/jhove +RUN git checkout v${JHOVE_VERSION} && mvn clean package && java -jar jhove-installer/target/jhove-xplt-installer-${JHOVE_VERSION}.jar docker-install.xml # Now build a Java JRE for the Alpine application image # https://github.com/docker-library/docs/blob/master/eclipse-temurin/README.md#creating-a-jre-using-jlink -FROM eclipse-temurin:11 as jre-builder +FROM eclipse-temurin:11-jdk-alpine AS jre-builder # Create a custom Java runtime RUN "$JAVA_HOME/bin/jlink" \ @@ -24,14 +28,14 @@ RUN "$JAVA_HOME/bin/jlink" \ --output /javaruntime # Now the final application image -FROM debian:bullseye-slim +FROM alpine:3 # Set for additional arguments passed to the java run command, no default ARG JAVA_OPTS ENV JAVA_OPTS=$JAVA_OPTS # Specify the veraPDF REST version if you want to (to be used in build automation) ARG JHOVE_VERSION -ENV JHOVE_VERSION=${JHOVE_VERSION:-1.32.0-RC1} +ENV JHOVE_VERSION=${JHOVE_VERSION} # Copy the JRE from the previous stage ENV JAVA_HOME=/opt/java/openjdk @@ -40,7 +44,7 @@ COPY --from=jre-builder /javaruntime $JAVA_HOME # Since this is a running network service we'll create an unprivileged account # which will be used to perform the rest of the work and run the actual service: -RUN useradd --system --user-group --home-dir=/opt/jhove jhove +RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove USER jhove diff --git a/Dockerfile_dev b/Dockerfile_dev new file mode 100644 index 000000000..739b125ea --- /dev/null +++ b/Dockerfile_dev @@ -0,0 +1,53 @@ +# See https://docs.docker.com/engine/userguide/eng-image/multistage-build/ +# First build the app on a maven open jdk 11 container +ARG JHOVE_VERSION=1.33.0-SNAPSHOT +FROM maven:3-eclipse-temurin-11-alpine AS dev-builder +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the current dev source branch to a local build dir +COPY . /build/jhove/ +WORKDIR /build/jhove + +RUN mvn clean package && java -jar jhove-installer/target/jhove-xplt-installer-${JHOVE_VERSION}.jar docker-install.xml + +# Now build a Java JRE for the Alpine application image +# https://github.com/docker-library/docs/blob/master/eclipse-temurin/README.md#creating-a-jre-using-jlink +FROM eclipse-temurin:11-jdk-alpine AS jre-builder + +# Create a custom Java runtime +RUN "$JAVA_HOME/bin/jlink" \ + --add-modules java.base,java.logging,java.xml,jdk.crypto.ec \ + --strip-debug \ + --no-man-pages \ + --no-header-files \ + --compress=2 \ + --output /javaruntime + +# Now the final application image +FROM alpine:3 + +# Set for additional arguments passed to the java run command, no default +ARG JAVA_OPTS +ENV JAVA_OPTS=$JAVA_OPTS +# Specify the veraPDF REST version if you want to (to be used in build automation) +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the JRE from the previous stage +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH "${JAVA_HOME}/bin:${PATH}" +COPY --from=jre-builder /javaruntime $JAVA_HOME + +# Since this is a running network service we'll create an unprivileged account +# which will be used to perform the rest of the work and run the actual service: +RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove +RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove + +USER jhove + +WORKDIR /opt/jhove +# Copy the application from the previous stage +COPY --from=dev-builder /opt/jhove/ /opt/jhove/ + +ENTRYPOINT ["/opt/jhove/jhove"] diff --git a/pom.xml b/pom.xml index 5d379b519..afa1bdfcd 100644 --- a/pom.xml +++ b/pom.xml @@ -202,11 +202,36 @@ - generate-code-coverage-report - test - - report - + generate-code-coverage-report + test + + report + + + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + copy-resources + validate + + copy-resources + + + ${basedir} + + + templates/docker + true + + + @@ -233,6 +258,7 @@ + jdk9 @@ -273,13 +299,13 @@ - - - org.sonarsource.java - sonar-jacoco-listeners - 5.14.0.18788 - test - + + + org.sonarsource.java + sonar-jacoco-listeners + 5.14.0.18788 + test + @@ -405,7 +431,6 @@ - diff --git a/templates/docker/Dockerfile b/templates/docker/Dockerfile new file mode 100644 index 000000000..123756828 --- /dev/null +++ b/templates/docker/Dockerfile @@ -0,0 +1,56 @@ +# See https://docs.docker.com/engine/userguide/eng-image/multistage-build/ +# First build the app on a maven open jdk 11 container +ARG JHOVE_VERSION=${project.version} +FROM maven:3-eclipse-temurin-11-alpine AS dev-builder +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +RUN apk add --no-cache git +WORKDIR /build + +# Clone the repo, checkout the revision and build the application +RUN git clone https://github.com/openpreserve/jhove.git + +WORKDIR /build/jhove +RUN git checkout v${JHOVE_VERSION} && mvn clean package && java -jar jhove-installer/target/jhove-xplt-installer-${JHOVE_VERSION}.jar docker-install.xml + +# Now build a Java JRE for the Alpine application image +# https://github.com/docker-library/docs/blob/master/eclipse-temurin/README.md#creating-a-jre-using-jlink +FROM eclipse-temurin:11-jdk-alpine AS jre-builder + +# Create a custom Java runtime +RUN "$JAVA_HOME/bin/jlink" \ + --add-modules java.base,java.logging,java.xml,jdk.crypto.ec \ + --strip-debug \ + --no-man-pages \ + --no-header-files \ + --compress=2 \ + --output /javaruntime + +# Now the final application image +FROM alpine:3 + +# Set for additional arguments passed to the java run command, no default +ARG JAVA_OPTS +ENV JAVA_OPTS=$JAVA_OPTS +# Specify the veraPDF REST version if you want to (to be used in build automation) +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the JRE from the previous stage +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH "${JAVA_HOME}/bin:${PATH}" +COPY --from=jre-builder /javaruntime $JAVA_HOME + +# Since this is a running network service we'll create an unprivileged account +# which will be used to perform the rest of the work and run the actual service: +RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove +RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove + +USER jhove + +WORKDIR /opt/jhove +# Copy the application from the previous stage +COPY --from=dev-builder /opt/jhove/ /opt/jhove/ + +ENTRYPOINT ["/opt/jhove/jhove"] diff --git a/templates/docker/Dockerfile_dev b/templates/docker/Dockerfile_dev new file mode 100644 index 000000000..33a38a623 --- /dev/null +++ b/templates/docker/Dockerfile_dev @@ -0,0 +1,53 @@ +# See https://docs.docker.com/engine/userguide/eng-image/multistage-build/ +# First build the app on a maven open jdk 11 container +ARG JHOVE_VERSION=${project.version} +FROM maven:3-eclipse-temurin-11-alpine AS dev-builder +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the current dev source branch to a local build dir +COPY . /build/jhove/ +WORKDIR /build/jhove + +RUN mvn clean package && java -jar jhove-installer/target/jhove-xplt-installer-${JHOVE_VERSION}.jar docker-install.xml + +# Now build a Java JRE for the Alpine application image +# https://github.com/docker-library/docs/blob/master/eclipse-temurin/README.md#creating-a-jre-using-jlink +FROM eclipse-temurin:11-jdk-alpine AS jre-builder + +# Create a custom Java runtime +RUN "$JAVA_HOME/bin/jlink" \ + --add-modules java.base,java.logging,java.xml,jdk.crypto.ec \ + --strip-debug \ + --no-man-pages \ + --no-header-files \ + --compress=2 \ + --output /javaruntime + +# Now the final application image +FROM alpine:3 + +# Set for additional arguments passed to the java run command, no default +ARG JAVA_OPTS +ENV JAVA_OPTS=$JAVA_OPTS +# Specify the veraPDF REST version if you want to (to be used in build automation) +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the JRE from the previous stage +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH "${JAVA_HOME}/bin:${PATH}" +COPY --from=jre-builder /javaruntime $JAVA_HOME + +# Since this is a running network service we'll create an unprivileged account +# which will be used to perform the rest of the work and run the actual service: +RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove +RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove + +USER jhove + +WORKDIR /opt/jhove +# Copy the application from the previous stage +COPY --from=dev-builder /opt/jhove/ /opt/jhove/ + +ENTRYPOINT ["/opt/jhove/jhove"] From f311d0d3f74a273ef4d4a255616546f92c574a11 Mon Sep 17 00:00:00 2001 From: Carl Wilson Date: Wed, 11 Sep 2024 13:29:42 +0100 Subject: [PATCH 2/3] FEAT: Installer based docker build - added Dockerfile_installer which uses the JHOVE installer for a faster and more reliable way of building containers. --- Dockerfile_installer | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Dockerfile_installer diff --git a/Dockerfile_installer b/Dockerfile_installer new file mode 100644 index 000000000..e11fcd447 --- /dev/null +++ b/Dockerfile_installer @@ -0,0 +1,52 @@ +# See https://docs.docker.com/engine/userguide/eng-image/multistage-build/ +# First build the app on a maven open jdk 11 container +ARG JHOVE_VERSION=1.32 +FROM eclipse-temurin:11-jdk-alpine AS app-installer +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +WORKDIR /tmp +COPY docker-install.xml . +RUN wget -O /tmp/jhove-installer.jar https://software.openpreservation.org/releases/jhove/jhove-${JHOVE_VERSION}.jar +RUN java -jar jhove-installer.jar docker-install.xml + +# Now build a Java JRE for the Alpine application image +# https://github.com/docker-library/docs/blob/master/eclipse-temurin/README.md#creating-a-jre-using-jlink +FROM eclipse-temurin:11-jdk-alpine AS jre-builder + +# Create a custom Java runtime +RUN "$JAVA_HOME/bin/jlink" \ + --add-modules java.base,java.logging,java.xml,jdk.crypto.ec \ + --strip-debug \ + --no-man-pages \ + --no-header-files \ + --compress=2 \ + --output /javaruntime + +# Now the final application image +FROM alpine:3 + +# Set for additional arguments passed to the java run command, no default +ARG JAVA_OPTS +ENV JAVA_OPTS=$JAVA_OPTS +# Specify the veraPDF REST version if you want to (to be used in build automation) +ARG JHOVE_VERSION +ENV JHOVE_VERSION=${JHOVE_VERSION} + +# Copy the JRE from the previous stage +ENV JAVA_HOME=/opt/java/openjdk +ENV PATH "${JAVA_HOME}/bin:${PATH}" +COPY --from=jre-builder /javaruntime $JAVA_HOME + +# Since this is a running network service we'll create an unprivileged account +# which will be used to perform the rest of the work and run the actual service: +RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove +RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove + +USER jhove + +WORKDIR /opt/jhove +# Copy the application from the previous stage +COPY --from=app-installer /opt/jhove/ /opt/jhove/ + +ENTRYPOINT ["/opt/jhove/jhove"] From b16d1143a09a8c277a6fafc18997abade34d1f31 Mon Sep 17 00:00:00 2001 From: Carl Wilson Date: Wed, 11 Sep 2024 20:37:19 +0100 Subject: [PATCH 3/3] FIX: Data VOLUME for local file validation. --- Dockerfile_installer | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile_installer b/Dockerfile_installer index e11fcd447..47c288ba7 100644 --- a/Dockerfile_installer +++ b/Dockerfile_installer @@ -44,9 +44,12 @@ RUN addgroup -S jhove && adduser -S -G jhove -h /opt/jhove jhove RUN mkdir --parents /var/opt/jhove/logs && chown -R jhove:jhove /var/opt/jhove USER jhove - WORKDIR /opt/jhove + # Copy the application from the previous stage COPY --from=app-installer /opt/jhove/ /opt/jhove/ +WORKDIR /data +VOLUME [ "/data" ] + ENTRYPOINT ["/opt/jhove/jhove"]