Github actions는 실행할 때 마다 새롭게 인스턴스가 뜨는 방식이므로 도커 캐시가 동작하지 않습니다.
캐시없이 도커를 빌드하는건 엄청난 인내심을 요구합니다.
이를 해결할 수 있는 방법은 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 형태로 캐시 데이터를 저장한다고 합니다.
# 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에서도 도커캐시가 적용되는것을 확인할 수 있습니다.