jibを用いたmulti-project docker build

https://github.com/GoogleContainerTools/jib/tree/master/examples/multi-module

やってみる。

# 背景
- gradleだと`com.palantir.docker`を使うのが一般的だと思うのだが、multi projectだとどうにも動かす方法が分からなかった。
- また、`com.palantir.docker`だとECR登録がとても面倒だった。
- jibを使ってみたかった。
- 現実逃避

# 構成
```
rootProject--sample1←ここがECRにPushするリポジトリ
           --sample2
```
# やってみた。

https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin#quickstart
を見ながらそれっぽく修正。
rootProjectのpluginsにapply falseを入れるのが重要。これ入れないとエラーになる。

```build.gradle(rootProject抜粋)
plugins {
    id 'org.springframework.boot' version '2.3.4.RELEASE'
    id 'io.spring.dependency-management' version "1.0.10.RELEASE"
    id 'com.google.cloud.tools.jib' version '2.6.0' apply false
}

ext {
    artifactGroup = 'prototype.app'
    artifactVersion = '1.0.0'
    springBootDependenciesVersion = '2.3.4.RELEASE'
}

/* 全プロジェクト共通 */
allprojects {

    ext {
        set('extention', 'jar')
        set('artifactVersion', "${artifactVersion}")
    }

    repositories {
        mavenCentral()
        jcenter()
        gradlePluginPortal()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
}

/* Javaプロジェクト共通 */
configure(subprojects) {

    apply plugin: 'java'
    apply plugin: 'java-library'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
  
    dependencyManagement {
        imports {
            // Spring Boot
            mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootDependenciesVersion}"
        }
        imports {
            // AWS SDK ver 2.X.X
            mavenBom "software.amazon.awssdk:bom:2.14.14"
        }
    }

    dependencies {
        // for Develop
        annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    }
}

/* Dockerプロジェクト共通 */
configure(subprojects - project('sample2') ) {
    apply plugin: "com.google.cloud.tools.jib"
}
```

```build.gradle(sample1抜粋)
plugins {
    id 'com.google.cloud.tools.jib'
}

jib {
    from {
        image = 'amazoncorretto:11'  
    }
    to {
        image = "XXXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/prototype"
    //    tags = ["${artifactVersion}"]       
    }
    container {
        environment = [SPRING_PROFILES_ACTIVE:"prod"]
    }
}
```

Codebuildも使うので、buildspec.ymlは作っておく。
ECRのリポジトリを作っておかないとエラーになるので、それは事前にterraformで作っておいた。
また普通はこんなことやらないのだが、動作するかどうかの確認のために、docker pullしてrunさせるものもpost_buildフェイズに追加しておいた。

```buildspec.yml
version: 0.2

env:
  variables:
    # FIXME:
    AWS_ACCOUNT   : "XXXXXXXXXXXXX"
    IMAGE_REPO    : "prototype"
    TAG           : "latest" 
phases:
  install:
    runtime-versions:
      java: corretto11
    commands:
      - chmod +x ./gradlew
      - touch gradle.properties
      - |
        cat <<EOL >> gradle.properties
        org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m
        EOL
        
      - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay&
      - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"

  pre_build:
    commands:
      - echo build start on `date`
      - $(aws ecr get-login --no-include-email)
      
  build:
    commands:
      - ./gradlew build 
      - ./gradlew :sample1:jib --info

  post_build:
    commands:
      # 動作確認用
      - docker pull ${AWS_ACCOUNT}.dkr.ecr.ap-northeast-1.amazonaws.com/${IMAGE_REPO}:${TAG}
      - docker run -p 8080:8080 ${AWS_ACCOUNT}.dkr.ecr.ap-northeast-1.amazonaws.com/${IMAGE_REPO}:${TAG}
      - echo build end on `date`
cache:
  paths:
    - /root/.gradle/caches/**/*
    - /root/.gradle/wrapper/**/*
```
# 結果
最初はECRの仕様に色々とやられましたが、動きましたね。(ログはそれっぽく修正してある)

```
Status: Downloaded newer image for XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/prototype:latest
XXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/prototype:latest

[Container] 2020/11/14 04:44:20 Running command docker run -p 8080:8080 ${AWS_ACCOUNT}.dkr.ecr.ap-northeast-1.amazonaws.com/${IMAGE_REPO}:${TAG}

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.4.RELEASE)

2020-11-14 04:44:24.281  INFO 1 --- [           main] p.b.transfer.BeforeTransferApplication   : Starting BeforeTransferApplication on f2ceab1be0d6 with PID 1 (/app/classes started by root in /)
2020-11-14 04:44:24.283  INFO 1 --- [           main] p.b.transfer.BeforeTransferApplication   : The following profiles are active: prod
2020-11-14 04:44:25.481  INFO 1 --- [           main] p.b.transfer.BeforeTransferApplication   : Started BeforeTransferApplication in 1.636 seconds (JVM running for 2.084)

[Container] 2020/11/14 04:44:25 Running command echo build end on `date`
build end on Sat Nov 14 04:44:25 UTC 2020

```