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.
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.
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
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