← 전체 글로 돌아가기

서버 운영

서버에서 npm install이 비정상적으로 느릴 때 확인한 것들

npm install이 로컬에서는 빠른데 서버에서만 오래 걸린다면 메모리 부족이나 DNS 문제가 원인인 경우가 많다.

배포 파이프라인에서 npm install 단계가 5분, 10분씩 걸리는 경우가 있다. 로컬에서는 1분도 안 걸리는데 서버에서만 느리다면 네트워크나 메모리를 먼저 본다.

메모리/스왑 확인

npm install은 패키지를 풀고 의존성 트리를 계산하면서 메모리를 꽤 쓴다. 서버 RAM이 부족하면 스왑을 쓰기 시작하고, 스왑은 디스크 I/O라서 극단적으로 느려진다.

free -h

Swap used가 수백 MB 이상이면 메모리 문제다. 실행 중인 프로세스를 확인해서 불필요한 것이 있으면 정리하거나, 스왑 크기를 늘리거나, 인스턴스를 업그레이드해야 한다.

# 메모리 많이 쓰는 프로세스 확인
ps aux --sort=-%mem | head -15

디스크 I/O

df -h          # 디스크 여유 공간
iostat -x 2    # 디스크 사용률 (sysstat 설치 필요)

%util이 계속 90% 이상이면 디스크가 병목이다. npm 캐시(~/.npm)가 오래되거나 깨진 경우 캐시를 지우면 오히려 빨라지는 경우도 있다.

npm cache clean --force

네트워크 문제

# npm 레지스트리 응답 속도 확인
curl -w "\nTotal: %{time_total}s\n" -o /dev/null -s https://registry.npmjs.org/react

응답이 수 초씩 걸린다면 레지스트리 자체 문제거나 서버의 DNS/라우팅 문제다. 국내에서 서버를 운영한다면 공식 레지스트리보다 미러를 쓰는 게 빠를 수 있다.

# 일회성으로 다른 레지스트리 사용
npm install --registry https://registry.npmjs.org

# 또는 설정 변경
npm config set registry https://registry.npmjs.org

npm install 대신 npm ci

CI/CD 환경에서 package-lock.json이 있다면 npm install 대신 npm ci를 쓰는 게 빠르고 안전하다. npm cinode_modules를 한 번 지우고 lock 파일에 명시된 버전만 설치하므로 의존성 해석 단계가 없다.

npm ci

단, package-lock.json이 없거나 package.json과 맞지 않으면 에러가 난다.

node_modules 캐시 레이어 활용

Dockerfile이라면 package.jsonpackage-lock.json만 먼저 복사해서 install하는 레이어를 분리한다. 코드만 바뀌고 의존성이 바뀌지 않은 경우 캐시된 레이어를 재사용해서 매번 설치를 건너뛸 수 있다.

COPY package.json package-lock.json ./
RUN npm ci

COPY . .
RUN npm run build

의존성 변경 빈도가 낮다면 이것만으로도 배포 시간이 크게 줄어든다.