Development

GitHub Actions 캐시 오염으로 배포가 흔들릴 때 복구 체크리스트

Mike발행일 2026년 3월 5일읽는 시간 약 3

💡 Key Takeaways

  • 캐시는 실패를 숨기는 장치가 아니라 실패를 더 빨리 드러내도록 설계해야 안전합니다.
  • 오염 의심 상황에서는 캐시 삭제보다 키 전략과 복구 순서를 먼저 고정해야 재발을 줄일 수 있습니다.
  • 의존성 캐시, 빌드 아티팩트 캐시, 툴체인 캐시를 분리하면 원인 추적 속도가 크게 빨라집니다.
  • 복구 완료 기준을 로그와 지표로 명확히 두어야 야간 배포에서 판단 실수를 줄일 수 있습니다.

GitHub Actions 캐시 오염으로 배포가 흔들릴 때 복구 체크리스트

팀에서 가장 자주 겪는 CI 장애 중 하나가 "어제까지 되던 빌드가 오늘만 랜덤하게 깨지는" 상황입니다. 처음에는 의존성 서버 장애나 코드 결함으로 의심하기 쉽지만, 실제로는 캐시 오염이 원인인 경우가 꽤 많습니다. 저희도 금요일 저녁 배포에서 같은 일을 겪었습니다. pnpm install 단계는 통과했는데 테스트 단계에서만 타입 정의 충돌이 나고, 재실행하면 또 통과했습니다. 담당자가 급하게 워크플로를 재실행해서 배포는 일단 넘겼지만, 다음 배포에서 같은 증상이 재발했습니다. 핵심은 속도를 위해 만든 캐시가 장애를 숨긴 상태였다는 점입니다. 캐시가 있으면 실패가 줄어드는 게 아니라, 실패가 특정 조건에서만 드러나서 진단이 더 어려워질 수 있습니다. 그래서 오염 의심 시에는 "지금 실패를 빨리 없애는 것"보다 "실패 패턴을 재현 가능한 상태로 고정하는 것"이 먼저입니다.

판단 기준은 단순하게 세 가지로 잡으면 됩니다. 첫째, 동일 커밋에서 재실행마다 결과가 바뀌면 캐시 오염 가능성을 가장 먼저 봅니다. 둘째, 로컬과 CI 결과가 다르고 락파일 변경이 없으면 의존성 캐시 키를 의심합니다. 셋째, 특정 브랜치에서만 깨지면 브랜치별 키 충돌 또는 restore-keys 과다 허용을 확인합니다. 여기서 중요한 건 캐시를 한 덩어리로 보지 않는 겁니다. 의존성 캐시(~/.pnpm-store, ~/.npm), 빌드 결과물 캐시(.next/cache, dist), 툴체인 캐시(테스트 바이너리, 브라우저 다운로드)를 분리해 봐야 원인이 빨리 좁혀집니다. 저희가 장애를 길게 끈 이유도 세 종류를 같은 키 규칙으로 묶어 둔 탓이었습니다. 결국 "캐시 히트율" 지표가 높아도 안정성이 좋아진 게 아니었습니다. 잘못된 캐시가 계속 히트되고 있었으니까요.

복구 절차는 네 단계로 고정해 두면 야간에도 흔들리지 않습니다. 1단계는 재현 고정입니다. 문제 커밋으로 워크플로를 2회 실행해 실패 패턴을 기록하고, 로그에 캐시 키/히트 여부를 남깁니다. 2단계는 격리입니다. actions/cache 키에서 브랜치 공통 restore-keys를 잠시 제거하고, 락파일 해시 기반 단일 키로 축소합니다. 3단계는 선택 삭제입니다. 모든 캐시를 비우지 말고 오염 가능성이 높은 범주만 지웁니다. 전체 삭제는 일시적으로 해결돼 보여도 어떤 캐시가 원인인지 학습 기회를 날립니다. 4단계는 검증입니다. 동일 커밋 3회 연속 성공, 설치 시간 변동폭, 실패 테스트 재발 여부를 확인합니다. 이 네 단계를 문서화한 뒤에는 "일단 rerun"이라는 반사 행동이 줄었습니다. 속도는 조금 느려져도, 복구 시간과 팀 스트레스는 확실히 줄어듭니다.

재발 방지에서 가장 효과가 컸던 건 키 설계와 운영 규칙입니다. 캐시 키는 최소한 OS + 런타임 버전 + 락파일 해시 + 워크플로 버전을 포함하고, 워크플로 구조를 바꾸면 버전을 강제로 올립니다. restore-keys는 편하지만 범위를 넓힐수록 오래된 쓰레기 캐시를 불러올 확률이 커집니다. 그래서 메인 브랜치에는 제한적으로만 두고, 릴리스 브랜치에는 아예 끄는 편이 안전했습니다. 또 캐시 히트율 대신 "히트된 실행의 실패율"을 같이 봐야 합니다. 히트율 90%가 좋아 보이지만, 히트된 잡의 실패율이 높으면 그건 최적화가 아니라 위험 신호입니다. 마지막으로 장애 회고에서는 "누가 캐시 키를 바꿨는가"보다 "왜 오염을 자동 감지하지 못했는가"를 먼저 봐야 다음 배포가 편해집니다. 캐시는 성능 기능이면서 동시에 운영 리스크라는 전제를 팀이 공유하면, 배포 품질이 눈에 띄게 안정됩니다.

현장에서 바로 쓰기 좋은 5분 점검표도 남겨 둡니다. 첫째, 실패한 잡의 캐시 키 문자열을 그대로 복사해 직전 성공 잡과 비교합니다. 둘째, 실패 잡에서 다운로드된 캐시 크기가 평소 대비 과하게 작거나 크지 않은지 봅니다. 셋째, 동일 커밋을 cache off 분기에서 한 번 더 돌려 결과 차이를 확인합니다. 넷째, 복구 후 첫 3개 PR의 설치 시간과 실패율을 함께 기록합니다. 다섯째, 일주일 뒤 캐시 정리 작업을 예약해 임시 키가 남지 않게 합니다. 이 다섯 줄만 지켜도 "이번엔 운 좋게 넘어갔다" 같은 불안한 배포를 크게 줄일 수 있습니다.

함께 읽으면 좋은 글

Development

Docker 빌드 캐시 미스가 반복될 때 비용과 시간을 줄이는 운영 플레이북

2026-03-09
Development

Kubernetes 프로브 오탐으로 재시작 루프가 날 때 복구 플레이북

2026-03-07

본문 작성/검수 원칙은 편집 원칙에서 확인할 수 있습니다.

← 목록으로 돌아가기