불필요한 캐시를 정리하고, 깃헙 액션에서 캐시가 되는 원리와 디렉토리 이해하기

문제상황

현재 이렇게 깃헙액션에서 캐시들이 잔뜩 생기고 있습니다.

캐시 해오는 것들의 크기는 엄청 큰데 세개만 있어도 10기가 가득 용량이 찹니다.

하지만 릴리즈를 한번 찍을때마다 캐시는 새로 생기고, 이때까지 저는 주기적으로 들어와서 캐시를 삭제해주는 번거로운 작업을 했었습니다.

그렇습니다 다른 사람들에게는 자동화를 주지만 스스로는 아날로그로 일한것입니다.

이제 저에게도 자유를 주는 깃헙액션 캐시 자동삭제 플로우를 만들어보려고합니다.

기존 워크플로우 구성

name: (PRD) Deploy to Amazon ECS

on:
release:
types: [published]

env:
AWS_REGION: ap-northeast-2
ECR_REGISTRY: 091xxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com
ECR_REPOSITORY: otl-xxxxxxxxxx
ECS_SERVICE_NAME: otl-xxxxxxxx
ECS_COLLECTOR_NAME: otl-xxxxxxxxx
ECS_CLUSTER_NAME: otl-xxxxxxxxx
TASK_DEFINITION_NAME: otl-task
TASK_COLLECTOR_DEFINITION_NAME: otl-xxxxxxxx
DOCKER_FILE_NAME: Dockerfile.production
VERSION: ${{ github.event.release.tag_name }}

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: prd

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ECS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_ECS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Get Build Version
run: echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV

- name: Create .env file
env:


run: |
uses: docker/setup-buildx-action@v1

# 캐시 사용 설정
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile.production', 'package.json', 'yarn.lock') }}
restore-keys: |
${{ runner.os }}-docker-

- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }}
VERSION: ${{ env.VERSION }}
run: |
docker buildx build \
--push \
--tag $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION \
--tag $ECR_REGISTRY/$ECR_REPOSITORY:latest \
--cache-from type=local,src=/tmp/.buildx-cache \
--file ${{ env.DOCKER_FILE_NAME }} \
.

- name: (Service) Download Task Definition Template
run: |
aws ecs describe-task-definition \
--task-definition ${{ env.TASK_DEFINITION_NAME }} \
--query taskDefinition \
> task-definition.json

- name: (Service) Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: task-definition.json
service: ${{ env.ECS_SERVICE_NAME }}
cluster: ${{ env.ECS_CLUSTER_NAME }}
wait-for-service-stability: true
force-new-deployment: true

다음과 같이 구성되어있는 깃헙액션 배포 워크플로우 입니다.

실행로그를 확인하면 실제로는 main 브랜치에서 만들어진 해당 캐시를 참조했음에도

워크플로우 끝에는 캐시를 굳이 한번 더 써주는 행위를 했습니다. 이로써 main브랜치에 있는 dev 배포를 하면서 dev의 캐시를 Prd 에서 참조를 함에도 불구하고, prd 배포 후 새로운 캐시가 늘 남았습니다.

그리고 매번 10기가에 압박에 못 버텨서 일정주기로 들어가서 손으로 캐시를 일일이 지웠습니다.. (지금도 10기가를 넘겼네요… 이렇게되면 문서에서는 말하기를 캐시를 불러오는데 문제가 생길 수 있다고 언급되어있습니다.)

해결

      # 캐시 삭제
- name: Delete Docker layers cache
run: |
if [ -d /tmp/.buildx-cache ]; then
rm -rf /tmp/.buildx-cache
echo "Docker cache directory deleted."
fi

깃헙 액션 워크플로우 끝에 도커레이어 캐시를 삭제하는 부분을 삽입했습니다.

그렇다면 /tmp/.buildx-cache 이 경로는 어디서 가져온 것일까요?

     # 캐시 사용 설정
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-docker-${{ hashFiles('**/Dockerfile.production', 'package.json', 'yarn.lock') }}
restore-keys: |
${{ runner.os }}-docker-

캐시 사용을 설정한 액션에서 지정한 path에 기입되어있는 경로에 따른 것입니다.

해당 경로가 기준이 되어 캐시가 저장되고 복원됩니다.

해당 경로의 캐시 파일을 빌드 과정에서 사용하며, 빌드가 끝난 후 이 경로를 삭제하는 방식입니다.

워크플로우 실행 중 마지막에 /tmp/.buildx-cache 경로에 생성된 캐시 파일을 삭제합니다.

따라서, 워크플로우가 끝난 후 새로운 캐시가 GitHub 서버에 저장되지 않습니다.

결론

- 캐시 생성 및 복원 경로: /tmp/.buildx-cache

- 캐시 삭제 경로: /tmp/.buildx-cache

- 결과: 워크플로우 실행 중 생성된 캐시가 삭제되어, 새로운 캐시가 서버에 남지 않습니다.

검증

새로운 깃헙액션 워크플로우 적용 후 v1.5.67 (29, May 2024) 릴리즈에 따른 prd 워크플로우가 실행이 되었고, Delete Docker layers Cache 가 추가되었습니다.

v1.5.66을 마지막으로 v1.5.67 브랜치에 따른 새로운 캐시가 생성되지 않은것을 확인할 수 있었습니다.

Prd는 dev의 캐시를 참조하니, 매번 남길 필요가 없으니 원하던 동작 대로 prd 배포 라인에서는 캐시를 안남기도록 실행이 된 것을 확인할 수 있었습니다.

--

--