AWS CDK DockerImageAssetのビルドエラー解決法:CodeBuildメモリ不足問題
問題の概要
AWS CDKのCodePipelineでDockerImageAssetを使用してコンテナイメージをビルドする際、以下のエラーが発生しました。
exit code: 137
26.40 Killed
ERROR: process "/bin/sh -c yarn workspaces focus example-app --all" did not complete successfully: exit code: 137
エラーの原因分析
Exit Code 137の意味
Exit code 137は、プロセスがSIGKILLシグナルによって強制終了されたことを示します。これは通常、以下の状況で発生します:
- メモリ不足(OOM: Out of Memory)
- コンテナのリソース制限に達した場合
- タイムアウトによる強制終了
DockerImageAssetの内部動作
AWS CDKのDockerImageAsset
は、内部的に専用のCodeBuildプロジェクトを自動生成してDockerイメージのビルドを実行します。重要な点は、このCodeBuildプロジェクトは、パイプラインで明示的に定義したCodeBuild設定とは別のプロジェクトであることです。
デフォルトの制限
DockerImageAsset
が使用するCodeBuildプロジェクトのデフォルト設定:
-
Build Image:
aws/codebuild/standard:7.0
-
Compute Type:
BUILD_GENERAL1_SMALL
- リソース: 3GB RAM, 2 vCPU
-
Privileged Mode:
true
今回のケースでは、Node.jsプロジェクトの大量の依存関係(1000+パッケージ)をインストールする際に、3GBのメモリでは不足していました。
解決方法
assetPublishingCodeBuildDefaultsの設定
AWS CDK Pipelinesでは、assetPublishingCodeBuildDefaults
プロパティを使用してアセット公開用のCodeBuild設定をカスタマイズできます。
const pipeline = new pipelines.CodePipeline(this, 'Pipeline', {
pipelineName: 'example-pipeline',
synth: new pipelines.ShellStep('Synth', {
input: pipelines.CodePipelineSource.gitHub('example-org/example-repo', 'main'),
commands: [
'yarn build',
'npx cdk synth'
],
}),
assetPublishingCodeBuildDefaults: {
buildEnvironment: {
computeType: codebuild.ComputeType.LARGE,
privileged: true,
},
},
});
この設定により、DockerImageAsset
が使用するCodeBuildプロジェクトのリソースが以下のように変更されます:
-
Compute Type:
BUILD_GENERAL1_LARGE
- リソース: 7GB RAM, 4 vCPU
DockerImageAssetの使用例
問題が発生していたDockerImageAssetの定義例:
// Node.jsアプリケーション用Dockerイメージ
const appDockerImage = new DockerImageAsset(this, 'AppDockerImage', {
directory: '.',
file: '.docker/apps/example-app/Dockerfile',
target: 'app',
});
// Nginx用Dockerイメージ
const nginxDockerImage = new DockerImageAsset(this, 'NginxDockerImage', {
directory: '.',
file: '.docker/apps/example-app/Dockerfile',
target: 'nginx',
});
注意点
- コスト影響: より大きなコンピューティングタイプは、ビルド時間あたりのコストが高くなります
- ビルド時間: メモリ増加により、ビルド時間が短縮される場合があります
-
適用範囲:
assetPublishingCodeBuildDefaults
は、パイプライン内のすべてのDockerImageAsset
に適用されます
まとめ
AWS CDKのDockerImageAssetでメモリ不足エラーが発生した場合、assetPublishingCodeBuildDefaults
を使用してCodeBuildのコンピューティングタイプを調整することで解決できます。この設定は、パイプライン全体のアセット公開プロセスに適用されるため、一箇所の変更で包括的な問題解決が可能です。
大規模なNode.jsプロジェクトやモノレポ構成では、このようなリソース調整が重要になるケースが多いため、初期設計時から考慮しておくことを推奨します。
Discussion