Help us understand the problem. What is going on with this article?

Javaアプリの軽量コンテナイメージのつくりかた

More than 1 year has passed since last update.

JavaのプロダクトでDockerイメージを作る場合、docker build時にmaven実行してもよいのですが、時間がかかるし、runtimeで必要のないアーティファクトもダウンロードされるので、イメージが大きくなってしまいます。

そこで、CircleCIでビルドして、作ったJarをダウンロードして実行するDockerfileにすると楽ちんでビルドも速くイメージサイズも小さくすみます。

Uber JAR or Zipを作る

依存ライブラリも全部含めたJarを作るには以下のようにshadeプラグインを使うと簡単です。ManifestResourceTransformerを使ってmainClassをMANIFESTファイルに含むようにすれば実行可能Jarにもなります。

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>

assemblyプラグイン使ってzipファイルを作ってもよいかと思います。

circleciの設定を書く

CircleCI 2.0はpom.xmlをキャッシュキーとしてビルドコンテナを作るので、pomを書き換えない限り、高速にビルドできます。またMavenのリポジトリはCircleCIでミラーされているので、依存ライブラリのダウンロードも高速です。

ビルドの設定は、プロジェクト直下に.circleci/config.ymlを作っておきます。GitHubプロジェクトと連携されるときにサンプルが表示されるので、だいたいそのままで使えますが、最後にUber JARまたはZIPをArtifactにアップロードするステップ(下記例だとstore_artifactsのところ)だけ追加します。

.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

Dockerfieを作る

Dockerfileでは、このアーティファクトをダウンロードして実行するように書きます。

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"]

最後にビルドが成功したアーティファクトのURLは、Publicリポジトリの場合、CircleCI API v1.1を使って、認証なしで取得できます。JSONからアーティファクトを特定し、URLを抜き出すのにはjqを使っています。

kawasima
Clojure関連のことをブログがわりに書き綴ります。 ※ここでの発言はシステムエンジニアを代表するものであって、所属する組織は二の次です。
https://github.com/kawasima/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした