개발 도구

Jenkins Pipeline에서 Node.js 버전 고정하는 방법 — tools 블록과 NodeJS 플러그인 설정

Jenkins 빌드 환경에서 서버 Node.js 버전에 끌려다니지 않으려면 Jenkinsfile tools 블록에 버전을 명시해야 한다. NodeJS 플러그인 설치부터 버전 고정까지 정리했다.

JenkinsNode.jsPipelinetoolsCI/CD
Jenkins Pipeline tools 블록에 Node.js 버전을 고정하는 방법을 설명하는 Jenkinsfile 코드 예시
  • ·NodeJS 플러그인: Jenkins 공식 플러그인, Update Center에서 설치 가능
  • ·tools 블록 위치: pipeline > agent 아래, stages 블록 앞
  • ·Global Tool Configuration: Manage Jenkins → Tools에서 설정
  • ·이름 일치 필수: tools 블록 이름과 Global Tool Configuration 등록 이름이 정확히 같아야 함
Next.js 파이프라인이 코드 변경 없이 갑자기 실패하기 시작해서 원인을 찾아보니 서버 Node.js가 18에서 20으로 올라가면서 의존성 충돌이 생긴 것이었다. 그 이후 NodeJS 플러그인을 설치하고 tools 블록에 버전을 고정했더니 서버 환경이 바뀌어도 빌드 환경이 흔들리지 않게 됐다. 처음에 Global Tool Configuration에서 등록한 이름과 Jenkinsfile의 이름이 공백 하나 차이로 달라서 오류가 났는데, 이름을 복사해서 붙여넣으니 바로 해결됐다.

Jenkins Pipeline에서 Node.js 버전 문제가 생기는 이유

Jenkins 빌드 환경에서 Node.js 버전이 달라지는 문제

Jenkins가 설치된 서버에는 대부분 시스템 Node.js가 이미 깔려 있다. 별도로 설정하지 않으면 Jenkins 파이프라인은 빌드할 때 서버에 설치된 Node.js를 그대로 가져다 쓴다. 문제는 서버 환경이 바뀔 때마다 빌드가 영향을 받는다는 점이다. 서버 관리자가 다른 프로젝트 때문에 Node.js 버전을 올리거나, OS 업데이트 과정에서 버전이 교체되면 아무 코드 변경 없이 빌드가 갑자기 실패하는 상황이 생긴다. 실제로 Next.js 파이프라인이 멀쩡히 돌다가 어느 날 갑자기 npm ci에서 오류가 났고, 원인을 추적하고 보니 서버 Node.js가 18에서 20으로 올라가면서 특정 패키지의 peer dependency 충돌이 생긴 것이었다. 코드는 전혀 바뀌지 않았는데 빌드가 깨지면 원인을 찾는 데 시간이 많이 걸린다. 팀원이 로컬에서 Node.js 18로 개발하고 있는데 CI 서버가 다른 버전을 쓴다면 로컬에서는 통과하는 빌드가 Jenkins에서는 실패하는 환경 불일치 문제도 생길 수 있다. Jenkinsfile 안에서 직접 버전을 명시하면 서버에 어떤 버전이 설치되어 있든 상관없이 항상 지정한 버전으로 빌드 환경이 구성된다.

Jenkins Pipeline tools 블록이 Node.js 버전 고정에 쓰이는 이유

Jenkins는 Jenkinsfile의 tools 블록을 통해 빌드에 필요한 도구 버전을 명시적으로 선언할 수 있다. tools 블록에 Node.js 버전을 지정하면 Jenkins는 파이프라인 실행 시 Global Tool Configuration에서 등록한 버전을 자동으로 가져와 빌드 환경을 구성한다. 서버에 Node.js가 여러 버전 설치되어 있어도, 혹은 아예 없어도 tools 블록에 지정한 버전이 사용된다. 이 방식의 장점은 Jenkinsfile 자체가 빌드 환경의 명세서 역할을 한다는 점이다. 코드를 보는 것만으로 이 프로젝트가 어떤 Node.js 버전에서 빌드되는지 바로 알 수 있다. tools 블록을 사용하기 위해서는 Jenkins에 NodeJS 플러그인이 설치되어 있어야 하고, Manage Jenkins의 Global Tool Configuration에서 사용할 버전을 미리 등록해두어야 한다. Jenkinsfile의 tools에 쓰는 이름은 Global Tool Configuration에서 등록할 때 입력한 이름과 정확히 일치해야 한다. 이름이 조금이라도 다르면 파이프라인 실행 시 도구를 찾지 못했다는 오류가 나고 빌드가 시작조차 안 된다.

Jenkins NodeJS 플러그인 설치와 버전 등록

Jenkins에 NodeJS 플러그인 설치하는 방법

NodeJS 플러그인은 Jenkins 관리 화면에서 직접 설치할 수 있다. Manage Jenkins → Plugins → Available plugins로 이동한다. 검색창에 'NodeJS'를 입력하면 해당 항목이 나타난다. 체크하고 Install 버튼을 누르면 설치가 시작된다. 설치 완료 후 Jenkins를 재시작할지 묻는 옵션이 나오는데, 재시작을 권장한다. 인터넷이 차단된 내부망 환경이라면 플러그인 파일(.hpi)을 직접 다운로드해서 올리는 방식으로 설치할 수도 있다. Manage Jenkins → Plugins → Advanced settings에서 .hpi 파일을 업로드하면 된다. 플러그인을 처음 설치하고 나서 Manage Jenkins 메뉴를 다시 열어보면 Tools 항목 안에 NodeJS 설정 섹션이 새로 생긴 것을 확인할 수 있다. 플러그인이 정상 설치됐다는 신호다. 설치 후 반드시 Global Tool Configuration에서 버전을 등록하는 단계로 넘어가야 tools 블록이 실제로 동작한다.

Jenkins Global Tool Configuration에서 Node.js 버전 등록하기

플러그인 설치가 끝나면 사용할 Node.js 버전을 Jenkins에 등록해야 한다. Manage Jenkins → Tools로 이동하면 하단에 NodeJS 섹션이 생겨 있다. 'Add NodeJS' 버튼을 클릭한다. Name 필드에는 Jenkinsfile의 tools 블록에서 참조할 이름을 입력한다. 예를 들어 'NodeJS 18'이라고 입력하면, Jenkinsfile에서도 nodejs 'NodeJS 18'이라고 정확히 같은 이름을 써야 한다. Version 드롭다운에서 원하는 버전을 선택한다. 'Install automatically' 옵션이 체크되어 있으면 Jenkins가 첫 빌드 실행 시 자동으로 해당 버전을 내려받아 설치해준다. 프로젝트마다 다른 Node.js 버전이 필요하다면 'NodeJS 18', 'NodeJS 20'처럼 여러 버전을 등록해두고 각 Jenkinsfile에서 필요한 버전을 참조하면 된다. 처음에 이름을 'nodejs18'로 등록하고 Jenkinsfile에는 'NodeJS 18'로 썼다가 대소문자와 공백 차이 때문에 오류가 난 적이 있다. 이름은 공백과 대소문자까지 완전히 일치해야 한다.

Jenkinsfile tools 블록으로 Node.js 버전 고정하기

Jenkinsfile tools 블록에 Node.js 버전 지정하는 방법

tools 블록은 Jenkinsfile의 pipeline { } 안에서 agent 선언 아래, stages { } 블록 앞에 위치한다. tools { nodejs 'NodeJS 18' } 형태로 작성하면 된다. 여기서 'NodeJS 18'은 Global Tool Configuration에서 등록한 이름과 정확히 일치해야 한다. tools 블록이 선언되면 파이프라인의 모든 stage에서 해당 Node.js 버전을 자동으로 사용할 수 있다. sh 'node --version'을 실행하면 지정한 버전이 출력되는 걸 확인할 수 있다. tools 블록에는 Node.js 외에도 Maven, JDK, Git 같은 도구를 함께 선언할 수 있다. 기존 Jenkinsfile에 tools 블록이 없었다면 agent any 아래에 한 줄 추가하는 것만으로 설정이 완료된다. cron 트리거나 다른 블록이 이미 있어도 tools는 독립적인 블록이라 순서대로 추가하면 된다.

pipeline {
  agent any
  tools { nodejs 'NodeJS 18' }
  stages {
    stage('Checkout') { steps { checkout scm } }
    stage('Verify')   { steps { sh 'node --version && npm --version' } }
    stage('Install')  { steps { sh 'npm ci' } }
    stage('Build')    { steps { sh 'npm run build' } }
  }
}

Jenkins Pipeline에서 Node.js 버전 고정 후 확인하는 방법

tools 블록을 추가한 뒤 파이프라인을 실행하면 빌드 로그에서 버전 설치 과정을 확인할 수 있다. 처음 실행할 때 'Install automatically'가 체크된 버전이라면 로그에 해당 버전을 내려받는 과정이 찍힌다. 이미 캐시된 버전이라면 바로 경로를 잡아주는 메시지가 나온다. 버전이 제대로 설정됐는지 확인하는 가장 간단한 방법은 파이프라인 초반 stage에 sh 'node --version'을 추가하는 것이다. 빌드 로그에서 'v18.x.x'처럼 의도한 버전이 출력되는 걸 확인하면 된다. 만약 여전히 서버의 시스템 Node.js 버전이 찍힌다면 tools 블록의 이름이 Global Tool Configuration 등록 이름과 다른 경우가 대부분이다. 이름을 복사해서 붙여넣으면 오타 실수를 방지할 수 있다. 버전 고정이 완료되면 서버 Node.js 버전이 바뀌어도 해당 파이프라인은 항상 동일한 버전으로 빌드된다. 다른 팀원이 서버에 접속해서 시스템 Node.js를 건드려도 이 파이프라인에는 영향이 없다.

자주 묻는 질문

tools 블록에 지정한 이름이 맞는 것 같은데도 오류가 나면 어떻게 하나요?+

Manage Jenkins → Tools에서 등록한 이름을 복사해서 Jenkinsfile에 붙여넣어 보세요. 공백이나 대소문자 차이가 원인인 경우가 많습니다. 그래도 안 된다면 'Install automatically'가 체크되어 있는지, Jenkins가 인터넷에 접근 가능한지 확인하세요.

프로젝트마다 다른 Node.js 버전을 써야 하면 어떻게 하나요?+

Global Tool Configuration에서 'NodeJS 18', 'NodeJS 20'처럼 버전별로 이름을 다르게 등록해두면 됩니다. 각 Jenkinsfile에서 tools { nodejs 'NodeJS 18' } 또는 tools { nodejs 'NodeJS 20' }처럼 다르게 지정하면 프로젝트마다 독립적으로 버전을 관리할 수 있습니다.

tools 블록 없이 sh 'nvm use 18' 방식으로 해도 되나요?+

가능은 하지만 권장하지 않습니다. nvm은 interactive shell에서 동작하는 방식이라 Jenkins 빌드 환경에서는 제대로 적용이 안 되는 경우가 있습니다. tools 블록을 사용하는 것이 Jenkins 공식 방식이고 가장 안정적입니다.

NodeJS 플러그인 없이 tools 블록을 쓸 수 있나요?+

없습니다. tools 블록에서 nodejs를 사용하려면 NodeJS 플러그인이 반드시 설치되어 있어야 합니다. 플러그인이 없으면 파이프라인 실행 시 'No tool named NodeJS' 같은 오류가 납니다.

관련 글