CI/CDでdocker buildする際にgradleのライブラリインストールをキャッシュを活用することでスキップしたい。

デプロイ用イメージのFROMに指定するイメージをECR登録

ビルドした最終成果物のjarファイルを素のJavaイメージに追加してECSにデプロイするため、FROMがあるだけのDockerfileを用意する。

echo 'FROM amazoncorretto:21' > Dockerfile-ecr-cache-java

AWSのCodeBuildを利用することを前提にするため、Docker HubのRate Limitを気にしなくて済むように、これをECRに保存する。

repo=java
docker image build . -f Dockerfile-ecr-cache-java -t ${repo}
aws_account_id=自身のid
region=ap-northeast-1
ecr=${aws_account_id}.dkr.ecr.${region}.amazonaws.com
aws ecr get-login-password --region ${region} | docker login --username AWS --password-stdin ${ecr}
docker tag ${repo}:latest ${ecr}/${repo}:lastest
docker push ${ecr}/${repo}:latest

ビルド用イメージのECR登録

ビルドに使うイメージを作成する。

FROM amazoncorretto:21
ENV GRADLE_USER_HOME=/gradle-cache
WORKDIR /app
COPY ./gradlew ./gradlew
COPY ./gradle ./gradle
COPY ./build.gradle ./settings.gradle ./
# 依存関係だけ先に解決
RUN ./gradlew dependencies --no-daemon || true

repo=buildjavaとして、同様にECRに保存する。

デプロイ用イメージのためのDockerfile

ビルド用イメージで、DockerfileにGRADLE_USER_HOMEを指定し、./gradlew dependenciesで依存関係を解決してキャッシュした。

このGRADLE_USER_HOMEをデプロイ用Dockerfileでも指定する。

# ${ecr}は要置き換え
FROM ${ecr}/buildjava:latest AS build
ENV GRADLE_USER_HOME=/gradle-cache
WORKDIR /app
COPY . .
RUN ./gradlew clean test bootJar

FROM ${ecr}/java:latest
RUN sed -i '/^networkaddress.cache.ttl=/d' $JAVA_HOME/conf/security/java.security \
    && sed -i '/^networkaddress.cache.negative.ttl=/d' $JAVA_HOME/conf/security/java.security \
    && echo 'networkaddress.cache.ttl=5' >> $JAVA_HOME/conf/security/java.security \
    && echo 'networkaddress.cache.negative.ttl=5' >> $JAVA_HOME/conf/security/java.security \
    ;
COPY --from=build /app/build/libs/app.jar /app.jar
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-XX:+ExitOnOutOfMemoryError", "-jar", "-Dspring.profiles.active=prd", "/app.jar"]

CI/CDパイプラインがこのDockerfileをビルドし、できあがったイメージをECRに保存、ECSデプロイを行う。