반응형
npm install은 package.json에 정의된 의존성들을 설치해 node_modules를 만드는 명령입니다. 컨텍스트에 따라 로컬 개발, CI, Docker 이미지 빌드 등에서 동작과 권장 사용법이 다릅니다.
1) 기본 동작 (터미널에서)
npm install
- package.json의 dependencies와 devDependencies를 읽어서 node_modules에 패키지들을 설치.
- package-lock.json(또는 npm-shrinkwrap.json)이 있으면 잠금 파일을 참고해 정확한 버전으로 설치하려고 시도(동일한 트리 재현).
- 설치 후 package-lock.json이 없으면 자동으로 생성/업데이트됨.
추가 옵션:
- npm install <pkg> : 특정 패키지 설치 (로컬).
- npm install -g <pkg> : 전역 설치.
- --save / --save-dev : 예전에는 필요했지만 최신 npm은 기본으로 dependencies에 추가. --save-dev는 개발용으로 devDependencies에 추가.
- --save-exact : 정확한 버전(=)으로 저장.
- --no-optional : optionalDependencies 설치 안 함.
- --only=production 또는 NODE_ENV=production npm install : devDependencies 제외(프로덕션 빌드).
- --legacy-peer-deps : peer dependency 충돌 무시(일부 최신 npm에서 필요).
- --silent / --no-audit 등 로그/감사 무시 옵션들.
실행 결과:
- node_modules/ 생성(혹은 업데이트)
- package-lock.json 생성/수정
- postinstall / 기타 lifecycle 스크립트(예: 빌드, 바이너리 설치) 실행
2) npm install vs npm ci
- npm install : 유연. package-lock.json이 있어도 package.json의 범위에서 필요한 변경을 할 수 있고 잠금파일을 업데이트할 수 있음.
- npm ci : CI 및 재현 가능한 빌드용. package-lock.json이 없으면 실패. node_modules를 삭제하고 잠금파일에 정확히 맞춰 설치(더 빠르고 안정적).
- 권장: CI, Docker 프로덕션 이미지 빌드시 npm ci --only=production 사용.
3) Dockerfile에서의 사용(권장 패턴)
Docker 이미지 빌드시 캐시 활용과 이미지를 작게 만드는 것이 중요합니다.
권장 Dockerfile(예시):
FROM node:20-alpine AS builder
WORKDIR /app
# package.json, package-lock.json만 먼저 복사 (의존성 변경 시에만 레이어 재설치)
COPY package*.json ./
# CI 스타일 설치 (devDependencies 포함해서 빌드 필요시)
RUN npm ci
# 앱 소스 복사 및 빌드
COPY . .
RUN npm run build
# 프로덕션 이미지 (멀티스테이지)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# package.json/lock만 복사해서 프로덕션 의존성만 설치
COPY package*.json ./
RUN npm ci --only=production
# 빌드 산출물 복사
COPY --from=builder /app/dist ./dist
# 사용자 권한 변경 (root 대신 비루트 권장)
USER node
CMD ["node", "dist/index.js"]
WORKDIR /app
# package.json, package-lock.json만 먼저 복사 (의존성 변경 시에만 레이어 재설치)
COPY package*.json ./
# CI 스타일 설치 (devDependencies 포함해서 빌드 필요시)
RUN npm ci
# 앱 소스 복사 및 빌드
COPY . .
RUN npm run build
# 프로덕션 이미지 (멀티스테이지)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# package.json/lock만 복사해서 프로덕션 의존성만 설치
COPY package*.json ./
RUN npm ci --only=production
# 빌드 산출물 복사
COPY --from=builder /app/dist ./dist
# 사용자 권한 변경 (root 대신 비루트 권장)
USER node
CMD ["node", "dist/index.js"]
핵심 포인트:
- COPY package*.json ./ 먼저 해서 의존성 설치가 코드 변경마다 재실행되는 것을 방지(레이어 캐싱).
- 빌드 단계와 런타임 단계를 분리(멀티스테이지)해 런타임 이미지 크기 축소.
- npm ci 사용: 재현성 보장, 빠름.
- NODE_ENV=production 설정으로 devDependencies 설치 방지.
- 가능하면 non-root 유저로 실행.
4) 성능/용량 최적화 팁
- npm ci --only=production으로 devDependencies 제외.
- --no-optional로 optionalDependencies 제거.
- npm pack + 복원 방식(특수 상황)으로 필요 패키지만 포함.
- node_modules를 이미지에 모두 넣지 않고 빌드 산출물(번들, transpile 결과)만 포함.
- npm prune --production으로 dev 의존성 제거(로컬에서 실수로 설치했을 때).
- 캐시: CI에서 npm 캐시 경로를 캐싱하면 설치 속도 향상 (~/.npm).
5) 보안 및 감사
- npm audit : 취약점 검사
- npm audit fix : 자동 패치 시도(주의: 자동 변경이 생길 수 있음)
- 프로덕션에서는 자동 업그레이드 / 패치 전에 테스트 필수.
6) 자주 발생하는 오류와 해결 방법
- EACCES (권한 오류)
- 원인: 글로벌 설치 시 패키지 디렉터리 권한 문제.
- 해결: sudo 사용(권장 X), npm 글로벌 디렉토리 변경, 또는 nvm 사용으로 사용자 권한 관리.
- ENOSPC / ENOMEM (디스크/메모리 부족)
- 원인: 디스크 공간 부족 또는 메모리 부족(특히 Docker 빌드).
- 해결: 디스크 정리, 도커 빌드에 더 많은 메모리 할당.
- network timeout / 504 / registry errors
- 원인: 네트워크/프록시/회사 방화벽.
- 해결: npm config set registry https://registry.npmjs.org/ 재설정, 프록시 설정, 사내 레지스트리(Artifactory, Nexus) 사용.
- peer dependency conflicts
- 원인: 라이브러리 간 peerDependencies 불일치.
- 해결: 버전 맞추기, --legacy-peer-deps로 임시 회피, 장기 해결은 패키지 버전 조정.
- postinstall 실패 (빌드 스크립트 실패)
- 원인: 네이티브 빌드 도구(심볼릭, node-gyp) 또는 환경변수 누락.
- 해결: 필요한 빌드툴(파이썬, make, g++ 등) 설치, 환경 설정.
7) package-lock.json의 중요성
- 동일한 의존성 트리를 재현하려면 반드시 커밋하고 사용.
- CI와 프로덕션 빌드에서는 npm ci + package-lock.json이 필수적.
8) 라이프사이클 훅 (설치 과정에 실행되는 스크립트)
- preinstall → install → postinstall → prepublishOnly 등.
- 패키지에 따라 설치 시 빌드나 바이너리 다운로드가 트리거될 수 있음(예: node-sass, sharp).
9) 실용 예제 (로컬에서 프로덕션 설치)
# 프로덕션 환경에서 devDependencies 없이 설치 NODE_ENV=production npm install # 또는 npm install --only=production
10) 요약된 권장사항
- 로컬 개발: npm install (혹은 npm ci로 잠금파일 기반 재현 설치)
- CI/빌드: npm ci
- Docker 프로덕션 이미지: 멀티스테이지 + npm ci --only=production + package*.json 먼저 복사
- 항상 package-lock.json 커밋
- 오류 발생 시 로그(에러 메시지) 보고 권한/네트워크/메모리/peer-deps 순으로 점검
반응형
'[AWS-FRF] > CICD' 카테고리의 다른 글
| [참고][Docker] Spring Boot 프로젝트를 Docker 이미지로 만들기 !! (0) | 2025.11.06 |
|---|---|
| clean package -DskipTests 정의 !! (1) | 2025.11.04 |
| [참고][Docker] 스프링부트 프로젝트 도커 이미지(Image) 만들고 실행하기 !! (0) | 2025.11.03 |
| [참고][Docker] Dockerfile 작성법 !! (Jar파일 실행 이미지 만들기) (1) | 2025.11.03 |
| [참고] Jenkins를 활용한 CI/CD 파이프라인 구축 (GitHub → Docker → ECR 업로드) (1) | 2025.10.30 |
| [docker builder prune] Docker 빌드 캐시(build cache) 및 중간 이미지 정리!! (1) | 2025.10.29 |
| [참고][Jenkins] Docker build 후 Amazon ECR로 이미지 업로드하기 !! (0) | 2025.10.29 |
| [참고][AWS][Jenkins] 변경된 설정을 이력으로 남기기 (config history)!! (8) | 2025.01.21 |
댓글