LoginSignup
17
9

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-02-27

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を使っています。

17
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
9