광고 빌드 실패로 막힌 배포 파이프라인 복구
목차
CI/CD 파이프라인에서 npm run build:ads가 죽는 문제를 핀포인트 수정했다.
왜 터졌나
배포 서버(/opt/games-hub-build) 쪽에 package.json이 없었다. 즉 npm run 자체가 실행 컨텍스트를 못 찾아서 뻗는 구조였다.
npm run <script>는 현재 디렉터리 또는 가장 가까운 상위 경로에서 package.json을 찾고, 거기 정의된 scripts 블록을 실행한다. 근데 배포 서버의 해당 경로는 빌드 아티팩트를 놓는 용도로 쓰이는 디렉터리였던 것 같고, package.json이 없으니 npm run이 아예 스크립트 진입점을 찾지 못했다.
npm ERR! enoent ENOENT: no such file or directory, open '/opt/games-hub-build/package.json'
이런 류의 에러는 CI 로그를 보면 바로 보이는데, 처음 마주치면 "왜 로컬에선 되는데?" 하고 한참 헤매기 쉽다. 로컬 개발 환경은 루트에 package.json이 있으니 npm run이 항상 성공하지만, 서버 배포 경로는 전혀 다른 디렉터리 구조를 갖는 경우가 흔하다.
변경 내용
수정은 단순하다. .github/workflows/deploy.yml 한 파일만 건드렸다.
| 변경 전 | 변경 후 |
|---|---|
npm run build:ads |
node build-ads.js |
npm run build:ads가 내부적으로 node build-ads.js를 호출하는 구조였을 테니, 중간 레이어(npm run)를 걷어내고 node로 직접 실행하도록 바꿨다. node는 package.json 없이도 실행 가능하고, 빌드 스크립트 파일만 해당 경로에 있으면 된다.
# before
- name: Build ads
run: npm run build:ads
# after
- name: Build ads
run: node build-ads.js
변경 파일이 deploy.yml 하나고 stat도 크지 않다. 전형적인 핀포인트 픽스다.
이런 상황이 생기는 이유
CI 워크플로우를 처음 짤 때 로컬 개발 환경 기준으로 명령어를 그대로 옮겨 쓰는 경우가 많다. 로컬에서 npm run build:ads가 잘 되니까, 그걸 그냥 run: 블록에 박아넣는 것이다.
문제는 배포 파이프라인이 항상 로컬과 같은 디렉터리 구조를 갖지 않는다는 점이다. 특히 배포 서버에 직접 체크아웃하거나 아티팩트를 특정 경로에 복사해서 실행하는 방식이라면, 해당 경로에 node_modules도, package.json도 없는 상태가 될 수 있다.
이 경우 선택지는 크게 세 가지였다.
package.json을 배포 경로에 함께 복사한다cd로package.json이 있는 경로로 이동 후 실행한다npm run을 쓰지 않고node로 직접 실행한다
첫 번째는 관리 포인트가 늘어난다. 두 번째는 워크플로우 내 경로 의존성이 생긴다. 세 번째가 이번 케이스에선 가장 깔끔하고, 빌드 스크립트가 독립적으로 실행 가능한 구조라면 자연스러운 선택이다.
팀 관점에서
이런 fix는 작업 크기로 보면 매우 작지만, 막혀 있던 배포 파이프라인을 풀어주는 것이기 때문에 팀 체감 임팩트는 크다. CI가 죽어있으면 다른 작업자들의 배포가 전부 블로킹되니까.
그리고 이런 문제는 대부분 "처음 배포 환경을 세팅할 때 한 번 제대로 확인했으면 됐던" 케이스다. 워크플로우 작성 시점에 실제 배포 경로의 디렉터리 구조를 직접 확인하거나, npm run을 쓰기 전에 해당 경로에 package.json이 있는지 체크하는 습관이 있었다면 애초에 안 터졌다.
배포 워크플로우는 로컬 재현이 어렵기 때문에, 한 번 잘못 들어가면 고치는 데 push → 실패 로그 확인 → 수정 → push 싸이클을 여러 번 돌게 된다. 귀찮더라도 실제 서버 환경을 미리 파악하고 짜는 게 맞다.
끝.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.