setup-node의 npm 캐시가 복원돼도 node_modules가 설치됐다는 뜻은 아닙니다. 이 캐시는 패키지 관리자의 다운로드 데이터를 재사용하는 기능이므로 실제 프로젝트 폴더에서 npm ci 같은 설치 단계가 필요합니다. 캐시가 맞았다는 이유로 설치를 건너뛰었다면 먼저 그 조건을 제거하고, lockfile 위치와 명령 실행 경로를 맞추세요.
자료 확인 기준일은 2026년 10월 13일입니다. 아래 예시는 공식 문서를 바탕으로 작성한 설계·점검 예이며, 이 글에서 실제 계정이나 서버에 실행한 시험 결과는 아닙니다.
원인: 다운로드 캐시와 설치된 의존성 폴더를 혼동합니다
setup-node 문서는 전역 패키지 데이터를 캐시하며 node_modules를 캐시하지 않는다고 설명합니다. 다운로드 캐시가 있다는 것은 설치에 재사용할 데이터가 있다는 의미입니다. 현재 작업 폴더에 의존성이 생성됐는지는 별도 설치 결과로 확인해야 합니다.
따라서 ‘캐시 복원 메시지는 정상인데 Cannot find module 또는 빌드 도구를 찾을 수 없음’이라는 상황에서는 캐시 삭제보다 설치 단계·폴더·의존성 종류를 먼저 확인하는 것이 합리적입니다. 캐시 문제로 단정하고 매번 새 캐시를 만드는 것은 원인을 확인하는 절차가 아닙니다.
| 관찰한 증상 | 먼저 확인할 원인 | 다음 확인 |
| 캐시는 복원, 모듈은 없음 | 캐시 성공 때 설치를 건너뜀 | npm ci가 실제 실행됐는지 로그 확인 |
| lockfile을 찾지 못함 | 캐시 경로 또는 작업 폴더가 다름 | package-lock.json의 저장 위치 대조 |
| npm ci 자체가 실패 | manifest와 lockfile 불일치 또는 설치 옵션 차이 | 첫 오류와 lockfile 생성 조건 확인 |
| 앱 실행 의존성은 있음, 빌드 도구는 없음 | devDependencies 제외 설정 | NODE_ENV·omit 설정과 빌드 단계 목적 확인 |
해결 절차 1: 캐시 경로와 명령 실행 경로를 맞춥니다
예를 들어 저장소 루트의 .nvmrc로 Node 버전을 정하고 web 폴더에 package.json과 package-lock.json이 있다면, cache-dependency-path와 working-directory는 서로 다른 설정입니다. 앞의 값은 캐시 키에 사용할 의존성 파일을 지정하고 뒤의 값은 run 명령의 실행 위치를 정합니다.
아래는 저장소 checkout이 이미 끝났고, 루트 .nvmrc 및 web/package-lock.json이 실제 존재한다는 전제의 단계 예입니다. 2026년 10월 13일 확인한 공식 README의 setup-node@v7 표기를 사용했습니다. 실행 검증된 워크플로가 아니며 사용 중인 runner의 지원 조건도 확인해야 합니다.
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: web/package-lock.json
- name: Install dependencies
working-directory: web
run: npm ci
캐시가 복원된 경우에도 설치 단계가 실행되도록 두세요. 단일 프로젝트가 저장소 루트에 있다면 web 경로를 그대로 복사하지 말고 실제 파일 위치에 맞춥니다. 모노레포의 다른 패키지를 설치해야 하는 경우도 해당 실행 폴더의 manifest와 lockfile을 짝지어 확인합니다.
명시적인 Node 버전은 프로젝트가 사용하는 버전 정책과 일치해야 합니다. 액션 내부 실행 런타임과 프로젝트에서 선택한 Node 버전은 같은 개념이 아닙니다. runner와 액션 버전 요구를 임의의 프로젝트 버전 숫자로 대체하지 않습니다.
해결 절차 2: npm ci 실패를 lockfile과 함께 읽습니다
npm ci에는 lockfile이 필요합니다. package.json과 맞지 않으면 lockfile을 고치는 대신 오류로 종료하며 기존 node_modules가 있다면 설치 전에 제거합니다. CI에서 임의로 npm install로 바꿔 파일을 갱신하기보다, 개발 환경에서 변경 이유와 lockfile을 검토한 뒤 저장소에 반영하세요.
lockfile을 만들 때 사용한 설치 옵션이 트리 모양을 바꾸는 경우 CI에서도 필요한 설정을 일치시켜야 합니다. 해당 옵션을 확인하지 않고 경고를 모두 무시하거나 임의의 설치 플래그를 추가하면 재현 조건이 달라집니다. 공유한 설치 로그에서는 토큰·비공개 레지스트리 정보 등 비밀 값을 지웁니다.
다음은 web 폴더에서 실행할 읽기 위주의 점검 예입니다. 파일이 없는 폴더에서 실행하면 그 자체가 경로 불일치의 단서가 됩니다. 전체 환경 변수나 인증 설정 파일을 출력할 필요는 없습니다.
pwd
node --version
npm --version
npm config get cache
ls -l package.json package-lock.json
해결 절차 3: 빌드에 필요한 devDependencies를 확인합니다
npm의 omit 설정에 따라 devDependencies가 디스크 설치에서 제외될 수 있습니다. NODE_ENV가 production인 경우의 기본 동작도 확인하세요. 빌드 도구가 devDependencies에 있고 이를 제외한 폴더에서 빌드를 실행하면 모듈을 찾지 못할 수 있습니다.
빌드 단계와 배포 산출물 단계를 구분해 필요한 의존성을 설치하도록 설계합니다. 운영 배포의 의존성 정책을 무조건 넓히는 해결책으로 바꾸지 말고, 어떤 단계에서 어떤 도구가 필요한지 확인하세요. 설치가 성공했는데도 상대 경로의 파일을 찾지 못하면 누락된 소스·생성 파일·빌드 작업 폴더 문제로 범위를 옮깁니다.
확인 방법: 캐시 표시보다 설치와 빌드 결과를 봅니다
- 설치 단계가 건너뛰어지지 않았는지와 npm ci의 종료 결과를 확인합니다.
- 설치 로그의 작업 폴더가 의도한 package.json·lockfile 위치인지 확인합니다.
- 필요한 빌드 도구가 설치되는 설정인지 확인한 뒤 같은 폴더에서 빌드를 수행합니다.
- 비운영 브랜치에서 캐시가 없는 실행과 복원되는 실행을 비교하되 두 경우 모두 설치 단계를 유지합니다.
- 설치 오류와 후속 빌드 오류를 분리해 첫 실패 단계부터 원인을 기록합니다.
실제로 워크플로를 실행했다면 commit·runner·Node/npm 버전·첫 실패 단계와 종료 결과를 보존하세요. 이 글은 공식 문서에 근거한 점검 가이드이며 캐시 적중률·빌드 시간 절감·재현 성공 로그를 측정하지 않았습니다.
주의사항: 캐시를 인증 정보 저장소로 쓰지 않습니다
토큰이나 비밀 값을 캐시에 담지 마세요. 캐시 접근 범위와 브랜치·워크플로 관계는 GitHub의 공식 문서로 확인합니다. 캐시를 삭제하거나 키를 계속 바꾸기 전에 동일한 파일·설치 옵션·작업 경로로 재현 가능한지 먼저 판단해야 합니다.
npm ci는 기존 node_modules를 제거하므로 로컬에서 확인할 때도 작업 폴더와 변경 내용을 보존해야 합니다. CI 예제를 운영 서버의 의존성 폴더에 그대로 실행하는 방식으로 사용하지 않습니다.
FAQ
캐시가 맞으면 npm ci를 생략해도 되나요? setup-node의 npm 캐시만으로 node_modules가 설치되지는 않습니다. 설치 결과를 별도로 만들어야 합니다.
cache-dependency-path를 지정하면 run 폴더도 바뀌나요? 명령 실행 위치는 working-directory로 정합니다. 두 값의 역할을 구분하세요.
npm ci가 lockfile을 자동으로 고치나요? 불일치가 있으면 오류로 끝납니다. 개발 환경의 의존성 변경과 lockfile을 검토해 반영하세요.
공식 출처와 관련 글
함께 읽기: 설치 이후 배포 단계의 SSH 인증 오류 점검

'소프트웨어개발' 카테고리의 다른 글
| systemd 203/EXEC 해결: 실행 경로·권한·shebang·noexec 점검 순서 (0) | 2026.10.14 |
|---|---|
| Session Manager와 배스천 서버 비교: EC2 접속·SSH 키·감사 기록 선택 기준 (0) | 2026.10.14 |
| EventBridge Scheduler와 서버 cron 비교: 예약 작업 재시도·중복 실행·운영 비용 선택 (0) | 2026.10.14 |