About me…•Chief of Research @codefresh.io
•github.com/alexei-led/pumba
•#docker, #golang, #aws
•medium.com/@alexeiled
•@alexeiled
The “Naive” ApproachFollow familiar VM build and install flow
# start from ubuntu FROM ubuntu:14.04
# add required packages and java repository RUN apt-get update && apt-get install -y python-software-properties software-properties-common RUN add-apt-repository ppa:webupd8team/java
# install Oracle JDK 8 with auto-accept license agreement RUN echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 boolean true" | debconf-set-selections RUN apt-get update && apt-get install -y oracle-java8-installer maven
# add ALL project files ADD . /usr/local/app
# build Java application with Maven (fetch packages, compile, test and deploy) RUN cd /usr/local/app && mvn install
# define default command to run the application CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=test", "/usr/local/app/target/spring-boot-rest-example-0.3.0.war"]
Docker Image Size = 1.3 GB Docker Built Time = 27 min
“Standard” Approach
FROM java:8
# Install maven RUN apt-get update RUN apt-get install -y maven
WORKDIR /code
# Prepare by downloading dependencies ADD pom.xml /code/pom.xml RUN ["mvn", "dependency:resolve"] RUN ["mvn", "verify"]
# Adding source, compile and package into a fat jar ADD src /code/src RUN ["mvn", "package"]
EXPOSE 4567 CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=test", "target/spring-boot-rest-example-0.3.0.war"]
Docker Image Size = 1.2 GB Docker Built Time = 15 min
Take Library OpenJDK image, add pom.xml first…
–Joe Fernandes, senior director, OpenShift Product Management, Red Hat
“A Linux container is nothing more than a process that runs on Linux. It shares a host kernel with other containerized processes.”
What is the bare minimum required to run Java App?
1. Base Image with C Runtime and Posix shell (Alpine)
2. Java Runtime Environment (OpenJDK JRE)
3. Application byte-code and resources (app.jar)
4. 3rd Party Libraries (lib/*.jar)
5. Optionally HTTP server (Tomcat/Jetty/Netty/…)
Docker Image Size• time to build
• network latency
• storage
• service availability and elasticity
• security
• development agility
Java Docker Builder1. Base Image with C Runtime and Posix shell (Alpine)
2. Java Development Kit (OpenJDK)
3. Javac or other JVM compiler (Scala, Kotlin, …)
4. Build Management Tool (Maven, SBT, Gradle, …)
5. Linters, code scanners, test frameworks, test tools, …
Maven Builder DockerfileFROM openjdk:8-jdk-alpine
RUN apk add --no-cache curl tar bash
ARG MAVEN_VERSION=3.3.9 ARG USER_HOME_DIR="/root"
RUN mkdir -p /usr/share/maven && \ curl -fsSL http://apache.osuosl.org/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz | tar -xzC /usr/share/maven --strip-components=1 && \ ln -s /usr/share/maven/bin/mvn /usr/bin/mvn
ENV MAVEN_HOME /usr/share/maven ENV MAVEN_CONFIG "$USER_HOME_DIR/.m2" # speed up Maven JVM a bit ENV MAVEN_OPTS="-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
ENTRYPOINT ["/usr/bin/mvn"]
# make source folder RUN mkdir -p /usr/src/app WORKDIR /usr/src/app
# install maven dependency packages (keep in image) COPY pom.xml /usr/src/app RUN mvn -T 1C install && rm -rf target
# copy other source files (keep in image) COPY src /usr/src/app/src
Java App DockerfileFROM openjdk:8-jre-alpine
COPY spring-boot-*.war /app.war
CMD ["/usr/bin/java", "-jar", "-Dspring.profiles.active=test", "/app.war"]
Makefile…
builder: docker build -t $(NS)/builder:mvn -f Dockerfile.build .
mvn-package: builder docker run -it --rm -v $(shell pwd)/target:/usr/src/app/target $(NS)/builder:mvn package -T 1C -o -Dmaven.test.skip=true
mvn-test: builder docker run -it --rm -v $(shell pwd)/target:/usr/src/app/target $(NS)/builder:mvn -T 1C -o test
docker: docker build -t $(NS)/$(REPO):$(VERSION) target
build: builder make docker
push: docker push $(NS)/$(REPO):$(VERSION)
release: build make push -e VERSION=$(VERSION)
…
default: build
version: '1.0'
steps:
mvn_builder: type: build description: create Maven builder dockerfile: Dockerfile.build image_name: alexeiled/mvn-builder
mvn_test: description: run unit tests image: ${{mvn_builder}} commands: - mvn -T 1C -o test mvn_package: description: package application WAR image: ${{mvn_builder}} commands: - mvn package -T 1C -o -Dmaven.test.skip=true
build_image: type: build description: create Docker image with application WAR dockerfile: Dockerfile working_directory: ${{main_clone}}/target image_name: alexei-led/sbdemo
image_push: type: push description: push to DockerHub candidate: '${{build_image}}' tag: ‘${{CF_BRANCH}}'
Codefresh YAML
Top Related