— 배포가 갑자기 안 됐던 진짜 이유
CI/CD를 쓰다 보면
"어제까지 되던 배포가 오늘 갑자기 안 되는" 순간이 온다.
이번에 내가 겪은 문제는 빌드도 성공했고 코드도 그대로인데 배포가 안 되는 상황이었다.
원인은 의외로 단순했다.
"Artifact가 만료(expired)" 된 것이었다.
1. Artifact란 무엇인가?
Artifact는 CI 파이프라인에서 job이 만들어낸 "결과물 파일"이다.
조금 더 풀어보자면,
- 빌드 결과물
- 컴파일된 파일
- 패키징된 산출물
- 다음 단계에서 다시 써야 하는 파일
이와 같은 것들을 GitLab이 임시로 보관해주는 파일 묶음이다.
예시로 보면 이해가 빠르다
프론트엔드 프로젝트(my-project)에서 보통 이런 흐름이 있다.
소스 코드
↓
빌드 (npm build / pnpm build)
↓
dist/ 폴더 생성
이때 CI에서:
artifacts:
paths:
- dist/
라고 설정하면,
👉 dist/ 폴더 전체를 artifact로 저장한다는 뜻이다.
2. Artifact는 왜 필요한가?
CI 파이프라인은 보통 여러 단계로 나뉜다.
build → publish → deploy
각 단계(job)는 서로 다른 환경에서 실행된다
즉,
- build job에서 만든
dist/파일은 - publish job으로 자동으로 넘어가지 않는다
그래서 GitLab은 중간 결과물을 artifact라는 형태로 저장해 두고,
다음 job이 다시 다운로드해서 사용하게 한다.
예시
build job
└─ dist/ 생성
└─ dist/를 artifact로 저장
publish job
└─ artifact 다운로드
└─ dist/를 사용해 배포 패키징
👉 publish job은 build를 다시 하지 않는다.
오직 artifact만 본다.
3. Artifact에는 "유통기한"이 있다
이게 이번 문제의 핵심이다.
GitLab에서는 artifact를 영구 보관하지 않는다.
보통 이렇게 설정한다.
artifacts:
expire_in: 1 week
의미는,
이 artifact는 1주일 후 자동 삭제된다
중요한 포인트
- build job이 성공했는지 여부와는 상관없다
- 시간이 지나면 artifact는 조용히 사라진다
- job 화면에는 여전히 "성공"으로 보일 수 있다
4. 이번에 실제로 발생한 문제
파이프라인 구조 (단순화)
build-live → artifact 생성 (dist-live)
publish-live → build artifact 필요
타임라인
artifact 생성
expire_in: 1 week
artifact 만료됨 ❌
publish-live 시작 불가
에러 메시지
This job could not start because it could not retrieve the needed artifacts
중요한 점은:
- publish-live는 시작조차 되지 않았다
- 로그도 없다
- 그냥 "필요한 artifact를 못 찾았다"고만 말한다
5. 왜 태그를 새로 따면 해결됐을까?
태그를 새로 만들면:
새 태그 생성
↓
새 파이프라인 실행
↓
build-live 다시 실행
↓
artifact 새로 생성
↓
publish-live 성공
즉,
문제가 해결된 게 아니라
새 artifact를 다시 만든 것뿐이었다
6. 헷갈리기 쉬운 포인트 정리
❌ "빌드는 성공했는데 왜 배포가 안 되지?"
→ publish는 빌드를 보지 않는다. artifact만 본다.
❌ "예전에는 일부 환경만 빌드해도 됐는데?"
→ 과거에는:
- publish가 artifact를 안 썼거나
- artifact 만료 시간이 길었거나
- publish에서 다시 빌드했을 가능성
❌ "로그가 없어서 원인을 못 찾겠어요"
→ artifact를 못 가져오면
GitLab은 job 자체를 시작시키지 않는다
CI/CD에서 가장 중요한 것은
'job 성공 여부'가 아니라
'필요한 artifact가 지금 존재하는가'이다.
8. 예방 방법
방법 1. Artifact 보관 기간 늘리기
artifacts:
expire_in: 4 weeks
- 태그 기반 배포
- 수동 publish 구조라면1 week는 너무 짧다
- 단점 : artifact가 계속 쌓이게 되어 기간을 길게 가지면 메모리 초과가 있을 수 있다.
방법 2. 환경별 의존성 최소화
publish-live:
needs:
- job: build-live
artifacts: true
- live 배포는 live artifact만 보게 설계 => 환경별 필요할때 개별 진행
- 다른 환경 artifact 만료와 분리
방법 3. 운영 룰 만들기
- 오래된 태그에서는 publish하지 않는다
- 배포 전 artifact 만료 여부 확인
GitLab CI에서 배포가 갑자기 안된다면,
빌드 로그보다 먼저
"artifact가 아직 살아 있는지"를 확인하자.