Closed12
GitHub ActionsでDockerイメージのビルドとECRへのpushをやってみるメモ
この記事を見ながらやってみている
特定リポジトリのECRへのPushができるIAMユーザーを作る。
探してみたらチュートリアルがあった。
terraformで管理しているのでこんな感じになった
resource "aws_iam_user" "this" {
name = "github_actions_deploy_${var.name}"
}
resource "aws_iam_user_policy_attachment" "this" {
user = aws_iam_user.this.name
policy_arn = aws_iam_policy.this.arn
}
resource "aws_iam_policy" "this" {
name = "github_actions_${var.name}"
policy = data.aws_iam_policy_document.iam_user.json
}
data "aws_iam_policy_document" "iam_user" {
statement {
actions = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
]
resources = [
data.aws_ecr_repository.this.arn,
]
}
}
失敗した。 ecr:GetAuthorizationToken
は全てのリポジトリに許可しないといけないらしい
data "aws_iam_policy_document" "iam_user" {
statement {
actions = [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
]
resources = [
data.aws_ecr_repository.this.arn,
]
}
statement {
actions = [
"ecr:GetAuthorizationToken",
]
resources = [
"*"
]
}
}
取り急ぎ通るようになった
name: Build and Push
on:
[push]
jobs:
build-and-push:
runs-on: ubuntu-18.04
timeout-minutes: 300
steps:
- uses: actions/checkout@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_STG }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_STG }}
aws-region: ap-northeast-1
- name: Build, tag, and push image to Amazon ECR
run: |
make -f deploy.mk build_push # Makefileにまとめているため、それを呼び出している
どうやらレイヤキャッシュが効いておらず毎回Dockerfileの上からビルドをやってるようだ。
BuildKitをうまく使えばGithub Actions上でもキャッシュを効かせられるらしい。
BuildKit、結局何なのか分からない。調べてみよう機密情報の埋め込み、ビルドの並列実行、ビルドキャッシュのインポート/エクスポートが出来る
buildターゲットをこんな感じにしてみる
build:
DOCKER_BUILDKIT=1 docker build \
--cache-from=$(DOCKER_IMAGE):latest --build-arg BUILDKIT_INLINE_CACHE=1 \
--pull -t $(DOCKER_IMAGE):$(GIT_REVISION) .
が、実行してみるとキャッシュが効いている感じがない。
#4 importing cache manifest from ***.dkr.ecr.ap-northeast-1.amazon...
#4 ERROR: ***.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest not found
ログを見るとlatestはないと言われていた。それはそう
試しにlatestを抜いたらいい感じに最新のイメージを引っ張ってきてくれないかなーと思ったけれど、
build:
DOCKER_BUILDKIT=1 docker build \
--cache-from=$(DOCKER_IMAGE) --build-arg BUILDKIT_INLINE_CACHE=1 \
--pull -t $(DOCKER_IMAGE):$(GIT_REVISION) .
結果は変わらず latest
を探しに行ってしまっていた。タグ指定がない場合は latestを探しに行くとのこと。
#4 importing cache manifest from ***.dkr.ecr.ap-northeast-1.amazon...
#4 ERROR: ***.dkr.ecr.ap-northeast-1.amazonaws.com/hogehoge:latest not found
最新イメージのタグを力技で取得して明示的にキャッシュ元を取得するようにした
build: latest_tag := $(shell aws ecr describe-images --registry-id ${ECR_REGISTRY_ID} --repository-name ${REPOSITORY_NAME} --query 'reverse(sort_by(imageDetails[], &imagePushedAt)[].imageTags[]) | [0]' | sed "s/\"//g")
build:
DOCKER_BUILDKIT=1 docker build -f ./deployment/Dockerfile \
--cache-from=$(DOCKER_IMAGE):${latest_tag} --build-arg BUILDKIT_INLINE_CACHE=1 \
-t $(DOCKER_IMAGE):$(GIT_REVISION) .
「これlatestタグを付け替え続ければ最新イメージを取得する処理簡単では…」と頭によぎったが、心を鬼にしてJMESPathと向き合いました
おおお!キャッシュされている!!!
DOCKER_BUILDKIT=1 docker build -f ./deployment/Dockerfile \
--cache-from=***.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:fuga --build-arg BUILDKIT_INLINE_CACHE=1 \
-t ***.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:piyo .
#1 [internal] load .dockerignore
#1 transferring context: 69B done
#1 DONE 0.0s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 920B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/ruby:2.6.6
#3 DONE 1.2s
#9 [internal] load build context
#9 DONE 0.0s
#5 [1/8] FROM docker.io/library/ruby:2.6.6@sha256:358f16e92d0f66599103318f7...
#5 DONE 0.0s
#4 importing cache manifest from ***.dkr.ecr.ap-northeast-1.amazon...
#4 DONE 1.4s
#9 [internal] load build context
#9 transferring context: 7.93MB 0.1s done
#9 DONE 0.2s
#10 [5/8] COPY Gemfile Gemfile.lock /app/
#10 CACHED
#6 [2/8] RUN mkdir /app
#6 CACHED
#7 [3/8] WORKDIR /app
#7 CACHED
#8 [4/8] RUN curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key ad...
#8 CACHED
#12 [7/8] RUN bundle config set deployment 'true' && bundle config set w...
実行順序がバラバラになっている。これがBuildKitの並列実行?
5分程度かかっていたビルドが1分程度で終わるように。これは嬉しい。
一定期間運用していて問題なく回っているので、このままで良さそう。閉じます。
このスクラップは2020/12/12にクローズされました