Skip to content

Instantly share code, notes, and snippets.

@fabri1983
Last active September 11, 2019 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabri1983/5cb392d8c05f0d90ae6a9de212db4f8c to your computer and use it in GitHub Desktop.
Save fabri1983/5cb392d8c05f0d90ae6a9de212db4f8c to your computer and use it in GitHub Desktop.
Multi stage Docker file for image creation based on Alpine Linux, Tomcat native, OpenJDK 12 custom JRE (jlink), and FFMPEG 4.x. WAR file has to be decompressed outside.
# OpenJDK 12 alpine jdk/jre uses alpine 3.10.
# Visit https://github.com/AdoptOpenJDK/openjdk-docker/tree/master/12
######################################################################################################
FROM adoptopenjdk/openjdk12:alpine AS STAGING-TOMCAT
############# INSTALL NATIVE TOMCAT #############
ENV CATALINA_HOME=/opt/tomcat \
TOMCAT_MAJOR="8" \
TOMCAT_VERSION="8.5.43"
# Download Tomcat, and then Build tc-native
RUN apk add --no-cache --virtual .my-build-deps apr-dev openssl-dev make g++ && \
cd /tmp && \
wget -O apache-tomcat.tar.gz http://archive.apache.org/dist/tomcat/tomcat-${TOMCAT_MAJOR}/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz && \
tar -C /opt -xf apache-tomcat.tar.gz && \
ln -s /opt/apache-tomcat-$TOMCAT_VERSION $CATALINA_HOME && \
cd $CATALINA_HOME/bin && \
tar -xf tomcat-native.tar.gz && \
rm -f tomcat-native.tar.gz && \
cd tomcat-native-*-src/native && \
./configure --with-java-home=$JAVA_HOME --prefix=$CATALINA_HOME && \
make && \
make install && \
make clean && \
rm -rf /tmp/* && \
# Remove added packages
apk del --purge .my-build-deps && \
rm -rf /var/cache/apk/*
#################################################
################ MINIMAL TOMCAT #################
# Minimal Tomcat: remove all default webapps
RUN rm -rf \
${CATALINA_HOME}/webapps/ROOT \
${CATALINA_HOME}/webapps/docs \
${CATALINA_HOME}/webapps/examples \
${CATALINA_HOME}/webapps/host-manager \
${CATALINA_HOME}/webapps/manager
#################################################
######################################################################################################
FROM alpine:3.10 AS STAGING-WAR
ARG DEPENDENCIES=docker-workdir
################# STAGING WAR ###################
# Create target folder
RUN mkdir -p /staging/app/
# Stage dependencies and classes
COPY ${DEPENDENCIES}/META-INF /staging/app/META-INF
COPY ${DEPENDENCIES}/WEB-INF /staging/app/WEB-INF
COPY ${DEPENDENCIES}/general-error.jsp /staging/app/
COPY ${DEPENDENCIES}/index.jsp /staging/app/
COPY ${DEPENDENCIES}/log4j2.xml /staging/app/
#################################################
######################################################################################################
FROM adoptopenjdk/openjdk12:alpine AS STAGING-OPENJDK12-MINI
# At this point JAVA_HOME refers to /opt/java/openjdk
# Build a smaller Java 12 JRE
RUN jlink \
--module-path ${JAVA_HOME}/jmods \
--compress=2 \
--add-modules java.base,java.instrument,java.logging,java.management,java.management.rmi,java.naming,java.net.http,java.prefs,java.rmi,java.se,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.unsupported \
--no-header-files \
--no-man-pages \
--strip-debug \
--output ${JAVA_HOME}/customjre
######################################################################################################
FROM alpine:3.10
ARG API_NAME
ENV CATALINA_HOME=/opt/tomcat \
JAVA_HOME=/opt/java/openjdk
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CATALINA_HOME/lib \
PATH=$PATH:$JAVA_HOME/bin
#################################################
# Download ffmpeg as a package (last version always, otherwise you need to build from source)
# Download libs used by Tomcat native
RUN apk add --no-cache ffmpeg apr openssl && \
rm -rf /var/cache/apk/*
#################################################
# Copy from symbolic link created in previous image
COPY --from=STAGING-TOMCAT $CATALINA_HOME $CATALINA_HOME
#################################################
# The JRE mini runtime we build in previous stage is based on glibc, and Alpine linux uses musl,
# so we need to add glibc support:
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
RUN apk add --no-cache --virtual .build-deps curl binutils \
&& GLIBC_VER="2.29-r0" \
&& ALPINE_GLIBC_REPO="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" \
&& GCC_LIBS_URL="https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-9.1.0-2-x86_64.pkg.tar.xz" \
&& GCC_LIBS_SHA256="91dba90f3c20d32fcf7f1dbe91523653018aa0b8d2230b00f822f6722804cf08" \
&& ZLIB_URL="https://archive.archlinux.org/packages/z/zlib/zlib-1%3A1.2.11-3-x86_64.pkg.tar.xz" \
&& ZLIB_SHA256=17aede0b9f8baa789c5aa3f358fbf8c68a5f1228c5e6cba1a5dd34102ef4d4e5 \
&& curl -LfsS https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
&& SGERRAND_RSA_SHA256="823b54589c93b02497f1ba4dc622eaef9c813e6b0f0ebbb2f771e32adf9f4ef2" \
&& echo "${SGERRAND_RSA_SHA256} */etc/apk/keys/sgerrand.rsa.pub" | sha256sum -c - \
&& curl -LfsS ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-${GLIBC_VER}.apk > /tmp/glibc-${GLIBC_VER}.apk \
&& apk add /tmp/glibc-${GLIBC_VER}.apk \
&& curl -LfsS ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk > /tmp/glibc-bin-${GLIBC_VER}.apk \
&& apk add /tmp/glibc-bin-${GLIBC_VER}.apk \
&& curl -Ls ${ALPINE_GLIBC_REPO}/${GLIBC_VER}/glibc-i18n-${GLIBC_VER}.apk > /tmp/glibc-i18n-${GLIBC_VER}.apk \
&& apk add /tmp/glibc-i18n-${GLIBC_VER}.apk \
&& /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \
&& echo "export LANG=$LANG" > /etc/profile.d/locale.sh \
&& curl -LfsS ${GCC_LIBS_URL} -o /tmp/gcc-libs.tar.xz \
&& echo "${GCC_LIBS_SHA256} */tmp/gcc-libs.tar.xz" | sha256sum -c - \
&& mkdir /tmp/gcc \
&& tar -xf /tmp/gcc-libs.tar.xz -C /tmp/gcc \
&& mv /tmp/gcc/usr/lib/libgcc* /tmp/gcc/usr/lib/libstdc++* /usr/glibc-compat/lib \
&& strip /usr/glibc-compat/lib/libgcc_s.so.* /usr/glibc-compat/lib/libstdc++.so* \
&& curl -LfsS ${ZLIB_URL} -o /tmp/libz.tar.xz \
&& echo "${ZLIB_SHA256} */tmp/libz.tar.xz" | sha256sum -c - \
&& mkdir /tmp/libz \
&& tar -xf /tmp/libz.tar.xz -C /tmp/libz \
&& mv /tmp/libz/usr/lib/libz.so* /usr/glibc-compat/lib \
&& apk del --purge .build-deps glibc-i18n \
&& rm -rf /tmp/*.apk /tmp/gcc /tmp/gcc-libs.tar.xz /tmp/libz /tmp/libz.tar.xz /var/cache/apk/*
# Copy JRE mini runtime from previous stage
COPY --from=STAGING-OPENJDK12-MINI $JAVA_HOME/customjre $JAVA_HOME
#################################################
# Copy staged files into Tomcat's webapp folder
COPY --from=STAGING-WAR /staging/app ${CATALINA_HOME}/webapps/${API_NAME}
EXPOSE 8080
ENTRYPOINT exec ${CATALINA_HOME}/bin/catalina.sh run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment