CodeBuildのローカル実行でハマった
はじめに
CodeBuildをローカルで動かしてみましたが、Dockerのバージョンのせいで少しハマってしまった備忘録です。
実施環境
Macbook Pro 2021 M1 Pro
Docker Desktop v4.28.0
やってみた
ビルドソースのセットアップ
なんでもいいですが、今回はgradleのKotlin/JVMプロジェクトをビルドしてみることにします。
gradle init
でデフォルトで作成されるサンプルプロジェクトを使用します。
サンプルコードはここにおいておきます。
buildspec.yml
は中身はなんでもいいのでとりあえずこのようにしておきます。
version: 0.2
phases:
install:
runtime-versions:
java: corretto17
pre_build:
on-failure: ABORT
commands:
- echo ビルド前の処理を書くよ
- echo ビルドがんばろう
build:
on-failure: ABORT
commands:
- echo ビルド開始するよ
- ./gradlew build
- echo ビルド完了したよ
post_build:
on-failure: ABORT
commands:
- echo ビルド後の処理を書くよ
- echo ビルドお疲れ様でした
artifacts:
files:
- app/build/libs/app.jar
ビルドイメージのセットアップ
今回CodeBuildで使用したいビルドイメージはこれです。(CodeBuildコンソールのスクショ)
まずは、これと同じビルドイメージをローカルでセットアップしていきます。
ECRパブリックレジストリに公開されているものをpullするだけです。
docker pull public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0
CodeBuild Agentのセットアップ
ローカルでCodeBuildを実行するためのAgent用Dockerイメージをpullします。
X86_64とARMのどちらを使用しているかでpullするイメージが異なるため、自分のマシンがどちらか確認します。
uname -m
自分のマシンはarm64と出たので、ドキュメントに従いARM用イメージをpullします。
docker pull public.ecr.aws/codebuild/local-builds:aarch64
CodeBuild Agent実行スクリプトをドキュメントに従いダウンロードします。
cd <ビルドしたいソースディレクトリ>
curl -O https://raw.githubusercontent.com/aws/aws-codebuild-docker-images/master/local_builds/codebuild_build.sh
chmod +x codebuild_build.sh
CodeBuildの実行失敗
早速実行してみます。
-i と -a は必須です。それぞれビルドイメージとアーティファクトのアウトプットディレクトリを指定します。
オプション一覧はGitHubにあるとおりです。
./codebuild_build.sh -i public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0 -a app/build/codebuild -l public.ecr.aws/codebuild/local-builds:aarch64
実行してみたところ以下のエラーが発生しました。
ERROR: client version 1.22 is too old. Minimum supported API version is 1.24, please upgrade your client to a newer version
とりあえずdockerのバージョンを確認してみます。
docker version
以下のようにDocker Desktopのバージョン情報が色々でてきます。
ここに minimum version 1.24とあります。
# 一部省略
Server: Docker Desktop 4.28.0 (139021)
Engine:
Version: 25.0.3
API version: 1.44 (minimum version 1.24)
2024/1/25にリリースされたDokcer Desktop 4.27.0からDocker Engineがv25にアップグレードされたことでAPIのminimum versionが変更されたことが原因のようです。
v24であれば問題ないようなので、Docker Engineのバージョンを24にダウングレードするため一度Docker Desktopを入れ直します。
[Docker Desktop release notes]を見に行くと、Docker Engine 24系を使ってる最新のDesktopのバージョンは4.26.1のようなので、それのMac Apple chip用をダウンロードします。
再インストールできたのでdockerのバージョンをもう一度見てみます。
docker version
# 一部省略
Server: Docker Desktop 4.26.1 (131620)
Engine:
Version: 24.0.7
API version: 1.43 (minimum version 1.12)
Docker Engineが24.0.7になり、API Versionがminimum version1.12となっているのが確認できました。
これでエラーは解決したはずなのでもう一度挑戦してみます。
CodeBuild の実行 再挑戦
先ほどと同様に再度実行してみます。
./codebuild_build.sh -i public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0 -a app/build/codebuild -l public.ecr.aws/codebuild/local-builds:aarch64
今度は無事できました。このようなアウトプットが得られます。
-a app/build/codebuild
で指定した通り、app/build/codebuild配下にapp.jarがアーティファクトとして保存されているのも確認できました。
Build Command:
# 省略
Removing agent-resources_build_1 ... done
Removing agent-resources_agent_1 ... done
Removing network agent-resources_default
Removing volume agent-resources_source_volume
Removing volume agent-resources_user_volume
Creating network "agent-resources_default" with the default driver
Creating volume "agent-resources_source_volume" with local driver
Creating volume "agent-resources_user_volume" with local driver
Creating agent-resources_agent_1 ... done
Creating agent-resources_build_1 ... done
Attaching to agent-resources_agent_1, agent-resources_build_1
agent_1 | [Container] 2024/03/05 14:15:35 Waiting for agent ping
agent_1 | [Container] 2024/03/05 14:15:37 Waiting for DOWNLOAD_SOURCE
agent_1 | [Container] 2024/03/05 14:15:38 Phase is DOWNLOAD_SOURCE
agent_1 | [Container] 2024/03/05 14:15:38 CODEBUILD_SRC_DIR=/codebuild/output/src531548424/src
agent_1 | [Container] 2024/03/05 14:15:38 YAML location is /codebuild/output/srcDownload/src/buildspec.yml
agent_1 | [Container] 2024/03/05 14:15:38 No commands found for phase name: install
agent_1 | [Container] 2024/03/05 14:15:38 Processing environment variables
agent_1 | [Container] 2024/03/05 14:15:38 Running command echo "Installing corretto(OpenJDK) version 17 ..."
agent_1 | Installing corretto(OpenJDK) version 17 ...
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:38 Running command export JAVA_HOME="$JAVA_17_HOME"
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:38 Running command export JRE_HOME="$JRE_17_HOME"
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:38 Running command export JDK_HOME="$JDK_17_HOME"
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:38 Running command for tool_path in "$JAVA_HOME"/bin/*;
agent_1 | do tool=`basename "$tool_path"`;
agent_1 | if [ $tool != 'java-rmi.cgi' ];
agent_1 | then
agent_1 | rm -f /usr/bin/$tool /var/lib/alternatives/$tool \
agent_1 | && update-alternatives --install /usr/bin/$tool $tool $tool_path 20000;
agent_1 | fi;
agent_1 | done
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:40 Moving to directory /codebuild/output/src531548424/src
agent_1 | [Container] 2024/03/05 14:15:40 Registering with agent
agent_1 | [Container] 2024/03/05 14:15:40 Phases found in YAML: 4
agent_1 | [Container] 2024/03/05 14:15:40 POST_BUILD: 2 commands
agent_1 | [Container] 2024/03/05 14:15:40 INSTALL: 0 commands
agent_1 | [Container] 2024/03/05 14:15:40 PRE_BUILD: 2 commands
agent_1 | [Container] 2024/03/05 14:15:40 BUILD: 3 commands
agent_1 | [Container] 2024/03/05 14:15:40 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:15:40 Phase context status code: Message:
agent_1 | [Container] 2024/03/05 14:15:40 Entering phase INSTALL
agent_1 | [Container] 2024/03/05 14:15:40 Phase complete: INSTALL State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:15:40 Phase context status code: Message:
agent_1 | [Container] 2024/03/05 14:15:40 Entering phase PRE_BUILD
agent_1 | [Container] 2024/03/05 14:15:40 Running command echo ビルド前の処理を書くよ
agent_1 | ビルド前の処理を書くよ
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:40 Running command echo ビルドがんばろう
agent_1 | ビルドがんばろう
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:40 Phase complete: PRE_BUILD State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:15:40 Phase context status code: Message:
agent_1 | [Container] 2024/03/05 14:15:40 Entering phase BUILD
agent_1 | [Container] 2024/03/05 14:15:40 Running command echo ビルド開始するよ
agent_1 | ビルド開始するよ
agent_1 |
agent_1 | [Container] 2024/03/05 14:15:40 Running command ./gradlew build
agent_1 | Downloading https://services.gradle.org/distributions/gradle-8.6-bin.zip
agent_1 | ............10%.............20%............30%.............40%.............50%............60%.............70%.............80%............90%.............100%
agent_1 |
agent_1 | Welcome to Gradle 8.6!
agent_1 |
agent_1 | Here are the highlights of this release:
agent_1 | - Configurable encryption key for configuration cache
agent_1 | - Build init improvements
agent_1 | - Build authoring improvements
agent_1 |
agent_1 | For more details see https://docs.gradle.org/8.6/release-notes.html
agent_1 |
agent_1 | Starting a Gradle Daemon (subsequent builds will be faster)
agent_1 | Caught exception: Couldn't poll for events, error = 4
agent_1 | Error while receiving file changes
agent_1 | net.rubygrapefruit.platform.NativeException: Couldn't poll for events, error = 4
agent_1 | at net.rubygrapefruit.platform.internal.jni.AbstractNativeFileEventFunctions$NativeFileWatcher.executeRunLoop0(Native Method)
agent_1 | at net.rubygrapefruit.platform.internal.jni.AbstractNativeFileEventFunctions$NativeFileWatcher.executeRunLoop(AbstractNativeFileEventFunctions.java:42)
agent_1 | at net.rubygrapefruit.platform.internal.jni.AbstractFileEventFunctions$AbstractFileWatcher$1.run(AbstractFileEventFunctions.java:154)
agent_1 | > Task :app:checkKotlinGradlePluginConfigurationErrors
agent_1 | > Task :app:processResources NO-SOURCE
agent_1 | > Task :app:processTestResources NO-SOURCE
agent_1 | > Task :app:compileKotlin
agent_1 | > Task :app:compileJava NO-SOURCE
agent_1 | > Task :app:classes UP-TO-DATE
agent_1 | > Task :app:jar
agent_1 | > Task :app:startScripts
agent_1 | > Task :app:distTar
agent_1 | > Task :app:distZip
agent_1 | > Task :app:assemble
agent_1 | > Task :app:compileTestKotlin
agent_1 | > Task :app:compileTestJava NO-SOURCE
agent_1 | > Task :app:testClasses UP-TO-DATE
agent_1 | > Task :app:test
agent_1 | > Task :app:check
agent_1 | > Task :app:build
agent_1 |
agent_1 | BUILD SUCCESSFUL in 1m 30s
agent_1 | 8 actionable tasks: 8 executed
agent_1 |
agent_1 | [Container] 2024/03/05 14:17:11 Running command echo ビルド完了したよ
agent_1 | ビルド完了したよ
agent_1 |
agent_1 | [Container] 2024/03/05 14:17:11 Phase complete: BUILD State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:17:11 Phase context status code: Message:
agent_1 | [Container] 2024/03/05 14:17:11 Entering phase POST_BUILD
agent_1 | [Container] 2024/03/05 14:17:11 Running command echo ビルド後の処理を書くよ
agent_1 | ビルド後の処理を書くよ
agent_1 |
agent_1 | [Container] 2024/03/05 14:17:11 Running command echo ビルドお疲れ様でした
agent_1 | ビルドお疲れ様でした
agent_1 |
agent_1 | [Container] 2024/03/05 14:17:11 Phase complete: POST_BUILD State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:17:11 Phase context status code: Message:
agent_1 | [Container] 2024/03/05 14:17:11 Expanding base directory path: .
agent_1 | [Container] 2024/03/05 14:17:11 Assembling file list
agent_1 | [Container] 2024/03/05 14:17:11 Expanding .
agent_1 | [Container] 2024/03/05 14:17:11 Expanding file paths for base directory .
agent_1 | [Container] 2024/03/05 14:17:11 Assembling file list
agent_1 | [Container] 2024/03/05 14:17:11 Expanding app/build/libs/app.jar
agent_1 | [Container] 2024/03/05 14:17:12 Found 1 file(s)
agent_1 | [Container] 2024/03/05 14:17:12 Preparing to copy secondary artifacts
agent_1 | [Container] 2024/03/05 14:17:12 No secondary artifacts defined in buildspec
agent_1 | [Container] 2024/03/05 14:17:12 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
agent_1 | [Container] 2024/03/05 14:17:12 Phase context status code: Message:
agent-resources_agent_1 exited with code 0
Aborting on container exit...
おわりに
いちいちCodeBuildをAWS上で実行せずとも簡単なデバッグに使えそうでいいなとおもいました。
Discussion