ちょっと話題の記事

CodeBuild で Docker イメージに Git のコミットIDをタグ付けてバージョン管理する

2018.02.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

CodeBuild で Docker イメージ作成時にバージョン管理のためにコミットIDとの紐付けを行い、どの Docker イメージがどの時点のソースコードのものなのか判断できるようにしました。

ども、藤本です。最近、CodeBuild をよく触っているので、CodeBuild のブログ多めです。

概要

CodeBuild は CodeCommit、S3、GitHub、BitBucket にあるソースコードをコンパイルしたり、スタイルチェックしたり、ユニットテストしたりできるビルドサービスです。最近、使った用途では GitHub リポジトリにあるソースコードから Docker イメージを作成して、ECR のリポジトリにプッシュするように自動化しました。

この仕組み自体は CodeBuild の公式ドキュメントに記載されている通りに設定すればできます。

ドキュメントに記載のビルド処理では latest でタグ打ちしているので最新版のイメージは分かるのですが、最新版以外のイメージがどの時点のソースコードなのか、むしろ最新版のイメージもどの時点のソースコードなのか判断することができません。デプロイのタイミングなどがちゃんと管理できているのであれば問題ないのですが、不定期に作成していると以前のイメージを使いたい時にどのイメージを使えばいいのか分からなくなります。なので、どのイメージがどの時点のソースコードなのか判断できる基準、タグが欲しかったのでやってみました。

コミットID でタグ打ちする

どの時点のソースコードなのか判断する一つの基準に Git のコミットIDがあります。コミット単位で払い出されます。そこでこのコミットID を Docker イメージのタグに付与することでどの時点のソースコードなのか判断できます。

buildspec.yml
version: 0.2
 
phases:
  pre_build:
    commands:
      - $(aws ecr get-login --region ${AWS_DEFAULT_REGION} --no-include-email)
      - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${ECR_REPOSITORY_NAME}
      - IMAGE_TAG=$(git rev-parse --short HEAD)
  build:
    commands:
      - docker build -t ${REPOSITORY_URI}:latest
      - docker tag ${REPOSITORY_URI}:latest ${REPOSITORY_URI}:${IMAGE_TAG}
  post_build:
    commands:
      - docker push ${REPOSITORY_URI}:${IMAGE_TAG}
      - docker push ${REPOSITORY_URI}:latest

ほとんど公式ドキュメントの設定ファイルなのでポイントを絞って説明します。

ECR のリポジトリ名は CodeBuild プロジェクトの環境変数で与えるといいと思います。ここでは ECR_REPOSITORY_NAME というキーの環境変数で設定しています。

9行目:タグに与える値として HEAD のコミットIDを取得します。フルの commit ID を取得する場合は --short を外してください。

17行目:latest に加えてコミットID のイメージもプッシュします。コミットIDのイメージと latest のイメージの実体は同じなので latest のプッシュはタグ情報のみ送信されます。(2つの Docker イメージが送信されるわけではない)

ビルドすると、latest とコミットID のタグが付与されています。

タグ名でタグ打ちする

もう一つの判断基準として、リリースバージョンをタグ打ちして、デプロイしている方もいるかと思います。その場合、Git のタグ名を Docker イメージのタグに付与すると分かりやすくていいですね。

version: 0.2
 
phases:
  pre_build:
    commands:
      - $(aws ecr get-login --region ${AWS_DEFAULT_REGION} --no-include-email)
      - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${ECR_REPOSITORY_NAME}
      - IMAGE_TAG=$(git describe --tags)
  build:
    commands:
      - docker build -t ${REPOSITORY_URI}:latest
      - docker tag ${REPOSITORY_URI}:latest ${REPOSITORY_URI}:${IMAGE_TAG}
  post_build:
    commands:
      - docker push ${REPOSITORY_URI}:${IMAGE_TAG}
      - docker push ${REPOSITORY_URI}:latest

9行目:ソースコードに割り当てられたタグ名を取得します。この場合、タグを割り当てていないとエラーになるのご注意ください。

ビルドすると、latest とタグ(今回は 0.0.2 でタグ打ち)のタグが付与されています。latest は前回のイメージから付け変わっています。

まとめ

いかがでしたでしょうか?
ECR に限らずですが、Docker イメージにタグ付けすることでバージョン管理が容易となります。デメリットはそんなにないと思うのでやっておいて損はないかと思います。