Github actions 에서 도커 캐시 적용하기

Key Kim
7 min readAug 10, 2021

--

Github actions는 실행할 때 마다 새롭게 인스턴스가 뜨는 방식이므로 도커 캐시가 동작하지 않습니다.

캐시없이 도커를 빌드하는건 엄청난 인내심을 요구합니다.

https://www.google.com/url?sa=i&url=https%3A%2F%2Ftwitter.com%2Fzzalbot%2Fstatus%2F296950756366483456%3Flang%3Dtr&psig=AOvVaw0oDHruAATACzN3QtxYf4__&ust=1628669454620000&source=images&cd=vfe&ved=0CAoQjRxqFwoTCLjtjNWApvICFQAAAAAdAAAAABAD

이를 해결할 수 있는 방법은 3가지 정도가 생각납니다.

Github actions cache

빌드한 이미지의 레이어를 tar 로 만들어서 캐시로 씁니다.

docker save myimage:latest > myimage.tardocker load < myimage.tar

위와 같이 빌드 후 떨어진 tar를 cache에 넣어 다음 빌드 때 불러와 사용합니다.

조금 찾아보니 제가 생각한 내용을 구현한 라이브러리가 있어서 사용해봤습니다.

음..?? 더 느려졌다??

캐시는 잘 되는데 캐시를 불러오는 시간이 빌드시간보다 길어졌습니다.

여기에 결과 캐시를 다시 저장해야하므로 추가로 시간이 더 소요됩니다.

또 캐시는 공식문서에서 5GB로 제한하고 있으니, 주기적으로 비워줘야합니다.

원격저장소에서 Pull한 이미지를 사용하여 cache 적용

docker pull로 원격저장소 이미지의 레이어를 사용해 캐시를 적용합니다.

github actions에서 사용하기엔 가장 심플한 방법인 것 같습니다.

$ docker build --cache-from $CONTAINER_REPOSITORY_URL:$REF_NAME --tag $CONTAINER_REPOSITORY_URL:$REF_NAME --tag $CONTAINER_REPOSITORY_URL:ref-$CODEBUILD_RESOLVED_SOURCE_VERSION .

특히 이미지는 작지만, 빌드 시간이 긴 경우 적용하면 알맞을 것 같습니다.

만약 이미지가 크다면 cache고 뭐고 pull이 받아질 때 까지 손가락을 빨고 있어야 합니다 ㅠㅠ .

2021.08.21

docker 18.09 이상부터 함께 설치되는 buildkit을 이용하여 빌드하면 캐시의 메타데이터를 레지스트리에 함께 기록하기 때문에 이미지를 pull 받아서 캐시를 비교할 필요가 없다고 합니다.

$ docker build -t myname/myapp --build-arg BUILDKIT_INLINE_CACHE=1 .
$ docker push myname/myapp
...
docker build --cache-from myname/myapp .

Docker buildX

최종적으로 제가 선택한 방법입니다.

가장 앞에서 소개드린 방법과 같이 github cache를 사용하는점은 동일하지만, buildKit이라는 기술로 컨테이너를 빌드하고 캐시를 생성합니다.

buildKit은 docker를 빌드할 때 사용할 수 있는 빌드 시스템입니다.(도커 뿐 아니라 OCI를 만족하는 다른 컨테이너 기술도 사용할 수 있는듯합니다)

자세한 동작 원리는 아직 파악하지 못했지만, 컨테이너를 더 빠르고 효율적으로 빌드할 수있는 기술로 파악됩니다.

캐시 부분에서는 이미지와 캐시를 별도로 저장할 수 있고, github actions을 지원하는 등 캐시를 다양한 환경에서 활용할 수 있도록 개발한 것 같습니다.

문서에 따르면 github actions Cache API를 사용하여 blob 형태로 캐시 데이터를 저장한다고 합니다.

좌측이 기존 방식, 우측이 buildX를 사용하여 캐싱한 방식
# deploy.yaml- name: Login to Amazon ECR  id: login-ecr  uses: aws-actions/amazon-ecr-login@v1- name: Set up Docker Buildx  uses: docker/setup-buildx-action@v1- name: Build, tag, and push image to Amazon ECR  uses: docker/build-push-action@v2  env:    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}    ECR_REPOSITORY: ${{ steps.login-ecr.outputs.repo }}    IMAGE_TAG: latest  with:    context: .    push: true    tags: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{   env.IMAGE_TAG }}    cache-from: type=gha    cache-to: type=gha,mode=max

위와 같이 yaml을 작성하고 실행시키면 github actions에서도 도커캐시가 적용되는것을 확인할 수 있습니다.

--

--

No responses yet