この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
FargateへCI/CDの設定をCodePipelineで行っていました。CodeBuildでgo build
時に以下のエラーによりビルドが失敗しました。メッセージ内容からCodeBuildの設定を疑っていたのですがCodeBuildの問題ではなく知っていればミスしない箇所でした。そのエラーと対応内容を紹介します。
CodeBuildのビルドログより
0.371 main.go:5:2: missing go.sum entry for module providing package github.com/labstack/echo/v4/middleware (imported by sample2-webapp-service/webapp); to add:
12 ERROR: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
原因
- 注目すべきメッセージは赤文字ではないところ missing go.sum entry for module providing package
- 適切な
go.sum
ファイルがなかった
- 適切な
go build
前にgo mod tidy
でgo.sum
ファイルを作成・更新する必要があった- 実行環境はGo version 1.16
CodeBuildの設定
CodeBuildの設定は問題なかったのですが、ビルドステージが2個ある構成なので簡単に紹介します。
1つのレポジトリから2つビルドのステージを作成していました。1つはWebアプリコンテナ、もう1つはサイドカーとして起動するFireLens(Fluent Bit)です。
buildspec.yml
の内容はほぼ共通です。docker buildで指定するDockerfileが異なるパスにあるため差異があります。変数はCodePipelineから渡してアカウントIDや、ECRのリポジトリ名を設定しています。
buildspec.yml
version: 0.2
env:
variables:
DOCKER_BUILDKIT: "1"
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com
- REPOSITORY_URI=${ACCOUNT_ID}.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/${REPOSITORY_NAME}
- IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-8)
build:
commands:
- echo Build started on `date`
- docker build -t $REPOSITORY_NAME:$IMAGE_TAG ./webapp
- docker tag $REPOSITORY_NAME:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $REPOSITORY_URI:$IMAGE_TAG
- printf '{"ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
files: imageDetail.json
レポジトリのディレクトリ構成は以下のとおりです。buildspec.yml
がディレクトリ違いで2個存在しています。
tree
.
├── README.md
├── appspec.yml
├── firelens
│ ├── Dockerfile
│ ├── buildspec.yml
│ └── extra.conf
├── taskdef.json
└── webapp
├── Dockerfile
├── buildspec.yml
├── go.mod
├── go.sum
├── handler
│ └── handler.go
└── main.go
ビルドプロジェクトも別れています。
以下のエラーメッセージが赤文字で表示されていたこともあり、当初はCodeBuildのビルドプロジェクトの設定を疑っていましたが関係ありませんでした。
ビルドログ
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c go build -o web-server .]: runc did not terminate sucessfully
Dockerfile
CodeBuildでエラーが発生したときのDockerfileです。 マルチステージビルドしているだけのシンプルな内容です。ローカルでは問題なくdocker buildできるのに、CodeBuildだとなぜ失敗するのか調べていました。
Dockerfile
FROM public.ecr.aws/bitnami/golang:1.16 as builder
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o web-server .
FROM gcr.io/distroless/base-debian10:latest
WORKDIR /app
COPY --from=builder /app/web-server /app/web-server
EXPOSE 80
ENTRYPOINT ["/app/web-server"]
ローカル実行環境
項目 | バージョン |
---|---|
Go | 1.16.6 |
Docker | 20.10.7 |
macOS | 10.15.7 |
CodeBuildのログから赤文字のエラーメッセージに気を取らていたのですが、よくみるとgo.sum
がないというメッセージも出力されています。
エラーメッセージ
0.371 main.go:5:2: missing go.sum entry for module providing package ...
go.sum
は.gitignore
に追加しています。ローカルには存在していますが、CodeCommitには存在していません。さらに調べてみるとGoのバージョン1.15まではgo build
時にgo.sum
が自動更新されていたのが、1.16からは更新されなくなった。
go mod tidyコマンドがgo.mod
を確認し不足しているエントリをgo.sum
に追加してくれることを知りました。つまり、go.sum
の作成・更新をしてくれる。不要になった依存関係を削除してくれることしか把握しておらず、go.sum
については意識すらしていませんでした。
というわけでgo build
前にgo mod tidyを追加した修正版です。
修正版Dockerfile
FROM public.ecr.aws/bitnami/golang:1.16 as builder
WORKDIR /app
COPY . .
RUN go mod download
RUN go mod tidy
RUN go build -o web-server .
FROM gcr.io/distroless/base-debian10:latest
WORKDIR /app
COPY --from=builder /app/web-server /app/web-server
EXPOSE 80
ENTRYPOINT ["/app/web-server"]
解決
修正版のDockerfileをCodeCommitへPushし、CodePipelineでCodeBuildが走りました。
go build
は正常に完了しました。
CodeBuildのログ
#11 [builder 4/6] RUN go mod download
#11 DONE 3.8s
#12 [builder 5/6] RUN go mod tidy
#12 DONE 0.6s
#13 [builder 6/6] RUN go build -o web-server .
#13 DONE 4.4s
その後、デプロイまで完了しました。
おわりに
以上、備忘録でした。たまに使ってみるとキャッチアップが全然できていないことに気付かされます。つい先日1.17がリリースされましたし、日々のキャッチアップが大切ですね。