🍣

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',
});

注意点

  1. コスト影響: より大きなコンピューティングタイプは、ビルド時間あたりのコストが高くなります
  2. ビルド時間: メモリ増加により、ビルド時間が短縮される場合があります
  3. 適用範囲: assetPublishingCodeBuildDefaultsは、パイプライン内のすべてのDockerImageAssetに適用されます

まとめ

AWS CDKのDockerImageAssetでメモリ不足エラーが発生した場合、assetPublishingCodeBuildDefaultsを使用してCodeBuildのコンピューティングタイプを調整することで解決できます。この設定は、パイプライン全体のアセット公開プロセスに適用されるため、一箇所の変更で包括的な問題解決が可能です。

大規模なNode.jsプロジェクトやモノレポ構成では、このようなリソース調整が重要になるケースが多いため、初期設計時から考慮しておくことを推奨します。

Discussion