実現したいこと
前回の記事 で構築したCIパイプラインの実行時間を短縮したい
具体的には,CodeBuildでDockerイメージを作成する際のgoモジュールを予めキャッシュしておき,ビルド毎に発生するダウンロード時間を短縮したい.
#環境
- Golang 1.13.5
- Docker 18
- AWS 東京リージョン
やったこと/ハマったこと
やったこと1
-
CodeBuildの設定変更
CodeBuildのアーティファクト設定からキャッシュタイプを"ローカルキャッシュ"に変更
オプションは"CustomCache"を選択 -
buildspec.yamlの編集
前回作成したbuildspec.ymlに cache項目を追加
version: 0.2
phases:
install:
runtime-versions:
docker: 18
commands:
- $(aws ecr get-login --no-include-email --region ap-northeast-1)
pre_build:
commands:
- make test
build:
commands:
- make build
post_build:
commands:
- make push-image
#キャッシュ対象にするディレクトリを指定
cache:
paths:
# goモジュールの保存先
- '/go/pkg/mod/**/*'
ハマったこと1
- goモジュールが
/go/pkg/mod/
に保存されていない
go buildをDockerbuildの中で行っていたため ダウンロードしたモジュールは
CodeBuild上で作成されたDockerコンテナの/go/pkg/mod/
に保存されていた
当然Dockerコンテナ自体をキャッシュすることは出来ないのでこの方法は破綻
go buildをCodeBuildのコンテナ上で行い,Docker build時にコピーすることに変更
これにより,goモジュールはCodeBuildコンテナの /go/pkg/mod/
に保存される
やったこと2
- buildspec.ymlを編集
version: 0.2
phases:
install:
runtime-versions:
docker: 18
# goのランタイムが必要になったので追加
golang: 1.13
commands:
- $(aws ecr get-login --no-include-email --region ap-northeast-1)
pre_build:
commands:
- make test
build:
commands:
# CodeBuildコンテナ上でbuildするため make buildから変更
- CGO_ENABLED=0 go build -ldflags '-d -w -s' -o app
- make build
post_build:
commands:
- make push-image
cache:
paths:
- '/go/pkg/mod/**/*'
# go buildで必要になる環境変数の指定
env:
variables:
GOOS: linux
GOARCH: amd64
- DockerFileを編集
元々はgo buildもdocker build内で行っていたので
docker buildでは既に作成されたgoアプリの実行ファイルを使用してイメージを作成するようにDockerFileを編集
ハマったこと2
- なぜかローカルキャッシュが機能していない
キャッシュの設定は上手くいっているようでログ上もローカルキャッシュを読み込んでいる(シンボリックリンクを作成している)
が,肝心のリンク先にキャッシュされているはずのファイルが存在しない.
AWSの仕様ページ を見るにローカルキャッシュが利用できない場合もあるとのことだが,今回の設定は該当していないように思える.
今回は原因調査まで行う余裕がなかったため 一旦ローカルキャッシュを諦め
S3にキャッシュさせることにした.
(課題は残るものの)完成
キャッシュ設定前後ではビルド時間が 3min43sec -> 3min09sec と多少なりキャッシュの恩恵を確認できた.
ただ,S3キャッシュはS3からキャッシュデータをダウンロードし,ビルド後にS3へアップロードするため,予めコンテナ内にデータを保持しておき,シンボリックリンクを作成するのみのローカルキャッシュと比べると時間がかかってしまう.
(今回はキャッシュデータが50MBを超えていたのでダウンロード/アップロードに時間がかかっているのが実感としてあった)