엔터프라이즈 환경에서 젠킨스(Jenkins) 서버 단 1대로 수십 개의 파이프라인을 운영하다 보면 필연적으로 '버전 충돌(Version Conflict)'이라는 거대한 장벽에 부딪히게 됩니다. 가장 대표적인 생태계가 바로 프론트엔드의 Node.js 입니다. 5년 전에 만들어진 구형 레거시 어드민 프로젝트는 반드시 Node.js v14 환경에서만 빌드되며, 오늘 새로 런칭한 최신 React 프로젝트는 Node.js v20 환경을 요구합니다. 만약 젠킨스 호스트 서버 리눅스에 apt-get install nodejs로 14 버전을 깔아버리면 새 프로젝트가 빌드 에러를 뿜고, 20 버전으로 올려버리면 레거시 프로젝트가 죽어버립니다.
이번 [Jenkins 실무 완벽 가이드] 시리즈에서는 인프라 엔지니어를 골머리 앓게 만드는 "하나의 젠킨스 서버에서 수십 가지의 Node.js 버전을 충돌 없이 동적으로 스위칭하는 마법의 베스트 프랙티스"에 대하여 3,000자 분량으로 아주 치밀하게 딥다이브 해보겠습니다.

🚫 1. nvm(Node Version Manager)의 치명적 함정
로컬 PC에서 개발할 때는 nvm을 설치하여 nvm use 14, nvm use 20 처럼 자유롭게 버전을 바꿉니다. 하지만 이를 젠킨스 쉘 스크립트(sh) 안에서 사용하려고 하면 십중팔구 "nvm: command not found" 에러를 맞고 좌절하게 됩니다.
젠킨스의 sh 스텝은 기본적으로 /bin/sh -xe 기반의 비대화형(Non-interactive) 쉘로 동작하기 때문에, 사용자의 .bashrc나 .zshrc에 등록된 nvm 초기화 스크립트를 전혀 읽어오지 못합니다. 억지로 스크립트 안에 nvm을 로드하는 코드를 덕지덕지 바를 수도 있지만, 이는 유지보수 관점에서 최악의 안티 패턴(Anti-pattern)입니다.
⚙️ 2. 정석 해결책: Global Tool Configuration (글로벌 툴)
젠킨스는 이러한 다중 버전 관리 문제를 해결하기 위해 전역 도구(Global Tool)라는 아주 훌륭한 시스템을 기본 내장하고 있습니다.
- 플러그인 설치: [플러그인 관리]에서
NodeJS Plugin을 검색하여 설치합니다. - 버전 등록: [Jenkins 관리] -> [Global Tool Configuration] 메뉴로 들어가면 NodeJS 섹션이 생겨 있습니다. 여기서
Add NodeJS버튼을 여러 번 눌러 필요한 버전들을 세팅합니다. - 식별자 명명:
- Name:
Node-14/ Version:NodeJS 14.21.3 - Name:
Node-18/ Version:NodeJS 18.17.1 - Name:
Node-20/ Version:NodeJS 20.10.0
- Name:
이렇게 등록하고 저장해두면, 젠킨스가 알아서 인터넷에서 해당 버전의 Node.js 바이너리를 다운받아 자체적인 캐시 폴더에 예쁘게 보관해 둡니다.
💻 3. tools 블록으로 파이프라인에 주입하기
이제 여러분의 Jenkinsfile 최상단에 tools 블록을 열고, 아까 등록했던 식별자 이름(Name)을 그대로 적어주기만 하면 끝납니다. 젠킨스는 파이프라인이 시작될 때 해당 버전의 Node.js 경로를 시스템 PATH 환경변수 최우선 순위로 밀어 넣어버립니다.
pipeline {
agent any
// 🌟 핵심: Global Tool에 등록된 'Node-18' 환경을 이 파이프라인 전체에 주입합니다.
tools {
nodejs 'Node-18'
}
stages {
stage('Check Version') {
steps {
// 이 스텝에서 실행되는 node는 무조건 호스트 서버의 버전이 아닌 18 버전이 됩니다.
sh 'node -v' // 출력: v18.17.1
sh 'npm -v'
}
}
stage('Build React App') {
steps {
sh 'npm ci'
sh 'npm run build'
}
}
}
}
🚀 4. 고급 심화: Docker Agent를 활용한 궁극의 격리
만약 글로벌 툴 세팅조차 귀찮고, 서버에 어떠한 파일도 남기기 싫다면 9단계에서 배웠던 Docker Agent 방식이 최고의 베스트 프랙티스입니다. 각 파이프라인마다 자신에게 딱 맞는 도커 이미지를 입고 빌드한 뒤 사라지면 됩니다.
pipeline {
// 🌟 궁극의 격리: Docker Hub에 있는 공식 Node.js 20 버전 컨테이너 안에서 빌드합니다.
agent {
docker {
image 'node:20.10-alpine'
// npm 캐시를 유지하기 위한 볼륨 마운트 (27단계 참고)
args '-v $HOME/.npm:/root/.npm'
}
}
stages {
stage('Build') {
steps {
sh 'node -v' // 출력: v20.10.x
sh 'npm ci && npm run build'
}
}
}
}
실무에서는 프론트엔드 프로젝트들이 아주 빠르게 버전을 업데이트하므로, Global Tool 방식보다는 Docker Agent 방식을 압도적으로 선호합니다. 개발자가 Jenkinsfile의 image 'node:20' 숫자 하나만 바꾸면 즉각적으로 환경이 업그레이드되기 때문입니다.
🎯 5. 마무리 및 다음 단계
지금까지 수많은 언어와 버전이 얽히고설킨 끔찍한 스파게티 서버 환경을 방지하고, 젠킨스의 Global Tool과 Docker Agent를 활용하여 100% 무결점 샌드박스 빌드 환경을 제공하는 Node.js 파이프라인 구축 비법에 대해 3,000자 분량으로 밀도 있게 다루어 보았습니다. 이제 어떤 프로젝트가 들어와도 버전 충돌 걱정 없이 깔끔하게 빌드할 수 있습니다.
열심히 빌드해서 build/ 폴더 안에 훌륭한 .zip 결과물이나 .jar 파일을 만들어 냈습니다. 그런데 파이프라인이 끝나는 순간 젠킨스 워크스페이스가 싹 지워지면서 이 결과물도 함께 우주로 날아가 버린다면 어떨까요? 나중에 운영 서버 배포가 실패해서 "어제 만든 이전 버전 파일로 급하게 롤백(Rollback)해줘!"라고 요청이 왔을 때 식은땀을 흘리게 될 것입니다. 이어지는 36단계 포스팅에서는 "빌드된 결과물(전리품)은 무조건 안전한 금고에 보관하라!" 과거의 자산을 소중하게 지켜주는 'Artifact(아티팩트) 보관 및 다운로드 기술'에 대해 아주 치밀하게 파헤쳐 보겠습니다!
'CI.CD > Jenkins' 카테고리의 다른 글
| [Jenkins] Artifact(아티팩트) 보관: 롤백을 위한 최후의 구명조끼 (0) | 2026.07.22 |
|---|---|
| [Jenkins] GitHub PR(Pull Request) 빌드 자동화 구축하기 (0) | 2026.07.22 |
| [Jenkins] Maven / Gradle 빌드 캐시 최적화 (빌드 시간 10배 단축의 비밀) (0) | 2026.07.22 |
| [Jenkins] 주기적 빌드(Cron Trigger) 완벽 가이드: 휴먼 리소스 제로화 (0) | 2026.07.22 |
| [Jenkins] Jenkins 백업 스크립트의 정석 (서버가 불타도 3분 만에 부활하기) (0) | 2026.07.22 |