How to create a lightweight container image for Java apps

When creating a Docker image with a Java product, you can execute maven at the time of docker build, but it takes time and artifacts that are not needed at runtime are downloaded, so the image becomes large.

Therefore, if you build with CircleCI and make a Dockerfile that downloads and executes the created Jar, it will be easier to build and the image size will be smaller.

Make Uber JAR or Zip

To create a Jar that includes all dependent libraries, it is easy to use the shade plugin as shown below. It can also be an executable Jar by using ManifestResourceTransformer to include the mainClass in the MANIFEST file.

pom.xml


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>xxx.Main</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

I think you can create a zip file using the assembly plugin.

Write circleci settings

CircleCI 2.0 creates a build container with pom.xml as the cache key, so you can build at high speed as long as you don't rewrite pom. Also, Maven repositories are mirrored by CircleCI, so downloading dependent libraries is fast.

For build settings, create .circleci / config.yml directly under the project. The sample will be displayed when it works with the GitHub project, so you can use it as it is, but at the end, add only the step of uploading the Uber JAR or ZIP to Artifact (in the example below, at store_artifacts).

yaml:.circleci/config.yml


version: 2
jobs:
  build:
    docker:
      - image: circleci/openjdk:8-jdk
    working_directory: ~/repo
    environment:
      MAVEN_OPTS: -Xmx3200m
    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "pom.xml" }}
          - v1-dependencies-
      - run: mvn dependency:go-offline
      - save_cache:
          paths:
            - ~/.m2
          key: v1-dependencies-{{ checksum "pom.xml" }}
      - run: mvn integration-test
      - store_artifacts:
          path: target/xxx-0.1.0-SNAPSHOT.jar

Make a Dockerfie

In the Dockerfile, write to download and run this artifact.

Dockerfile


FROM openjdk:8-alpine

RUN apk --no-cache add curl jq

RUN curl 'https://circleci.com/api/v1.1/project/github/kawasima/xxx/latest/artifacts?branch=develop&filter=successful' \
    | jq 'map(select(.["path"] == "home/circleci/repo/target/xxx-0.1.0-SNAPSHOT.jar"))' \
    | jq '.[0]["url"]' \
    | xargs curl -o xxx.jar

RUN apk del --purge curl jq

ENTRYPOINT ["java", "-jar", "xxx.jar"]

The URL of the last successful build artifact can be obtained without authentication using CircleCI API v1.1 for Public repositories. I'm using jq to identify the artifact from JSON and extract the URL.

Recommended Posts

How to create a lightweight container image for Java apps
How to make a Java container
[Java] How to create a folder
How to create a Maven repository for 2020
How to create a database for H2 Database anywhere
Create a Lambda Container Image based on Java 15
How to create pagination for a "kaminari" array
How to make a lightweight JRE for distribution
[Docker] How to create a virtual environment for Rails and Nuxt.js apps
How to create a method
How to create a Java environment in just 3 seconds
[Rails] How to create a signed URL for CloudFront
[Spring Boot] How to create a project (for beginners)
How to create a data URI (base64) in Java
Create a Kibana container image for ARM64 (Raspberry Pi/Mac M1)
How to make a Java array
How to create and launch a Dockerfile for Payara Micro
How to create a new Gradle + Java + Jar project in Intellij 2016.03
How to check for the contents of a java fixed-length string
How to make a groundbreaking diamond using Java for statement wwww
How to make a Java calendar Summary
[Introduction to Java] How to write a Java program
How to make a Discord bot (Java)
How to print a Java Word document
[Swift5] How to create a splash screen
[rails] How to create a partial template
[Java] How to turn a two-dimensional array with an extended for statement
[Java] [For beginners] How to insert elements directly in a 2D array
[Java] How to test for null with JUnit
How to deploy a container on AWS Lambda
[Rails] How to create a graph using lazy_high_charts
How to get a heapdump from a Docker container
How to display a web page in Java
Try to create a bulletin board in Java
How to create a class that inherits class information
How to convert a solidity contract to a Java contract class
[Java] Let's create a mod for Minecraft 1.14.4 [Introduction]
How to create a theme in Liferay 7 / DXP
[Java] Let's create a mod for Minecraft 1.16.1 [Introduction]
[Java] (for MacOS) How to set the classpath
[1st] How to create a Spring-MVC framework project
How to easily create a pull-down in Rails
[Rails] How to create a Twitter share button
[Java] Let's create a mod for Minecraft 1.14.4 [99. Mod output]
[Java] How to make multiple for loops single
How to create a small docker image of openjdk 11 (ea) application (1GB → 85MB)
[Azure] I tried to create a Java application for free-Web App creation- [Beginner]
[Introduction to Docker] Create a Docker image for machine learning and use Jupyter notebook
[Java] Create a filter
How to create docker-compose
Create a docker image that runs a simple Java app
How to use an array for a TreeMap key
How to jump from Eclipse Java to a SQL file
How to write a unit test for Spring Boot 2
How to deploy to Heroku from a local docker image
[Java] Let's create a mod for Minecraft 1.14.4 [Extra edition]
[Java] Let's create a mod for Minecraft 1.14.4 [7. Add progress]
java: How to write a generic type list [Note]
[Java] How to play rock-paper-scissors (equivalent to paiza rank A)
[Java] Let's create a mod for Minecraft 1.14.4 [6. Add recipe]
How to create a JDBC URL (Oracle Database, Thin)